Skip to content

Commit

Permalink
Draft HeightDataLoader for ClickableWay (backend)
Browse files Browse the repository at this point in the history
  • Loading branch information
RZR-UA committed Jan 15, 2025
1 parent c93de76 commit 8a7cea9
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 19 deletions.
136 changes: 136 additions & 0 deletions OsmAnd-java/src/main/java/net/osmand/binary/HeightDataLoader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package net.osmand.binary;

import static net.osmand.router.RouteResultPreparation.SHIFT_ID;

import net.osmand.PlatformUtil;
import net.osmand.ResultMatcher;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteSubregion;
import net.osmand.data.LatLon;
import net.osmand.data.QuadRect;
import net.osmand.router.network.NetworkRouteContext;
import net.osmand.router.network.NetworkRouteSelector;
import net.osmand.util.MapUtils;

import org.apache.commons.logging.Log;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class HeightDataLoader {
public static final int ZOOM_TO_LOAD_TILES = 15;
public static final int ZOOM_TO_LOAD_TILES_SHIFT_L = ZOOM_TO_LOAD_TILES + 1;
public static final int ZOOM_TO_LOAD_TILES_SHIFT_R = 31 - ZOOM_TO_LOAD_TILES;

private final static Log log = PlatformUtil.getLog(HeightDataLoader.class);
private final Map<RouteSubregion, List<RouteDataObject>> loadedSubregions = new HashMap<>();
private final Map<BinaryMapIndexReader, List<RouteSubregion>> readers = new LinkedHashMap<>();

public HeightDataLoader(BinaryMapIndexReader[] readers) {
for (BinaryMapIndexReader r : readers) {
List<RouteSubregion> subregions = new ArrayList<>();
for (BinaryMapRouteReaderAdapter.RouteRegion rInd : r.getRoutingIndexes()) {
List<RouteSubregion> subregs = rInd.getSubregions();
// create a copy to avoid leaks to the original structure
for (RouteSubregion rs : subregs) {
subregions.add(new RouteSubregion(rs));
}
}
this.readers.put(r, subregions);
}
}

public void loadHeightData(long osmId, QuadRect bbox31) {
Map<Long, RouteDataObject> results = new HashMap<>();
ResultMatcher<RouteDataObject> matcher = new ResultMatcher<>() {
@Override
public boolean publish(RouteDataObject routeDataObject) {
return routeDataObject != null && routeDataObject.getId() >> SHIFT_ID == osmId;
}

@Override
public boolean isCancelled() {
return results.containsKey(osmId); // fast up search
}
};

try {
loadRouteDataObjects(bbox31, results, matcher);
} catch (IOException e) {
log.error(e);
}

// TODO calculateHeightArray() and return results
}

private boolean loadRouteDataObjects(QuadRect bbox31,
Map<Long, RouteDataObject> results,
ResultMatcher<RouteDataObject> matcher) throws IOException {
int loaded = 0;
int left = (int) bbox31.left >> ZOOM_TO_LOAD_TILES_SHIFT_R;
int top = (int) bbox31.top >> ZOOM_TO_LOAD_TILES_SHIFT_R;
int right = (int) bbox31.right >> ZOOM_TO_LOAD_TILES_SHIFT_R;
int bottom = (int) bbox31.bottom >> ZOOM_TO_LOAD_TILES_SHIFT_R;
for (int x = left; x <= right; x++) {
for (int y = top; y <= bottom; y++) {
if (matcher.isCancelled()) {
return loaded > 0;
}
loaded += loadRouteDataObjects(x, y, results, matcher);
}
}
return loaded > 0;
}

private int loadRouteDataObjects(int x, int y,
Map<Long, RouteDataObject> results,
ResultMatcher<RouteDataObject> matcher) throws IOException {
int loaded = 0;
HashSet<Long> deletedIds = new HashSet<>();
Map<Long, BinaryMapRouteReaderAdapter.RouteRegion> usedIds = new HashMap<>();
BinaryMapIndexReader.SearchRequest<RouteDataObject> req = BinaryMapIndexReader.buildSearchRouteRequest(
x << ZOOM_TO_LOAD_TILES_SHIFT_L, (x + 1) << ZOOM_TO_LOAD_TILES_SHIFT_L,
y << ZOOM_TO_LOAD_TILES_SHIFT_L, (y + 1) << ZOOM_TO_LOAD_TILES_SHIFT_L, null);
for (Map.Entry<BinaryMapIndexReader, List<RouteSubregion>> readerSubregions : readers.entrySet()) {
req.clearSearchResults();
BinaryMapIndexReader reader = readerSubregions.getKey();
synchronized (reader) {
List<RouteSubregion> routeSubregions = readerSubregions.getValue();
List<RouteSubregion> subregions = reader.searchRouteIndexTree(req, routeSubregions);
for (RouteSubregion sub : subregions) {
List<RouteDataObject> objects = loadedSubregions.get(sub);
if (objects == null) {
objects = reader.loadRouteIndexData(sub);
loadedSubregions.put(sub, objects);
}
for (RouteDataObject obj : objects) {
if (matcher.isCancelled()) {
return loaded;
}
if (matcher.publish(obj)) {
if (deletedIds.contains(obj.id)) {
// live-updates, osmand_change=delete
continue;
}
if (obj.isRoadDeleted()) {
deletedIds.add(obj.id);
continue;
}
if (usedIds.containsKey(obj.id) && usedIds.get(obj.id) != obj.region) {
// live-update, changed tags
continue;
}
loaded += (results.put(obj.getId() >> SHIFT_ID, obj) == null) ? 1 : 0;
usedIds.put(obj.id, obj.region);
}
}
}
}
}
return loaded;
}
}
23 changes: 4 additions & 19 deletions OsmAnd/src/net/osmand/plus/track/clickable/ClickableWayHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import androidx.annotation.Nullable;

