diff --git a/packages/turf-boolean-point-in-polygon/index.ts b/packages/turf-boolean-point-in-polygon/index.ts index b383cd9b8..121cf6d0a 100644 --- a/packages/turf-boolean-point-in-polygon/index.ts +++ b/packages/turf-boolean-point-in-polygon/index.ts @@ -68,14 +68,17 @@ function booleanPointInPolygon< if (type === "Polygon") { polys = [polys]; } - let result = false; + for (var i = 0; i < polys.length; ++i) { const polyResult = pip(pt, polys[i]); - if (polyResult === 0) return options.ignoreBoundary ? false : true; - else if (polyResult) result = true; + // If being on the boundary doesn't count, stay in the loop to see if we're inside another polygon + // The RFC does not prevent polygons from overlapping; https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.7 + if (polyResult === 0 && !options.ignoreBoundary) return true; + // If point is in the polygon, exit early the loop + else if (polyResult) return true; } - return result; + return false; } /** diff --git a/packages/turf-boolean-point-in-polygon/test.ts b/packages/turf-boolean-point-in-polygon/test.ts index 113e21657..9296694f2 100644 --- a/packages/turf-boolean-point-in-polygon/test.ts +++ b/packages/turf-boolean-point-in-polygon/test.ts @@ -2,7 +2,7 @@ import fs from "fs"; import path from "path"; import { fileURLToPath } from "url"; import test from "tape"; -import { point } from "@turf/helpers"; +import { multiPolygon, point } from "@turf/helpers"; import { polygon } from "@turf/helpers"; import { booleanPointInPolygon } from "./index.js"; @@ -143,6 +143,26 @@ test("boolean-point-in-polygon -- Boundary test", function (t) { [10, 20], ], ]); + var poly6 = multiPolygon([ + [ + [ + [10, 20], + [20, 10], + [30, 20], + [20, 30], + [10, 20], + ], + ], + [ + [ + [0, 20], + [20, 0], + [40, 20], + [20, 40], + [0, 20], + ], + ], + ]); function runTest(t, ignoreBoundary) { var isBoundaryIncluded = ignoreBoundary === false; var tests = [ @@ -183,6 +203,7 @@ test("boolean-point-in-polygon -- Boundary test", function (t) { [poly5, point([10, 20]), isBoundaryIncluded], [poly5, point([15, 25]), isBoundaryIncluded], [poly5, point([20, 20]), false], + [poly6, point([25, 25]), true], // Point on the boundary of the first polygon, but inside the second polygon ]; var testTitle =