Skip to content

Commit 864dd68

Browse files
authored
Primitive implementation of line intersect (#1348)
* fix lineIntersects to align with Turf.js implementation * implement line intersect
1 parent 4213399 commit 864dd68

2 files changed

Lines changed: 112 additions & 2 deletions

File tree

services-turf/src/main/java/com/mapbox/turf/TurfMisc.java

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,44 @@ private TurfMisc() {
2626
throw new AssertionError("No Instances.");
2727
}
2828

29+
/**
30+
* Takes lines {@link LineString} and returns intersect points. The time complexity is O(nm)
31+
* that is not as efficient as Turf.js implementation.
32+
*
33+
* @param line1 LineString 1
34+
* @param line2 LineString 2
35+
* @return Intersect points
36+
* @see <a href="https://turfjs.org/docs/#lineIntersect">Turf Line intersect documentation</a>
37+
* @since 6.2.0
38+
*/
39+
@NonNull
40+
public static List<Point> lineIntersect(@NonNull LineString line1, @NonNull LineString line2) {
41+
List<Point> result = new ArrayList<>();
42+
Point[] line1Points = line1.coordinates().toArray(new Point[line1.coordinates().size()]);
43+
Point[] line2Points = line2.coordinates().toArray(new Point[line2.coordinates().size()]);
44+
45+
for (int i = 0; i < line1Points.length - 1; i++) {
46+
for (int j = 0; j < line2Points.length - 1; j++) {
47+
LineIntersectsResult intersects = lineIntersects(
48+
line1Points[i].longitude(),
49+
line1Points[i].latitude(),
50+
line1Points[i + 1].longitude(),
51+
line1Points[i + 1].latitude(),
52+
line2Points[j].longitude(),
53+
line2Points[j].latitude(),
54+
line2Points[j + 1].longitude(),
55+
line2Points[j + 1].latitude());
56+
57+
if (intersects != null) {
58+
result.add(Point.fromLngLat(
59+
intersects.horizontalIntersection(),
60+
intersects.verticalIntersection()));
61+
}
62+
}
63+
}
64+
return result;
65+
}
66+
2967
/**
3068
* Takes a line, a start {@link Point}, and a stop point and returns the line in between those
3169
* points.
@@ -346,11 +384,11 @@ private static LineIntersectsResult lineIntersects(double line1StartX, double li
346384
+ (varA * (line1EndY - line1StartY))).build();
347385

348386
// if line1 is a segment and line2 is infinite, they intersect if:
349-
if (varA > 0 && varA < 1) {
387+
if (varA >= 0 && varA <= 1) {
350388
result = result.toBuilder().onLine1(true).build();
351389
}
352390
// if line2 is a segment and line1 is infinite, they intersect if:
353-
if (varB > 0 && varB < 1) {
391+
if (varB >= 0 && varB <= 1) {
354392
result = result.toBuilder().onLine2(true).build();
355393
}
356394
// if line1 and line2 are segments, they intersect if both of the above are true

services-turf/src/test/java/com/mapbox/turf/TurfMiscTest.java

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,78 @@ public class TurfMiscTest extends TestUtils {
3333
@Rule
3434
public ExpectedException thrown = ExpectedException.none();
3535

36+
@Test
37+
public void lineIntersect_intersectingEdge() {
38+
List<Point> line1Coords = new ArrayList<>();
39+
line1Coords.add(Point.fromLngLat(1.0, 2.0));
40+
line1Coords.add(Point.fromLngLat(2.0, 3.0));
41+
LineString line1 = LineString.fromLngLats(line1Coords);
42+
43+
List<Point> line2Coords = new ArrayList<>();
44+
line2Coords.add(Point.fromLngLat(2.0, 3.0));
45+
line2Coords.add(Point.fromLngLat(4.0, 2.0));
46+
LineString line2 = LineString.fromLngLats(line2Coords);
47+
48+
List<Point> result1 = TurfMisc.lineIntersect(line1, line2);
49+
assertEquals(1, result1.size());
50+
assertEquals(Point.fromLngLat(2.0, 3.0), result1.get(0));
51+
52+
List<Point> line3Coords = new ArrayList<>();
53+
line3Coords.add(Point.fromLngLat(0.0, 3.0));
54+
line3Coords.add(Point.fromLngLat(1.0, 2.0));
55+
LineString line3 = LineString.fromLngLats(line3Coords);
56+
57+
List<Point> result2 = TurfMisc.lineIntersect(line1, line3);
58+
assertEquals(1, result2.size());
59+
assertEquals(Point.fromLngLat(1.0, 2.0), result2.get(0));
60+
}
61+
62+
@Test
63+
public void lineIntersect_intersecting() {
64+
List<Point> line1Coords = new ArrayList<>();
65+
line1Coords.add(Point.fromLngLat(2.0, 1.0));
66+
line1Coords.add(Point.fromLngLat(2.0, 5.0));
67+
line1Coords.add(Point.fromLngLat(2.0, 9.0));
68+
LineString line1 = LineString.fromLngLats(line1Coords);
69+
70+
List<Point> line2Coords = new ArrayList<>();
71+
line2Coords.add(Point.fromLngLat(4.0, 1.0));
72+
line2Coords.add(Point.fromLngLat(0.0, 5.0));
73+
line2Coords.add(Point.fromLngLat(2.0, 9.0));
74+
LineString line2 = LineString.fromLngLats(line2Coords);
75+
76+
List<Point> expected = new ArrayList<>();
77+
expected.add(Point.fromLngLat(2.0, 3.0));
78+
expected.add(Point.fromLngLat(2.0, 9.0));
79+
80+
List<Point> result = TurfMisc.lineIntersect(line1, line2);
81+
for(int i = 0; i < result.size(); i++) {
82+
assertEquals(expected.get(i), result.get(i));
83+
}
84+
}
85+
86+
@Test
87+
public void lineIntersect_nonintersecting() {
88+
List<Point> line1Coords = new ArrayList<>();
89+
line1Coords.add(Point.fromLngLat(2.0, 1.0));
90+
line1Coords.add(Point.fromLngLat(2.0, 5.0));
91+
line1Coords.add(Point.fromLngLat(2.0, 9.0));
92+
LineString line1 = LineString.fromLngLats(line1Coords);
93+
94+
List<Point> line2Coords = new ArrayList<>();
95+
line2Coords.add(Point.fromLngLat(1.0, 1.0));
96+
line2Coords.add(Point.fromLngLat(1.0, 5.0));
97+
line2Coords.add(Point.fromLngLat(1.0, 9.0));
98+
LineString line2 = LineString.fromLngLats(line2Coords);
99+
100+
List<Point> expected = new ArrayList<>();
101+
expected.add(Point.fromLngLat(2.0, 3.0));
102+
expected.add(Point.fromLngLat(2.0, 9.0));
103+
104+
List<Point> result = TurfMisc.lineIntersect(line1, line2);
105+
assertEquals(0, result.size());
106+
}
107+
36108
@Test
37109
public void lineSlice_throwsStartStopPointException() throws Exception {
38110
thrown.expect(TurfException.class);

0 commit comments

Comments
 (0)