UNPKG

gis-tools-ts

Version:

A collection of geospatial tools primarily designed for WGS84, Web Mercator, and S2.

122 lines 4.33 kB
import { orient2d, pointOverlap } from '../../../index.js'; /** * A robust method to see if a point is in a collection of polygons or not. * Be sure the point and polygon are in the same projection space. * @param point - the point to check * @param polygons - the collection of polygons * @param ignoreBoundary - if true, ignore when the point is on the boundary * @returns - true if the point is in the polygon */ export function pointInPolygons(point, polygons, ignoreBoundary = false) { const vectorPolygons = 'geometry' in polygons ? polygons.geometry.coordinates : 'coordinates' in polygons ? polygons.coordinates : polygons; let res = false; for (let i = 0; i < vectorPolygons.length; i++) { const test = pointInPolygon(point, vectorPolygons[i], ignoreBoundary); if (test === true) return true; else if (!ignoreBoundary && test === 0) res = 0; } return res; } /** * A robust method to see if a point is in a polygon or not. * Be sure the point and polygon are in the same projection space. * @param point - the point to check * @param polygon - the polygon * @param ignoreBoundary - if true, ignore when the point is on the boundary * @returns - true if the point is in the polygon */ export function pointInPolygon(point, polygon, ignoreBoundary = false) { // bbox test case - if it doesn't even fit within the bbox, we know it's not in the polygon const bbox = 'geometry' in polygon ? polygon.geometry.bbox : 'bbox' in polygon ? polygon.bbox : undefined; if (bbox !== undefined && !pointOverlap(bbox, point)) return false; // check poly against the point const vectorPolygon = 'geometry' in polygon ? polygon.geometry.coordinates : 'coordinates' in polygon ? polygon.coordinates : polygon; const pip = _pointInPolygon(point, vectorPolygon); if (ignoreBoundary && pip === 0) return false; return pip; } /** * Check if a hole is inside an outer ring * @param hole - the hole to test if inside the outer * @param outer - the outer to test against * @returns true if the hole is inside the outer */ export function polylineInPolyline(hole, outer) { const outerPoly = [outer]; for (const point of hole) { const result = pointInPolygon(point, outerPoly, false); if (result === true) return true; else if (result === false) return false; } // If we make it means all points of the hole were on the boundary therefore its inside the outer return true; } /** * A Robust point in polygon test * @param point - the point * @param polygon - the polygon * @returns - true if the point is in the polygon, 0 if on the boundary, false otherwise */ function _pointInPolygon(point, polygon) { let i; let ii; let k = 0; let f; let u1; let v1; let u2; let v2; let currentP; let nextP; const { x, y } = point; const numContours = polygon.length; for (i = 0; i < numContours; i++) { ii = 0; const contour = polygon[i]; const contourLen = contour.length - 1; currentP = contour[0]; if (currentP.x !== contour[contourLen].x && currentP.y !== contour[contourLen].y) { // since the first and last coordinates in a ring are not the same, assume it's not a polygon and return false return false; } u1 = currentP.x - x; v1 = currentP.y - y; for (ii; ii < contourLen; ii++) { nextP = contour[ii + 1]; u2 = nextP.x - x; v2 = nextP.y - y; if (v1 === 0 && v2 === 0) { if ((u2 <= 0 && u1 >= 0) || (u1 <= 0 && u2 >= 0)) return 0; } else if ((v2 >= 0 && v1 <= 0) || (v2 <= 0 && v1 >= 0)) { f = orient2d(u1, u2, v1, v2, 0, 0); if (f === 0) return 0; if ((f > 0 && v2 > 0 && v1 <= 0) || (f < 0 && v2 <= 0 && v1 > 0)) k++; } // currentP = nextP; v1 = v2; u1 = u2; } } if (k % 2 === 0) return false; return true; } //# sourceMappingURL=pointInPoly.js.map