Am 30.12.2009 01:13, schrieb Ronny Klier:
Am 20:59, schrieb Mark Burton:
Hi,
I'm trying to understand how the --generate-sea stuff works. I want to
know how it decides whether an "island" is water or land. The code does
not really contain sufficient comments for me to work out what it's
doing. I would expect it to close coastline segments that reach the
tile boundary in a direction that is consistent with the "water on the
right" convention but I can't see that in the code. Can anyone help
please?
Thanks,
Mark
Hi,
I'm working for a while on the flooded island problem. Here's what I
found:
To solve this I added code to find the nearest border and add a point
at this border. There should be no new problem through this because
the created point is in an empty area. (sea attached patch)
I hope this helps a bit.
Ronny
Sorry, I forgot to attach the patch in my last mail
Index: Osm5XmlHandler.java
===================================================================
--- Osm5XmlHandler.java (Revision 1445)
+++ Osm5XmlHandler.java (Arbeitskopie)
@@ -604,7 +604,6 @@
// "soft clip" each way that crosses a boundary by adding a point
// at each place where it meets the boundary
private void makeBoundaryNodes() {
- log.info("Making boundary nodes");
int numBoundaryNodesDetected = 0;
int numBoundaryNodesAdded = 0;
for(Way way : wayMap.values()) {
@@ -663,7 +662,6 @@
}
}
}
- log.info("Making boundary nodes - finished (" +
numBoundaryNodesAdded + " added, " + numBoundaryNodesDetected + " detected)");
}
private void incArcCount(Map<Coord, Integer> map, Coord p, int inc) {
@@ -1114,7 +1112,7 @@
* border to Poland)
* 2. Create a "sea sector" only for this
shoreline segment. This may also be the best solution
* (see German border to the Netherlands
where the shoreline continues in the Netherlands)
- * The first choice may lead to "flooded"
areas, the second may lead to "triangles".
+ * The first choice may lead to "flooded"
areas, the second may lead to "triangles" or inverted areas.
*
* Usually, the first choice is appropriate if
the segment is "nearly" closed.
*/
@@ -1129,19 +1127,22 @@
if (nearlyClosed) {
// close the way
points.add(pStart);
+ log.warn("adding pseudo island " +
w.toBrowseURL());
seaRelation.addElement("inner", w);
}
else {
- seaId = (1L << 62) + nextFakeId++;
- sea = new Way(seaId);
- sea.getPoints().addAll(points);
- sea.addPoint(new
Coord(pEnd.getLatitude(), pStart.getLongitude()));
- sea.addPoint(pStart);
- sea.addTag("natural", "sea");
- log.info("sea: ", sea);
- wayMap.put(seaId, sea);
- seaRelation.addElement("outer", sea);
- generateSeaBackground = false;
+ // create additional points at next
border
+ if (null == hStart) {
+ hStart =
getNextEdgeHit(seaBounds, pStart);
+ w.getPoints().add(0,
hStart.getPoint(seaBounds));
+ }
+ if (null == hEnd) {
+ hEnd =
getNextEdgeHit(seaBounds, pEnd);
+
w.getPoints().add(hEnd.getPoint(seaBounds));
+ }
+ log.debug("hits (second try): ",
hStart, hEnd);
+ hitMap.put(hStart, w);
+ hitMap.put(hEnd, null);
}
}
else {
@@ -1179,17 +1180,17 @@
EdgeHit hNext;
if (segment != null) {
// add the segment and get the "ending
hit"
- log.info("adding: ", segment);
+ log.warn("adding: ", segment.getId());
w.getPoints().addAll(segment.getPoints());
hNext = getEdgeHit(seaBounds,
segment.getPoints().get(segment.getPoints().size()-1));
}
else {
- w.addPoint(hit.getPoint(seaBounds));
+ Coord p = hit.getPoint(seaBounds);
+ w.addPoint(p);
hNext = hits.higher(hit);
if (hNext == null)
hNext = hFirst;
- Coord p;
if (hit.compareTo(hNext) < 0) {
log.info("joining: ", hit,
hNext);
for (int i=hit.edge;
i<hNext.edge; i++) {
@@ -1214,19 +1215,18 @@
w.addPoint(p);
}
}
- w.addPoint(hNext.getPoint(seaBounds));
+ p = hNext.getPoint(seaBounds);
+ w.addPoint(p);
}
hits.remove(hit);
hit = hNext;
} while (!hits.isEmpty() && !hit.equals(hFirst));
-
if (!w.isClosed())
w.getPoints().add(w.getPoints().get(0));
- log.info("adding non-island landmass, hits.size()=" +
hits.size());
+ log.info("adding non-island landmass, hits.size()=" +
hits.size(), w);
//w.addTag("highway", "motorway");
seaRelation.addElement("inner", w);
}
-
seaRelation = new MultiPolygonRelation(seaRelation, wayMap);
relationMap.put(multiId, seaRelation);
seaRelation.processElements();
@@ -1323,6 +1323,36 @@
return null;
}
+ private EdgeHit getNextEdgeHit(Area a, Coord p)
+ {
+ int lat = p.getLatitude();
+ int lon = p.getLongitude();
+ int minLat = a.getMinLat();
+ int maxLat = a.getMaxLat();
+ int minLong = a.getMinLong();
+ int maxLong = a.getMaxLong();
+
+ log.info(String.format("getNextEdgeHit: (%d %d) (%d %d %d %d)",
lat, lon, minLat, minLong, maxLat, maxLong));
+ int min = lat - minLat;
+ int i = 0;
+ double l = ((double)(lon - minLong))/(maxLong-minLong);
+ if (maxLong - lon < min) {
+ min = maxLong - lon;
+ i = 1;
+ l = ((double)(lat - minLat))/(maxLat-minLat);
+ }
+ if (maxLat - lat < min) {
+ min = maxLat - lat;
+ i = 2;
+ l = ((double)(maxLong - lon))/(maxLong-minLong);
+ }
+ if (lon - minLong < min) {
+ i = 3;
+ l = ((double)(maxLat - lat))/(maxLat-minLat);
+ }
+ return new EdgeHit(i, l);
+ }
+
private void concatenateWays(List<Way> ways) {
Map<Coord, Way> beginMap = new HashMap<Coord, Way>();
_______________________________________________
mkgmap-dev mailing list
[email protected]
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev