Hopefully, these changes will fix the bad routing directions we have
been seeing recently - please test and report success/failure.
diff --git a/src/uk/me/parabola/imgfmt/app/net/RouteNode.java b/src/uk/me/parabola/imgfmt/app/net/RouteNode.java
index 2b8ca79..ea6651e 100644
--- a/src/uk/me/parabola/imgfmt/app/net/RouteNode.java
+++ b/src/uk/me/parabola/imgfmt/app/net/RouteNode.java
@@ -15,6 +15,8 @@
package uk.me.parabola.imgfmt.app.net;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
@@ -339,6 +341,29 @@ public class RouteNode implements Comparable<RouteNode> {
return false;
}
+ private static boolean rightTurnRequired(int inHeading, int outHeading, int sideHeading) {
+ // given the headings of the incoming, outgoing and side
+ // roads, decide whether a side road is to the left or the
+ // right of the main road
+
+ // side road heading must be < inverse of incoming heading
+ int a = sideHeading - (inHeading + 180);
+ while(a < -180)
+ a += 360;
+ while(a > 180)
+ a -= 360;
+ if(a > 0)
+ return false;
+
+ // side road heading must be > outgoing heading
+ a = sideHeading - outHeading;
+ while(a < -180)
+ a += 360;
+ while(a > 180)
+ a -= 360;
+ return a > 0;
+ }
+
private static int ATH_OUTGOING = 1;
private static int ATH_INCOMING = 2;
@@ -375,7 +400,25 @@ public class RouteNode implements Comparable<RouteNode> {
final int minDiffBetweenOutgoingAndOtherArcs = 45;
final int minDiffBetweenIncomingAndOtherArcs = 50;
- for(RouteArc inArc : incomingArcs) {
+ // list of outgoing arcs discovered at this node
+ List<RouteArc> outgoingArcs = new ArrayList<RouteArc>();
+
+ // sort incoming arcs by decreasing class/speed
+ List<RouteArc> inArcs = new ArrayList<RouteArc>(incomingArcs);
+
+ Collections.sort(inArcs, new Comparator<RouteArc>() {
+ public int compare(RouteArc ra1, RouteArc ra2) {
+ int c1 = ra1.getRoadDef().getRoadClass();
+ int c2 = ra2.getRoadDef().getRoadClass();
+ if(c1 == c2)
+ return (ra2.getRoadDef().getRoadSpeed() -
+ ra1.getRoadDef().getRoadSpeed());
+ return c2 - c1;
+ }
+ });
+
+ // look at incoming arcs in order of decreasing class/speed
+ for(RouteArc inArc : inArcs) {
if(!inArc.isForward() && inArc.getRoadDef().isOneway()) {
// ignore reverse arc if road is oneway
@@ -442,16 +485,27 @@ public class RouteNode implements Comparable<RouteNode> {
oa.getRoadDef().getRoadSpeed() == inArcSpeed) {
if(outArc != null) {
// multiple arcs have the same road
- // class as the incoming arc so don't
- // use any of them as the outgoing arc
+ // class/speed as the incoming arc so
+ // don't use any of them as the
+ // outgoing arc
outArc = null;
break;
}
- outArc = oa;
+ // oa has the same class/speed as inArc,
+ // now check that oa is not part of
+ // another road by matching names rather
+ // than class/speed because they could be
+ // different
+ boolean paired = false;
+ for(RouteArc z : arcs)
+ if(z != oa && possiblySameRoad(z, oa))
+ paired = true;
+ if(!paired)
+ outArc = oa;
}
}
if(outArc != null)
- log.info("Matched outgoing arc " + outArc.getRoadDef() + " to " + inArc.getRoadDef() + " using road class (" + inArcClass + ") and speed (" + inArcSpeed + ")");
+ log.info("Matched outgoing arc " + outArc.getRoadDef() + " to " + inArc.getRoadDef() + " using road class (" + inArcClass + ") and speed (" + inArcSpeed + ") at " + coord.toOSMURL());
}
// if we did not find the outgoing arc, give up with
@@ -460,6 +514,10 @@ public class RouteNode implements Comparable<RouteNode> {
//log.info("Can't continue road " + inArc.getRoadDef() + " at " + coord.toOSMURL());
continue;
}
+
+ // remember that this arc is an outgoing arc
+ outgoingArcs.add(outArc);
+
int outHeading = outArc.getInitialHeading();
int mainHeadingDelta = outHeading - inHeading;
while(mainHeadingDelta > 180)
@@ -507,6 +565,13 @@ public class RouteNode implements Comparable<RouteNode> {
continue;
}
+ if(outgoingArcs.contains(otherArc)) {
+ // this arc was previously matched as an
+ // outgoing arc so we don't want to change its
+ // heading now
+ continue;
+ }
+
int otherHeading = otherArc.getInitialHeading();
int outToOtherDelta = otherHeading - outHeading;
while(outToOtherDelta > 180)
@@ -520,13 +585,13 @@ public class RouteNode implements Comparable<RouteNode> {
inToOtherDelta += 360;
int newHeading = otherHeading;
- if(outToOtherDelta > 0) {
+ if(rightTurnRequired(inHeading, outHeading, otherHeading)) {
// side road to the right
if((mask & ATH_OUTGOING) != 0 &&
- outToOtherDelta < minDiffBetweenOutgoingAndOtherArcs)
+ Math.abs(outToOtherDelta) < minDiffBetweenOutgoingAndOtherArcs)
newHeading = outHeading + minDiffBetweenOutgoingAndOtherArcs;
if((mask & ATH_INCOMING) != 0 &&
- inToOtherDelta < minDiffBetweenIncomingAndOtherArcs) {
+ Math.abs(inToOtherDelta) < minDiffBetweenIncomingAndOtherArcs) {
int nh = inHeading + minDiffBetweenIncomingAndOtherArcs;
if(nh > newHeading)
newHeading = nh;
@@ -535,13 +600,13 @@ public class RouteNode implements Comparable<RouteNode> {
if(newHeading > 180)
newHeading -= 360;
}
- else if(outToOtherDelta < 0) {
+ else {
// side road to the left
if((mask & ATH_OUTGOING) != 0 &&
- outToOtherDelta > -minDiffBetweenOutgoingAndOtherArcs)
+ Math.abs(outToOtherDelta) < minDiffBetweenOutgoingAndOtherArcs)
newHeading = outHeading - minDiffBetweenOutgoingAndOtherArcs;
if((mask & ATH_INCOMING) != 0 &&
- inToOtherDelta > -minDiffBetweenIncomingAndOtherArcs) {
+ Math.abs(inToOtherDelta) < minDiffBetweenIncomingAndOtherArcs) {
int nh = inHeading - minDiffBetweenIncomingAndOtherArcs;
if(nh < newHeading)
newHeading = nh;
_______________________________________________
mkgmap-dev mailing list
[email protected]
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev