diff --git a/android/app/src/main/cpp/app/organicmaps/Framework.cpp b/android/app/src/main/cpp/app/organicmaps/Framework.cpp index 7b47eef574..a943f83ac8 100644 --- a/android/app/src/main/cpp/app/organicmaps/Framework.cpp +++ b/android/app/src/main/cpp/app/organicmaps/Framework.cpp @@ -971,6 +971,48 @@ Java_app_organicmaps_Framework_nativeRemovePlacePageActivationListener(JNIEnv *e g_placePageActivationListener = nullptr; } +JNIEXPORT jlong JNICALL +Java_app_organicmaps_bookmarks_data_BookmarkManager_nativeFindBookmarkAtPoint(JNIEnv * env, jobject thiz, jdouble lat, jdouble lon) +{ +LOG(LINFO, ("Native: Searching for bookmark at", lat, lon)); + +auto * framework = g_framework->NativeFramework(); + +auto const mercatorPoint = mercator::FromLatLon(lat, lon); + +place_page::BuildInfo buildInfo; +buildInfo.m_mercator = mercatorPoint; + +framework->BuildAndSetPlacePageInfo(buildInfo); + +if (framework->HasPlacePageInfo()) +{ +auto const & placePageInfo = framework->GetCurrentPlacePageInfo(); +if (placePageInfo.IsBookmark()) +{ +auto bookmarkId = placePageInfo.GetBookmarkId(); +return static_cast(bookmarkId); +} +} + + +double const searchRadiusM = 2.0; +auto const & bmManager = framework->GetBookmarkManager(); + +auto const rect = mercator::RectByCenterXYAndSizeInMeters(mercatorPoint, searchRadiusM); +m2::AnyRectD searchRect(rect); + +auto const * userMark = bmManager.FindNearestUserMark(searchRect); + +if (userMark && userMark->GetMarkType() == UserMark::Type::BOOKMARK) +{ +auto const bookmarkId = userMark->GetId(); +return static_cast(bookmarkId); +} + +return -1; +} + JNIEXPORT jstring JNICALL Java_app_organicmaps_Framework_nativeGetGe0Url(JNIEnv * env, jclass, jdouble lat, jdouble lon, jdouble zoomLevel, jstring name) { diff --git a/android/app/src/main/java/app/organicmaps/MwmActivity.java b/android/app/src/main/java/app/organicmaps/MwmActivity.java index 128e367295..376f41553e 100644 --- a/android/app/src/main/java/app/organicmaps/MwmActivity.java +++ b/android/app/src/main/java/app/organicmaps/MwmActivity.java @@ -331,7 +331,6 @@ public class MwmActivity extends BaseMwmFragmentActivity if (intent != null && "app.organicmaps.action.SHOW_BOOKMARK".equals(intent.getAction())) { - boolean fromWidget = intent.getBooleanExtra("FROM_WIDGET", false); String bookmarkName = intent.getStringExtra("BOOKMARK_NAME"); double lat = intent.getDoubleExtra("BOOKMARK_LAT", Double.NaN); @@ -340,23 +339,15 @@ public class MwmActivity extends BaseMwmFragmentActivity if (!Double.isNaN(lat) && !Double.isNaN(lon)) { - try + BookmarkInfo nearestBookmark = BookmarkManager.INSTANCE.findBookmarkByCoordinates( + lat, lon, bookmarkName, categoryName + ); + + if (nearestBookmark != null) { - BookmarkInfo nearestBookmark = BookmarkManager.INSTANCE.findBookmarkByCoordinates( - lat, lon, bookmarkName, categoryName - ); - - if (nearestBookmark != null) - { - - BookmarkManager.INSTANCE.showBookmarkOnMap(nearestBookmark.getBookmarkId()); - return; - } - } catch (Exception e) - { - + BookmarkManager.INSTANCE.showBookmarkOnMap(nearestBookmark.getBookmarkId()); + return; } - Framework.nativeZoomToPoint(lat, lon, 16, true); } } diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/FavoriteBookmarkWidget.java b/android/app/src/main/java/app/organicmaps/bookmarks/FavoriteBookmarkWidget.java index d68b3d19e9..5093d3ae29 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/FavoriteBookmarkWidget.java +++ b/android/app/src/main/java/app/organicmaps/bookmarks/FavoriteBookmarkWidget.java @@ -13,7 +13,6 @@ import app.organicmaps.R; import app.organicmaps.bookmarks.data.BookmarkCategory; import app.organicmaps.bookmarks.data.BookmarkInfo; import app.organicmaps.bookmarks.data.BookmarkManager; -import app.organicmaps.bookmarks.data.Icon; public class FavoriteBookmarkWidget extends AppWidgetProvider { @@ -55,7 +54,6 @@ public class FavoriteBookmarkWidget extends AppWidgetProvider bookmarkInfo = BookmarkManager.INSTANCE.findBookmarkByCoordinates(lat, lon, bookmarkName, categoryName); } - // Always set the bookmark name, using stored name as fallback String displayName = bookmarkInfo != null ? bookmarkInfo.getName() : (bookmarkName != null && !bookmarkName.isEmpty() ? bookmarkName : context.getString(R.string.select_bookmark)); @@ -64,7 +62,6 @@ public class FavoriteBookmarkWidget extends AppWidgetProvider if (bookmarkInfo != null) { - int color = iconColor != 0 ? iconColor : bookmarkInfo.getIcon().getColor(); int iconResId = BookmarkManager.INSTANCE.getBookmarkIcon(bookmarkInfo.getBookmarkId()); if (iconResId == 0) @@ -119,19 +116,19 @@ public class FavoriteBookmarkWidget extends AppWidgetProvider { SharedPreferences.Editor prefs = context.getSharedPreferences(PREFS_NAME, 0).edit(); - prefs.putFloat(PREF_PREFIX_KEY + appWidgetId + SUFFIX_LAT, (float) bookmarkInfo.getLat()); prefs.putFloat(PREF_PREFIX_KEY + appWidgetId + SUFFIX_LON, (float) bookmarkInfo.getLon()); prefs.putString(PREF_PREFIX_KEY + appWidgetId + SUFFIX_NAME, bookmarkInfo.getName()); - - prefs.putString(PREF_PREFIX_KEY + appWidgetId + "_category_name", category.getName()); + prefs.putString(PREF_PREFIX_KEY + appWidgetId + SUFFIX_CATEGORY_NAME, category.getName()); + prefs.putLong(PREF_PREFIX_KEY + appWidgetId + "_bookmark_id", bookmarkInfo.getBookmarkId()); + prefs.putLong(PREF_PREFIX_KEY + appWidgetId + "_category_id", category.getId()); prefs.putString(PREF_PREFIX_KEY + appWidgetId + "_name_hash", String.valueOf(bookmarkInfo.getName().hashCode())); prefs.putString(PREF_PREFIX_KEY + appWidgetId + "_lat_lon_hash", String.valueOf((bookmarkInfo.getLat() + "," + bookmarkInfo.getLon()).hashCode())); - boolean success = prefs.commit(); + prefs.apply(); } @Override diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/data/BookmarkManager.java b/android/app/src/main/java/app/organicmaps/bookmarks/data/BookmarkManager.java index 9feafafd8c..0eaece47f2 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/data/BookmarkManager.java +++ b/android/app/src/main/java/app/organicmaps/bookmarks/data/BookmarkManager.java @@ -148,189 +148,26 @@ public enum BookmarkManager } @Nullable - public BookmarkInfo findBookmarkByCoordinates(double latitude, double longitude, @Nullable String name, @Nullable String categoryName) + public BookmarkInfo findBookmarkByCoordinates(double lat, double lon, @Nullable String name, @Nullable String categoryName) { - final double MAX_DISTANCE_TOLERANCE = 50.0; + long bookmarkId = nativeFindBookmarkAtPoint(lat, lon); - List categories = getCategories(); + if (bookmarkId == -1) + return null; - BookmarkInfo closestMatch = null; - double closestDistance = Double.MAX_VALUE; + BookmarkInfo info = getBookmarkInfo(bookmarkId); - for (BookmarkCategory category : categories) + if (info != null && + (name == null || name.isEmpty() || name.equals(info.getName())) && + (categoryName == null || categoryName.isEmpty() || + categoryName.equals(getCategoryById(info.getCategoryId()).getName()))) { - if (categoryName != null && !categoryName.isEmpty() && - !category.getName().equals(categoryName)) - { - continue; - } - - for (int i = 0; i < category.getBookmarksCount(); i++) - { - long bookmarkId = getBookmarkIdByPosition(category.getId(), i); - BookmarkInfo bookmarkInfo = getBookmarkInfo(bookmarkId); - - if (bookmarkInfo == null) - continue; - - boolean nameMatches = name == null || name.isEmpty() || - bookmarkInfo.getName().equals(name); - - double distance = calculateDistance(latitude, longitude, - bookmarkInfo.getLat(), - bookmarkInfo.getLon()); - - if (nameMatches && distance <= MAX_DISTANCE_TOLERANCE) - { - if (distance < closestDistance) - { - closestMatch = bookmarkInfo; - closestDistance = distance; - } - } - } - } - - return closestMatch; - } - - @Nullable - private BookmarkInfo findExactBookmarkByCoordinates(double lat, double lon, @Nullable String name, @Nullable String categoryName) - { - final double COORD_TOLERANCE = 0.0001; - - List categories = getCategories(); - - if (categoryName != null && !categoryName.isEmpty()) - { - for (BookmarkCategory category : categories) - { - if (categoryName.equals(category.getName())) - { - for (int i = 0; i < category.getBookmarksCount(); i++) - { - long bookmarkId = getBookmarkIdByPosition(category.getId(), i); - BookmarkInfo bookmark = getBookmarkInfo(bookmarkId); - - if (bookmark != null && - (name == null || name.isEmpty() || name.equals(bookmark.getName())) && - Math.abs(bookmark.getLat() - lat) < COORD_TOLERANCE && - Math.abs(bookmark.getLon() - lon) < COORD_TOLERANCE) - { - return bookmark; - } - } - } - } - } - - for (BookmarkCategory category : categories) - { - for (int i = 0; i < category.getBookmarksCount(); i++) - { - long bookmarkId = getBookmarkIdByPosition(category.getId(), i); - BookmarkInfo bookmark = getBookmarkInfo(bookmarkId); - - if (bookmark != null && - (name == null || name.isEmpty() || name.equals(bookmark.getName())) && - Math.abs(bookmark.getLat() - lat) < COORD_TOLERANCE && - Math.abs(bookmark.getLon() - lon) < COORD_TOLERANCE) - { - return bookmark; - } - } + return info; } return null; } - @Nullable - private BookmarkInfo findNearestBookmark(double lat, double lon, double maxDistanceMeters, - @Nullable String name, @Nullable String categoryName) - { - List categories = getCategories(); - BookmarkInfo closestBookmark = null; - double closestDistance = Double.MAX_VALUE; - - if (categoryName != null && !categoryName.isEmpty()) - { - for (BookmarkCategory category : categories) - { - if (categoryName.equals(category.getName())) - { - BookmarkInfo categoryResult = findNearestInCategory(category, lat, lon, - maxDistanceMeters, name, closestDistance); - if (categoryResult != null) - { - return categoryResult; - } - break; - } - } - } - - for (BookmarkCategory category : categories) - { - if (categoryName != null && !categoryName.isEmpty() && categoryName.equals(category.getName())) - { - continue; - } - - BookmarkInfo categoryResult = findNearestInCategory(category, lat, lon, - maxDistanceMeters, name, closestDistance); - if (categoryResult != null) - { - closestBookmark = categoryResult; - closestDistance = calculateDistance(lat, lon, closestBookmark.getLat(), closestBookmark.getLon()); - } - } - - return closestBookmark; - } - - @Nullable - private BookmarkInfo findNearestInCategory(BookmarkCategory category, double lat, double lon, - double maxDistanceMeters, @Nullable String name, double currentClosestDistance) - { - BookmarkInfo closestBookmark = null; - double closestDistance = currentClosestDistance; - - for (int i = 0; i < category.getBookmarksCount(); i++) - { - long bookmarkId = getBookmarkIdByPosition(category.getId(), i); - BookmarkInfo bookmark = getBookmarkInfo(bookmarkId); - - if (bookmark != null && (name == null || name.isEmpty() || name.equals(bookmark.getName()))) - { - double distance = calculateDistance(lat, lon, bookmark.getLat(), bookmark.getLon()); - - if (distance < closestDistance && distance <= maxDistanceMeters) - { - closestBookmark = bookmark; - closestDistance = distance; - } - } - } - - return closestBookmark; - } - - private double calculateDistance(double lat1, double lon1, double lat2, double lon2) - { - final double earthRadius = 6371000; - - double dLat = Math.toRadians(lat2 - lat1); - double dLon = Math.toRadians(lon2 - lon1); - - double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + - Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * - Math.sin(dLon / 2) * Math.sin(dLon / 2); - - double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); - - return earthRadius * c; - } - // Called from JNI. @Keep @SuppressWarnings("unused") @@ -927,6 +764,8 @@ public enum BookmarkManager return nativeGetElevationActivePointDistance(trackId); } + private native long nativeFindBookmarkAtPoint(double lat, double lon); + @Nullable private native Bookmark nativeUpdateBookmarkPlacePage(long bmkId); diff --git a/android/app/src/main/res/xml/favorite_bookmark_widget_info.xml b/android/app/src/main/res/xml/favorite_bookmark_widget_info.xml index 3f5fbf70ed..e3b645f908 100644 --- a/android/app/src/main/res/xml/favorite_bookmark_widget_info.xml +++ b/android/app/src/main/res/xml/favorite_bookmark_widget_info.xml @@ -9,4 +9,5 @@ android:widgetCategory="home_screen" android:description="@string/widget_description" android:configure="app.organicmaps.bookmarks.FavoriteBookmarkWidgetConfigActivity" /> + \ No newline at end of file