new surrounding check'
This commit is contained in:
parent
1040780c2d
commit
6a8863510d
161
brouter-core/src/main/java/btools/router/AreaReader.java
Normal file
161
brouter-core/src/main/java/btools/router/AreaReader.java
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
package btools.router;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import btools.codec.DataBuffers;
|
||||||
|
import btools.codec.MicroCache;
|
||||||
|
import btools.expressions.BExpressionContextWay;
|
||||||
|
import btools.mapaccess.NodesCache;
|
||||||
|
import btools.mapaccess.OsmFile;
|
||||||
|
import btools.mapaccess.OsmLink;
|
||||||
|
import btools.mapaccess.OsmNode;
|
||||||
|
import btools.mapaccess.OsmNodesMap;
|
||||||
|
import btools.mapaccess.PhysicalFile;
|
||||||
|
|
||||||
|
public class AreaReader {
|
||||||
|
|
||||||
|
File segmentFolder;
|
||||||
|
|
||||||
|
public void getDirectAllData(File folder, RoutingContext rc, OsmNodeNamed wp, int maxscale, BExpressionContextWay expctxWay, OsmNogoPolygon searchRect, List<AreaInfo> ais) {
|
||||||
|
this.segmentFolder = folder;
|
||||||
|
|
||||||
|
int cellsize = 1000000 / 32;
|
||||||
|
int scale = maxscale;
|
||||||
|
int count = 0;
|
||||||
|
int used = 0;
|
||||||
|
for (int idxLat = -scale; idxLat <= scale; idxLat++) {
|
||||||
|
for (int idxLon = -scale; idxLon <= scale; idxLon++) {
|
||||||
|
int tmplon = wp.ilon + cellsize * idxLon;
|
||||||
|
int tmplat = wp.ilat + cellsize * idxLat;
|
||||||
|
if (getDirectData(tmplon, tmplat, rc, expctxWay, searchRect, ais)) used++;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getDirectData(int inlon, int inlat, RoutingContext rc, BExpressionContextWay expctxWay, OsmNogoPolygon searchRect, List<AreaInfo> ais) {
|
||||||
|
int lonDegree = inlon / 1000000;
|
||||||
|
int latDegree = inlat / 1000000;
|
||||||
|
int lonMod5 = (int) lonDegree % 5;
|
||||||
|
int latMod5 = (int) latDegree % 5;
|
||||||
|
|
||||||
|
int lon = (int) lonDegree - 180 - lonMod5;
|
||||||
|
String slon = lon < 0 ? "W" + (-lon) : "E" + lon;
|
||||||
|
|
||||||
|
int lat = (int) latDegree - 90 - latMod5;
|
||||||
|
String slat = lat < 0 ? "S" + (-lat) : "N" + lat;
|
||||||
|
lon = 180000000 + (int) (lon * 1000000 + 0.5);
|
||||||
|
lat = 90000000 + (int) (lat * 1000000 + 0.5);
|
||||||
|
|
||||||
|
String filenameBase = slon + "_" + slat;
|
||||||
|
|
||||||
|
File file = new File(segmentFolder, filenameBase + ".rd5");
|
||||||
|
PhysicalFile pf = null;
|
||||||
|
|
||||||
|
long maxmem = rc.memoryclass * 1024L * 1024L; // in MB
|
||||||
|
NodesCache nodesCache = new NodesCache(segmentFolder, expctxWay, rc.forceSecondaryData, maxmem, null, false);
|
||||||
|
|
||||||
|
OsmNodesMap nodesMap = new OsmNodesMap();
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
DataBuffers dataBuffers = new DataBuffers();
|
||||||
|
pf = new PhysicalFile(file, dataBuffers, -1, -1);
|
||||||
|
int div = pf.divisor;
|
||||||
|
|
||||||
|
OsmFile osmf = new OsmFile(pf, lonDegree, latDegree, dataBuffers);
|
||||||
|
if (osmf.hasData()) {
|
||||||
|
int cellsize = 1000000 / div;
|
||||||
|
int tmplon = inlon; // + cellsize * idxLon;
|
||||||
|
int tmplat = inlat; // + cellsize * idxLat;
|
||||||
|
int lonIdx = tmplon / cellsize;
|
||||||
|
int latIdx = tmplat / cellsize;
|
||||||
|
int subIdx = (latIdx - div * latDegree) * div + (lonIdx - div * lonDegree);
|
||||||
|
|
||||||
|
int subLonIdx = (lonIdx - div * lonDegree);
|
||||||
|
int subLatIdx = (latIdx - div * latDegree);
|
||||||
|
|
||||||
|
OsmNogoPolygon dataRect = new OsmNogoPolygon(true);
|
||||||
|
lon = lonDegree * 1000000;
|
||||||
|
lat = latDegree * 1000000;
|
||||||
|
int tmplon2 = lon + cellsize * (subLonIdx);
|
||||||
|
int tmplat2 = lat + cellsize * (subLatIdx);
|
||||||
|
dataRect.addVertex(tmplon2, tmplat2);
|
||||||
|
|
||||||
|
tmplon2 = lon + cellsize * (subLonIdx + 1);
|
||||||
|
tmplat2 = lat + cellsize * (subLatIdx);
|
||||||
|
dataRect.addVertex(tmplon2, tmplat2);
|
||||||
|
|
||||||
|
tmplon2 = lon + cellsize * (subLonIdx + 1);
|
||||||
|
tmplat2 = lat + cellsize * (subLatIdx + 1);
|
||||||
|
dataRect.addVertex(tmplon2, tmplat2);
|
||||||
|
|
||||||
|
tmplon2 = lon + cellsize * (subLonIdx);
|
||||||
|
tmplat2 = lat + cellsize * (subLatIdx + 1);
|
||||||
|
dataRect.addVertex(tmplon2, tmplat2);
|
||||||
|
|
||||||
|
boolean intersects = searchRect.intersects(dataRect.points.get(0).x, dataRect.points.get(0).y, dataRect.points.get(2).x, dataRect.points.get(2).y);
|
||||||
|
if (!intersects)
|
||||||
|
intersects = searchRect.intersects(dataRect.points.get(1).x, dataRect.points.get(1).y, dataRect.points.get(3).x, dataRect.points.get(3).y);
|
||||||
|
if (!intersects)
|
||||||
|
intersects = containsRect(searchRect, dataRect.points.get(0).x, dataRect.points.get(0).y, dataRect.points.get(2).x, dataRect.points.get(2).y);
|
||||||
|
|
||||||
|
if (!intersects) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
MicroCache segment = osmf.createMicroCache(lonIdx, latIdx, dataBuffers, expctxWay, null, true, null);
|
||||||
|
|
||||||
|
if (segment != null /*&& segment.getDataSize()>0*/) {
|
||||||
|
int size = segment.getSize();
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
long id = segment.getIdForIndex(i);
|
||||||
|
OsmNode node = new OsmNode(id);
|
||||||
|
if (segment.getAndClear(id)) {
|
||||||
|
node.parseNodeBody(segment, nodesMap, expctxWay);
|
||||||
|
if (node.firstlink instanceof OsmLink) {
|
||||||
|
for (OsmLink link = node.firstlink; link != null; link = link.getNext(node)) {
|
||||||
|
OsmNode nextNode = link.getTarget(node);
|
||||||
|
if (nextNode.firstlink == null)
|
||||||
|
continue; // don't care about dead ends
|
||||||
|
if (nextNode.firstlink.descriptionBitmap == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (AreaInfo ai : ais) {
|
||||||
|
if (ai.polygon.isWithin(node.ilon, node.ilat)) {
|
||||||
|
ai.checkAreaInfo(expctxWay, node.getElev(), nextNode.firstlink.descriptionBitmap);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if (pf != null)
|
||||||
|
try {
|
||||||
|
pf.close();
|
||||||
|
} catch (Exception ee) {
|
||||||
|
}
|
||||||
|
nodesCache.close();
|
||||||
|
nodesCache = null;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
in this case the polygon is 'only' a rectangle
|
||||||
|
*/
|
||||||
|
boolean containsRect(OsmNogoPolygon searchRect, int p1x, int p1y, int p2x, int p2y) {
|
||||||
|
return searchRect.isWithin((long) p1x, (long) p1y) &&
|
||||||
|
searchRect.isWithin(p2x, p2y);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -485,15 +485,13 @@ public class RoutingEngine extends Thread {
|
|||||||
public void doRoundTrip() {
|
public void doRoundTrip() {
|
||||||
try {
|
try {
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
MatchedWaypoint wpt1 = new MatchedWaypoint();
|
|
||||||
wpt1.waypoint = waypoints.get(0);
|
|
||||||
wpt1.name = "roundtrip";
|
|
||||||
|
|
||||||
routingContext.useDynamicDistance = true;
|
routingContext.useDynamicDistance = true;
|
||||||
double searchRadius = (routingContext.roundTripDistance == null ? 1500 : routingContext.roundTripDistance);
|
double searchRadius = (routingContext.roundTripDistance == null ? 1500 :routingContext.roundTripDistance);
|
||||||
double direction = (routingContext.startDirection == null ? -1 : routingContext.startDirection);
|
double direction = (routingContext.startDirection == null ? -1 :routingContext.startDirection);
|
||||||
double directionAdd = (routingContext.roundTripDirectionAdd == null ? ROUNDTRIP_DEFAULT_DIRECTIONADD : routingContext.roundTripDirectionAdd);
|
double directionAdd = (routingContext.roundTripDirectionAdd == null ? ROUNDTRIP_DEFAULT_DIRECTIONADD :routingContext.roundTripDirectionAdd);
|
||||||
if (direction == -1) direction = getRandomDirectionByRouting(waypoints.get(0), searchRadius);
|
//if (direction == -1) direction = getRandomDirectionFromRouting(waypoints.get(0), searchRadius);
|
||||||
|
if (direction == -1) direction = getRandomDirectionFromData(waypoints.get(0), searchRadius);
|
||||||
|
|
||||||
if (routingContext.allowSamewayback) {
|
if (routingContext.allowSamewayback) {
|
||||||
int[] pos = CheapRuler.destination(waypoints.get(0).ilon, waypoints.get(0).ilat, searchRadius, direction);
|
int[] pos = CheapRuler.destination(waypoints.get(0).ilon, waypoints.get(0).ilat, searchRadius, direction);
|
||||||
@ -565,7 +563,141 @@ public class RoutingEngine extends Thread {
|
|||||||
waypoints.add(onn);
|
waypoints.add(onn);
|
||||||
}
|
}
|
||||||
|
|
||||||
int getRandomDirectionByRouting(OsmNodeNamed wp, double searchRadius) {
|
int getRandomDirectionFromData(OsmNodeNamed wp, double searchRadius) {
|
||||||
|
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
|
||||||
|
int preferredRandomType = 0;
|
||||||
|
boolean consider_elevation = routingContext.expctxWay.getVariableValue("consider_elevation", 0f) == 1f;
|
||||||
|
boolean consider_forest = routingContext.expctxWay.getVariableValue("consider_forest", 0f) == 1f;
|
||||||
|
boolean consider_river = routingContext.expctxWay.getVariableValue("consider_river", 0f) == 1f;
|
||||||
|
if (consider_elevation) {
|
||||||
|
preferredRandomType = AreaInfo.RESULT_TYPE_ELEV50;
|
||||||
|
} else if (consider_forest) {
|
||||||
|
preferredRandomType = AreaInfo.RESULT_TYPE_GREEN;
|
||||||
|
} else if (consider_river) {
|
||||||
|
preferredRandomType = AreaInfo.RESULT_TYPE_RIVER;
|
||||||
|
} else {
|
||||||
|
return (int) (Math.random()*360);
|
||||||
|
}
|
||||||
|
|
||||||
|
MatchedWaypoint wpt1 = new MatchedWaypoint();
|
||||||
|
wpt1.waypoint = wp;
|
||||||
|
wpt1.name = "start_info";
|
||||||
|
List<MatchedWaypoint> listStart = new ArrayList<>();
|
||||||
|
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();
|
||||||
|
rc.localFunction = "dummy";
|
||||||
|
|
||||||
|
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<>();
|
||||||
|
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);
|
||||||
|
|
||||||
|
new AreaReader().getDirectAllData(segmentDir, rc, wp, maxscale, rc.expctxWay, searchRect, ais);
|
||||||
|
|
||||||
|
logInfo("round trip execution time = " + (System.currentTimeMillis() - start) / 1000. + " seconds");
|
||||||
|
|
||||||
|
//for (AreaInfo ai: ais) {
|
||||||
|
// System.out.println("\n" + ai.toString());
|
||||||
|
//}
|
||||||
|
|
||||||
|
switch (preferredRandomType) {
|
||||||
|
case AreaInfo.RESULT_TYPE_ELEV50:
|
||||||
|
Collections.sort(ais, new Comparator<>() {
|
||||||
|
public int compare(AreaInfo o1, AreaInfo o2) {
|
||||||
|
return o2.getElev50Weight() - o1.getElev50Weight();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case AreaInfo.RESULT_TYPE_GREEN:
|
||||||
|
Collections.sort(ais, new Comparator<>() {
|
||||||
|
public int compare(AreaInfo o1, AreaInfo o2) {
|
||||||
|
return o2.getGreen() - o1.getGreen();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case AreaInfo.RESULT_TYPE_RIVER:
|
||||||
|
Collections.sort(ais, new Comparator<>() {
|
||||||
|
public int compare(AreaInfo o1, AreaInfo o2) {
|
||||||
|
return o2.getRiver() - o1.getRiver();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (int) (Math.random()*360);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc.ai = null;
|
||||||
|
|
||||||
|
int angle = ais.get(0).direction;
|
||||||
|
return angle - 45 + (int) (Math.random()*90);
|
||||||
|
}
|
||||||
|
|
||||||
|
int getRandomDirectionFromRouting(OsmNodeNamed wp, double searchRadius) {
|
||||||
|
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
|
|
||||||
@ -698,6 +830,8 @@ public class RoutingEngine extends Thread {
|
|||||||
return angle - 45 + (int) (Math.random()*90);
|
return angle - 45 + (int) (Math.random()*90);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void postElevationCheck(OsmTrack track) {
|
private void postElevationCheck(OsmTrack track) {
|
||||||
OsmPathElement lastPt = null;
|
OsmPathElement lastPt = null;
|
||||||
OsmPathElement startPt = null;
|
OsmPathElement startPt = null;
|
||||||
|
|||||||
@ -17,7 +17,7 @@ import btools.codec.WaypointMatcher;
|
|||||||
import btools.util.ByteDataReader;
|
import btools.util.ByteDataReader;
|
||||||
import btools.util.Crc32;
|
import btools.util.Crc32;
|
||||||
|
|
||||||
final class OsmFile {
|
final public class OsmFile {
|
||||||
private RandomAccessFile is = null;
|
private RandomAccessFile is = null;
|
||||||
private long fileOffset;
|
private long fileOffset;
|
||||||
|
|
||||||
|
|||||||
@ -143,4 +143,14 @@ final public class PhysicalFile {
|
|||||||
elevationType = dis.readByte();
|
elevationType = dis.readByte();
|
||||||
} catch (Exception e) {}
|
} catch (Exception e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void close(){
|
||||||
|
if (ra != null) {
|
||||||
|
try {
|
||||||
|
ra.close();
|
||||||
|
} catch (Exception ee) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user