Calculate route from center of city

This commit is contained in:
Victor Shcherb 2014-10-29 01:56:25 +01:00
parent 8f0ebe1046
commit 34a4b9825e
2 changed files with 79 additions and 24 deletions

View file

@ -6,6 +6,7 @@ import java.io.IOException;
import java.text.MessageFormat;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.PriorityQueue;
import net.osmand.PlatformUtil;
@ -64,7 +65,7 @@ public class BinaryRoutePlanner {
* return list of segments
*/
@SuppressWarnings("unused")
FinalRouteSegment searchRouteInternal(final RoutingContext ctx, RouteSegment start, RouteSegment end) throws InterruptedException, IOException {
FinalRouteSegment searchRouteInternal(final RoutingContext ctx, RouteSegmentPoint start, RouteSegmentPoint end) throws InterruptedException, IOException {
// measure time
ctx.timeToLoad = 0;
ctx.visitedSegments = 0;
@ -128,12 +129,11 @@ public class BinaryRoutePlanner {
visitedDirectSegments, doNotAddIntersections);
}
updateCalculationProgress(ctx, graphDirectSegments, graphReverseSegments);
if(ctx.getPlanRoadDirection() <= 0 && graphReverseSegments.isEmpty()){
throw new IllegalArgumentException("Route is not found to selected target point.");
}
if(ctx.getPlanRoadDirection() >= 0 && graphDirectSegments.isEmpty()){
throw new IllegalArgumentException("Route is not found from selected start point.");
}
checkIfGraphIsEmpty(ctx, ctx.getPlanRoadDirection() <= 0, graphReverseSegments, end, visitedOppositeSegments,
"Route is not found to selected target point.");
checkIfGraphIsEmpty(ctx, ctx.getPlanRoadDirection() >= 0, graphDirectSegments, start, visitedDirectSegments,
"Route is not found from selected start point.");
if (ctx.planRouteIn2Directions()) {
forwardSearch = (nonHeuristicSegmentsComparator.compare(graphDirectSegments.peek(), graphReverseSegments.peek()) < 0);
// if (graphDirectSegments.size() * 2 > graphReverseSegments.size()) {
@ -167,6 +167,47 @@ public class BinaryRoutePlanner {
}
protected void checkIfGraphIsEmpty(final RoutingContext ctx, boolean allowDirection,
PriorityQueue<RouteSegment> graphSegments, RouteSegmentPoint pnt, TLongObjectHashMap<RouteSegment> visited,
String msg) {
if (allowDirection && graphSegments.isEmpty()) {
if (pnt.others != null) {
Iterator<RouteSegmentPoint> pntIterator = pnt.others.iterator();
while (pntIterator.hasNext()) {
RouteSegmentPoint next = pntIterator.next();
boolean visitedAlready = false;
if (next.getSegmentStart() > 0 && visited.containsKey(calculateRoutePointId(next, false))) {
visitedAlready = true;
} else if (next.getSegmentStart() < next.getRoad().getPointsLength() - 1
&& visited.containsKey(calculateRoutePointId(next, true))) {
visitedAlready = true;
}
pntIterator.remove();
if (!visitedAlready) {
float estimatedDistance = (float) estimatedDistance(ctx, ctx.targetX, ctx.targetY, ctx.startX,
ctx.startY);
RouteSegment pos = next.initRouteSegment(true);
RouteSegment neg = next.initRouteSegment(false);
if (pos != null) {
pos.distanceToEnd = estimatedDistance;
graphSegments.add(pos);
}
if (neg != null) {
neg.distanceToEnd = estimatedDistance;
graphSegments.add(neg);
}
println("Reiterate point with new start/destination " + next.getRoad());
break;
}
}
if (graphSegments.isEmpty()) {
throw new IllegalArgumentException(msg);
}
}
}
}
private void initQueuesWithStartEnd(final RoutingContext ctx, RouteSegment start, RouteSegment end,
PriorityQueue<RouteSegment> graphDirectSegments, PriorityQueue<RouteSegment> graphReverseSegments) {
RouteSegment startPos = start.initRouteSegment(true);
@ -700,12 +741,16 @@ public class BinaryRoutePlanner {
public void visitSegment(RouteSegment segment, int segmentEnd, boolean poll);
}
public static class RouteSegmentPoint extends RouteSegment{
public RouteSegmentPoint(RouteDataObject road, int segmentStart) {
public static class RouteSegmentPoint extends RouteSegment {
public RouteSegmentPoint(RouteDataObject road, int segmentStart, double dist) {
super(road, segmentStart);
this.dist = dist;
}
public double dist;
public int preciseX;
public int preciseY;
public List<RouteSegmentPoint> others;
}
public static class RouteSegment {

View file

@ -4,6 +4,8 @@ package net.osmand.router;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import net.osmand.NativeLibrary;
@ -14,7 +16,6 @@ import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
import net.osmand.binary.RouteDataObject;
import net.osmand.data.LatLon;
import net.osmand.data.QuadPoint;
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
import net.osmand.router.BinaryRoutePlanner.RouteSegmentPoint;
import net.osmand.util.MapUtils;
@ -59,30 +60,39 @@ public class RoutePlannerFrontEnd {
if (dataObjects.isEmpty()) {
ctx.loadTileData(px, py, 15, dataObjects);
}
RouteSegmentPoint road = null;
double sdist = 0;
List<RouteSegmentPoint> list = new ArrayList<BinaryRoutePlanner.RouteSegmentPoint>();
for (RouteDataObject r : dataObjects) {
if (r.getPointsLength() > 1) {
RouteSegmentPoint road = null;
for (int j = 1; j < r.getPointsLength(); j++) {
QuadPoint pr = MapUtils.getProjectionPoint31(px, py, r.getPoint31XTile(j - 1),
r.getPoint31YTile(j - 1), r.getPoint31XTile(j ), r.getPoint31YTile(j ));
double currentsDist = squareDist((int) pr.x, (int)pr.y, px, py);
if (road == null || currentsDist < sdist) {
if (road == null || currentsDist < road.dist) {
RouteDataObject ro = new RouteDataObject(r);
road = new RouteSegmentPoint(ro, j);
road = new RouteSegmentPoint(ro, j, currentsDist);
road.preciseX = (int) pr.x;
road.preciseY = (int) pr.y;
sdist = currentsDist;
}
}
if(road != null) {
list.add(road);
}
}
}
// if (road != null) {
// re-register the best road because one more point was inserted
// ctx.registerRouteDataObject(road.getRoad());
// }
return road;
Collections.sort(list, new Comparator<RouteSegmentPoint>() {
@Override
public int compare(RouteSegmentPoint o1, RouteSegmentPoint o2) {
return Double.compare(o1.dist, o2.dist);
}
});
if(list.size() > 0) {
RouteSegmentPoint ps = list.remove(0);
ps.others = list;
return ps;
}
return null;
}
@ -271,7 +281,7 @@ public class RoutePlannerFrontEnd {
}
private List<RouteSegmentResult> searchRouteInternalPrepare(final RoutingContext ctx, RouteSegment start, RouteSegment end,
private List<RouteSegmentResult> searchRouteInternalPrepare(final RoutingContext ctx, RouteSegmentPoint start, RouteSegmentPoint end,
PrecalculatedRouteDirection routeDirection) throws IOException, InterruptedException {
ctx.initStartAndTargetPoints(start, end);
if(routeDirection != null) {
@ -391,8 +401,8 @@ public class RoutePlannerFrontEnd {
}
@SuppressWarnings("static-access")
private List<RouteSegmentResult> searchRoute(final RoutingContext ctx, RouteSegment start, RouteSegment end, PrecalculatedRouteDirection routeDirection)
throws IOException, InterruptedException {
private List<RouteSegmentResult> searchRoute(final RoutingContext ctx, RouteSegmentPoint start, RouteSegmentPoint end,
PrecalculatedRouteDirection routeDirection) throws IOException, InterruptedException {
if(ctx.SHOW_GC_SIZE){
long h1 = ctx.runGCUsedMemory();
float mb = (1 << 20);