OK, so it's proving to be a little harder to fix than I thought but I
have high hopes for this version.

BTW - Valentijn, this version could help routing through "the tunnel".
Please see if it changes anything.
diff --git a/src/uk/me/parabola/imgfmt/app/Area.java b/src/uk/me/parabola/imgfmt/app/Area.java
index 13b0ee4..9279b40 100644
--- a/src/uk/me/parabola/imgfmt/app/Area.java
+++ b/src/uk/me/parabola/imgfmt/app/Area.java
@@ -149,19 +149,30 @@ public class Area {
 	}
 
 	public boolean contains(Coord co) {
+		// return true if co is inside the Area (it may touch the
+		// boundary)
 		return co.getLatitude() >= minLat
 				&& co.getLatitude() <= maxLat
 				&& co.getLongitude() >= minLong
 				&& co.getLongitude() <= maxLong;
 	}
 
+	public boolean insideBoundary(Coord co) {
+		// return true if co is inside the Area and doesn't touch the
+		// boundary
+		return co.getLatitude() > minLat
+				&& co.getLatitude() < maxLat
+				&& co.getLongitude() > minLong
+				&& co.getLongitude() < maxLong;
+	}
+
 	public boolean isEmpty() {
 		return minLat >= maxLat || minLong >= maxLong;
 	}
 
-	public boolean allInside(List<Coord> coords) {
+	public boolean allInsideBoundary(List<Coord> coords) {
 		for (Coord co : coords) {
-			if (!contains(co))
+			if (!insideBoundary(co))
 				return false;
 		}
 		return true;
diff --git a/src/uk/me/parabola/imgfmt/app/Coord.java b/src/uk/me/parabola/imgfmt/app/Coord.java
index 54cdc5f..84df73c 100644
--- a/src/uk/me/parabola/imgfmt/app/Coord.java
+++ b/src/uk/me/parabola/imgfmt/app/Coord.java
@@ -78,6 +78,10 @@ public class Coord implements Comparable<Coord> {
 		++highwayCount;
 	}
 
+	public void zeroHighwayCount() {
+		highwayCount = 0;
+	}
+
 	public int hashCode() {
 		return latitude+longitude;
 	}
diff --git a/src/uk/me/parabola/mkgmap/general/LineClipper.java b/src/uk/me/parabola/mkgmap/general/LineClipper.java
index 55aa51d..ecce6df 100644
--- a/src/uk/me/parabola/mkgmap/general/LineClipper.java
+++ b/src/uk/me/parabola/mkgmap/general/LineClipper.java
@@ -44,7 +44,7 @@ public class LineClipper {
 		// If all the points are inside the box then we just return null
 		// to show that nothing was done and the line can be used.  This
 		// is expected to be the normal case.
-		if (a == null || a.allInside(coords))
+		if (a == null || a.allInsideBoundary(coords))
 			return null;
 
 		class LineCollector {
@@ -135,11 +135,43 @@ public class LineClipper {
 		assert t[1] <= 1;
 
 		double d = 0.5;
-		if (t[0] > 0)
+		Coord orig0 = ends[0];
+		Coord orig1 = ends[1];
+		if (t[0] > 0) {
 			ends[0] = new Coord((int) (y0 + t[0] * dy + d), (int) (x0 + t[0] * dx + d));
+		}
+		else if(!a.insideBoundary(ends[0])) {
+			// flag as boundary node
+			ends[0].zeroHighwayCount();
+		}
 
-		if (t[1] < 1)
+		if (t[1] < 1) {
 			ends[1] = new Coord((int)(y0 + t[1] * dy + d), (int) (x0 + t[1] * dx + d));
+		}
+		else if(!a.insideBoundary(ends[1])) {
+			// flag as boundary node
+			ends[1].zeroHighwayCount();
+		}
+
+		if(ends[0].equals(ends[1])) {
+			// throw away zero length segments
+			return null;
+		}
+
+		if(ends[0] != orig0 && ends[0].equals(orig0)) {
+			// new Coord has same coordinates as original so use the
+			// original Coord and flag it as a boundary node
+			orig0.zeroHighwayCount();
+			ends[0] = orig0;
+		}
+
+		if(ends[1] != orig1 && ends[1].equals(orig1)) {
+			// new Coord has same coordinates as original so use the
+			// original Coord and flag it as a boundary node
+			orig1.zeroHighwayCount();
+			ends[1] = orig1;
+		}
+
 		return ends;
 	}
 
diff --git a/src/uk/me/parabola/mkgmap/general/RoadNetwork.java b/src/uk/me/parabola/mkgmap/general/RoadNetwork.java
index 9bc6b83..5b8d8db 100644
--- a/src/uk/me/parabola/mkgmap/general/RoadNetwork.java
+++ b/src/uk/me/parabola/mkgmap/general/RoadNetwork.java
@@ -103,6 +103,9 @@ public class RoadNetwork {
 
 				if(node1 == node2)
 					log.error("Road " + road.getRoadDef().getName() + " (OSM id " + road.getRoadDef().getId() + ") contains consecutive identical nodes - routing will be broken");
+				else if(arcLength == 0) {
+					log.error("Road " + road.getRoadDef().getName() + " (OSM id " + road.getRoadDef().getId() + ") contains zero length arc");
+				}
 
 				// Create forward arc from node1 to node2
 				Coord bearing = coordList.get(lastIndex + 1);
_______________________________________________
mkgmap-dev mailing list
[email protected]
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev

Reply via email to