I came to the conclusion that the first patch only tries to covers a shortcoming of the LineClipper.

I started a small investigation and observed the following problems of the LineClipper:
* Lines are split when two subsequent coordinates are equal
* In case a line is closed it's quite probable that two unconnected lines are returned by the LineClipper * The clip algorithm seems to be a bit inefficient because it does not check the common case first if both coordinates are within the bounding box

The patch fixes all described problems.
The code in the SeaGenerator the joins the ways after the bounding box clipping can be removed because of the LineClipper fixes.

@Steve: Can you have a short look on the patch? The LineClipper was committed by you so it might be good to have a small code review.

WanMil

The patch removes artefacts from the LineClipper that might cause
floodings.

WanMil

Index: src/uk/me/parabola/mkgmap/reader/osm/SeaGenerator.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/SeaGenerator.java      (revision 1952)
+++ src/uk/me/parabola/mkgmap/reader/osm/SeaGenerator.java      (working copy)
@@ -453,23 +453,6 @@
                        List<List<Coord>> clipped = LineClipper.clip(bounds, 
points);
                        if (clipped != null) {
                                log.info("clipping", segment);
-                               if (clipped.size() > 0) {
-                                       // the LineClipper sometimes returns 
un-joined clips
-                                       // need to rejoin them here
-                                       log.info(clipped.size(),"clippings. Try 
to join them.");
-                                       List<Way> clippedWays = new 
ArrayList<Way>(clipped.size());
-                                       for (List<Coord> clippedPoints : 
clipped) {
-                                               clippedWays.add(new 
Way(FakeIdGenerator.makeFakeId(), clippedPoints));
-                                       }
-                                       clippedWays = joinWays(clippedWays);
-                                       if (clippedWays.size() != 
clipped.size()) {
-                                               clipped = new 
ArrayList<List<Coord>>(clippedWays.size());
-                                               for (Way w : clippedWays) {
-                                                       
clipped.add(w.getPoints());
-                                               }
-                                       }
-                                       log.info(clipped.size(),"joined 
clippings.");
-                               }
                                toBeRemoved.add(segment);
                                for (List<Coord> pts : clipped) {
                                        long id = FakeIdGenerator.makeFakeId();
@@ -479,7 +462,7 @@
                        }
                }
 
-               log.info("clipping: adding ", toBeAdded.size(), ", removing ", 
toBeRemoved.size());
+               log.info("clipping: adding", toBeAdded.size(), ", removing", 
toBeRemoved.size());
                shoreline.removeAll(toBeRemoved);
                shoreline.addAll(toBeAdded);
        }
Index: src/uk/me/parabola/mkgmap/general/LineClipper.java
===================================================================
--- src/uk/me/parabola/mkgmap/general/LineClipper.java  (revision 1952)
+++ src/uk/me/parabola/mkgmap/general/LineClipper.java  (working copy)
@@ -78,9 +78,27 @@
                // lines from it.
                for (int i = 0; i <= coords.size() - 2; i++) {
                        Coord[] pair = {coords.get(i), coords.get(i+1)};
+                       if (pair[0].equals(pair[1])) {
+                               continue;
+                       }
                        Coord[] clippedPair = clip(a, pair);
                        seg.add(clippedPair);
                }
+               
+               // in case the coords build a closed way the first and the last 
clipped line 
+               // might have to be joined
+               if (seg.ret.size() >= 2 && 
coords.get(0).equals(coords.get(coords.size()-1))) {
+                       List<Coord> firstSeg = seg.ret.get(0);
+                       List<Coord> lastSeg = seg.ret.get(seg.ret.size()-1);
+                       // compare the first point of the first segment with 
the last point of 
+                       // the last segment
+                       if 
(firstSeg.get(0).equals(lastSeg.get(lastSeg.size()-1))) {
+                               // they are the same so the two segments should 
be joined
+                               lastSeg.addAll(firstSeg.subList(1, 
firstSeg.size()));
+                               seg.ret.remove(0);
+                       }
+               }
+               
                return seg.ret;
        }
 
@@ -100,6 +118,10 @@
        public static Coord[] clip(Area a, Coord[] ends) {
                assert ends.length == 2;
 
+               if (a.insideBoundary(ends[0]) && a.insideBoundary(ends[1])) {
+                       return ends;
+               }
+               
                int x0 = ends[0].getLongitude();
                int y0 = ends[0].getLatitude();
 
_______________________________________________
mkgmap-dev mailing list
[email protected]
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev

Reply via email to