From 0caa02c50e61cc2dc307395392f23bf9243b552d Mon Sep 17 00:00:00 2001 From: Corwin-Kh Date: Thu, 20 Feb 2025 23:54:08 +0200 Subject: [PATCH] Implemented cache --- .../java/net/osmand/wiki/WikiCoreHelper.java | 7 ++- .../net/osmand/shared/data/KQuadRect.kt | 22 +++++++ .../plus/nearbyplaces/NearbyPlacesHelper.kt | 56 +++++++++++++++--- .../NearbyPlacesLoadSavedTask.java | 58 +++++++++++++++++++ .../plus/nearbyplaces/SaveNearbyPlacesTask.kt | 38 ++++++++++++ .../plus/search/GetNearbyPlacesImagesTask.kt | 4 +- .../search/listitems/NearbyPlacesCard.java | 4 +- 7 files changed, 176 insertions(+), 13 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/nearbyplaces/NearbyPlacesLoadSavedTask.java create mode 100644 OsmAnd/src/net/osmand/plus/nearbyplaces/SaveNearbyPlacesTask.kt diff --git a/OsmAnd-java/src/main/java/net/osmand/wiki/WikiCoreHelper.java b/OsmAnd-java/src/main/java/net/osmand/wiki/WikiCoreHelper.java index a9ad141c2ab..fd69a9b21ab 100644 --- a/OsmAnd-java/src/main/java/net/osmand/wiki/WikiCoreHelper.java +++ b/OsmAnd-java/src/main/java/net/osmand/wiki/WikiCoreHelper.java @@ -9,6 +9,7 @@ import net.osmand.data.Amenity; import net.osmand.data.QuadRect; import net.osmand.osm.io.NetworkUtils; +import net.osmand.shared.data.KQuadRect; import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; @@ -46,12 +47,12 @@ public class WikiCoreHelper { private static final List IMAGE_EXTENSIONS = new ArrayList<>(Arrays.asList(".jpeg", ".jpg", ".png", ".gif")); - public static List getExploreImageList(QuadRect mapRect, int zoom, String lang) { + public static List getExploreImageList(KQuadRect mapRect, int zoom, String lang) { List wikiImages = new ArrayList<>(); StringBuilder url = new StringBuilder(); String baseApiActionUrl = OSMAND_SEARCH_ENDPOINT + GET_WIKI_DATA_ACTION; - String northWest = String.format(Locale.US, "%f,%f", mapRect.top, mapRect.left); - String southEast = String.format(Locale.US, "%f,%f", mapRect.bottom, mapRect.right); + String northWest = String.format(Locale.US, "%f,%f", mapRect.getTop(), mapRect.getLeft()); + String southEast = String.format(Locale.US, "%f,%f", mapRect.getBottom(), mapRect.getRight()); url.append(baseApiActionUrl); try { url.append(String.format(Locale.US, "northWest=%s", URLEncoder.encode(northWest, "UTF-8"))); diff --git a/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/data/KQuadRect.kt b/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/data/KQuadRect.kt index 7ae71026d9d..146767a0838 100644 --- a/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/data/KQuadRect.kt +++ b/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/data/KQuadRect.kt @@ -58,6 +58,10 @@ class KQuadRect { return contains(box.left, box.top, box.right, box.bottom) } + fun contains(point: KLatLon): Boolean { + return point.latitude in left..right && point.longitude in top..bottom + } + companion object { fun intersects(a: KQuadRect, b: KQuadRect): Boolean { return kotlin.math.min(a.left, a.right) <= kotlin.math.max(b.left, b.right) @@ -109,6 +113,24 @@ class KQuadRect { return left == 0.0 && right == 0.0 && top == 0.0 && bottom == 0.0 } + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is KQuadRect) return false + + return left == other.left && + right == other.right && + top == other.top && + bottom == other.bottom + } + + override fun hashCode(): Int { + var result = left.hashCode() + result = 31 * result + right.hashCode() + result = 31 * result + top.hashCode() + result = 31 * result + bottom.hashCode() + return result + } + override fun toString(): String { return "[${left.toFloat()},${top.toFloat()} - ${right.toFloat()},${bottom.toFloat()}]" } diff --git a/OsmAnd/src/net/osmand/plus/nearbyplaces/NearbyPlacesHelper.kt b/OsmAnd/src/net/osmand/plus/nearbyplaces/NearbyPlacesHelper.kt index d163bad3a75..ef4dc88c9be 100644 --- a/OsmAnd/src/net/osmand/plus/nearbyplaces/NearbyPlacesHelper.kt +++ b/OsmAnd/src/net/osmand/plus/nearbyplaces/NearbyPlacesHelper.kt @@ -1,5 +1,6 @@ package net.osmand.plus.nearbyplaces +import android.os.AsyncTask import com.squareup.picasso.Picasso import net.osmand.ResultMatcher import net.osmand.binary.BinaryMapIndexReader @@ -11,28 +12,32 @@ import net.osmand.data.QuadRect import net.osmand.plus.OsmandApplication import net.osmand.plus.activities.MapActivity import net.osmand.plus.search.GetNearbyPlacesImagesTask -import net.osmand.plus.views.layers.ContextMenuLayer -import net.osmand.plus.views.layers.ContextMenuLayer.IContextMenuProvider import net.osmand.search.core.SearchCoreFactory +import net.osmand.shared.data.KLatLon +import net.osmand.shared.data.KQuadRect +import net.osmand.shared.util.KMapUtils import net.osmand.util.Algorithms import net.osmand.util.CollectionUtils import net.osmand.util.MapUtils import net.osmand.wiki.WikiCoreHelper.OsmandApiFeatureData import java.util.Collections +import kotlin.math.max import kotlin.math.min object NearbyPlacesHelper { private lateinit var app: OsmandApplication private var lastModifiedTime: Long = 0 - private const val PLACES_LIMIT = 50 + private const val PLACES_LIMIT = 50000 private const val NEARBY_MIN_RADIUS: Int = 50 - private var prevMapRect: QuadRect = QuadRect() + private var prevMapRect: KQuadRect = KQuadRect() private var prevZoom = 0 private var prevLang = "" fun init(app: OsmandApplication) { this.app = app + val loadSavedPlaces = NearbyPlacesLoadSavedTask(app) + loadSavedPlaces.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } private var listeners: List = Collections.emptyList() @@ -56,6 +61,7 @@ object NearbyPlacesHelper { .load(point.iconUrl) .fetch() } + SaveNearbyPlacesTask(app, it).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR) } updateLastModifiedTime() notifyListeners() @@ -82,15 +88,51 @@ object NearbyPlacesHelper { return this.dataCollection ?: Collections.emptyList() } + fun onCacheLoaded(cachedPLaces: List) { + if (!Algorithms.isEmpty(cachedPLaces)) { + val firstPoint = cachedPLaces[0] + val qRect = KQuadRect( + firstPoint.latitude, + firstPoint.longitude, + firstPoint.latitude, + firstPoint.longitude) + cachedPLaces.forEach { _ -> + qRect.left = min(firstPoint.latitude, qRect.left) + qRect.right = max(firstPoint.latitude, qRect.right) + qRect.top = min(firstPoint.longitude, qRect.top) + qRect.left = min(firstPoint.longitude, qRect.bottom) + } + dataCollection = cachedPLaces + prevMapRect = qRect + } + } + + fun getDataCollection(rect: QuadRect): List { + val qRect = KQuadRect(rect.left, rect.top, rect.right, rect.bottom) + val fullCollection = this.dataCollection ?: Collections.emptyList() + return fullCollection.filter { qRect.contains(KLatLon(it.latitude, it.longitude)) } + } + fun startLoadingNearestPhotos() { val mapView = app.osmandMap.mapView - val mapRect = mapView.currentRotatedTileBox.latLonBounds + var rect = QuadRect(mapView.currentRotatedTileBox.latLonBounds) + val qRect = KQuadRect(rect.left, rect.top, rect.right, rect.bottom) +// var mapRect = calculatedRect +// mapRect.left = get31LongitudeX(calculatedRect.left.toInt()) +// mapRect.top = get31LatitudeY(calculatedRect.top.toInt()) +// mapRect.right = get31LongitudeX(calculatedRect.right.toInt()) +// mapRect.bottom = get31LatitudeY(calculatedRect.bottom.toInt()) +// Log.d("Corwin", "startLoadingNearestPhotos: ${mapRect}") + var preferredLang = app.settings.MAP_PREFERRED_LOCALE.get() if (Algorithms.isEmpty(preferredLang)) { preferredLang = app.language } - if (prevMapRect != mapRect || prevZoom != mapView.zoom || prevLang != preferredLang) { - prevMapRect = mapRect + if (!prevMapRect.contains(qRect) || + prevLang != preferredLang) { + val mapCenter = mapView.currentRotatedTileBox.centerLatLon + prevMapRect = + KMapUtils.calculateLatLonBbox(mapCenter.latitude, mapCenter.longitude, 30000) prevZoom = mapView.zoom prevLang = preferredLang GetNearbyPlacesImagesTask( diff --git a/OsmAnd/src/net/osmand/plus/nearbyplaces/NearbyPlacesLoadSavedTask.java b/OsmAnd/src/net/osmand/plus/nearbyplaces/NearbyPlacesLoadSavedTask.java new file mode 100644 index 00000000000..bd20d8cc7a7 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/nearbyplaces/NearbyPlacesLoadSavedTask.java @@ -0,0 +1,58 @@ +package net.osmand.plus.nearbyplaces; + +import android.os.AsyncTask; + +import androidx.annotation.NonNull; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +import net.osmand.PlatformUtil; +import net.osmand.data.NearbyPlacePoint; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.utils.FileUtils; + +import org.apache.commons.logging.Log; + +import java.io.File; +import java.io.FileReader; +import java.lang.reflect.Type; +import java.util.Collections; +import java.util.List; + +public class NearbyPlacesLoadSavedTask extends AsyncTask> { + + private static final Log LOG = PlatformUtil.getLog(NearbyPlacesLoadSavedTask.class.getName()); + + private final OsmandApplication app; + private File file; + + public NearbyPlacesLoadSavedTask(@NonNull OsmandApplication app) { + this.app = app; + } + + @Override + protected List doInBackground(Void... voids) { + file = new File(FileUtils.getTempDir(app), "nearby_places"); + return loadPlaces(); + } + + @NonNull + private List loadPlaces() { + List nearbyPlaces = Collections.emptyList(); + Gson gson = new Gson(); + try (FileReader reader = new FileReader(file)) { + Type type = new TypeToken>() { + }.getType(); + nearbyPlaces = gson.fromJson(reader, type); + } catch (Exception e) { + LOG.error("Error loading nearby places from file", e); + } + return nearbyPlaces; + } + + @Override + protected void onPostExecute(@NonNull List nearbyPlaces) { + NearbyPlacesHelper.INSTANCE.onCacheLoaded(nearbyPlaces); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/nearbyplaces/SaveNearbyPlacesTask.kt b/OsmAnd/src/net/osmand/plus/nearbyplaces/SaveNearbyPlacesTask.kt new file mode 100644 index 00000000000..c9286bb89a6 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/nearbyplaces/SaveNearbyPlacesTask.kt @@ -0,0 +1,38 @@ +package net.osmand.plus.nearbyplaces + +import android.os.AsyncTask +import com.google.gson.Gson +import net.osmand.PlatformUtil +import net.osmand.data.NearbyPlacePoint +import net.osmand.plus.OsmandApplication +import net.osmand.plus.utils.FileUtils +import org.apache.commons.logging.Log +import java.io.File +import java.io.FileWriter + +class SaveNearbyPlacesTask(val app:OsmandApplication, val collection: List) : AsyncTask() { + private val LOG: Log = PlatformUtil.getLog( + NearbyPlacesLoadSavedTask::class.java.name) + + override fun doInBackground(vararg params: Void?): Boolean { + val file = File(FileUtils.getTempDir(app), "nearby_places") + val gson = Gson() + return try { + FileWriter(file).use { writer -> + val jsonString = gson.toJson(collection) + writer.write(jsonString) + } + true // Success + } catch (e: Exception) { + false // Failure + } + } + + override fun onPostExecute(success: Boolean) { + if (success) { + LOG.debug("Nearby places saved successfully.") + } else { + LOG.error("Failed to save nearby places.") + } + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/search/GetNearbyPlacesImagesTask.kt b/OsmAnd/src/net/osmand/plus/search/GetNearbyPlacesImagesTask.kt index d5bea74c84c..c9141e07fed 100644 --- a/OsmAnd/src/net/osmand/plus/search/GetNearbyPlacesImagesTask.kt +++ b/OsmAnd/src/net/osmand/plus/search/GetNearbyPlacesImagesTask.kt @@ -1,9 +1,9 @@ package net.osmand.plus.search import android.net.TrafficStats -import net.osmand.data.QuadRect import net.osmand.plus.OsmandApplication import net.osmand.shared.KAsyncTask +import net.osmand.shared.data.KQuadRect import net.osmand.shared.util.LoggerFactory import net.osmand.wiki.WikiCoreHelper import net.osmand.wiki.WikiCoreHelper.OsmandApiFeatureData @@ -11,7 +11,7 @@ import java.util.Collections class GetNearbyPlacesImagesTask( val app: OsmandApplication, - val mapRect: QuadRect, + val mapRect: KQuadRect, val zoom: Int, val locale: String, val listener: GetImageCardsListener) : diff --git a/OsmAnd/src/net/osmand/plus/search/listitems/NearbyPlacesCard.java b/OsmAnd/src/net/osmand/plus/search/listitems/NearbyPlacesCard.java index 4d1596ae68f..e40b4ae0670 100644 --- a/OsmAnd/src/net/osmand/plus/search/listitems/NearbyPlacesCard.java +++ b/OsmAnd/src/net/osmand/plus/search/listitems/NearbyPlacesCard.java @@ -10,6 +10,7 @@ import androidx.recyclerview.widget.RecyclerView; import net.osmand.data.NearbyPlacePoint; +import net.osmand.data.QuadRect; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; @@ -80,7 +81,8 @@ private void setupRecyclerView() { LinearLayoutManager layoutManager = new LinearLayoutManager(getContext(), RecyclerView.HORIZONTAL, false); nearByList.setLayoutManager(layoutManager); nearByList.setItemAnimator(null); - adapter = new NearbyPlacesAdapter(app, NearbyPlacesHelper.INSTANCE.getDataCollection(), false, clickListener); + QuadRect mapRect = app.getOsmandMap().getMapView().getCurrentRotatedTileBox().getLatLonBounds(); + adapter = new NearbyPlacesAdapter(app, NearbyPlacesHelper.INSTANCE.getDataCollection(mapRect), false, clickListener); nearByList.setAdapter(adapter); }