"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var boolean_point_in_polygon_1 = __importDefault(require("@turf/boolean-point-in-polygon")); var line_intersect_1 = __importDefault(require("@turf/line-intersect")); var meta_1 = require("@turf/meta"); var polygon_to_line_1 = __importDefault(require("@turf/polygon-to-line")); /** * Boolean-disjoint returns (TRUE) if the intersection of the two geometries is an empty set. * * @name booleanDisjoint * @param {Geometry|Feature} feature1 GeoJSON Feature or Geometry * @param {Geometry|Feature} feature2 GeoJSON Feature or Geometry * @returns {boolean} true/false * @example * var point = turf.point([2, 2]); * var line = turf.lineString([[1, 1], [1, 2], [1, 3], [1, 4]]); * * turf.booleanDisjoint(line, point); * //=true */ function booleanDisjoint(feature1, feature2) { var bool = true; meta_1.flattenEach(feature1, function (flatten1) { meta_1.flattenEach(feature2, function (flatten2) { if (bool === false) { return false; } bool = disjoint(flatten1.geometry, flatten2.geometry); }); }); return bool; } /** * Disjoint operation for simple Geometries (Point/LineString/Polygon) * * @private * @param {Geometry} geom1 GeoJSON Geometry * @param {Geometry} geom2 GeoJSON Geometry * @returns {boolean} true/false */ function disjoint(geom1, geom2) { switch (geom1.type) { case "Point": switch (geom2.type) { case "Point": return !compareCoords(geom1.coordinates, geom2.coordinates); case "LineString": return !isPointOnLine(geom2, geom1); case "Polygon": return !boolean_point_in_polygon_1.default(geom1, geom2); } /* istanbul ignore next */ break; case "LineString": switch (geom2.type) { case "Point": return !isPointOnLine(geom1, geom2); case "LineString": return !isLineOnLine(geom1, geom2); case "Polygon": return !isLineInPoly(geom2, geom1); } /* istanbul ignore next */ break; case "Polygon": switch (geom2.type) { case "Point": return !boolean_point_in_polygon_1.default(geom2, geom1); case "LineString": return !isLineInPoly(geom1, geom2); case "Polygon": return !isPolyInPoly(geom2, geom1); } } return false; } // http://stackoverflow.com/a/11908158/1979085 function isPointOnLine(lineString, pt) { for (var i = 0; i < lineString.coordinates.length - 1; i++) { if (isPointOnLineSegment(lineString.coordinates[i], lineString.coordinates[i + 1], pt.coordinates)) { return true; } } return false; } function isLineOnLine(lineString1, lineString2) { var doLinesIntersect = line_intersect_1.default(lineString1, lineString2); if (doLinesIntersect.features.length > 0) { return true; } return false; } function isLineInPoly(polygon, lineString) { for (var _i = 0, _a = lineString.coordinates; _i < _a.length; _i++) { var coord = _a[_i]; if (boolean_point_in_polygon_1.default(coord, polygon)) { return true; } } var doLinesIntersect = line_intersect_1.default(lineString, polygon_to_line_1.default(polygon)); if (doLinesIntersect.features.length > 0) { return true; } return false; } /** * Is Polygon (geom1) in Polygon (geom2) * Only takes into account outer rings * See http://stackoverflow.com/a/4833823/1979085 * * @private * @param {Geometry|Feature} feature1 Polygon1 * @param {Geometry|Feature} feature2 Polygon2 * @returns {boolean} true/false */ function isPolyInPoly(feature1, feature2) { for (var _i = 0, _a = feature1.coordinates[0]; _i < _a.length; _i++) { var coord1 = _a[_i]; if (boolean_point_in_polygon_1.default(coord1, feature2)) { return true; } } for (var _b = 0, _c = feature2.coordinates[0]; _b < _c.length; _b++) { var coord2 = _c[_b]; if (boolean_point_in_polygon_1.default(coord2, feature1)) { return true; } } var doLinesIntersect = line_intersect_1.default(polygon_to_line_1.default(feature1), polygon_to_line_1.default(feature2)); if (doLinesIntersect.features.length > 0) { return true; } return false; } function isPointOnLineSegment(lineSegmentStart, lineSegmentEnd, pt) { var dxc = pt[0] - lineSegmentStart[0]; var dyc = pt[1] - lineSegmentStart[1]; var dxl = lineSegmentEnd[0] - lineSegmentStart[0]; var dyl = lineSegmentEnd[1] - lineSegmentStart[1]; var cross = dxc * dyl - dyc * dxl; if (cross !== 0) { return false; } if (Math.abs(dxl) >= Math.abs(dyl)) { if (dxl > 0) { return lineSegmentStart[0] <= pt[0] && pt[0] <= lineSegmentEnd[0]; } else { return lineSegmentEnd[0] <= pt[0] && pt[0] <= lineSegmentStart[0]; } } else if (dyl > 0) { return lineSegmentStart[1] <= pt[1] && pt[1] <= lineSegmentEnd[1]; } else { return lineSegmentEnd[1] <= pt[1] && pt[1] <= lineSegmentStart[1]; } } /** * compareCoords * * @private * @param {Position} pair1 point [x,y] * @param {Position} pair2 point [x,y] * @returns {boolean} true/false if coord pairs match */ function compareCoords(pair1, pair2) { return pair1[0] === pair2[0] && pair1[1] === pair2[1]; } exports.default = booleanDisjoint;