{"version":3,"sources":["../../index.js"],"sourcesContent":["import { geojsonRbush as rbush } from \"@turf/geojson-rbush\";\nimport { truncate } from \"@turf/truncate\";\nimport { lineSegment } from \"@turf/line-segment\";\nimport { lineIntersect } from \"@turf/line-intersect\";\nimport { nearestPointOnLine } from \"@turf/nearest-point-on-line\";\nimport { getCoords, getCoord, getType } from \"@turf/invariant\";\nimport { featureEach, featureReduce, flattenEach } from \"@turf/meta\";\nimport { lineString, featureCollection } from \"@turf/helpers\";\n\n/**\n * Split a LineString by another GeoJSON Feature.\n *\n * @function\n * @param {Feature} line LineString Feature to split\n * @param {Feature} splitter Feature used to split line\n * @returns {FeatureCollection} Split LineStrings\n * @example\n * var line = turf.lineString([[120, -25], [145, -25]]);\n * var splitter = turf.lineString([[130, -15], [130, -35]]);\n *\n * var split = turf.lineSplit(line, splitter);\n *\n * //addToMap\n * var addToMap = [line, splitter, split]\n *\n * split.features[0].properties.stroke = \"red\";\n * split.features[1].properties.stroke = \"blue\";\n */\nfunction lineSplit(line, splitter) {\n if (!line) throw new Error(\"line is required\");\n if (!splitter) throw new Error(\"splitter is required\");\n\n var lineType = getType(line);\n var splitterType = getType(splitter);\n\n if (lineType !== \"LineString\") throw new Error(\"line must be LineString\");\n if (splitterType === \"FeatureCollection\")\n throw new Error(\"splitter cannot be a FeatureCollection\");\n if (splitterType === \"GeometryCollection\")\n throw new Error(\"splitter cannot be a GeometryCollection\");\n\n // remove excessive decimals from splitter\n // to avoid possible approximation issues in rbush\n var truncatedSplitter = truncate(splitter, { precision: 7 });\n\n switch (splitterType) {\n case \"Point\":\n return splitLineWithPoint(line, truncatedSplitter);\n case \"MultiPoint\":\n return splitLineWithPoints(line, truncatedSplitter);\n case \"LineString\":\n case \"MultiLineString\":\n case \"Polygon\":\n case \"MultiPolygon\":\n return splitLineWithPoints(\n line,\n lineIntersect(line, truncatedSplitter, {\n ignoreSelfIntersections: true,\n })\n );\n }\n}\n\n/**\n * Split LineString with MultiPoint\n *\n * @private\n * @param {Feature} line LineString\n * @param {FeatureCollection} splitter Point\n * @returns {FeatureCollection} split LineStrings\n */\nfunction splitLineWithPoints(line, splitter) {\n var results = [];\n var tree = rbush();\n\n flattenEach(splitter, function (point) {\n // Add index/id to features (needed for filter)\n results.forEach(function (feature, index) {\n feature.id = index;\n });\n // First Point - doesn't need to handle any previous line results\n if (!results.length) {\n results = splitLineWithPoint(line, point).features;\n tree.load(featureCollection(results));\n // Split with remaining points - lines might needed to be split multiple times\n } else {\n // Find all lines that are within the splitter's bbox\n var search = tree.search(point);\n\n if (search.features.length) {\n // RBush might return multiple lines - only process the closest line to splitter\n var closestLine = findClosestFeature(point, search);\n\n // Remove closest line from results since this will be split into two lines\n // This removes any duplicates inside the results & index\n results = results.filter(function (feature) {\n return feature.id !== closestLine.id;\n });\n tree.remove(closestLine);\n\n // Append the two newly split lines into the results\n featureEach(splitLineWithPoint(closestLine, point), function (line) {\n results.push(line);\n tree.insert(line);\n });\n }\n }\n });\n return featureCollection(results);\n}\n\n/**\n * Split LineString with Point\n *\n * @private\n * @param {Feature} line LineString\n * @param {Feature} splitter Point\n * @returns {FeatureCollection} split LineStrings\n */\nfunction splitLineWithPoint(line, splitter) {\n var results = [];\n\n // handle endpoints\n var startPoint = getCoords(line)[0];\n var endPoint = getCoords(line)[line.geometry.coordinates.length - 1];\n if (\n pointsEquals(startPoint, getCoord(splitter)) ||\n pointsEquals(endPoint, getCoord(splitter))\n )\n return featureCollection([line]);\n\n // Create spatial index\n var tree = rbush();\n var segments = lineSegment(line);\n tree.load(segments);\n\n // Find all segments that are within bbox of splitter\n var search = tree.search(splitter);\n\n // Return itself if point is not within spatial index\n if (!search.features.length) return featureCollection([line]);\n\n // RBush might return multiple lines - only process the closest line to splitter\n var closestSegment = findClosestFeature(splitter, search);\n\n // Initial value is the first point of the first segments (beginning of line)\n var initialValue = [startPoint];\n var lastCoords = featureReduce(\n segments,\n function (previous, current, index) {\n var currentCoords = getCoords(current)[1];\n var splitterCoords = getCoord(splitter);\n\n // Location where segment intersects with line\n if (index === closestSegment.id) {\n previous.push(splitterCoords);\n results.push(lineString(previous));\n // Don't duplicate splitter coordinate (Issue #688)\n if (pointsEquals(splitterCoords, currentCoords))\n return [splitterCoords];\n return [splitterCoords, currentCoords];\n\n // Keep iterating over coords until finished or intersection is found\n } else {\n previous.push(currentCoords);\n return previous;\n }\n },\n initialValue\n );\n // Append last line to final split results\n if (lastCoords.length > 1) {\n results.push(lineString(lastCoords));\n }\n return featureCollection(results);\n}\n\n/**\n * Find Closest Feature\n *\n * @private\n * @param {Feature} point Feature must be closest to this point\n * @param {FeatureCollection} lines Collection of Features\n * @returns {Feature} closest LineString\n */\nfunction findClosestFeature(point, lines) {\n if (!lines.features.length) throw new Error(\"lines must contain features\");\n // Filter to one segment that is the closest to the line\n if (lines.features.length === 1) return lines.features[0];\n\n var closestFeature;\n var closestDistance = Infinity;\n featureEach(lines, function (segment) {\n var pt = nearestPointOnLine(segment, point);\n var dist = pt.properties.dist;\n if (dist < closestDistance) {\n closestFeature = segment;\n closestDistance = dist;\n }\n });\n return closestFeature;\n}\n\n/**\n * Compares two points and returns if they are equals\n *\n * @private\n * @param {Array} pt1 point\n * @param {Array} pt2 point\n * @returns {boolean} true if they are equals\n */\nfunction pointsEquals(pt1, pt2) {\n return pt1[0] === pt2[0] && pt1[1] === pt2[1];\n}\n\nexport { lineSplit };\nexport default lineSplit;\n"],"mappings":"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","names":["line"]}