Implement size limit approach (Java routing)
This commit is contained in:
parent
a64904469f
commit
1aac6c9cb7
11 changed files with 183 additions and 87 deletions
|
@ -123,7 +123,6 @@ public class RouterTestsSuite {
|
|||
for (int i = 0; i < tests.getLength(); i++) {
|
||||
Element e = (Element) tests.item(i);
|
||||
BinaryRoutePlanner router = new BinaryRoutePlanner(lib, rs);
|
||||
RoutingConfiguration.DEFAULT_DESIRABLE_TILES_IN_MEMORY = 100;
|
||||
testRoute(e, router, config);
|
||||
}
|
||||
|
||||
|
@ -159,7 +158,7 @@ public class RouterTestsSuite {
|
|||
System.err.println("\n\n!! Skipped test case '" + testDescription + "' because 'best_percent' attribute is not specified \n\n" );
|
||||
return;
|
||||
}
|
||||
RoutingContext ctx = new RoutingContext(config.build(vehicle));
|
||||
RoutingContext ctx = new RoutingContext(config.build(vehicle, RoutingConfiguration.DEFAULT_MEMORY_LIMIT));
|
||||
String skip = testCase.getAttribute("skip_comment");
|
||||
if (skip != null && skip.length() > 0) {
|
||||
System.err.println("\n\n!! Skipped test case '" + testDescription + "' because '" + skip + "'\n\n" );
|
||||
|
|
|
@ -49,7 +49,7 @@ public class BinaryInspector {
|
|||
// test cases show info
|
||||
|
||||
|
||||
//inspector(new String[]{"-vaddress",/* "-bbox=-121.785,37.35,-121.744,37.33", */"/home/victor/projects/OsmAnd/data/osm-gen/Map.obf"});
|
||||
inspector(new String[]{/*"-vaddress", "-bbox=-121.785,37.35,-121.744,37.33", */"/home/victor/projects/OsmAnd/data/osm-gen/Netherlands_europe.obf"});
|
||||
// test case extract parts
|
||||
// test case
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package net.osmand.binary;
|
||||
|
||||
|
||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
|
||||
|
|
|
@ -42,13 +42,11 @@ public class BinaryRoutePlanner {
|
|||
|
||||
private static final int ROUTE_POINTS = 11;
|
||||
private static final float TURN_DEGREE_MIN = 45;
|
||||
private static final boolean SHOW_GC_SIZE = false;
|
||||
|
||||
|
||||
public BinaryRoutePlanner(NativeLibrary nativeLib, BinaryMapIndexReader... map) {
|
||||
this.nativeLib = nativeLib;
|
||||
if(nativeLib != null) {
|
||||
RoutingConfiguration.DEFAULT_DESIRABLE_TILES_IN_MEMORY = 100;
|
||||
}
|
||||
this.nativeLib = null; //nativeLib;
|
||||
for (BinaryMapIndexReader mr : map) {
|
||||
List<RouteRegion> rr = mr.getRoutingIndexes();
|
||||
List<RouteSubregion> subregions = new ArrayList<BinaryMapRouteReaderAdapter.RouteSubregion>();
|
||||
|
@ -378,9 +376,6 @@ public class BinaryRoutePlanner {
|
|||
graphSegments = graphDirectSegments;
|
||||
}
|
||||
|
||||
if(ctx.runTilesGC()) {
|
||||
unloadUnusedTiles(ctx, ctx.config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY);
|
||||
}
|
||||
if(ctx.runRelaxingStrategy() ) {
|
||||
relaxNotNeededSegments(ctx, graphDirectSegments, true);
|
||||
relaxNotNeededSegments(ctx, graphReverseSegments, false);
|
||||
|
@ -398,8 +393,9 @@ public class BinaryRoutePlanner {
|
|||
return resultPrepared;
|
||||
}
|
||||
|
||||
private void unloadUnusedTiles(RoutingContext ctx, int desirableSize) {
|
||||
private void unloadUnusedTiles(RoutingContext ctx) {
|
||||
// now delete all
|
||||
float desirableSize = ctx.config.memoryLimitation * 0.7f;
|
||||
List<RoutingTile> list = new ArrayList<RoutingContext.RoutingTile>();
|
||||
TIntObjectIterator<RoutingTile> it = ctx.tiles.iterator();
|
||||
int loaded = 0;
|
||||
|
@ -428,15 +424,30 @@ public class BinaryRoutePlanner {
|
|||
return v1 < v2 ? -1 : (v1 == v2 ? 0 : 1);
|
||||
}
|
||||
});
|
||||
if (loaded >= 0.9f * desirableSize) {
|
||||
int toUnload = Math.max(loaded / 5, loaded - desirableSize);
|
||||
for (int i = 0; i < loaded; i++) {
|
||||
list.get(i).access = 0;
|
||||
if (i < toUnload) {
|
||||
ctx.unloadTile(list.get(i), true);
|
||||
}
|
||||
while(ctx.getCurrentEstimatedSize() >= desirableSize && list.size() > loaded / 5) {
|
||||
RoutingTile unload = list.remove(0);
|
||||
// System.out.println("Unload " + unload);
|
||||
unload.access = 0;
|
||||
ctx.unloadTile(unload, true);
|
||||
}
|
||||
}
|
||||
|
||||
private static long runGCUsedMemory() {
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
long usedMem1 = runtime.totalMemory() - runtime.freeMemory();
|
||||
long usedMem2 = Long.MAX_VALUE;
|
||||
int cnt = 4;
|
||||
while (cnt-- >= 0) {
|
||||
for (int i = 0; (usedMem1 < usedMem2) && (i < 1000); ++i) {
|
||||
runtime.runFinalization();
|
||||
runtime.gc();
|
||||
Thread.yield();
|
||||
|
||||
usedMem2 = usedMem1;
|
||||
usedMem1 = runtime.totalMemory() - runtime.freeMemory();
|
||||
}
|
||||
}
|
||||
return usedMem1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -498,19 +509,23 @@ public class BinaryRoutePlanner {
|
|||
System.out.println(logMsg);
|
||||
}
|
||||
|
||||
private static void printInfo(String logMsg) {
|
||||
log.warn(logMsg);
|
||||
}
|
||||
|
||||
public void printDebugMemoryInformation(RoutingContext ctx, PriorityQueue<RouteSegment> graphDirectSegments, PriorityQueue<RouteSegment> graphReverseSegments,
|
||||
TLongObjectHashMap<RouteSegment> visitedDirectSegments,TLongObjectHashMap<RouteSegment> visitedOppositeSegments) {
|
||||
println("Time to calculate : " + (System.nanoTime() - ctx.timeToCalculate) / 1e6 + ", time to load : " + ctx.timeToLoad / 1e6);
|
||||
println("Current loaded tiles : " + ctx.getCurrentlyLoadedTiles() + ", maximum loaded tiles " + ctx.maxLoadedTiles);
|
||||
println("Loaded tiles " + ctx.loadedTiles + " (distinct "+ctx.distinctLoadedTiles+ "), unloaded tiles " + ctx.unloadedTiles +
|
||||
printInfo("Time to calculate : " + (System.nanoTime() - ctx.timeToCalculate) / 1e6 + ", time to load : " + ctx.timeToLoad / 1e6);
|
||||
printInfo("Current loaded tiles : " + ctx.getCurrentlyLoadedTiles() + ", maximum loaded tiles " + ctx.maxLoadedTiles);
|
||||
printInfo("Loaded tiles " + ctx.loadedTiles + " (distinct "+ctx.distinctLoadedTiles+ "), unloaded tiles " + ctx.unloadedTiles +
|
||||
" (distinct " + ctx.distinctUnloadedTiles.size()+") "+ ", loaded more than once same tiles "
|
||||
+ ctx.loadedPrevUnloadedTiles );
|
||||
println("Visited roads, " + ctx.visitedSegments + ", relaxed roads " + ctx.relaxedSegments);
|
||||
printInfo("Visited roads, " + ctx.visitedSegments + ", relaxed roads " + ctx.relaxedSegments);
|
||||
if (graphDirectSegments != null && graphReverseSegments != null) {
|
||||
println("Priority queues sizes : " + graphDirectSegments.size() + "/" + graphReverseSegments.size());
|
||||
printInfo("Priority queues sizes : " + graphDirectSegments.size() + "/" + graphReverseSegments.size());
|
||||
}
|
||||
if (visitedDirectSegments != null && visitedOppositeSegments != null) {
|
||||
println("Visited segments sizes: " + visitedDirectSegments.size() + "/" + visitedOppositeSegments.size());
|
||||
printInfo("Visited segments sizes: " + visitedDirectSegments.size() + "/" + visitedOppositeSegments.size());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -521,6 +536,24 @@ public class BinaryRoutePlanner {
|
|||
tile.access++;
|
||||
return tile;
|
||||
}
|
||||
if(ctx.getCurrentEstimatedSize() > 0.95 *ctx.config.memoryLimitation) {
|
||||
int sz1 = ctx.getCurrentEstimatedSize();
|
||||
long h1 = 0;
|
||||
if(SHOW_GC_SIZE && sz1 > 0.7 * ctx.config.memoryLimitation ) {
|
||||
runGCUsedMemory();
|
||||
h1 = runGCUsedMemory();
|
||||
}
|
||||
int clt = ctx.getCurrentlyLoadedTiles();
|
||||
unloadUnusedTiles(ctx);
|
||||
if (h1 != 0 && ctx.getCurrentlyLoadedTiles() != clt) {
|
||||
int sz2 = ctx.getCurrentEstimatedSize();
|
||||
runGCUsedMemory();
|
||||
long h2 = runGCUsedMemory();
|
||||
float mb = (1 << 20);
|
||||
log.warn("Unload tiles : estimated " + (sz1 - sz2) / mb + " ?= " + (h1 - h2) / mb+ " actual");
|
||||
log.warn("Used after " + h2 / mb + " of " + Runtime.getRuntime().totalMemory() / mb + " max " + Runtime.getRuntime().maxMemory() / mb);
|
||||
}
|
||||
}
|
||||
ctx.loadTileData(tile, null, nativeLib, map);
|
||||
return tile;
|
||||
}
|
||||
|
@ -886,8 +919,8 @@ public class BinaryRoutePlanner {
|
|||
|
||||
// calculate time
|
||||
for (int i = 0; i < result.size(); i++) {
|
||||
if(ctx.runTilesGC()) {
|
||||
unloadUnusedTiles(ctx, ctx.config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY);
|
||||
if(ctx.getCurrentEstimatedSize() > 0.9 *ctx.config.memoryLimitation) {
|
||||
unloadUnusedTiles(ctx);
|
||||
}
|
||||
RouteSegmentResult rr = result.get(i);
|
||||
RouteDataObject road = rr.getObject();
|
||||
|
|
|
@ -19,12 +19,13 @@ public class RoutingConfiguration {
|
|||
// 1. parameters of routing and different tweaks
|
||||
// Influence on A* : f(x) + heuristicCoefficient*g(X)
|
||||
public double heuristicCoefficient = 1;
|
||||
|
||||
public static final int DEFAULT_MEMORY_LIMIT = 30;
|
||||
|
||||
|
||||
// 1.1 tile load parameters (should not affect routing)
|
||||
public int ZOOM_TO_LOAD_TILES = 13; // 12?, 14?
|
||||
public int ITERATIONS_TO_RUN_GC = 100;
|
||||
public static int DEFAULT_DESIRABLE_TILES_IN_MEMORY = 30;
|
||||
public int NUMBER_OF_DESIRABLE_TILES_IN_MEMORY = DEFAULT_DESIRABLE_TILES_IN_MEMORY;
|
||||
public int memoryLimitation;
|
||||
|
||||
// 1.2 Dynamic road prioritizing (heuristic)
|
||||
public boolean useDynamicRoadPrioritising = true;
|
||||
|
@ -53,10 +54,10 @@ public class RoutingConfiguration {
|
|||
private Map<String, GeneralRouter> routers = new LinkedHashMap<String, GeneralRouter>();
|
||||
private Map<String, String> attributes = new LinkedHashMap<String, String>();
|
||||
|
||||
public RoutingConfiguration build(String router, String... specialization) {
|
||||
return build(router, null, specialization);
|
||||
public RoutingConfiguration build(String router, int memoryLimitMB, String... specialization) {
|
||||
return build(router, null, memoryLimitMB, specialization);
|
||||
}
|
||||
public RoutingConfiguration build(String router, Double direction, String... specialization) {
|
||||
public RoutingConfiguration build(String router, Double direction, int memoryLimitMB, String... specialization) {
|
||||
if (!routers.containsKey(router)) {
|
||||
router = defaultRouter;
|
||||
}
|
||||
|
@ -64,10 +65,15 @@ public class RoutingConfiguration {
|
|||
i.initialDirection = direction;
|
||||
i.heuristicCoefficient = parseSilentDouble(getAttribute(router, "heuristicCoefficient"), i.heuristicCoefficient);
|
||||
i.ZOOM_TO_LOAD_TILES = parseSilentInt(getAttribute(router, "zoomToLoadTiles"), i.ZOOM_TO_LOAD_TILES);
|
||||
i.ITERATIONS_TO_RUN_GC = parseSilentInt(getAttribute(router, "iterationsToRunGC"), i.ITERATIONS_TO_RUN_GC);
|
||||
i.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY = parseSilentInt(getAttribute(router, "desirableTilesInMemory"),
|
||||
i.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY);
|
||||
|
||||
int desirable = parseSilentInt(getAttribute(router, "memoryLimitInMB"), 0);
|
||||
if(desirable != 0) {
|
||||
i.memoryLimitation = desirable * (1 << 20);
|
||||
} else {
|
||||
if(memoryLimitMB == 0) {
|
||||
memoryLimitMB = DEFAULT_MEMORY_LIMIT;
|
||||
}
|
||||
i.memoryLimitation = memoryLimitMB * (1 << 20);
|
||||
}
|
||||
i.useDynamicRoadPrioritising = parseSilentBoolean(getAttribute(router, "useDynamicRoadPrioritising"), i.useDynamicRoadPrioritising);
|
||||
i.useRelaxingStrategy = parseSilentBoolean(getAttribute(router, "useRelaxingStrategy"), i.useRelaxingStrategy);
|
||||
i.dynamicRoadPriorityDistance = parseSilentInt(getAttribute(router, "dynamicRoadPriorityDistance"), i.dynamicRoadPriorityDistance);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package net.osmand.router;
|
||||
|
||||
import gnu.trove.iterator.TIntObjectIterator;
|
||||
import gnu.trove.map.TLongObjectMap;
|
||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||
import gnu.trove.map.hash.TLongObjectHashMap;
|
||||
|
@ -31,7 +32,7 @@ public class RoutingContext {
|
|||
|
||||
public final RoutingConfiguration config;
|
||||
// 1. Initial variables
|
||||
private int garbageCollectorIteration = 0;
|
||||
|
||||
private int relaxingIteration = 0;
|
||||
public long firstRoadId = 0;
|
||||
public int firstRoadDirection = 0;
|
||||
|
@ -70,6 +71,8 @@ public class RoutingContext {
|
|||
// callback of processing segments
|
||||
RouteSegmentVisitor visitor = null;
|
||||
|
||||
private TileStatistics global = new TileStatistics();
|
||||
|
||||
public RoutingContext(RoutingConfiguration config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
@ -90,15 +93,8 @@ public class RoutingContext {
|
|||
return cnt;
|
||||
}
|
||||
|
||||
public boolean runTilesGC() {
|
||||
garbageCollectorIteration++;
|
||||
int loadedTilesCritical = config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY * 3 /2;
|
||||
if (garbageCollectorIteration > config.ITERATIONS_TO_RUN_GC ||
|
||||
getCurrentlyLoadedTiles() > loadedTilesCritical) {
|
||||
garbageCollectorIteration = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
public int getCurrentEstimatedSize(){
|
||||
return global.size;
|
||||
}
|
||||
|
||||
public boolean runRelaxingStrategy(){
|
||||
|
@ -186,12 +182,64 @@ public class RoutingContext {
|
|||
RoutingTile old = tiles.remove(l);
|
||||
RoutingTile n = new RoutingTile(tile.tileX, tile.tileY, config.ZOOM_TO_LOAD_TILES);
|
||||
n.isLoaded = old.isLoaded;
|
||||
|
||||
n.setUnloaded();
|
||||
tiles.put(l, n);
|
||||
unloadedTiles++;
|
||||
global.size -= tile.tileStatistics.size;
|
||||
distinctUnloadedTiles.add(l);
|
||||
}
|
||||
|
||||
private static class TileStatistics {
|
||||
public int size = 0;
|
||||
public int allRoutes = 0;
|
||||
public int coordinates = 0;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "All routes " + allRoutes +
|
||||
" size " + (size / 1024f) + " KB coordinates " + coordinates + " ratio coord " + (((float)size) / coordinates)
|
||||
+ " ratio routes " + (((float)size) / allRoutes);
|
||||
}
|
||||
|
||||
public void addObject(RouteDataObject o) {
|
||||
allRoutes++;
|
||||
coordinates += o.getPointsLength() * 2;
|
||||
// calculate size
|
||||
int sz = 0;
|
||||
sz += 8 + 4; // overhead
|
||||
if (o.names != null) {
|
||||
sz += 12;
|
||||
TIntObjectIterator<String> it = o.names.iterator();
|
||||
while(it.hasNext()) {
|
||||
it.advance();
|
||||
String vl = it.value();
|
||||
sz += 12 + vl.length();
|
||||
}
|
||||
sz += 12 + o.names.size() * 25;
|
||||
}
|
||||
sz += 8; // id
|
||||
// coordinates
|
||||
sz += (8 + 4 + 4 * o.getPointsLength()) * 4;
|
||||
sz += o.types == null ? 4 : (8 + 4 + 4 * o.types.length);
|
||||
sz += o.restrictions == null ? 4 : (8 + 4 + 8 * o.restrictions.length);
|
||||
sz += 4;
|
||||
if (o.pointTypes != null) {
|
||||
sz += 8 + 4 * o.pointTypes.length;
|
||||
for (int i = 0; i < o.pointTypes.length; i++) {
|
||||
sz += 4;
|
||||
if (o.pointTypes[i] != null) {
|
||||
sz += 8 + 8 * o.pointTypes[i].length;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Standard overhead?
|
||||
size += sz * 3;
|
||||
// size += coordinates * 20;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void loadTileData(final RoutingTile tile, final List<RouteDataObject> toFillIn, NativeLibrary nativeLib,
|
||||
Map<BinaryMapIndexReader, List<RouteSubregion>> map) {
|
||||
|
@ -200,15 +248,15 @@ public class RoutingContext {
|
|||
final int zoomToLoad = 31 - tile.getZoom();
|
||||
final int tileX = tile.getTileX();
|
||||
final int tileY = tile.getTileY();
|
||||
final TileStatistics ts = new TileStatistics();
|
||||
ResultMatcher<RouteDataObject> matcher = new ResultMatcher<RouteDataObject>() {
|
||||
int intersectionObjects = 0, all = 0, allout = 0;
|
||||
@Override
|
||||
public boolean publish(RouteDataObject o) {
|
||||
if(o.getPointsLength() == 0) {
|
||||
return false;
|
||||
}
|
||||
all++;
|
||||
boolean out = false;
|
||||
ts.allRoutes++;
|
||||
|
||||
int minx, maxx, miny, maxy;
|
||||
minx = maxx = o.getPoint31XTile(0);
|
||||
miny = maxy = o.getPoint31YTile(0);
|
||||
|
@ -217,22 +265,15 @@ public class RoutingContext {
|
|||
maxx = Math.max(o.getPoint31XTile(ti), maxx);
|
||||
miny = Math.min(o.getPoint31YTile(ti), miny);
|
||||
maxy = Math.max(o.getPoint31YTile(ti), maxy);
|
||||
if(!tile.checkContains(o.getPoint31XTile(ti), o.getPoint31YTile(ti))) {
|
||||
out = true;
|
||||
}
|
||||
}
|
||||
minx = minx >> zoomToLoad;
|
||||
maxx = maxx >> zoomToLoad;
|
||||
miny = miny >> zoomToLoad;
|
||||
maxy = maxy >> zoomToLoad;
|
||||
if(minx > tileX || maxx < tileX || miny > tileY || maxy < tileY) {
|
||||
allout++;
|
||||
return false;
|
||||
}
|
||||
if(out) {
|
||||
intersectionObjects++;
|
||||
}
|
||||
|
||||
ts.addObject(o);
|
||||
if (toFillIn != null) {
|
||||
if (getRouter().acceptLine(o)) {
|
||||
toFillIn.add(o);
|
||||
|
@ -244,7 +285,7 @@ public class RoutingContext {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Tile " + tileX + "/"+ tileY + " boundaries " + intersectionObjects + " of " + all + " out " + allout;
|
||||
return "Tile " + tileX + "/"+ tileY + " : " + ts;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -290,12 +331,20 @@ public class RoutingContext {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
loadedTiles++;
|
||||
if (tile.isUnloaded()) {
|
||||
loadedPrevUnloadedTiles++;
|
||||
} else {
|
||||
if(global != null) {
|
||||
global.allRoutes += ts.allRoutes;
|
||||
global.coordinates += ts.coordinates;
|
||||
}
|
||||
distinctLoadedTiles++;
|
||||
}
|
||||
tile.tileStatistics = ts;
|
||||
global.size += ts.size;
|
||||
// System.out.println("Loaded " + tile + " global " + global);
|
||||
tile.setLoaded();
|
||||
if(nativeRouteSearchResults.size() > 0) {
|
||||
tile.nativeLib = nativeLib;
|
||||
|
@ -405,6 +454,7 @@ public class RoutingContext {
|
|||
|
||||
private TLongObjectMap<RouteSegment> routes = new TLongObjectHashMap<RouteSegment>();
|
||||
private TLongObjectHashMap<RouteDataObject> idObjects = new TLongObjectHashMap<RouteDataObject>();
|
||||
private TileStatistics tileStatistics = new TileStatistics();
|
||||
|
||||
public RouteSegment getSegment(long id, RoutingContext ctx) {
|
||||
if(nativeResults != null) {
|
||||
|
@ -506,6 +556,11 @@ public class RoutingContext {
|
|||
return tileX == (x31 >> (31 - zoom)) && tileY == (y31 >> (31 - zoom));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Tile " + tileX + "/" + tileY + " : " + tileStatistics;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -129,7 +129,6 @@
|
|||
</avoid>
|
||||
</routingProfile>
|
||||
|
||||
|
||||
<routingProfile name="bicycle" baseProfile="bicycle" restrictionsAware="true" minDefaultSpeed="7" maxDefaultSpeed="16"
|
||||
leftTurn="0" rightTurn="0" followSpeedLimitations="false" onewayAware="true">
|
||||
<!-- <attribute name="relaxNodesIfStartDistSmallCoeff" value="2.5"/> -->
|
||||
|
|
|
@ -122,8 +122,7 @@ public class MapClusterLayer implements MapPanelLayer {
|
|||
BinaryRoutePlanner router = new BinaryRoutePlanner(NativeSwingRendering.getDefaultFromSettings(),
|
||||
rs.toArray(new BinaryMapIndexReader[rs.size()]));
|
||||
Builder builder = RoutingConfiguration.getDefault();
|
||||
RoutingConfiguration config = builder.build("car");
|
||||
config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY = 300;
|
||||
RoutingConfiguration config = builder.build("car", RoutingConfiguration.DEFAULT_MEMORY_LIMIT * 3);
|
||||
RoutingContext ctx = new RoutingContext(config);
|
||||
// find closest way
|
||||
RouteSegment st = router.findRouteSegment(lat, lon, ctx);
|
||||
|
|
|
@ -305,20 +305,6 @@ public class MapRouterLayer implements MapPanelLayer {
|
|||
}
|
||||
|
||||
|
||||
// for vector rendering we should extract from osm
|
||||
// 1. Ways (different kinds) with tag highway= ?,highway=stop ...
|
||||
// 2. Junction = roundabout
|
||||
// 3. barrier, traffic_calming=bump
|
||||
// 4. Save {name, ref} of way to unify it
|
||||
|
||||
// + for future routing we should extract from osm
|
||||
// 1. oneway
|
||||
// 2. max_speed
|
||||
// 3. toll
|
||||
// 4. traffic_signals
|
||||
// 5. max_heigtht, max_width, min_speed, ...
|
||||
// 6. incline ?
|
||||
|
||||
public static List<Way> route_YOURS(LatLon start, LatLon end){
|
||||
List<Way> res = new ArrayList<Way>();
|
||||
long time = System.currentTimeMillis();
|
||||
|
@ -626,7 +612,7 @@ public class MapRouterLayer implements MapPanelLayer {
|
|||
String m = DataExtractionSettings.getSettings().getRouteMode();
|
||||
String[] props = m.split("\\,");
|
||||
BinaryRoutePlanner router = new BinaryRoutePlanner(NativeSwingRendering.getDefaultFromSettings(), rs);
|
||||
RoutingConfiguration config = builder.build(props[0], props);
|
||||
RoutingConfiguration config = builder.build(props[0], RoutingConfiguration.DEFAULT_MEMORY_LIMIT * 3, props);
|
||||
// config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY = 300;
|
||||
// config.ZOOM_TO_LOAD_TILES = 14;
|
||||
RoutingContext ctx = new RoutingContext(config);
|
||||
|
@ -638,13 +624,13 @@ public class MapRouterLayer implements MapPanelLayer {
|
|||
if (st == null) {
|
||||
throw new RuntimeException("Starting point for route not found");
|
||||
}
|
||||
System.out.println("ROAD TO START " + st.getRoad().getHighway() + " " + st.getRoad().id);
|
||||
log.info("Start road " + st.getRoad().getHighway() + " " + st.getRoad().id);
|
||||
|
||||
RouteSegment e = router.findRouteSegment(end.getLatitude(), end.getLongitude(), ctx);
|
||||
if (e == null) {
|
||||
throw new RuntimeException("End point to calculate route was not found");
|
||||
}
|
||||
System.out.println("ROAD TO END " + e.getRoad().getHighway() + " " + e.getRoad().id);
|
||||
log.info("End road " + e.getRoad().getHighway() + " " + e.getRoad().id);
|
||||
|
||||
List<RouteSegment> inters = new ArrayList<BinaryRoutePlanner.RouteSegment>();
|
||||
if (intermediates != null) {
|
||||
|
|
|
@ -630,10 +630,14 @@ public class MapRenderRepositories {
|
|||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
|
||||
activityManager.getMemoryInfo(memoryInfo);
|
||||
AccessibleToast.makeText(context, context.getString(R.string.rendering_out_of_memory) + " (" + memoryInfo.availMem / 1048576L + " MB available) ", Toast.LENGTH_SHORT).show();
|
||||
// ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
// ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
|
||||
// activityManager.getMemoryInfo(memoryInfo);
|
||||
// int avl = (int) (memoryInfo.availMem / (1 << 20));
|
||||
int max = (int) (Runtime.getRuntime().maxMemory() / (1 << 20));
|
||||
int avl = (int) (Runtime.getRuntime().freeMemory() / (1 << 20));
|
||||
String s = " (" + avl + " MB available of " + max + ") ";
|
||||
AccessibleToast.makeText(context, context.getString(R.string.rendering_out_of_memory) + s , Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
|
|
|
@ -27,6 +27,7 @@ import net.osmand.GPXUtilities.Track;
|
|||
import net.osmand.GPXUtilities.TrkSegment;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.LogUtil;
|
||||
import net.osmand.access.AccessibleToast;
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.osm.LatLon;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
|
@ -55,6 +56,7 @@ import org.xml.sax.SAXException;
|
|||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.location.Location;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class RouteProvider {
|
||||
private static final org.apache.commons.logging.Log log = LogUtil.getLog(RouteProvider.class);
|
||||
|
@ -350,7 +352,15 @@ public class RouteProvider {
|
|||
specs.add(GeneralRouter.AVOID_UNPAVED);
|
||||
}
|
||||
String[] specialization = specs.toArray(new String[specs.size()]);
|
||||
RoutingContext ctx = new RoutingContext(config.build(p.name().toLowerCase(), start.hasBearing() ? start.getBearing() / 180d * Math.PI : null, specialization));
|
||||
float mb = (1 << 20);
|
||||
Runtime rt = Runtime.getRuntime();
|
||||
// make visible
|
||||
int memoryLimit = (int) (0.9 * ((rt.maxMemory() - rt.totalMemory()) + rt.freeMemory()) / mb);
|
||||
log.error("Use " + memoryLimit + "Free " + rt.freeMemory() / mb + " of " + rt.totalMemory() / mb + " max " + rt.maxMemory() / mb);
|
||||
|
||||
RoutingConfiguration cf = config.build(p.name().toLowerCase(), start.hasBearing() ? start.getBearing() / 180d * Math.PI : null,
|
||||
memoryLimit, specialization);
|
||||
RoutingContext ctx = new RoutingContext(cf);
|
||||
ctx.interruptable = interruptable;
|
||||
ctx.previouslyCalculatedRoute = previousRoute;
|
||||
RouteSegment st= router.findRouteSegment(start.getLatitude(), start.getLongitude(), ctx);
|
||||
|
@ -387,10 +397,14 @@ public class RouteProvider {
|
|||
return new RouteCalculationResult(result, start, end, intermediates, app, leftSide);
|
||||
}
|
||||
} catch (OutOfMemoryError e) {
|
||||
ActivityManager activityManager = (ActivityManager)app.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
|
||||
activityManager.getMemoryInfo(memoryInfo);
|
||||
return new RouteCalculationResult("Not enough process memory "+ "(" + memoryInfo.availMem / 1048576L + " MB available) ");
|
||||
// ActivityManager activityManager = (ActivityManager)app.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
// ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
|
||||
// activityManager.getMemoryInfo(memoryInfo);
|
||||
// int avl = (int) (memoryInfo.availMem / (1 << 20));
|
||||
int max = (int) (Runtime.getRuntime().maxMemory() / (1 << 20));
|
||||
int avl = (int) (Runtime.getRuntime().freeMemory() / (1 << 20));
|
||||
String s = " (" + avl + " MB available of " + max + ") ";
|
||||
return new RouteCalculationResult("Not enough process memory "+ s);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue