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

Reply via email to