From 8b072855b9b441949d24c5f0a72540648697fbc6 Mon Sep 17 00:00:00 2001 From: Yoshikage Ochi Date: Fri, 14 Jan 2022 16:16:29 +0900 Subject: [PATCH] implement line intersect --- .../main/java/com/mapbox/turf/TurfMisc.java | 38 ++++++++++ .../java/com/mapbox/turf/TurfMiscTest.java | 72 +++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/services-turf/src/main/java/com/mapbox/turf/TurfMisc.java b/services-turf/src/main/java/com/mapbox/turf/TurfMisc.java index d315c1bd1..abe828d39 100644 --- a/services-turf/src/main/java/com/mapbox/turf/TurfMisc.java +++ b/services-turf/src/main/java/com/mapbox/turf/TurfMisc.java @@ -26,6 +26,44 @@ private TurfMisc() { throw new AssertionError("No Instances."); } + /** + * Takes lines {@link LineString} and returns intersect points. The time complexity is O(nm) + * that is not as efficient as Turf.js implementation. + * + * @param line1 LineString 1 + * @param line2 LineString 2 + * @return Intersect points + * @see Turf Line intersect documentation + * @since 6.2.0 + */ + @NonNull + public static List lineIntersect(@NonNull LineString line1, @NonNull LineString line2) { + List result = new ArrayList<>(); + Point[] line1Points = line1.coordinates().toArray(new Point[line1.coordinates().size()]); + Point[] line2Points = line2.coordinates().toArray(new Point[line2.coordinates().size()]); + + for (int i = 0; i < line1Points.length - 1; i++) { + for (int j = 0; j < line2Points.length - 1; j++) { + LineIntersectsResult intersects = lineIntersects( + line1Points[i].longitude(), + line1Points[i].latitude(), + line1Points[i + 1].longitude(), + line1Points[i + 1].latitude(), + line2Points[j].longitude(), + line2Points[j].latitude(), + line2Points[j + 1].longitude(), + line2Points[j + 1].latitude()); + + if (intersects != null) { + result.add(Point.fromLngLat( + intersects.horizontalIntersection(), + intersects.verticalIntersection())); + } + } + } + return result; + } + /** * Takes a line, a start {@link Point}, and a stop point and returns the line in between those * points. diff --git a/services-turf/src/test/java/com/mapbox/turf/TurfMiscTest.java b/services-turf/src/test/java/com/mapbox/turf/TurfMiscTest.java index f2b4a1055..f2d4f7770 100644 --- a/services-turf/src/test/java/com/mapbox/turf/TurfMiscTest.java +++ b/services-turf/src/test/java/com/mapbox/turf/TurfMiscTest.java @@ -33,6 +33,78 @@ public class TurfMiscTest extends TestUtils { @Rule public ExpectedException thrown = ExpectedException.none(); + @Test + public void lineIntersect_intersectingEdge() { + List line1Coords = new ArrayList<>(); + line1Coords.add(Point.fromLngLat(1.0, 2.0)); + line1Coords.add(Point.fromLngLat(2.0, 3.0)); + LineString line1 = LineString.fromLngLats(line1Coords); + + List line2Coords = new ArrayList<>(); + line2Coords.add(Point.fromLngLat(2.0, 3.0)); + line2Coords.add(Point.fromLngLat(4.0, 2.0)); + LineString line2 = LineString.fromLngLats(line2Coords); + + List result1 = TurfMisc.lineIntersect(line1, line2); + assertEquals(1, result1.size()); + assertEquals(Point.fromLngLat(2.0, 3.0), result1.get(0)); + + List line3Coords = new ArrayList<>(); + line3Coords.add(Point.fromLngLat(0.0, 3.0)); + line3Coords.add(Point.fromLngLat(1.0, 2.0)); + LineString line3 = LineString.fromLngLats(line3Coords); + + List result2 = TurfMisc.lineIntersect(line1, line3); + assertEquals(1, result2.size()); + assertEquals(Point.fromLngLat(1.0, 2.0), result2.get(0)); + } + + @Test + public void lineIntersect_intersecting() { + List line1Coords = new ArrayList<>(); + line1Coords.add(Point.fromLngLat(2.0, 1.0)); + line1Coords.add(Point.fromLngLat(2.0, 5.0)); + line1Coords.add(Point.fromLngLat(2.0, 9.0)); + LineString line1 = LineString.fromLngLats(line1Coords); + + List line2Coords = new ArrayList<>(); + line2Coords.add(Point.fromLngLat(4.0, 1.0)); + line2Coords.add(Point.fromLngLat(0.0, 5.0)); + line2Coords.add(Point.fromLngLat(2.0, 9.0)); + LineString line2 = LineString.fromLngLats(line2Coords); + + List expected = new ArrayList<>(); + expected.add(Point.fromLngLat(2.0, 3.0)); + expected.add(Point.fromLngLat(2.0, 9.0)); + + List result = TurfMisc.lineIntersect(line1, line2); + for(int i = 0; i < result.size(); i++) { + assertEquals(expected.get(i), result.get(i)); + } + } + + @Test + public void lineIntersect_nonintersecting() { + List line1Coords = new ArrayList<>(); + line1Coords.add(Point.fromLngLat(2.0, 1.0)); + line1Coords.add(Point.fromLngLat(2.0, 5.0)); + line1Coords.add(Point.fromLngLat(2.0, 9.0)); + LineString line1 = LineString.fromLngLats(line1Coords); + + List line2Coords = new ArrayList<>(); + line2Coords.add(Point.fromLngLat(1.0, 1.0)); + line2Coords.add(Point.fromLngLat(1.0, 5.0)); + line2Coords.add(Point.fromLngLat(1.0, 9.0)); + LineString line2 = LineString.fromLngLats(line2Coords); + + List expected = new ArrayList<>(); + expected.add(Point.fromLngLat(2.0, 3.0)); + expected.add(Point.fromLngLat(2.0, 9.0)); + + List result = TurfMisc.lineIntersect(line1, line2); + assertEquals(0, result.size()); + } + @Test public void lineSlice_throwsStartStopPointException() throws Exception { thrown.expect(TurfException.class);