import net.osmand.NativeLibrary.RenderedObject;
import net.osmand.binary.HeightDataLoader;
import net.osmand.binary.ObfConstants;
import net.osmand.core.jni.ObfMapObject;
import net.osmand.core.jni.QVectorPointI;
Expand Down Expand Up @@ -64,8 +65,6 @@ public class ClickableWayHelper {
private final OsmandMapTileView view;
private final ClickableWayMenuActivator activator;

// private static final Log log = PlatformUtil.getLog(ClickableWay.class);

public ClickableWayHelper(@NonNull OsmandApplication app, @NonNull OsmandMapTileView view) {
this.app = app;
this.view = view;
Expand Down Expand Up @@ -195,23 +194,9 @@ private boolean isClickableWayTags(@NonNull Map<String, String> tags) {
}

private boolean readHeightData(ClickableWay clickableWay) {
// TODO read height data, implement simple cache
// BinaryMapIndexReader[] readers = app.getResourceManager().getReverseGeocodingMapFiles();
// NetworkRouteSelector.NetworkRouteSelectorFilter selectorFilter = new NetworkRouteSelector.NetworkRouteSelectorFilter();
// NetworkRouteSelector routeSelector = new NetworkRouteSelector(readers, selectorFilter, null);
// try {
// QuadRect bbox31 = clickableWay.getBbox();
// QuadRect bboxLatLon = new QuadRect(
// MapUtils.get31LongitudeX((int)bbox31.left),
// MapUtils.get31LatitudeY((int)bbox31.top),
// MapUtils.get31LongitudeX((int)bbox31.right),
// MapUtils.get31LatitudeY((int)bbox31.bottom)
// );
// Map<NetworkRouteSelector.RouteKey, GpxFile> routes = routeSelector.getRoutes(bboxLatLon, true, null);
// System.err.printf("XXX routes\n");
// } catch (IOException e) {
// log.error(e);
// }
HeightDataLoader loader = new HeightDataLoader(app.getResourceManager().getReverseGeocodingMapFiles());
loader.loadHeightData(clickableWay.getOsmId(), clickableWay.getBbox());
// TODO read height data, apply to the GpxFile points
return true;
}

Expand Down

0 comments on commit 8a7cea9

Please sign in to comment.