From 240be060185de90e1243d9cdd5a89886f96029b0 Mon Sep 17 00:00:00 2001 From: "Phyks (Lucas Verney)" Date: Thu, 13 Dec 2018 15:00:33 +0100 Subject: [PATCH] Fix nogo weights with polylines --- .../java/btools/router/OsmNogoPolygon.java | 20 +++++++++++-- .../btools/router/OsmNogoPolygonTest.java | 30 +++++++++++++++++-- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/brouter-core/src/main/java/btools/router/OsmNogoPolygon.java b/brouter-core/src/main/java/btools/router/OsmNogoPolygon.java index 598b673..1460410 100644 --- a/brouter-core/src/main/java/btools/router/OsmNogoPolygon.java +++ b/brouter-core/src/main/java/btools/router/OsmNogoPolygon.java @@ -330,9 +330,11 @@ public class OsmNogoPolygon extends OsmNodeNamed Point edgePoint1 = points.get(j); Point edgePoint2 = points.get(i); int intersectsEdge = intersect2D_2Segments(p1, p2, edgePoint1, edgePoint2); - if (intersectsEdge == 1) + + if (isClosed && intersectsEdge == 1) { - // Intersects in a single point + // Intersects with a (closed) polygon edge on a single point + // Distance is zero when crossing a polyline. // Let's find this intersection point int xdiffSegment = lon1 - lon2; int xdiffEdge = edgePoint1.x - edgePoint2.x; @@ -364,7 +366,19 @@ public class OsmNogoPolygon extends OsmNodeNamed } else if (intersectsEdge == 2) { // Segment and edge overlaps - distance += CheapRulerSingleton.distance(lon1, lat1, lon2, lat2); + // FIXME: Could probably be done in a smarter way + distance += Math.min( + CheapRulerSingleton.distance(p1.x, p1.y, p2.x, p2.y), + Math.min( + CheapRulerSingleton.distance(edgePoint1.x, edgePoint1.y, edgePoint2.x, edgePoint2.y), + Math.min( + CheapRulerSingleton.distance(p1.x, p1.y, edgePoint2.x, edgePoint2.y), + CheapRulerSingleton.distance(edgePoint1.x, edgePoint1.y, p2.x, p2.y) + ) + ) + ); + // FIXME: We could store intersection. + previousIntersectionOnSegment = null; } } diff --git a/brouter-core/src/test/java/btools/router/OsmNogoPolygonTest.java b/brouter-core/src/test/java/btools/router/OsmNogoPolygonTest.java index 08b4338..9fa6db2 100644 --- a/brouter-core/src/test/java/btools/router/OsmNogoPolygonTest.java +++ b/brouter-core/src/test/java/btools/router/OsmNogoPolygonTest.java @@ -148,12 +148,16 @@ public class OsmNogoPolygonTest { @Test public void testDistanceWithinPolygon() { // Testing polygon - final double[] lons = { 2.333523, 2.333432, 2.333833, 2.333983, 2.334815, 2.334766, 2.333523 }; - final double[] lats = { 48.823778, 48.824091, 48.82389, 48.824165, 48.824232, 48.82384, 48.823778 }; + final double[] lons = { 2.333523, 2.333432, 2.333833, 2.333983, 2.334815, 2.334766 }; + final double[] lats = { 48.823778, 48.824091, 48.82389, 48.824165, 48.824232, 48.82384 }; OsmNogoPolygon polygon = new OsmNogoPolygon(true); for (int i = 0; i < lons.length; i++) { polygon.addVertex(toOsmLon(lons[i], 0), toOsmLat(lats[i], 0)); } + OsmNogoPolygon polyline = new OsmNogoPolygon(false); + for (int i = 0; i < lons.length; i++) { + polyline.addVertex(toOsmLon(lons[i], 0), toOsmLat(lats[i], 0)); + } // Check with a segment with a single intersection with the polygon int lon1 = toOsmLon(2.33308732509613, 0); @@ -196,5 +200,27 @@ public class OsmNogoPolygonTest { polygon.distanceWithinPolygon(lon1, lat1, lon2, lat2), 0.05 * 35 ); + + lon1 = toOsmLon(2.333523, 0); + lat1 = toOsmLat(48.823778, 0); + lon2 = toOsmLon(2.333432, 0); + lat2 = toOsmLat(48.824091, 0); + assertEquals( + "Should give the correct length if the segment overlaps with an edge of the polygon", + CheapRulerSingleton.distance(lon1, lat1, lon2, lat2), + polygon.distanceWithinPolygon(lon1, lat1, lon2, lat2), + 0.05 * CheapRulerSingleton.distance(lon1, lat1, lon2, lat2) + ); + + lon1 = toOsmLon(2.333523, 0); + lat1 = toOsmLat(48.823778, 0); + lon2 = toOsmLon(2.3334775, 0); + lat2 = toOsmLat(48.8239345, 0); + assertEquals( + "Should give the correct length if the segment overlaps with a polyline", + CheapRulerSingleton.distance(lon1, lat1, lon2, lat2), + polyline.distanceWithinPolygon(lon1, lat1, lon2, lat2), + 0.05 * CheapRulerSingleton.distance(lon1, lat1, lon2, lat2) + ); } }