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() {
|
||||
try {
|
||||
long startTime = System.currentTimeMillis();
|
||||
MatchedWaypoint wpt1 = new MatchedWaypoint();
|
||||
wpt1.waypoint = waypoints.get(0);
|
||||
wpt1.name = "roundtrip";
|
||||
|
||||
routingContext.useDynamicDistance = true;
|
||||
double searchRadius = (routingContext.roundTripDistance == null ? 1500 : routingContext.roundTripDistance);
|
||||
double direction = (routingContext.startDirection == null ? -1 : routingContext.startDirection);
|
||||
double directionAdd = (routingContext.roundTripDirectionAdd == null ? ROUNDTRIP_DEFAULT_DIRECTIONADD : routingContext.roundTripDirectionAdd);
|
||||
if (direction == -1) direction = getRandomDirectionByRouting(waypoints.get(0), searchRadius);
|
||||
double searchRadius = (routingContext.roundTripDistance == null ? 1500 :routingContext.roundTripDistance);
|
||||
double direction = (routingContext.startDirection == null ? -1 :routingContext.startDirection);
|
||||
double directionAdd = (routingContext.roundTripDirectionAdd == null ? ROUNDTRIP_DEFAULT_DIRECTIONADD :routingContext.roundTripDirectionAdd);
|
||||
//if (direction == -1) direction = getRandomDirectionFromRouting(waypoints.get(0), searchRadius);
|
||||
if (direction == -1) direction = getRandomDirectionFromData(waypoints.get(0), searchRadius);
|
||||
|
||||
if (routingContext.allowSamewayback) {
|
||||
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);
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
@ -698,6 +830,8 @@ public class RoutingEngine extends Thread {
|
||||
return angle - 45 + (int) (Math.random()*90);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void postElevationCheck(OsmTrack track) {
|
||||
OsmPathElement lastPt = null;
|
||||
OsmPathElement startPt = null;
|
||||
|
||||
@ -17,7 +17,7 @@ import btools.codec.WaypointMatcher;
|
||||
import btools.util.ByteDataReader;
|
||||
import btools.util.Crc32;
|
||||
|
||||
final class OsmFile {
|
||||
final public class OsmFile {
|
||||
private RandomAccessFile is = null;
|
||||
private long fileOffset;
|
||||
|
||||
|
||||
@ -143,4 +143,14 @@ final public class PhysicalFile {
|
||||
elevationType = dis.readByte();
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
|
||||
public void close(){
|
||||
if (ra != null) {
|
||||
try {
|
||||
ra.close();
|
||||
} catch (Exception ee) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user