Skip to content

fix(boolean-touches): check all LineString vertices against a MultiLineString#3088

Open
spokodev wants to merge 1 commit into
Turfjs:masterfrom
spokodev:w32/turf-touches-mls
Open

fix(boolean-touches): check all LineString vertices against a MultiLineString#3088
spokodev wants to merge 1 commit into
Turfjs:masterfrom
spokodev:w32/turf-touches-mls

Conversation

@spokodev

@spokodev spokodev commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Description

booleanTouches(LineString, MultiLineString) returns true for some pairs whose interiors actually intersect, violating the DE-9IM rule that touches requires disjoint interiors.

In packages/turf-boolean-touches/index.ts, the interior-intersection guard loops ii < geom1.coordinates[i].length, where i indexes the MultiLineString's members. But geom1 is the LineString, so geom1.coordinates[i] is a single [lon, lat] pair whose .length is always 2. Only the first two LineString vertices are ever checked against each member's interior, so a LineString whose interior vertex (index >= 2) passes through a member's interior, while an endpoint touches a member endpoint, is wrongly reported as touching.

booleanTouches(
  lineString([[0,0],[-3,4],[5,0],[8,8]]),
  multiLineString([[[4,0],[6,0]],[[0,0],[0,-5]]])
) // true, should be false: vertex [5,0] is strictly inside member [4,0]-[6,0]

Fix

Loop over the LineString's own vertices, matching the LineString to LineString branch:

-            for (var ii = 0; ii < geom1.coordinates[i].length; ii++) {
+            for (var ii = 0; ii < geom1.coordinates.length; ii++) {

Two-vertex lines are unaffected, so existing fixtures stay green.

Test

Added a false fixture where a LineString interior vertex crosses a MultiLineString member. It fails before the change (not ok ... LineStringInteriorVertexCrossesMultiLineString) and passes after; the package suite stays green (91/91).

…String

In the LineString vs MultiLineString branch, the interior-intersection
guard looped `ii < geom1.coordinates[i].length` where `i` indexes the
MultiLineString's members, so the bound was always 2 (the length of a
coordinate pair) and only the first two vertices of the LineString were
ever tested against each member's interior.

A LineString whose interior vertex (index >= 2) lies on the interior of
a MultiLineString member — while an endpoint touches a member endpoint —
was therefore reported as touching, even though the interiors intersect
(DE-9IM touches requires disjoint interiors).

Iterate over all of `geom1.coordinates`, matching the LineString vs
LineString branch. Added a false fixture that fails before and passes
after.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant