This version should do the same as v3 as far as the bug fix is
concerned but I have cleaned things up a little so please test this
version if possible.
Thanks,
Mark
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..bc84197 100644
--- a/src/uk/me/parabola/imgfmt/app/Coord.java
+++ b/src/uk/me/parabola/imgfmt/app/Coord.java
@@ -36,7 +36,8 @@ import uk.me.parabola.imgfmt.Utils;
public class Coord implements Comparable<Coord> {
private final int latitude;
private final int longitude;
- private int highwayCount; // number of highways that use this point
+ private byte highwayCount; // number of highways that use this point
+ private boolean onBoundary; // true if point lies on a boundary
/**
* Construct from co-ordinates that are already in map-units.
@@ -75,7 +76,17 @@ public class Coord implements Comparable<Coord> {
}
public void incHighwayCount() {
- ++highwayCount;
+ // don't let it wrap
+ if(highwayCount < Byte.MAX_VALUE)
+ ++highwayCount;
+ }
+
+ public boolean getOnBoundary() {
+ return onBoundary;
+ }
+
+ public void setOnBoundary(boolean onBoundary) {
+ this.onBoundary = onBoundary;
}
public int hashCode() {
diff --git a/src/uk/me/parabola/mkgmap/general/LineClipper.java b/src/uk/me/parabola/mkgmap/general/LineClipper.java
index 55aa51d..7423c3c 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,56 @@ 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) {
+ // line is clipped so create the new end point and mark it
+ // as a boundary node
ends[0] = new Coord((int) (y0 + t[0] * dy + d), (int) (x0 + t[0] * dx + d));
+ ends[0].setOnBoundary(true);
+ }
+ else if(!a.insideBoundary(ends[0])) {
+ // point lies on the boundary so it's a boundary node
+ ends[0].setOnBoundary(true);
+ }
- if (t[1] < 1)
+ if (t[1] < 1) {
+ // line is clipped so create the new end point and mark it
+ // as a boundary node
ends[1] = new Coord((int)(y0 + t[1] * dy + d), (int) (x0 + t[1] * dx + d));
+ ends[1].setOnBoundary(true);
+ }
+ else if(!a.insideBoundary(ends[1])) {
+ // point lies on the boundary so it's a boundary node
+ ends[1].setOnBoundary(true);
+ }
+
+ // zero length segments can be created if one point lies on
+ // the boundary and the other is outside of the area
+ if(ends[0].equals(ends[1])) {
+ // throw away zero length segments
+ return null;
+ }
+
+ // these last two tests catch the situation where the new point
+ // on the clipped line is so close to the original point that
+ // they have the same coordinates - in which case we need to use
+ // the original point so it maintains its identity
+
+ 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.setOnBoundary(true);
+ 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.setOnBoundary(true);
+ 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);
diff --git a/src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java b/src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
index aa5bab1..1b84766 100644
--- a/src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
+++ b/src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
@@ -68,7 +68,6 @@ public class StyledConverter implements OsmConverter {
private Clipper clipper = Clipper.NULL_CLIPPER;
private Area bbox;
- private Set<Coord> boundaryCoords = new HashSet<Coord>();
// restrictions associates lists of turn restrictions with the
// Coord corresponding to the restrictions' 'via' node
@@ -432,7 +431,6 @@ public class StyledConverter implements OsmConverter {
if(bbox != null) {
List<List<Coord>> lineSegs = LineClipper.clip(bbox, way.getPoints());
- boundaryCoords = new HashSet<Coord>();
if (lineSegs != null) {
@@ -444,8 +442,9 @@ public class StyledConverter implements OsmConverter {
nWay.copyTags(way);
for(Coord co : lco) {
nWay.addPoint(co);
- if(co.getHighwayCount() == 0) {
- boundaryCoords.add(co);
+ if(co.getOnBoundary()) {
+ // this point lies on a boundary
+ // make sure it becomes a node
co.incHighwayCount();
}
}
@@ -723,7 +722,7 @@ public class StyledConverter implements OsmConverter {
hasInternalNodes = true;
Coord coord = points.get(n);
Integer nodeId = nodeIdMap.get(coord);
- boolean boundary = boundaryCoords.contains(coord);
+ boolean boundary = coord.getOnBoundary();
if(boundary) {
log.info("Way " + debugWayName + "'s point #" + n + " at " + points.get(n).toDegreeString() + " is a boundary node");
}
_______________________________________________
mkgmap-dev mailing list
[email protected]
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev