diff --git a/src/uk/me/parabola/mkgmap/general/LineClipper.java b/src/uk/me/parabola/mkgmap/general/LineClipper.java index 55aa51d..06c61f4 100644 --- a/src/uk/me/parabola/mkgmap/general/LineClipper.java +++ b/src/uk/me/parabola/mkgmap/general/LineClipper.java @@ -135,11 +135,17 @@ public class LineClipper { assert t[1] <= 1; double d = 0.5; - if (t[0] > 0) - ends[0] = new Coord((int) (y0 + t[0] * dy + d), (int) (x0 + t[0] * dx + d)); + if (t[0] > 0) { + double lat = y0 + t[0] * dy; + double lon = x0 + t[0] * dx; + ends[0] = new Coord((int) ( lat + (lat > 0 ? d : -d)), (int) (lon + (lon > 0 ? d : -d))); + } - if (t[1] < 1) - ends[1] = new Coord((int)(y0 + t[1] * dy + d), (int) (x0 + t[1] * dx + d)); + if (t[1] < 1) { + double lat = y0 + t[1] * dy; + double lon = x0 + t[1] * dx; + ends[1] = new Coord((int)(lat + (lat > 0 ? d : -d)), (int) (lon + (lon > 0 ? d : -d))); + } return ends; } diff --git a/test/uk/me/parabola/mkgmap/general/LineClipperTest.java b/test/uk/me/parabola/mkgmap/general/LineClipperTest.java index 80fdbb9..78fa03b 100644 --- a/test/uk/me/parabola/mkgmap/general/LineClipperTest.java +++ b/test/uk/me/parabola/mkgmap/general/LineClipperTest.java @@ -51,6 +51,11 @@ public class LineClipperTest { new Coord(132, 230) }; assertArrayEquals("example result", result, listList.get(0).toArray()); + + // All points should be inside Area + for (List list : listList) { + assertTrue("all coords should be inside area", a.allInside(list)); + } } /** @@ -77,6 +82,10 @@ public class LineClipperTest { for (List lco : list) assertTrue("empty list", !lco.isEmpty()); + // All points should be inside Area + for (List lco : list) + assertTrue("all coords should be inside area", a.allInside(lco)); + // Check values Coord[] firstExpectedLine = { new Coord(100, 108), @@ -106,4 +115,25 @@ public class LineClipperTest { List> list = LineClipper.clip(a, l); assertNull("all lines inside", list); } + + /** + * This test comes from real osm data that caused a problem. + */ + @Test + public void testAreaInSecondQuadrant() { + Area a = new Area(435809, -3916474, 436165, -3915960); + Coord[] co = { + new Coord(436009, -3915955), + new Coord(435956, -3916034), + }; + + List> listList = LineClipper.clip(a, Arrays.asList(co)); + assertTrue("list should be empty", !listList.isEmpty()); + + // All points should be inside Area + for (List list : listList) { + assertTrue("all coords should be inside area", a.allInside(list)); + } + } + }