The patch connects unclosed ways out of the bounding box. In some situation this fixes a problem with multipolygons that are larger that the tile.

WanMil
Index: src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java      
(revision 1952)
+++ src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java      
(working copy)
@@ -3,6 +3,7 @@
 import java.awt.*;
 import java.awt.geom.Area;
 import java.awt.geom.Line2D;
+import java.util.AbstractMap;
 import java.util.ArrayList;
 import java.util.BitSet;
 import java.util.Collection;
@@ -324,11 +325,8 @@
         *            a list of ways
         */
        private void closeWays(ArrayList<JoinedWay> wayList) {
-               // this is a VERY simple algorithm to close the ways
-               // need to be improved
-
                for (JoinedWay way : wayList) {
-                       if (way.isClosed() || way.getPoints().size() <= 3) {
+                       if (way.isClosed() || way.getPoints().size() < 3) {
                                continue;
                        }
                        Coord p1 = way.getPoints().get(0);
@@ -424,6 +422,93 @@
                        }
                }
        }
+       
+       private boolean connectUnclosedWays(List<JoinedWay> allWays) {
+               List<JoinedWay> unclosed = new ArrayList<JoinedWay>();
+
+               for (JoinedWay w : allWays) {
+                       if (w.isClosed() == false) {
+                               unclosed.add(w);
+                       }
+               }
+               // try to connect ways lying outside or on the bbox
+               if (unclosed.size() >= 2) {
+                       log.debug("Checking",unclosed.size(),"unclosed ways for 
connections outside the bbox");
+                       Map<Coord, JoinedWay> outOfBboxPoints = new 
HashMap<Coord, JoinedWay>();
+                       
+                       // check all ways for endpoints outside or on the bbox
+                       for (JoinedWay w : unclosed) {
+                               Coord c1 = w.getPoints().get(0);
+                               if (bbox.insideBoundary(c1)==false) {
+                                       log.debug("Point",c1,"of 
way",w.getId(),"outside bbox");
+                                       outOfBboxPoints.put(c1, w);
+                               }
+
+                               Coord c2 = 
w.getPoints().get(w.getPoints().size()-1);
+                               if (bbox.insideBoundary(c2)==false) {
+                                       log.debug("Point",c2,"of 
way",w.getId(),"outside bbox");
+                                       outOfBboxPoints.put(c2, w);
+                               }
+                       }
+                       
+                       if (outOfBboxPoints.size() < 2) {
+                               log.debug(outOfBboxPoints.size(),"point outside 
the bbox. No connection possible.");
+                               return false;
+                       }
+                       
+                       List<Entry<Coord,Coord>> coordPairs = new 
ArrayList<Entry<Coord,Coord>>();
+                       ArrayList<Coord> coords = new 
ArrayList<Coord>(outOfBboxPoints.keySet());
+                       for (int i = 0; i < coords.size(); i++) {
+                               for (int j = i + 1; j < coords.size(); j++) {
+                                       Coord c1 = coords.get(i);
+                                       Coord c2 = coords.get(j);
+                                       if (lineCutsBbox(c1, c2) == false) {
+                                               coordPairs.add(new 
AbstractMap.SimpleEntry<Coord, Coord>(
+                                                               c1, c2));
+                                       }
+                               }
+                       }
+                       
+                       // sort the point pairs by distance
+                       Collections.sort(coordPairs, new 
Comparator<Entry<Coord,Coord>>() {
+                               public int compare(Entry<Coord, Coord> o1,
+                                               Entry<Coord, Coord> o2) {
+                                       double d1 = 
o1.getKey().distance(o1.getValue());
+                                       double d2 = 
o2.getKey().distance(o2.getValue());
+                                       return Double.compare(d1, d2);
+                               }
+                       });
+                       
+                       if (coordPairs.isEmpty()) {
+                               log.debug("All potential connections cross the 
bbox. No connection possible.");
+                       } else {
+                               Entry<Coord, Coord> closestGap = 
coordPairs.get(0);
+
+                               JoinedWay w1 = 
outOfBboxPoints.get(closestGap.getKey());
+                               JoinedWay w2 = 
outOfBboxPoints.get(closestGap.getValue());
+                               log.debug("Connect", w1, "with", w2);
+
+                               if (w1 == w2) {
+                                       log.error("Cannot connect the a way to 
itself "+w1);
+                               } else {
+                               
+                               if 
(w1.getPoints().get(0).equals(closestGap.getKey())) {
+                                       Collections.reverse(w1.getPoints());
+                               }
+                               if 
(w2.getPoints().get(0).equals(closestGap.getValue()) == false) {
+                                       Collections.reverse(w2.getPoints());
+                               }
+
+                               w1.getPoints().addAll(w2.getPoints());
+                               w1.addWay(w2);
+                               allWays.remove(w2);
+                               return true;
+                               }
+                       }
+                       
+               }
+               return false;
+       }
 
        /**
         * Removes all ways non closed ways from the given list (
@@ -619,6 +704,10 @@
                outerTags = new HashMap<String,String>();
                
                closeWays(polygons);
+               
+               while (connectUnclosedWays(polygons)) {
+                       closeWays(polygons);
+               }
                removeUnclosedWays(polygons);
 
                // now only closed ways are left => polygons only
_______________________________________________
mkgmap-dev mailing list
[email protected]
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev

Reply via email to