| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- // index.ts
- import { getCoords, getType } from "@turf/invariant";
- import { point, featureCollection } from "@turf/helpers";
- import { bbox as calcBbox } from "@turf/bbox";
- import { explode } from "@turf/explode";
- import { nearestPoint } from "@turf/nearest-point";
- function polygonTangents(pt, polygon) {
- const pointCoords = getCoords(pt);
- const polyCoords = getCoords(polygon);
- let rtan = [];
- let ltan = [];
- let eprev;
- const bbox = calcBbox(polygon);
- let nearestPtIndex = 0;
- let nearest = null;
- if (pointCoords[0] > bbox[0] && pointCoords[0] < bbox[2] && pointCoords[1] > bbox[1] && pointCoords[1] < bbox[3]) {
- nearest = nearestPoint(pt, explode(polygon));
- nearestPtIndex = nearest.properties.featureIndex;
- }
- const type = getType(polygon);
- switch (type) {
- case "Polygon":
- rtan = polyCoords[0][nearestPtIndex];
- ltan = polyCoords[0][0];
- if (nearest !== null) {
- if (nearest.geometry.coordinates[1] < pointCoords[1])
- ltan = polyCoords[0][nearestPtIndex];
- }
- eprev = isLeft(
- polyCoords[0][0],
- polyCoords[0][polyCoords[0].length - 1],
- pointCoords
- );
- [rtan, ltan] = processPolygon(
- polyCoords[0],
- pointCoords,
- eprev,
- rtan,
- ltan
- );
- break;
- case "MultiPolygon":
- var closestFeature = 0;
- var closestVertex = 0;
- var verticesCounted = 0;
- for (var i = 0; i < polyCoords[0].length; i++) {
- closestFeature = i;
- var verticeFound = false;
- for (var i2 = 0; i2 < polyCoords[0][i].length; i2++) {
- closestVertex = i2;
- if (verticesCounted === nearestPtIndex) {
- verticeFound = true;
- break;
- }
- verticesCounted++;
- }
- if (verticeFound) break;
- }
- rtan = polyCoords[0][closestFeature][closestVertex];
- ltan = polyCoords[0][closestFeature][closestVertex];
- eprev = isLeft(
- polyCoords[0][0][0],
- polyCoords[0][0][polyCoords[0][0].length - 1],
- pointCoords
- );
- polyCoords.forEach(function(ring) {
- [rtan, ltan] = processPolygon(ring[0], pointCoords, eprev, rtan, ltan);
- });
- break;
- }
- return featureCollection([point(rtan), point(ltan)]);
- }
- function processPolygon(polygonCoords, ptCoords, eprev, rtan, ltan) {
- for (let i = 0; i < polygonCoords.length; i++) {
- const currentCoords = polygonCoords[i];
- let nextCoordPair = polygonCoords[i + 1];
- if (i === polygonCoords.length - 1) {
- nextCoordPair = polygonCoords[0];
- }
- const enext = isLeft(currentCoords, nextCoordPair, ptCoords);
- if (eprev <= 0 && enext > 0) {
- if (!isBelow(ptCoords, currentCoords, rtan)) {
- rtan = currentCoords;
- }
- } else if (eprev > 0 && enext <= 0) {
- if (!isAbove(ptCoords, currentCoords, ltan)) {
- ltan = currentCoords;
- }
- }
- eprev = enext;
- }
- return [rtan, ltan];
- }
- function isAbove(point1, point2, point3) {
- return isLeft(point1, point2, point3) > 0;
- }
- function isBelow(point1, point2, point3) {
- return isLeft(point1, point2, point3) < 0;
- }
- function isLeft(point1, point2, point3) {
- return (point2[0] - point1[0]) * (point3[1] - point1[1]) - (point3[0] - point1[0]) * (point2[1] - point1[1]);
- }
- var turf_polygon_tangents_default = polygonTangents;
- export {
- turf_polygon_tangents_default as default,
- polygonTangents
- };
- //# sourceMappingURL=index.js.map
|