| 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;
 |