added write/read area info

This commit is contained in:
afischerdev 2025-03-18 10:26:45 +01:00
parent a3c3b1e17b
commit ddeb08c67d
3 changed files with 159 additions and 78 deletions

View File

@ -1,11 +1,19 @@
package btools.router; 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.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List; import java.util.List;
import btools.codec.DataBuffers; import btools.codec.DataBuffers;
import btools.codec.MicroCache; import btools.codec.MicroCache;
import btools.expressions.BExpressionContextWay; import btools.expressions.BExpressionContextWay;
import btools.mapaccess.MatchedWaypoint;
import btools.mapaccess.NodesCache; import btools.mapaccess.NodesCache;
import btools.mapaccess.OsmFile; import btools.mapaccess.OsmFile;
import btools.mapaccess.OsmLink; import btools.mapaccess.OsmLink;
@ -99,7 +107,8 @@ public class AreaReader {
// check for quadrant border // 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); 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) { if (intersects) {
return false; return false;
} }
@ -159,10 +168,10 @@ public class AreaReader {
} }
boolean ignoreCenter(int maxscale, int idxLon, int idxLat) { 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 (centerScale < 0) return false;
if (idxLon >= -centerScale && idxLon <= centerScale && if (idxLon >= -centerScale && idxLon <= centerScale &&
idxLat >= -centerScale && idxLat <= centerScale) return true; idxLat >= -centerScale && idxLat <= centerScale) return true;
return false; return false;
} }
@ -173,4 +182,55 @@ public class AreaReader {
return searchRect.isWithin((long) p1x, (long) p1y) && return searchRect.isWithin((long) p1x, (long) p1y) &&
searchRect.isWithin(p2x, p2y); searchRect.isWithin(p2x, p2y);
} }
public void writeAreaInfo(String filename, MatchedWaypoint wp, List<AreaInfo> 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<AreaInfo> 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) {
}
}
}
}
} }

View File

@ -36,6 +36,7 @@ public final class RoutingContext {
public Map<String, String> keyValues; public Map<String, String> keyValues;
public String rawTrackPath; public String rawTrackPath;
public String rawAreaPath;
public String getProfileName() { public String getProfileName() {
String name = localFunction == null ? "unknown" : localFunction; String name = localFunction == null ? "unknown" : localFunction;

View File

@ -583,87 +583,109 @@ public class RoutingEngine extends Thread {
MatchedWaypoint wpt1 = new MatchedWaypoint(); MatchedWaypoint wpt1 = new MatchedWaypoint();
wpt1.waypoint = wp; wpt1.waypoint = wp;
wpt1.name = "start_info"; wpt1.name = "info";
List<MatchedWaypoint> listStart = new ArrayList<>(); wpt1.radius = searchRadius * 1.5;
listStart.add(wpt1);
List<OsmNodeNamed> wpliststart = new ArrayList<>();
wpliststart.add(wp);
List<OsmNodeNamed> 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();
List<AreaInfo> ais = new ArrayList<>(); List<AreaInfo> ais = new ArrayList<>();
int maxlon = Integer.MIN_VALUE; AreaReader areareader = new AreaReader();
int minlon = Integer.MAX_VALUE; if (routingContext.rawAreaPath != null) {
int maxlat = Integer.MIN_VALUE; File fai = new File(routingContext.rawAreaPath);
int minlat = Integer.MAX_VALUE; if (fai.exists()) {
for (OsmNodeNamed on: listOne) { areareader.readAreaInfo(fai, wpt1, ais);
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); if (ais.isEmpty()) {
maxscale = Math.max(1, Math.round(maxscale/31250f/2)+1); List<MatchedWaypoint> listStart = new ArrayList<>();
listStart.add(wpt1);
new AreaReader().getDirectAllData(segmentDir, rc, wp, maxscale, rc.expctxWay, searchRect, ais); List<OsmNodeNamed> wpliststart = new ArrayList<>();
wpliststart.add(wp);
List<OsmNodeNamed> 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"); logInfo("round trip execution time = " + (System.currentTimeMillis() - start) / 1000. + " seconds");
//for (AreaInfo ai: ais) { // for (AreaInfo ai: ais) {
// System.out.println("\n" + ai.toString()); // System.out.println("\n" + ai.toString());
//} //}
@ -693,8 +715,6 @@ public class RoutingEngine extends Thread {
return (int) (Math.random()*360); return (int) (Math.random()*360);
} }
rc.ai = null;
int angle = ais.get(0).direction; int angle = ais.get(0).direction;
return angle - 45 + (int) (Math.random()*90); return angle - 45 + (int) (Math.random()*90);
} }