Skip to content

Commit

Permalink
Implemented cache
Browse files Browse the repository at this point in the history
  • Loading branch information
Corwin-Kh committed Feb 20, 2025
1 parent 9619e0c commit 0caa02c
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 13 deletions.
7 changes: 4 additions & 3 deletions OsmAnd-java/src/main/java/net/osmand/wiki/WikiCoreHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -46,12 +47,12 @@ public class WikiCoreHelper {
private static final List<String> IMAGE_EXTENSIONS = new ArrayList<>(Arrays.asList(".jpeg", ".jpg", ".png", ".gif"));


public static List<OsmandApiFeatureData> getExploreImageList(QuadRect mapRect, int zoom, String lang) {
public static List<OsmandApiFeatureData> getExploreImageList(KQuadRect mapRect, int zoom, String lang) {
List<OsmandApiFeatureData> 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")));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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()}]"
}
Expand Down
56 changes: 49 additions & 7 deletions OsmAnd/src/net/osmand/plus/nearbyplaces/NearbyPlacesHelper.kt
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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<NearbyPlacesListener> = Collections.emptyList()
Expand All @@ -56,6 +61,7 @@ object NearbyPlacesHelper {
.load(point.iconUrl)
.fetch()
}
SaveNearbyPlacesTask(app, it).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)
}
updateLastModifiedTime()
notifyListeners()
Expand All @@ -82,15 +88,51 @@ object NearbyPlacesHelper {
return this.dataCollection ?: Collections.emptyList()
}

fun onCacheLoaded(cachedPLaces: List<NearbyPlacePoint>) {
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<NearbyPlacePoint> {
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(
Expand Down
Original file line number Diff line number Diff line change
@@ -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<Void, Void, List<NearbyPlacePoint>> {

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<NearbyPlacePoint> doInBackground(Void... voids) {
file = new File(FileUtils.getTempDir(app), "nearby_places");
return loadPlaces();
}

@NonNull
private List<NearbyPlacePoint> loadPlaces() {
List<NearbyPlacePoint> nearbyPlaces = Collections.emptyList();
Gson gson = new Gson();
try (FileReader reader = new FileReader(file)) {
Type type = new TypeToken<List<NearbyPlacePoint>>() {
}.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<NearbyPlacePoint> nearbyPlaces) {
NearbyPlacesHelper.INSTANCE.onCacheLoaded(nearbyPlaces);
}
}
38 changes: 38 additions & 0 deletions OsmAnd/src/net/osmand/plus/nearbyplaces/SaveNearbyPlacesTask.kt
Original file line number Diff line number Diff line change
@@ -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<NearbyPlacePoint>) : AsyncTask<Void, Void, Boolean>() {
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.")
}
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
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
import java.util.Collections

class GetNearbyPlacesImagesTask(
val app: OsmandApplication,
val mapRect: QuadRect,
val mapRect: KQuadRect,
val zoom: Int,
val locale: String,
val listener: GetImageCardsListener) :
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down

2 comments on commit 0caa02c

@sonora
Copy link
Member

@sonora sonora commented on 0caa02c Feb 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Corwin-Kh There are 2 issues after this commit:

  1. I now get suggestions from way outside the map view box.
  2. The results are not correctly sorted by distance any more. The first place I see listed is very far away.

Both issues were not present immeditately before this commit.

@Corwin-Kh
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your reply. Actually, the feature is still in progress and appeared in master by mistake, reverted it.
Answering you questions - items are sorted by popularity, not distance

Please sign in to comment.