{"version":3,"sources":["../../index.js","../../lib/intersection.js"],"sourcesContent":["import { flattenEach } from \"@turf/meta\";\nimport { getCoords, getType } from \"@turf/invariant\";\nimport {\n isObject,\n lineString,\n multiLineString,\n lengthToDegrees,\n} from \"@turf/helpers\";\nimport { intersection } from \"./lib/intersection.js\";\n\n/**\n * Takes a {@link LineString|line} and returns a {@link LineString|line} at offset by the specified distance.\n *\n * @function\n * @param {Geometry|Feature} geojson input GeoJSON\n * @param {number} distance distance to offset the line (can be of negative value)\n * @param {Object} [options={}] Optional parameters\n * @param {string} [options.units='kilometers'] can be degrees, radians, miles, kilometers, inches, yards, meters\n * @returns {Feature} Line offset from the input line\n * @example\n * var line = turf.lineString([[-83, 30], [-84, 36], [-78, 41]], { \"stroke\": \"#F00\" });\n *\n * var offsetLine = turf.lineOffset(line, 2, {units: 'miles'});\n *\n * //addToMap\n * var addToMap = [offsetLine, line]\n * offsetLine.properties.stroke = \"#00F\"\n */\nfunction lineOffset(geojson, distance, options) {\n // Optional parameters\n options = options || {};\n if (!isObject(options)) throw new Error(\"options is invalid\");\n var units = options.units;\n\n // Valdiation\n if (!geojson) throw new Error(\"geojson is required\");\n if (distance === undefined || distance === null || isNaN(distance))\n throw new Error(\"distance is required\");\n\n var type = getType(geojson);\n var properties = geojson.properties;\n\n switch (type) {\n case \"LineString\":\n return lineOffsetFeature(geojson, distance, units);\n case \"MultiLineString\":\n var coords = [];\n flattenEach(geojson, function (feature) {\n coords.push(\n lineOffsetFeature(feature, distance, units).geometry.coordinates\n );\n });\n return multiLineString(coords, properties);\n default:\n throw new Error(\"geometry \" + type + \" is not supported\");\n }\n}\n\n/**\n * Line Offset\n *\n * @private\n * @param {Geometry|Feature} line input line\n * @param {number} distance distance to offset the line (can be of negative value)\n * @param {string} [units=kilometers] units\n * @returns {Feature} Line offset from the input line\n */\nfunction lineOffsetFeature(line, distance, units) {\n var segments = [];\n var offsetDegrees = lengthToDegrees(distance, units);\n var coords = getCoords(line);\n var finalCoords = [];\n coords.forEach(function (currentCoords, index) {\n if (index !== coords.length - 1) {\n var segment = processSegment(\n currentCoords,\n coords[index + 1],\n offsetDegrees\n );\n segments.push(segment);\n if (index > 0) {\n var seg2Coords = segments[index - 1];\n var intersects = intersection(segment, seg2Coords);\n\n // Handling for line segments that aren't straight\n if (intersects !== false) {\n seg2Coords[1] = intersects;\n segment[0] = intersects;\n }\n\n finalCoords.push(seg2Coords[0]);\n if (index === coords.length - 2) {\n finalCoords.push(segment[0]);\n finalCoords.push(segment[1]);\n }\n }\n // Handling for lines that only have 1 segment\n if (coords.length === 2) {\n finalCoords.push(segment[0]);\n finalCoords.push(segment[1]);\n }\n }\n });\n return lineString(finalCoords, line.properties);\n}\n\n/**\n * Process Segment\n * Inspiration taken from http://stackoverflow.com/questions/2825412/draw-a-parallel-line\n *\n * @private\n * @param {Array} point1 Point coordinates\n * @param {Array} point2 Point coordinates\n * @param {number} offset Offset\n * @returns {Array>} offset points\n */\nfunction processSegment(point1, point2, offset) {\n var L = Math.sqrt(\n (point1[0] - point2[0]) * (point1[0] - point2[0]) +\n (point1[1] - point2[1]) * (point1[1] - point2[1])\n );\n\n var out1x = point1[0] + (offset * (point2[1] - point1[1])) / L;\n var out2x = point2[0] + (offset * (point2[1] - point1[1])) / L;\n var out1y = point1[1] + (offset * (point1[0] - point2[0])) / L;\n var out2y = point2[1] + (offset * (point1[0] - point2[0])) / L;\n return [\n [out1x, out1y],\n [out2x, out2y],\n ];\n}\n\nexport { lineOffset };\nexport default lineOffset;\n","/**\n * https://github.com/rook2pawn/node-intersection\n *\n * Author @rook2pawn\n */\n\n/**\n * AB\n *\n * @private\n * @param {Array>} segment - 2 vertex line segment\n * @returns {Array} coordinates [x, y]\n */\nfunction ab(segment) {\n var start = segment[0];\n var end = segment[1];\n return [end[0] - start[0], end[1] - start[1]];\n}\n\n/**\n * Cross Product\n *\n * @private\n * @param {Array} v1 coordinates [x, y]\n * @param {Array} v2 coordinates [x, y]\n * @returns {Array} Cross Product\n */\nfunction crossProduct(v1, v2) {\n return v1[0] * v2[1] - v2[0] * v1[1];\n}\n\n/**\n * Add\n *\n * @private\n * @param {Array} v1 coordinates [x, y]\n * @param {Array} v2 coordinates [x, y]\n * @returns {Array} Add\n */\nfunction add(v1, v2) {\n return [v1[0] + v2[0], v1[1] + v2[1]];\n}\n\n/**\n * Sub\n *\n * @private\n * @param {Array} v1 coordinates [x, y]\n * @param {Array} v2 coordinates [x, y]\n * @returns {Array} Sub\n */\nfunction sub(v1, v2) {\n return [v1[0] - v2[0], v1[1] - v2[1]];\n}\n\n/**\n * scalarMult\n *\n * @private\n * @param {number} s scalar\n * @param {Array} v coordinates [x, y]\n * @returns {Array} scalarMult\n */\nfunction scalarMult(s, v) {\n return [s * v[0], s * v[1]];\n}\n\n/**\n * Intersect Segments\n *\n * @private\n * @param {Array} a coordinates [x, y]\n * @param {Array} b coordinates [x, y]\n * @returns {Array} intersection\n */\nfunction intersectSegments(a, b) {\n var p = a[0];\n var r = ab(a);\n var q = b[0];\n var s = ab(b);\n\n var cross = crossProduct(r, s);\n var qmp = sub(q, p);\n var numerator = crossProduct(qmp, s);\n var t = numerator / cross;\n var intersection = add(p, scalarMult(t, r));\n return intersection;\n}\n\n/**\n * Is Parallel\n *\n * @private\n * @param {Array} a coordinates [x, y]\n * @param {Array} b coordinates [x, y]\n * @returns {boolean} true if a and b are parallel (or co-linear)\n */\nfunction isParallel(a, b) {\n var r = ab(a);\n var s = ab(b);\n return crossProduct(r, s) === 0;\n}\n\n/**\n * Intersection\n *\n * @private\n * @param {Array} a coordinates [x, y]\n * @param {Array} b coordinates [x, y]\n * @returns {Array|boolean} true if a and b are parallel (or co-linear)\n */\nfunction intersection(a, b) {\n if (isParallel(a, b)) return false;\n return intersectSegments(a, b);\n}\n\nexport { intersection };\nexport default intersection;\n"],"mappings":"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","names":["intersection"]}