diff --git a/brouter-core/src/main/java/btools/router/AreaReader.java b/brouter-core/src/main/java/btools/router/AreaReader.java index 86e5be7..698f52a 100644 --- a/brouter-core/src/main/java/btools/router/AreaReader.java +++ b/brouter-core/src/main/java/btools/router/AreaReader.java @@ -1,11 +1,19 @@ package btools.router; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; import java.util.List; import btools.codec.DataBuffers; import btools.codec.MicroCache; import btools.expressions.BExpressionContextWay; +import btools.mapaccess.MatchedWaypoint; import btools.mapaccess.NodesCache; import btools.mapaccess.OsmFile; import btools.mapaccess.OsmLink; @@ -99,7 +107,8 @@ public class AreaReader { // check for quadrant border boolean intersects = checkBorder && dataRect.intersects(searchRect.points.get(0).x, searchRect.points.get(0).y, searchRect.points.get(2).x, searchRect.points.get(2).y); - if (!intersects && checkBorder) intersects = dataRect.intersects(searchRect.points.get(1).x, searchRect.points.get(1).y, searchRect.points.get(2).x, searchRect.points.get(3).y); + if (!intersects && checkBorder) + intersects = dataRect.intersects(searchRect.points.get(1).x, searchRect.points.get(1).y, searchRect.points.get(2).x, searchRect.points.get(3).y); if (intersects) { return false; } @@ -159,10 +168,10 @@ public class AreaReader { } boolean ignoreCenter(int maxscale, int idxLon, int idxLat) { - int centerScale = (int) Math.round(maxscale * .2) -1; + int centerScale = (int) Math.round(maxscale * .2) - 1; if (centerScale < 0) return false; if (idxLon >= -centerScale && idxLon <= centerScale && - idxLat >= -centerScale && idxLat <= centerScale) return true; + idxLat >= -centerScale && idxLat <= centerScale) return true; return false; } @@ -173,4 +182,55 @@ public class AreaReader { return searchRect.isWithin((long) p1x, (long) p1y) && searchRect.isWithin(p2x, p2y); } + + public void writeAreaInfo(String filename, MatchedWaypoint wp, List ais) throws Exception { + DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(filename))); + + wp.writeToStream(dos); + for (AreaInfo ai : ais) { + dos.writeInt(ai.direction); + dos.writeDouble(ai.elevStart); + dos.writeInt(ai.ways); + dos.writeInt(ai.greenWays); + dos.writeInt(ai.riverWays); + dos.writeInt(ai.elev50); + } + dos.close(); + } + + public void readAreaInfo(File fai, MatchedWaypoint wp, List ais) { + DataInputStream dis = null; + MatchedWaypoint ep = null; + try { + dis = new DataInputStream(new BufferedInputStream(new FileInputStream(fai))); + ep = MatchedWaypoint.readFromStream(dis); + if (Math.abs(ep.waypoint.ilon - wp.waypoint.ilon) > 500 && + Math.abs(ep.waypoint.ilat - wp.waypoint.ilat) > 500) { + return; + } + if (Math.abs(ep.radius - wp.radius) > 500) { + return; + } + for (int i = 0; i < 4; i++) { + int direction = dis.readInt(); + AreaInfo ai = new AreaInfo(direction); + ai.elevStart = dis.readDouble(); + ai.ways = dis.readInt(); + ai.greenWays = dis.readInt(); + ai.riverWays = dis.readInt(); + ai.elev50 = dis.readInt(); + ais.add(ai); + } + } catch (IOException e) { + ais.clear(); + } finally { + if (dis != null) { + try { + dis.close(); + } catch (IOException e) { + } + } + } + } + } diff --git a/brouter-core/src/main/java/btools/router/RoutingContext.java b/brouter-core/src/main/java/btools/router/RoutingContext.java index 8daa9da..f5b2bf3 100644 --- a/brouter-core/src/main/java/btools/router/RoutingContext.java +++ b/brouter-core/src/main/java/btools/router/RoutingContext.java @@ -36,6 +36,7 @@ public final class RoutingContext { public Map keyValues; public String rawTrackPath; + public String rawAreaPath; public String getProfileName() { String name = localFunction == null ? "unknown" : localFunction; diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index f58a618..f4e1109 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -583,87 +583,109 @@ public class RoutingEngine extends Thread { MatchedWaypoint wpt1 = new MatchedWaypoint(); wpt1.waypoint = wp; - wpt1.name = "start_info"; - List listStart = new ArrayList<>(); - listStart.add(wpt1); - - List wpliststart = new ArrayList<>(); - wpliststart.add(wp); - - List listOne = new ArrayList<>(); - - for (int a = 45; a < 360; a +=90) { - int[] pos = CheapRuler.destination(wp.ilon, wp.ilat, searchRadius * 1.5, a); - OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); - onn.name = "via" + a; - listOne.add(onn); - - MatchedWaypoint wpt = new MatchedWaypoint(); - wpt.waypoint = onn; - wpt.name = onn.name; - listStart.add(wpt); - } - - RoutingEngine re = null; - RoutingContext rc = new RoutingContext(); - String name = routingContext.localFunction; - int idx = name.lastIndexOf(File.separator); - rc.localFunction = idx == -1 ? "dummy" : name.substring(0, idx+1) + "dummy.brf"; - - re = new RoutingEngine(null, null, segmentDir, wpliststart, rc, BROUTER_ENGINEMODE_ROUNDTRIP); - rc.useDynamicDistance = true; - re.matchWaypointsToNodes(listStart); - re.resetCache(true); - - int numForest = rc.expctxWay.getLookupKey("estimated_forest_class"); - int numRiver = rc.expctxWay.getLookupKey("estimated_river_class"); - - OsmNode start1 = re.nodesCache.getStartNode(listStart.get(0).node1.getIdFromPos()); - - double elev = (start1 == null ? 0 : start1.getElev()); // listOne.get(0).crosspoint.getElev(); + wpt1.name = "info"; + wpt1.radius = searchRadius * 1.5; List ais = new ArrayList<>(); - int maxlon = Integer.MIN_VALUE; - int minlon = Integer.MAX_VALUE; - int maxlat = Integer.MIN_VALUE; - int minlat = Integer.MAX_VALUE; - for (OsmNodeNamed on: listOne) { - maxlon = Math.max(on.ilon, maxlon); - minlon = Math.min(on.ilon, minlon); - maxlat = Math.max(on.ilat, maxlat); - minlat = Math.min(on.ilat, minlat); - } - OsmNogoPolygon searchRect = new OsmNogoPolygon(true); - searchRect.addVertex(maxlon, maxlat); - searchRect.addVertex(maxlon, minlat); - searchRect.addVertex(minlon, minlat); - searchRect.addVertex(minlon, maxlat); - - for (int a = 0; a < 4; a++) { - rc.ai = new AreaInfo(a * 90 +90); - rc.ai.elevStart = elev; - rc.ai.numForest = numForest; - rc.ai.numRiver = numRiver; - - rc.ai.polygon = new OsmNogoPolygon(true); - rc.ai.polygon.addVertex(wp.ilon, wp.ilat); - rc.ai.polygon.addVertex(listOne.get(a).ilon, listOne.get(a).ilat); - if (a==3) - rc.ai.polygon.addVertex(listOne.get(0).ilon, listOne.get(0).ilat); - else - rc.ai.polygon.addVertex(listOne.get(a+1).ilon, listOne.get(a+1).ilat); - - ais.add(rc.ai); + AreaReader areareader = new AreaReader(); + if (routingContext.rawAreaPath != null) { + File fai = new File(routingContext.rawAreaPath); + if (fai.exists()) { + areareader.readAreaInfo(fai, wpt1, ais); + } } - int maxscale = Math.abs(searchRect.points.get(2).x - searchRect.points.get(0).x); - maxscale = Math.max(1, Math.round(maxscale/31250f/2)+1); + if (ais.isEmpty()) { + List listStart = new ArrayList<>(); + listStart.add(wpt1); - new AreaReader().getDirectAllData(segmentDir, rc, wp, maxscale, rc.expctxWay, searchRect, ais); + List wpliststart = new ArrayList<>(); + wpliststart.add(wp); + + List listOne = new ArrayList<>(); + + for (int a = 45; a < 360; a += 90) { + int[] pos = CheapRuler.destination(wp.ilon, wp.ilat, searchRadius * 1.5, a); + OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); + onn.name = "via" + a; + listOne.add(onn); + + MatchedWaypoint wpt = new MatchedWaypoint(); + wpt.waypoint = onn; + wpt.name = onn.name; + listStart.add(wpt); + } + + RoutingEngine re = null; + RoutingContext rc = new RoutingContext(); + String name = routingContext.localFunction; + int idx = name.lastIndexOf(File.separator); + rc.localFunction = idx == -1 ? "dummy" : name.substring(0, idx + 1) + "dummy.brf"; + + re = new RoutingEngine(null, null, segmentDir, wpliststart, rc, BROUTER_ENGINEMODE_ROUNDTRIP); + rc.useDynamicDistance = true; + re.matchWaypointsToNodes(listStart); + re.resetCache(true); + + int numForest = rc.expctxWay.getLookupKey("estimated_forest_class"); + int numRiver = rc.expctxWay.getLookupKey("estimated_river_class"); + + OsmNode start1 = re.nodesCache.getStartNode(listStart.get(0).node1.getIdFromPos()); + + double elev = (start1 == null ? 0 : start1.getElev()); // listOne.get(0).crosspoint.getElev(); + + int maxlon = Integer.MIN_VALUE; + int minlon = Integer.MAX_VALUE; + int maxlat = Integer.MIN_VALUE; + int minlat = Integer.MAX_VALUE; + for (OsmNodeNamed on : listOne) { + maxlon = Math.max(on.ilon, maxlon); + minlon = Math.min(on.ilon, minlon); + maxlat = Math.max(on.ilat, maxlat); + minlat = Math.min(on.ilat, minlat); + } + OsmNogoPolygon searchRect = new OsmNogoPolygon(true); + searchRect.addVertex(maxlon, maxlat); + searchRect.addVertex(maxlon, minlat); + searchRect.addVertex(minlon, minlat); + searchRect.addVertex(minlon, maxlat); + + for (int a = 0; a < 4; a++) { + rc.ai = new AreaInfo(a * 90 + 90); + rc.ai.elevStart = elev; + rc.ai.numForest = numForest; + rc.ai.numRiver = numRiver; + + rc.ai.polygon = new OsmNogoPolygon(true); + rc.ai.polygon.addVertex(wp.ilon, wp.ilat); + rc.ai.polygon.addVertex(listOne.get(a).ilon, listOne.get(a).ilat); + if (a == 3) + rc.ai.polygon.addVertex(listOne.get(0).ilon, listOne.get(0).ilat); + else + rc.ai.polygon.addVertex(listOne.get(a + 1).ilon, listOne.get(a + 1).ilat); + + ais.add(rc.ai); + } + + int maxscale = Math.abs(searchRect.points.get(2).x - searchRect.points.get(0).x); + maxscale = Math.max(1, Math.round(maxscale / 31250f / 2) + 1); + + areareader.getDirectAllData(segmentDir, rc, wp, maxscale, rc.expctxWay, searchRect, ais); + + if (routingContext.rawAreaPath != null) { + try { + wpt1.radius = searchRadius * 1.5; + areareader.writeAreaInfo(routingContext.rawAreaPath, wpt1, ais); + } catch (Exception e) { + } + } + rc.ai = null; + + } logInfo("round trip execution time = " + (System.currentTimeMillis() - start) / 1000. + " seconds"); - //for (AreaInfo ai: ais) { + // for (AreaInfo ai: ais) { // System.out.println("\n" + ai.toString()); //} @@ -693,8 +715,6 @@ public class RoutingEngine extends Thread { return (int) (Math.random()*360); } - rc.ai = null; - int angle = ais.get(0).direction; return angle - 45 + (int) (Math.random()*90); }