This patch extends the sea generation stuff to cope with anti-islands
(water inside, land outside and, presumably, where the anti-treasure
is hidden). Anti-islands are tagged natural=water (you can't use
natural=sea because it will be beneath the surrounding land polygon).
Note that if your map contains any islands whose direction is incorrect,
they will now be filled with water. To help find such islands, a
warning message is output when an anti-island is discovered. The upside
is that if your map contains anti-islands whose direction is correct,
they will now become visible.
Mark
diff --git a/src/uk/me/parabola/mkgmap/reader/osm/Way.java b/src/uk/me/parabola/mkgmap/reader/osm/Way.java
index a8812bf..53b50d2 100644
--- a/src/uk/me/parabola/mkgmap/reader/osm/Way.java
+++ b/src/uk/me/parabola/mkgmap/reader/osm/Way.java
@@ -138,6 +138,26 @@ public class Way extends Element {
(lon + numPoints / 2) / numPoints);
}
+ // returns true if the way is a closed polygon with a clockwise
+ // direction
+ public boolean clockwise() {
+
+ if(points.size() < 3 || !points.get(0).equals(points.get(points.size() - 1)))
+ return false;
+
+ long area = 0;
+ Coord p1 = points.get(0);
+ for(int i = 1; i < points.size(); ++i) {
+ Coord p2 = points.get(i);
+ area += ((long)p1.getLongitude() * p2.getLatitude() -
+ (long)p2.getLongitude() * p1.getLatitude());
+ p1 = p2;
+ }
+
+ // this test looks to be inverted but gives the expected result!
+ return area < 0;
+ }
+
public String kind() {
return "way";
}
diff --git a/src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java b/src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java
index 7cffaed..b3d249a 100644
--- a/src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java
+++ b/src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java
@@ -1168,12 +1168,16 @@ class Osm5XmlHandler extends DefaultHandler {
}
}
- // create a "inner" way for each island
+ boolean haveAntiIslands = false;
+
for (Way w : islands) {
log.info("adding island " + w);
- if(generateSeaUsingMP)
+ if(generateSeaUsingMP) {
+ // create a "inner" way for each island
seaRelation.addElement("inner", w);
+ }
else {
+ Way savew = w;
if(!FakeIdGenerator.isFakeId(w.getId())) {
Way w1 = new Way(FakeIdGenerator.makeFakeId());
w1.getPoints().addAll(w.getPoints());
@@ -1183,12 +1187,27 @@ class Osm5XmlHandler extends DefaultHandler {
w1.addTag(tag, w.getTag(tag));
w = w1;
}
- w.addTag(landTag[0], landTag[1]);
+ // determine where the water is
+ if(w.clockwise()) {
+ // water on the inside of the poly, it's an
+ // "anti-island" so tag with natural=water (to
+ // make it visible above the land)
+ w.addTag("natural", "water");
+ haveAntiIslands = true;
+ log.warn("Found anti-island (water on the inside, land on the outside) starting at " + w.getPoints().get(0).toOSMURL());
+ }
+ else {
+ // water on the outside of the poly, it's an
+ // island so tag it as land
+ w.addTag(landTag[0], landTag[1]);
+ }
+
wayMap.put(w.getId(), w);
}
}
boolean generateSeaBackground = true;
+ boolean coastlineIntersectsBoundary = false;
// the remaining shoreline segments should intersect the boundary
// find the intersection points and store them in a SortedMap
@@ -1273,6 +1292,7 @@ class Osm5XmlHandler extends DefaultHandler {
log.debug("hits (second try): ", hStart, hEnd);
hitMap.put(hStart, w);
hitMap.put(hEnd, null);
+ coastlineIntersectsBoundary = true;
}
else {
// show the coastline even though we can't produce
@@ -1285,8 +1305,17 @@ class Osm5XmlHandler extends DefaultHandler {
log.debug("hits: ", hStart, hEnd);
hitMap.put(hStart, w);
hitMap.put(hEnd, null);
+ coastlineIntersectsBoundary = true;
}
}
+
+ if(!coastlineIntersectsBoundary && haveAntiIslands) {
+ // the coast doesn't reach the boundary and the tile
+ // contains "anti-islands" so assume what we have is land
+ // with a sea in the middle
+ generateSeaBackground = false;
+ }
+
if (generateSeaBackground) {
seaId = FakeIdGenerator.makeFakeId();
sea = new Way(seaId);
_______________________________________________
mkgmap-dev mailing list
[email protected]
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev