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