123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- import { feature, featureCollection, point, } from "@turf/helpers";
- import { getCoords } from "@turf/invariant";
- import lineSegment from "@turf/line-segment";
- import { featureEach } from "@turf/meta";
- import rbush from "geojson-rbush";
- /**
- * Takes any LineString or Polygon GeoJSON and returns the intersecting point(s).
- *
- * @name lineIntersect
- * @param {GeoJSON} line1 any LineString or Polygon
- * @param {GeoJSON} line2 any LineString or Polygon
- * @returns {FeatureCollection<Point>} point(s) that intersect both
- * @example
- * var line1 = turf.lineString([[126, -11], [129, -21]]);
- * var line2 = turf.lineString([[123, -18], [131, -14]]);
- * var intersects = turf.lineIntersect(line1, line2);
- *
- * //addToMap
- * var addToMap = [line1, line2, intersects]
- */
- function lineIntersect(line1, line2) {
- var unique = {};
- var results = [];
- // First, normalize geometries to features
- // Then, handle simple 2-vertex segments
- if (line1.type === "LineString") {
- line1 = feature(line1);
- }
- if (line2.type === "LineString") {
- line2 = feature(line2);
- }
- if (line1.type === "Feature" &&
- line2.type === "Feature" &&
- line1.geometry !== null &&
- line2.geometry !== null &&
- line1.geometry.type === "LineString" &&
- line2.geometry.type === "LineString" &&
- line1.geometry.coordinates.length === 2 &&
- line2.geometry.coordinates.length === 2) {
- var intersect = intersects(line1, line2);
- if (intersect) {
- results.push(intersect);
- }
- return featureCollection(results);
- }
- // Handles complex GeoJSON Geometries
- var tree = rbush();
- tree.load(lineSegment(line2));
- featureEach(lineSegment(line1), function (segment) {
- featureEach(tree.search(segment), function (match) {
- var intersect = intersects(segment, match);
- if (intersect) {
- // prevent duplicate points https://github.com/Turfjs/turf/issues/688
- var key = getCoords(intersect).join(",");
- if (!unique[key]) {
- unique[key] = true;
- results.push(intersect);
- }
- }
- });
- });
- return featureCollection(results);
- }
- /**
- * Find a point that intersects LineStrings with two coordinates each
- *
- * @private
- * @param {Feature<LineString>} line1 GeoJSON LineString (Must only contain 2 coordinates)
- * @param {Feature<LineString>} line2 GeoJSON LineString (Must only contain 2 coordinates)
- * @returns {Feature<Point>} intersecting GeoJSON Point
- */
- function intersects(line1, line2) {
- var coords1 = getCoords(line1);
- var coords2 = getCoords(line2);
- if (coords1.length !== 2) {
- throw new Error("<intersects> line1 must only contain 2 coordinates");
- }
- if (coords2.length !== 2) {
- throw new Error("<intersects> line2 must only contain 2 coordinates");
- }
- var x1 = coords1[0][0];
- var y1 = coords1[0][1];
- var x2 = coords1[1][0];
- var y2 = coords1[1][1];
- var x3 = coords2[0][0];
- var y3 = coords2[0][1];
- var x4 = coords2[1][0];
- var y4 = coords2[1][1];
- var denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
- var numeA = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3);
- var numeB = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3);
- if (denom === 0) {
- if (numeA === 0 && numeB === 0) {
- return null;
- }
- return null;
- }
- var uA = numeA / denom;
- var uB = numeB / denom;
- if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) {
- var x = x1 + uA * (x2 - x1);
- var y = y1 + uA * (y2 - y1);
- return point([x, y]);
- }
- return null;
- }
- export default lineIntersect;
|