diff --git a/packages/turf-boolean-point-on-line/index.ts b/packages/turf-boolean-point-on-line/index.ts index 9bfb98e43..df9c62522 100644 --- a/packages/turf-boolean-point-on-line/index.ts +++ b/packages/turf-boolean-point-on-line/index.ts @@ -97,6 +97,25 @@ function isPointOnLineSegment( } else if (cross !== 0) { return false; } + + // Special cases for zero length lines + // https://github.com/Turfjs/turf/issues/2750 + if (Math.abs(dxl) === Math.abs(dyl) && Math.abs(dxl) === 0) { + // Zero length line. + if (excludeBoundary) { + // To be on a zero length line pt has to be on the start (and end), BUT we + // are excluding start and end from possible matches. + return false; + } + if (pt[0] === lineSegmentStart[0] && pt[1] === lineSegmentStart[1]) { + // If point is same as start (and end) it's on the line segment + return true; + } else { + // Otherwise point is somewhere else + return false; + } + } + if (!excludeBoundary) { if (Math.abs(dxl) >= Math.abs(dyl)) { return dxl > 0 ? x1 <= x && x <= x2 : x2 <= x && x <= x1; diff --git a/packages/turf-boolean-point-on-line/test.ts b/packages/turf-boolean-point-on-line/test.ts index bbf9d39fa..dbcccb258 100644 --- a/packages/turf-boolean-point-on-line/test.ts +++ b/packages/turf-boolean-point-on-line/test.ts @@ -3,7 +3,10 @@ import path from "path"; import { fileURLToPath } from "url"; import test from "tape"; import { loadJsonFileSync } from "load-json-file"; -import { booleanPointOnLine as pointOnLine } from "./index.js"; +import { point, lineString } from "@turf/helpers"; +import booleanPointOnLine, { + booleanPointOnLine as pointOnLine, +} from "./index.js"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -36,3 +39,33 @@ test("turf-boolean-point-on-line", (t) => { }); t.end(); }); + +test("turf-boolean-point-on-line - issue 2750", (t) => { + // Issue 2750 was that in the first test below where point is on a different + // longitude to a zero length line booleanPointOnLine gave the correct result, + // while the second test where a point on the SAME longitude, but nowhere + // near, that zero length line incorrectly returned true. + t.false( + booleanPointOnLine( + point([2, 13]), + lineString([ + [1, 1], + [1, 1], + ]) + ), + "#2750 different longitude point not on zero length line" + ); + + t.false( + booleanPointOnLine( + point([1, 13]), + lineString([ + [1, 1], + [1, 1], + ]) + ), + "#2750 same longitude point not on zero length line" + ); + + t.end(); +});