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