{"version":3,"sources":["../../index.ts"],"sourcesContent":["import type {\n Feature,\n FeatureCollection,\n Point,\n Polygon,\n Position,\n MultiPolygon,\n} from \"geojson\";\nimport type { Coord } from \"@turf/helpers\";\nimport { getCoords, getType } from \"@turf/invariant\";\nimport { point, featureCollection } from \"@turf/helpers\";\nimport { bbox as calcBbox } from \"@turf/bbox\";\nimport { explode } from \"@turf/explode\";\nimport { nearestPoint } from \"@turf/nearest-point\";\n\n/**\n * Finds the tangents of a {@link Polygon|(Multi)Polygon} from a {@link Point}.\n *\n * @function\n * @param {Coord} pt to calculate the tangent points from\n * @param {Feature} polygon to get tangents from\n * @returns {FeatureCollection} Feature Collection containing the two tangent points\n * @example\n * var polygon = turf.polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]);\n * var point = turf.point([61, 5]);\n *\n * var tangents = turf.polygonTangents(point, polygon)\n *\n * //addToMap\n * var addToMap = [tangents, point, polygon];\n */\nfunction polygonTangents(\n pt: Coord,\n polygon: Feature | T\n): FeatureCollection {\n const pointCoords = getCoords(pt);\n const polyCoords = getCoords(polygon);\n\n let rtan: Position = [];\n let ltan: Position = [];\n let eprev: number;\n const bbox = calcBbox(polygon);\n let nearestPtIndex = 0;\n let nearest = null;\n\n // If the point lies inside the polygon bbox then we need to be a bit trickier\n // otherwise points lying inside reflex angles on concave polys can have issues\n if (\n pointCoords[0] > bbox[0] &&\n pointCoords[0] < bbox[2] &&\n pointCoords[1] > bbox[1] &&\n pointCoords[1] < bbox[3]\n ) {\n nearest = nearestPoint(pt, explode(polygon));\n nearestPtIndex = nearest.properties.featureIndex;\n }\n const type = getType(polygon);\n switch (type) {\n case \"Polygon\":\n rtan = polyCoords[0][nearestPtIndex];\n ltan = polyCoords[0][0];\n if (nearest !== null) {\n if (nearest.geometry.coordinates[1] < pointCoords[1])\n ltan = polyCoords[0][nearestPtIndex];\n }\n eprev = isLeft(\n polyCoords[0][0],\n polyCoords[0][polyCoords[0].length - 1],\n pointCoords\n );\n [rtan, ltan] = processPolygon(\n polyCoords[0],\n pointCoords,\n eprev,\n rtan,\n ltan\n );\n break;\n case \"MultiPolygon\":\n var closestFeature = 0;\n var closestVertex = 0;\n var verticesCounted = 0;\n for (var i = 0; i < polyCoords[0].length; i++) {\n closestFeature = i;\n var verticeFound = false;\n for (var i2 = 0; i2 < polyCoords[0][i].length; i2++) {\n closestVertex = i2;\n if (verticesCounted === nearestPtIndex) {\n verticeFound = true;\n break;\n }\n verticesCounted++;\n }\n if (verticeFound) break;\n }\n rtan = polyCoords[0][closestFeature][closestVertex];\n ltan = polyCoords[0][closestFeature][closestVertex];\n eprev = isLeft(\n polyCoords[0][0][0],\n polyCoords[0][0][polyCoords[0][0].length - 1],\n pointCoords\n );\n polyCoords.forEach(function (ring) {\n [rtan, ltan] = processPolygon(ring[0], pointCoords, eprev, rtan, ltan);\n });\n break;\n }\n return featureCollection([point(rtan), point(ltan)]);\n}\n\nfunction processPolygon(\n polygonCoords: Position[],\n ptCoords: Position,\n eprev: number,\n rtan: Position,\n ltan: Position\n) {\n for (let i = 0; i < polygonCoords.length; i++) {\n const currentCoords = polygonCoords[i];\n let nextCoordPair = polygonCoords[i + 1];\n if (i === polygonCoords.length - 1) {\n nextCoordPair = polygonCoords[0];\n }\n const enext = isLeft(currentCoords, nextCoordPair, ptCoords);\n if (eprev <= 0 && enext > 0) {\n if (!isBelow(ptCoords, currentCoords, rtan)) {\n rtan = currentCoords;\n }\n } else if (eprev > 0 && enext <= 0) {\n if (!isAbove(ptCoords, currentCoords, ltan)) {\n ltan = currentCoords;\n }\n }\n eprev = enext;\n }\n return [rtan, ltan];\n}\n\nfunction isAbove(point1: Position, point2: Position, point3: Position) {\n return isLeft(point1, point2, point3) > 0;\n}\n\nfunction isBelow(point1: Position, point2: Position, point3: Position) {\n return isLeft(point1, point2, point3) < 0;\n}\n\nfunction isLeft(point1: Position, point2: Position, point3: Position) {\n return (\n (point2[0] - point1[0]) * (point3[1] - point1[1]) -\n (point3[0] - point1[0]) * (point2[1] - point1[1])\n );\n}\n\nexport { polygonTangents };\nexport default polygonTangents;\n"],"mappings":"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","names":[]}