@turf/nearest-point-on-line 7.0.0-alpha.0 → 7.0.0-alpha.110
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -9
- package/dist/cjs/index.cjs +110 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/{js → cjs}/index.d.ts +5 -3
- package/dist/esm/index.d.mts +39 -0
- package/dist/esm/index.mjs +110 -0
- package/dist/esm/index.mjs.map +1 -0
- package/package.json +39 -34
- package/dist/es/index.js +0 -87
- package/dist/es/package.json +0 -1
- package/dist/js/index.js +0 -90
package/README.md
CHANGED
|
@@ -58,26 +58,21 @@ Returns **[Feature][4]<[Point][7]>** closest point on the `line` to `point`. The
|
|
|
58
58
|
|
|
59
59
|
[11]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
|
|
60
60
|
|
|
61
|
-
<!-- This file is automatically generated. Please don't edit it directly
|
|
62
|
-
if you find an error, edit the source file (likely index.js), and re-run
|
|
63
|
-
./scripts/generate-readmes in the turf project. -->
|
|
61
|
+
<!-- This file is automatically generated. Please don't edit it directly. If you find an error, edit the source file of the module in question (likely index.js or index.ts), and re-run "yarn docs" from the root of the turf project. -->
|
|
64
62
|
|
|
65
63
|
---
|
|
66
64
|
|
|
67
|
-
This module is part of the [Turfjs project](
|
|
68
|
-
module collection dedicated to geographic algorithms. It is maintained in the
|
|
69
|
-
[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create
|
|
70
|
-
PRs and issues.
|
|
65
|
+
This module is part of the [Turfjs project](https://turfjs.org/), an open source module collection dedicated to geographic algorithms. It is maintained in the [Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create PRs and issues.
|
|
71
66
|
|
|
72
67
|
### Installation
|
|
73
68
|
|
|
74
|
-
Install this module individually:
|
|
69
|
+
Install this single module individually:
|
|
75
70
|
|
|
76
71
|
```sh
|
|
77
72
|
$ npm install @turf/nearest-point-on-line
|
|
78
73
|
```
|
|
79
74
|
|
|
80
|
-
Or install the
|
|
75
|
+
Or install the all-encompassing @turf/turf module that includes all modules as functions:
|
|
81
76
|
|
|
82
77
|
```sh
|
|
83
78
|
$ npm install @turf/turf
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
+
var __spreadValues = (a, b) => {
|
|
9
|
+
for (var prop in b || (b = {}))
|
|
10
|
+
if (__hasOwnProp.call(b, prop))
|
|
11
|
+
__defNormalProp(a, prop, b[prop]);
|
|
12
|
+
if (__getOwnPropSymbols)
|
|
13
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
+
if (__propIsEnum.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
}
|
|
17
|
+
return a;
|
|
18
|
+
};
|
|
19
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
21
|
+
|
|
22
|
+
// index.ts
|
|
23
|
+
var _bearing = require('@turf/bearing');
|
|
24
|
+
var _distance = require('@turf/distance');
|
|
25
|
+
var _destination = require('@turf/destination');
|
|
26
|
+
var _lineintersect = require('@turf/line-intersect');
|
|
27
|
+
var _meta = require('@turf/meta');
|
|
28
|
+
var _helpers = require('@turf/helpers');
|
|
29
|
+
var _invariant = require('@turf/invariant');
|
|
30
|
+
function nearestPointOnLine(lines, pt, options = {}) {
|
|
31
|
+
if (!lines || !pt) {
|
|
32
|
+
throw new Error("lines and pt are required arguments");
|
|
33
|
+
}
|
|
34
|
+
let closestPt = _helpers.point.call(void 0, [Infinity, Infinity], {
|
|
35
|
+
dist: Infinity,
|
|
36
|
+
index: -1,
|
|
37
|
+
location: -1
|
|
38
|
+
});
|
|
39
|
+
let length = 0;
|
|
40
|
+
_meta.flattenEach.call(void 0, lines, function(line) {
|
|
41
|
+
const coords = _invariant.getCoords.call(void 0, line);
|
|
42
|
+
for (let i = 0; i < coords.length - 1; i++) {
|
|
43
|
+
const start = _helpers.point.call(void 0, coords[i]);
|
|
44
|
+
start.properties.dist = _distance.distance.call(void 0, pt, start, options);
|
|
45
|
+
const stop = _helpers.point.call(void 0, coords[i + 1]);
|
|
46
|
+
stop.properties.dist = _distance.distance.call(void 0, pt, stop, options);
|
|
47
|
+
const sectionLength = _distance.distance.call(void 0, start, stop, options);
|
|
48
|
+
const heightDistance = Math.max(
|
|
49
|
+
start.properties.dist,
|
|
50
|
+
stop.properties.dist
|
|
51
|
+
);
|
|
52
|
+
const direction = _bearing.bearing.call(void 0, start, stop);
|
|
53
|
+
const perpendicularPt1 = _destination.destination.call(void 0,
|
|
54
|
+
pt,
|
|
55
|
+
heightDistance,
|
|
56
|
+
direction + 90,
|
|
57
|
+
options
|
|
58
|
+
);
|
|
59
|
+
const perpendicularPt2 = _destination.destination.call(void 0,
|
|
60
|
+
pt,
|
|
61
|
+
heightDistance,
|
|
62
|
+
direction - 90,
|
|
63
|
+
options
|
|
64
|
+
);
|
|
65
|
+
const intersect = _lineintersect.lineIntersect.call(void 0,
|
|
66
|
+
_helpers.lineString.call(void 0, [
|
|
67
|
+
perpendicularPt1.geometry.coordinates,
|
|
68
|
+
perpendicularPt2.geometry.coordinates
|
|
69
|
+
]),
|
|
70
|
+
_helpers.lineString.call(void 0, [start.geometry.coordinates, stop.geometry.coordinates])
|
|
71
|
+
);
|
|
72
|
+
let intersectPt;
|
|
73
|
+
if (intersect.features.length > 0 && intersect.features[0]) {
|
|
74
|
+
intersectPt = __spreadProps(__spreadValues({}, intersect.features[0]), {
|
|
75
|
+
properties: {
|
|
76
|
+
dist: _distance.distance.call(void 0, pt, intersect.features[0], options),
|
|
77
|
+
location: length + _distance.distance.call(void 0, start, intersect.features[0], options)
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
if (start.properties.dist < closestPt.properties.dist) {
|
|
82
|
+
closestPt = __spreadProps(__spreadValues({}, start), {
|
|
83
|
+
properties: __spreadProps(__spreadValues({}, start.properties), { index: i, location: length })
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
if (stop.properties.dist < closestPt.properties.dist) {
|
|
87
|
+
closestPt = __spreadProps(__spreadValues({}, stop), {
|
|
88
|
+
properties: __spreadProps(__spreadValues({}, stop.properties), {
|
|
89
|
+
index: i + 1,
|
|
90
|
+
location: length + sectionLength
|
|
91
|
+
})
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
if (intersectPt && intersectPt.properties.dist < closestPt.properties.dist) {
|
|
95
|
+
closestPt = __spreadProps(__spreadValues({}, intersectPt), {
|
|
96
|
+
properties: __spreadProps(__spreadValues({}, intersectPt.properties), { index: i })
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
length += sectionLength;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
return closestPt;
|
|
103
|
+
}
|
|
104
|
+
__name(nearestPointOnLine, "nearestPointOnLine");
|
|
105
|
+
var turf_nearest_point_on_line_default = nearestPointOnLine;
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
exports.default = turf_nearest_point_on_line_default; exports.nearestPointOnLine = nearestPointOnLine;
|
|
110
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AACA,SAAS,eAAe;AACxB,SAAS,gBAAgB;AACzB,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB,sBAAsB;AAChD,SAAS,mBAAmB;AAC5B,SAAS,OAAO,kBAAgC;AAChD,SAAS,iBAAiB;AA4B1B,SAAS,mBACP,OACA,IACA,UAA6B,CAAC,GAS9B;AACA,MAAI,CAAC,SAAS,CAAC,IAAI;AACjB,UAAM,IAAI,MAAM,qCAAqC;AAAA,EACvD;AAEA,MAAI,YAGA,MAAM,CAAC,UAAU,QAAQ,GAAG;AAAA,IAC9B,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,EACZ,CAAC;AAED,MAAI,SAAS;AACb,cAAY,OAAO,SAAU,MAAW;AACtC,UAAM,SAAc,UAAU,IAAI;AAElC,aAAS,IAAI,GAAG,IAAI,OAAO,SAAS,GAAG,KAAK;AAE1C,YAAM,QAA0C,MAAM,OAAO,CAAC,CAAC;AAC/D,YAAM,WAAW,OAAO,SAAS,IAAI,OAAO,OAAO;AAEnD,YAAM,OAAyC,MAAM,OAAO,IAAI,CAAC,CAAC;AAClE,WAAK,WAAW,OAAO,SAAS,IAAI,MAAM,OAAO;AAEjD,YAAM,gBAAgB,SAAS,OAAO,MAAM,OAAO;AAEnD,YAAM,iBAAiB,KAAK;AAAA,QAC1B,MAAM,WAAW;AAAA,QACjB,KAAK,WAAW;AAAA,MAClB;AACA,YAAM,YAAY,QAAQ,OAAO,IAAI;AACrC,YAAM,mBAAmB;AAAA,QACvB;AAAA,QACA;AAAA,QACA,YAAY;AAAA,QACZ;AAAA,MACF;AACA,YAAM,mBAAmB;AAAA,QACvB;AAAA,QACA;AAAA,QACA,YAAY;AAAA,QACZ;AAAA,MACF;AACA,YAAM,YAAY;AAAA,QAChB,WAAW;AAAA,UACT,iBAAiB,SAAS;AAAA,UAC1B,iBAAiB,SAAS;AAAA,QAC5B,CAAC;AAAA,QACD,WAAW,CAAC,MAAM,SAAS,aAAa,KAAK,SAAS,WAAW,CAAC;AAAA,MACpE;AACA,UAAI;AAIJ,UAAI,UAAU,SAAS,SAAS,KAAK,UAAU,SAAS,CAAC,GAAG;AAC1D,sBAAc,iCACT,UAAU,SAAS,CAAC,IADX;AAAA,UAEZ,YAAY;AAAA,YACV,MAAM,SAAS,IAAI,UAAU,SAAS,CAAC,GAAG,OAAO;AAAA,YACjD,UAAU,SAAS,SAAS,OAAO,UAAU,SAAS,CAAC,GAAG,OAAO;AAAA,UACnE;AAAA,QACF;AAAA,MACF;AAEA,UAAI,MAAM,WAAW,OAAO,UAAU,WAAW,MAAM;AACrD,oBAAY,iCACP,QADO;AAAA,UAEV,YAAY,iCAAK,MAAM,aAAX,EAAuB,OAAO,GAAG,UAAU,OAAO;AAAA,QAChE;AAAA,MACF;AAEA,UAAI,KAAK,WAAW,OAAO,UAAU,WAAW,MAAM;AACpD,oBAAY,iCACP,OADO;AAAA,UAEV,YAAY,iCACP,KAAK,aADE;AAAA,YAEV,OAAO,IAAI;AAAA,YACX,UAAU,SAAS;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAEA,UACE,eACA,YAAY,WAAW,OAAO,UAAU,WAAW,MACnD;AACA,oBAAY,iCACP,cADO;AAAA,UAEV,YAAY,iCAAK,YAAY,aAAjB,EAA6B,OAAO,EAAE;AAAA,QACpD;AAAA,MACF;AAEA,gBAAU;AAAA,IACZ;AAAA,EACF,CAAC;AAED,SAAO;AACT;AA/GS;AAkHT,IAAO,qCAAQ","sourcesContent":["import { Feature, Point, LineString, MultiLineString } from \"geojson\";\nimport { bearing } from \"@turf/bearing\";\nimport { distance } from \"@turf/distance\";\nimport { destination } from \"@turf/destination\";\nimport { lineIntersect as lineIntersects } from \"@turf/line-intersect\";\nimport { flattenEach } from \"@turf/meta\";\nimport { point, lineString, Coord, Units } from \"@turf/helpers\";\nimport { getCoords } from \"@turf/invariant\";\n\n/**\n * Takes a {@link Point} and a {@link LineString} and calculates the closest Point on the (Multi)LineString.\n *\n * @name nearestPointOnLine\n * @param {Geometry|Feature<LineString|MultiLineString>} lines lines to snap to\n * @param {Geometry|Feature<Point>|number[]} pt point to snap from\n * @param {Object} [options={}] Optional parameters\n * @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers\n * @returns {Feature<Point>} closest point on the `line` to `point`. The properties object will contain three values: `index`: closest point was found on nth line part, `dist`: distance between pt and the closest point, `location`: distance along the line between start and the closest point.\n * @example\n * var line = turf.lineString([\n * [-77.031669, 38.878605],\n * [-77.029609, 38.881946],\n * [-77.020339, 38.884084],\n * [-77.025661, 38.885821],\n * [-77.021884, 38.889563],\n * [-77.019824, 38.892368]\n * ]);\n * var pt = turf.point([-77.037076, 38.884017]);\n *\n * var snapped = turf.nearestPointOnLine(line, pt, {units: 'miles'});\n *\n * //addToMap\n * var addToMap = [line, pt, snapped];\n * snapped.properties['marker-color'] = '#00f';\n */\nfunction nearestPointOnLine<G extends LineString | MultiLineString>(\n lines: Feature<G> | G,\n pt: Coord,\n options: { units?: Units } = {}\n): Feature<\n Point,\n {\n dist: number;\n index: number;\n location: number;\n [key: string]: any;\n }\n> {\n if (!lines || !pt) {\n throw new Error(\"lines and pt are required arguments\");\n }\n\n let closestPt: Feature<\n Point,\n { dist: number; index: number; location: number }\n > = point([Infinity, Infinity], {\n dist: Infinity,\n index: -1,\n location: -1,\n });\n\n let length = 0.0;\n flattenEach(lines, function (line: any) {\n const coords: any = getCoords(line);\n\n for (let i = 0; i < coords.length - 1; i++) {\n //start\n const start: Feature<Point, { dist: number }> = point(coords[i]);\n start.properties.dist = distance(pt, start, options);\n //stop\n const stop: Feature<Point, { dist: number }> = point(coords[i + 1]);\n stop.properties.dist = distance(pt, stop, options);\n // sectionLength\n const sectionLength = distance(start, stop, options);\n //perpendicular\n const heightDistance = Math.max(\n start.properties.dist,\n stop.properties.dist\n );\n const direction = bearing(start, stop);\n const perpendicularPt1 = destination(\n pt,\n heightDistance,\n direction + 90,\n options\n );\n const perpendicularPt2 = destination(\n pt,\n heightDistance,\n direction - 90,\n options\n );\n const intersect = lineIntersects(\n lineString([\n perpendicularPt1.geometry.coordinates,\n perpendicularPt2.geometry.coordinates,\n ]),\n lineString([start.geometry.coordinates, stop.geometry.coordinates])\n );\n let intersectPt:\n | Feature<Point, { dist: number; location: number }>\n | undefined;\n\n if (intersect.features.length > 0 && intersect.features[0]) {\n intersectPt = {\n ...intersect.features[0],\n properties: {\n dist: distance(pt, intersect.features[0], options),\n location: length + distance(start, intersect.features[0], options),\n },\n };\n }\n\n if (start.properties.dist < closestPt.properties.dist) {\n closestPt = {\n ...start,\n properties: { ...start.properties, index: i, location: length },\n };\n }\n\n if (stop.properties.dist < closestPt.properties.dist) {\n closestPt = {\n ...stop,\n properties: {\n ...stop.properties,\n index: i + 1,\n location: length + sectionLength,\n },\n };\n }\n\n if (\n intersectPt &&\n intersectPt.properties.dist < closestPt.properties.dist\n ) {\n closestPt = {\n ...intersectPt,\n properties: { ...intersectPt.properties, index: i },\n };\n }\n // update length\n length += sectionLength;\n }\n });\n\n return closestPt;\n}\n\nexport { nearestPointOnLine };\nexport default nearestPointOnLine;\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Coord, Units } from
|
|
1
|
+
import { LineString, MultiLineString, Feature, Point } from 'geojson';
|
|
2
|
+
import { Coord, Units } from '@turf/helpers';
|
|
3
|
+
|
|
3
4
|
/**
|
|
4
5
|
* Takes a {@link Point} and a {@link LineString} and calculates the closest Point on the (Multi)LineString.
|
|
5
6
|
*
|
|
@@ -34,4 +35,5 @@ declare function nearestPointOnLine<G extends LineString | MultiLineString>(line
|
|
|
34
35
|
location: number;
|
|
35
36
|
[key: string]: any;
|
|
36
37
|
}>;
|
|
37
|
-
|
|
38
|
+
|
|
39
|
+
export { nearestPointOnLine as default, nearestPointOnLine };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { LineString, MultiLineString, Feature, Point } from 'geojson';
|
|
2
|
+
import { Coord, Units } from '@turf/helpers';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Takes a {@link Point} and a {@link LineString} and calculates the closest Point on the (Multi)LineString.
|
|
6
|
+
*
|
|
7
|
+
* @name nearestPointOnLine
|
|
8
|
+
* @param {Geometry|Feature<LineString|MultiLineString>} lines lines to snap to
|
|
9
|
+
* @param {Geometry|Feature<Point>|number[]} pt point to snap from
|
|
10
|
+
* @param {Object} [options={}] Optional parameters
|
|
11
|
+
* @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers
|
|
12
|
+
* @returns {Feature<Point>} closest point on the `line` to `point`. The properties object will contain three values: `index`: closest point was found on nth line part, `dist`: distance between pt and the closest point, `location`: distance along the line between start and the closest point.
|
|
13
|
+
* @example
|
|
14
|
+
* var line = turf.lineString([
|
|
15
|
+
* [-77.031669, 38.878605],
|
|
16
|
+
* [-77.029609, 38.881946],
|
|
17
|
+
* [-77.020339, 38.884084],
|
|
18
|
+
* [-77.025661, 38.885821],
|
|
19
|
+
* [-77.021884, 38.889563],
|
|
20
|
+
* [-77.019824, 38.892368]
|
|
21
|
+
* ]);
|
|
22
|
+
* var pt = turf.point([-77.037076, 38.884017]);
|
|
23
|
+
*
|
|
24
|
+
* var snapped = turf.nearestPointOnLine(line, pt, {units: 'miles'});
|
|
25
|
+
*
|
|
26
|
+
* //addToMap
|
|
27
|
+
* var addToMap = [line, pt, snapped];
|
|
28
|
+
* snapped.properties['marker-color'] = '#00f';
|
|
29
|
+
*/
|
|
30
|
+
declare function nearestPointOnLine<G extends LineString | MultiLineString>(lines: Feature<G> | G, pt: Coord, options?: {
|
|
31
|
+
units?: Units;
|
|
32
|
+
}): Feature<Point, {
|
|
33
|
+
dist: number;
|
|
34
|
+
index: number;
|
|
35
|
+
location: number;
|
|
36
|
+
[key: string]: any;
|
|
37
|
+
}>;
|
|
38
|
+
|
|
39
|
+
export { nearestPointOnLine as default, nearestPointOnLine };
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
+
var __spreadValues = (a, b) => {
|
|
9
|
+
for (var prop in b || (b = {}))
|
|
10
|
+
if (__hasOwnProp.call(b, prop))
|
|
11
|
+
__defNormalProp(a, prop, b[prop]);
|
|
12
|
+
if (__getOwnPropSymbols)
|
|
13
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
+
if (__propIsEnum.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
}
|
|
17
|
+
return a;
|
|
18
|
+
};
|
|
19
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
21
|
+
|
|
22
|
+
// index.ts
|
|
23
|
+
import { bearing } from "@turf/bearing";
|
|
24
|
+
import { distance } from "@turf/distance";
|
|
25
|
+
import { destination } from "@turf/destination";
|
|
26
|
+
import { lineIntersect as lineIntersects } from "@turf/line-intersect";
|
|
27
|
+
import { flattenEach } from "@turf/meta";
|
|
28
|
+
import { point, lineString } from "@turf/helpers";
|
|
29
|
+
import { getCoords } from "@turf/invariant";
|
|
30
|
+
function nearestPointOnLine(lines, pt, options = {}) {
|
|
31
|
+
if (!lines || !pt) {
|
|
32
|
+
throw new Error("lines and pt are required arguments");
|
|
33
|
+
}
|
|
34
|
+
let closestPt = point([Infinity, Infinity], {
|
|
35
|
+
dist: Infinity,
|
|
36
|
+
index: -1,
|
|
37
|
+
location: -1
|
|
38
|
+
});
|
|
39
|
+
let length = 0;
|
|
40
|
+
flattenEach(lines, function(line) {
|
|
41
|
+
const coords = getCoords(line);
|
|
42
|
+
for (let i = 0; i < coords.length - 1; i++) {
|
|
43
|
+
const start = point(coords[i]);
|
|
44
|
+
start.properties.dist = distance(pt, start, options);
|
|
45
|
+
const stop = point(coords[i + 1]);
|
|
46
|
+
stop.properties.dist = distance(pt, stop, options);
|
|
47
|
+
const sectionLength = distance(start, stop, options);
|
|
48
|
+
const heightDistance = Math.max(
|
|
49
|
+
start.properties.dist,
|
|
50
|
+
stop.properties.dist
|
|
51
|
+
);
|
|
52
|
+
const direction = bearing(start, stop);
|
|
53
|
+
const perpendicularPt1 = destination(
|
|
54
|
+
pt,
|
|
55
|
+
heightDistance,
|
|
56
|
+
direction + 90,
|
|
57
|
+
options
|
|
58
|
+
);
|
|
59
|
+
const perpendicularPt2 = destination(
|
|
60
|
+
pt,
|
|
61
|
+
heightDistance,
|
|
62
|
+
direction - 90,
|
|
63
|
+
options
|
|
64
|
+
);
|
|
65
|
+
const intersect = lineIntersects(
|
|
66
|
+
lineString([
|
|
67
|
+
perpendicularPt1.geometry.coordinates,
|
|
68
|
+
perpendicularPt2.geometry.coordinates
|
|
69
|
+
]),
|
|
70
|
+
lineString([start.geometry.coordinates, stop.geometry.coordinates])
|
|
71
|
+
);
|
|
72
|
+
let intersectPt;
|
|
73
|
+
if (intersect.features.length > 0 && intersect.features[0]) {
|
|
74
|
+
intersectPt = __spreadProps(__spreadValues({}, intersect.features[0]), {
|
|
75
|
+
properties: {
|
|
76
|
+
dist: distance(pt, intersect.features[0], options),
|
|
77
|
+
location: length + distance(start, intersect.features[0], options)
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
if (start.properties.dist < closestPt.properties.dist) {
|
|
82
|
+
closestPt = __spreadProps(__spreadValues({}, start), {
|
|
83
|
+
properties: __spreadProps(__spreadValues({}, start.properties), { index: i, location: length })
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
if (stop.properties.dist < closestPt.properties.dist) {
|
|
87
|
+
closestPt = __spreadProps(__spreadValues({}, stop), {
|
|
88
|
+
properties: __spreadProps(__spreadValues({}, stop.properties), {
|
|
89
|
+
index: i + 1,
|
|
90
|
+
location: length + sectionLength
|
|
91
|
+
})
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
if (intersectPt && intersectPt.properties.dist < closestPt.properties.dist) {
|
|
95
|
+
closestPt = __spreadProps(__spreadValues({}, intersectPt), {
|
|
96
|
+
properties: __spreadProps(__spreadValues({}, intersectPt.properties), { index: i })
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
length += sectionLength;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
return closestPt;
|
|
103
|
+
}
|
|
104
|
+
__name(nearestPointOnLine, "nearestPointOnLine");
|
|
105
|
+
var turf_nearest_point_on_line_default = nearestPointOnLine;
|
|
106
|
+
export {
|
|
107
|
+
turf_nearest_point_on_line_default as default,
|
|
108
|
+
nearestPointOnLine
|
|
109
|
+
};
|
|
110
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../index.ts"],"sourcesContent":["import { Feature, Point, LineString, MultiLineString } from \"geojson\";\nimport { bearing } from \"@turf/bearing\";\nimport { distance } from \"@turf/distance\";\nimport { destination } from \"@turf/destination\";\nimport { lineIntersect as lineIntersects } from \"@turf/line-intersect\";\nimport { flattenEach } from \"@turf/meta\";\nimport { point, lineString, Coord, Units } from \"@turf/helpers\";\nimport { getCoords } from \"@turf/invariant\";\n\n/**\n * Takes a {@link Point} and a {@link LineString} and calculates the closest Point on the (Multi)LineString.\n *\n * @name nearestPointOnLine\n * @param {Geometry|Feature<LineString|MultiLineString>} lines lines to snap to\n * @param {Geometry|Feature<Point>|number[]} pt point to snap from\n * @param {Object} [options={}] Optional parameters\n * @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers\n * @returns {Feature<Point>} closest point on the `line` to `point`. The properties object will contain three values: `index`: closest point was found on nth line part, `dist`: distance between pt and the closest point, `location`: distance along the line between start and the closest point.\n * @example\n * var line = turf.lineString([\n * [-77.031669, 38.878605],\n * [-77.029609, 38.881946],\n * [-77.020339, 38.884084],\n * [-77.025661, 38.885821],\n * [-77.021884, 38.889563],\n * [-77.019824, 38.892368]\n * ]);\n * var pt = turf.point([-77.037076, 38.884017]);\n *\n * var snapped = turf.nearestPointOnLine(line, pt, {units: 'miles'});\n *\n * //addToMap\n * var addToMap = [line, pt, snapped];\n * snapped.properties['marker-color'] = '#00f';\n */\nfunction nearestPointOnLine<G extends LineString | MultiLineString>(\n lines: Feature<G> | G,\n pt: Coord,\n options: { units?: Units } = {}\n): Feature<\n Point,\n {\n dist: number;\n index: number;\n location: number;\n [key: string]: any;\n }\n> {\n if (!lines || !pt) {\n throw new Error(\"lines and pt are required arguments\");\n }\n\n let closestPt: Feature<\n Point,\n { dist: number; index: number; location: number }\n > = point([Infinity, Infinity], {\n dist: Infinity,\n index: -1,\n location: -1,\n });\n\n let length = 0.0;\n flattenEach(lines, function (line: any) {\n const coords: any = getCoords(line);\n\n for (let i = 0; i < coords.length - 1; i++) {\n //start\n const start: Feature<Point, { dist: number }> = point(coords[i]);\n start.properties.dist = distance(pt, start, options);\n //stop\n const stop: Feature<Point, { dist: number }> = point(coords[i + 1]);\n stop.properties.dist = distance(pt, stop, options);\n // sectionLength\n const sectionLength = distance(start, stop, options);\n //perpendicular\n const heightDistance = Math.max(\n start.properties.dist,\n stop.properties.dist\n );\n const direction = bearing(start, stop);\n const perpendicularPt1 = destination(\n pt,\n heightDistance,\n direction + 90,\n options\n );\n const perpendicularPt2 = destination(\n pt,\n heightDistance,\n direction - 90,\n options\n );\n const intersect = lineIntersects(\n lineString([\n perpendicularPt1.geometry.coordinates,\n perpendicularPt2.geometry.coordinates,\n ]),\n lineString([start.geometry.coordinates, stop.geometry.coordinates])\n );\n let intersectPt:\n | Feature<Point, { dist: number; location: number }>\n | undefined;\n\n if (intersect.features.length > 0 && intersect.features[0]) {\n intersectPt = {\n ...intersect.features[0],\n properties: {\n dist: distance(pt, intersect.features[0], options),\n location: length + distance(start, intersect.features[0], options),\n },\n };\n }\n\n if (start.properties.dist < closestPt.properties.dist) {\n closestPt = {\n ...start,\n properties: { ...start.properties, index: i, location: length },\n };\n }\n\n if (stop.properties.dist < closestPt.properties.dist) {\n closestPt = {\n ...stop,\n properties: {\n ...stop.properties,\n index: i + 1,\n location: length + sectionLength,\n },\n };\n }\n\n if (\n intersectPt &&\n intersectPt.properties.dist < closestPt.properties.dist\n ) {\n closestPt = {\n ...intersectPt,\n properties: { ...intersectPt.properties, index: i },\n };\n }\n // update length\n length += sectionLength;\n }\n });\n\n return closestPt;\n}\n\nexport { nearestPointOnLine };\nexport default nearestPointOnLine;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AACA,SAAS,eAAe;AACxB,SAAS,gBAAgB;AACzB,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB,sBAAsB;AAChD,SAAS,mBAAmB;AAC5B,SAAS,OAAO,kBAAgC;AAChD,SAAS,iBAAiB;AA4B1B,SAAS,mBACP,OACA,IACA,UAA6B,CAAC,GAS9B;AACA,MAAI,CAAC,SAAS,CAAC,IAAI;AACjB,UAAM,IAAI,MAAM,qCAAqC;AAAA,EACvD;AAEA,MAAI,YAGA,MAAM,CAAC,UAAU,QAAQ,GAAG;AAAA,IAC9B,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,EACZ,CAAC;AAED,MAAI,SAAS;AACb,cAAY,OAAO,SAAU,MAAW;AACtC,UAAM,SAAc,UAAU,IAAI;AAElC,aAAS,IAAI,GAAG,IAAI,OAAO,SAAS,GAAG,KAAK;AAE1C,YAAM,QAA0C,MAAM,OAAO,CAAC,CAAC;AAC/D,YAAM,WAAW,OAAO,SAAS,IAAI,OAAO,OAAO;AAEnD,YAAM,OAAyC,MAAM,OAAO,IAAI,CAAC,CAAC;AAClE,WAAK,WAAW,OAAO,SAAS,IAAI,MAAM,OAAO;AAEjD,YAAM,gBAAgB,SAAS,OAAO,MAAM,OAAO;AAEnD,YAAM,iBAAiB,KAAK;AAAA,QAC1B,MAAM,WAAW;AAAA,QACjB,KAAK,WAAW;AAAA,MAClB;AACA,YAAM,YAAY,QAAQ,OAAO,IAAI;AACrC,YAAM,mBAAmB;AAAA,QACvB;AAAA,QACA;AAAA,QACA,YAAY;AAAA,QACZ;AAAA,MACF;AACA,YAAM,mBAAmB;AAAA,QACvB;AAAA,QACA;AAAA,QACA,YAAY;AAAA,QACZ;AAAA,MACF;AACA,YAAM,YAAY;AAAA,QAChB,WAAW;AAAA,UACT,iBAAiB,SAAS;AAAA,UAC1B,iBAAiB,SAAS;AAAA,QAC5B,CAAC;AAAA,QACD,WAAW,CAAC,MAAM,SAAS,aAAa,KAAK,SAAS,WAAW,CAAC;AAAA,MACpE;AACA,UAAI;AAIJ,UAAI,UAAU,SAAS,SAAS,KAAK,UAAU,SAAS,CAAC,GAAG;AAC1D,sBAAc,iCACT,UAAU,SAAS,CAAC,IADX;AAAA,UAEZ,YAAY;AAAA,YACV,MAAM,SAAS,IAAI,UAAU,SAAS,CAAC,GAAG,OAAO;AAAA,YACjD,UAAU,SAAS,SAAS,OAAO,UAAU,SAAS,CAAC,GAAG,OAAO;AAAA,UACnE;AAAA,QACF;AAAA,MACF;AAEA,UAAI,MAAM,WAAW,OAAO,UAAU,WAAW,MAAM;AACrD,oBAAY,iCACP,QADO;AAAA,UAEV,YAAY,iCAAK,MAAM,aAAX,EAAuB,OAAO,GAAG,UAAU,OAAO;AAAA,QAChE;AAAA,MACF;AAEA,UAAI,KAAK,WAAW,OAAO,UAAU,WAAW,MAAM;AACpD,oBAAY,iCACP,OADO;AAAA,UAEV,YAAY,iCACP,KAAK,aADE;AAAA,YAEV,OAAO,IAAI;AAAA,YACX,UAAU,SAAS;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAEA,UACE,eACA,YAAY,WAAW,OAAO,UAAU,WAAW,MACnD;AACA,oBAAY,iCACP,cADO;AAAA,UAEV,YAAY,iCAAK,YAAY,aAAjB,EAA6B,OAAO,EAAE;AAAA,QACpD;AAAA,MACF;AAEA,gBAAU;AAAA,IACZ;AAAA,EACF,CAAC;AAED,SAAO;AACT;AA/GS;AAkHT,IAAO,qCAAQ;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@turf/nearest-point-on-line",
|
|
3
|
-
"version": "7.0.0-alpha.
|
|
3
|
+
"version": "7.0.0-alpha.110+1411d63a7",
|
|
4
4
|
"description": "turf nearest-point-on-line module",
|
|
5
5
|
"author": "Turf Authors",
|
|
6
6
|
"license": "MIT",
|
|
@@ -16,53 +16,58 @@
|
|
|
16
16
|
"publishConfig": {
|
|
17
17
|
"access": "public"
|
|
18
18
|
},
|
|
19
|
-
"main": "dist/
|
|
20
|
-
"module": "dist/
|
|
19
|
+
"main": "dist/cjs/index.cjs",
|
|
20
|
+
"module": "dist/esm/index.mjs",
|
|
21
|
+
"types": "dist/cjs/index.d.ts",
|
|
21
22
|
"exports": {
|
|
22
23
|
"./package.json": "./package.json",
|
|
23
24
|
".": {
|
|
24
|
-
"import":
|
|
25
|
-
|
|
25
|
+
"import": {
|
|
26
|
+
"types": "./dist/esm/index.d.mts",
|
|
27
|
+
"default": "./dist/esm/index.mjs"
|
|
28
|
+
},
|
|
29
|
+
"require": {
|
|
30
|
+
"types": "./dist/cjs/index.d.ts",
|
|
31
|
+
"default": "./dist/cjs/index.cjs"
|
|
32
|
+
}
|
|
26
33
|
}
|
|
27
34
|
},
|
|
28
|
-
"types": "dist/js/index.d.ts",
|
|
29
35
|
"sideEffects": false,
|
|
30
36
|
"files": [
|
|
31
37
|
"dist"
|
|
32
38
|
],
|
|
33
39
|
"scripts": {
|
|
34
|
-
"bench": "
|
|
35
|
-
"build": "
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"test": "npm-run-all test:*",
|
|
40
|
-
"test:tape": "ts-node -r esm test.js",
|
|
40
|
+
"bench": "tsx bench.ts",
|
|
41
|
+
"build": "tsup --config ../../tsup.config.ts",
|
|
42
|
+
"docs": "tsx ../../scripts/generate-readmes.ts",
|
|
43
|
+
"test": "npm-run-all --npm-path npm test:*",
|
|
44
|
+
"test:tape": "tsx test.ts",
|
|
41
45
|
"test:types": "tsc --esModuleInterop --noEmit --strict types.ts"
|
|
42
46
|
},
|
|
43
47
|
"devDependencies": {
|
|
44
|
-
"@turf/along": "^7.0.0-alpha.
|
|
45
|
-
"@turf/length": "^7.0.0-alpha.
|
|
46
|
-
"@turf/truncate": "^7.0.0-alpha.
|
|
47
|
-
"@types/
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
48
|
+
"@turf/along": "^7.0.0-alpha.110+1411d63a7",
|
|
49
|
+
"@turf/length": "^7.0.0-alpha.110+1411d63a7",
|
|
50
|
+
"@turf/truncate": "^7.0.0-alpha.110+1411d63a7",
|
|
51
|
+
"@types/benchmark": "^2.1.5",
|
|
52
|
+
"@types/tape": "^4.2.32",
|
|
53
|
+
"benchmark": "^2.1.4",
|
|
54
|
+
"load-json-file": "^7.0.1",
|
|
55
|
+
"npm-run-all": "^4.1.5",
|
|
56
|
+
"tape": "^5.7.2",
|
|
57
|
+
"tsup": "^8.0.1",
|
|
58
|
+
"tsx": "^4.6.2",
|
|
59
|
+
"typescript": "^5.2.2",
|
|
60
|
+
"write-json-file": "^5.0.0"
|
|
56
61
|
},
|
|
57
62
|
"dependencies": {
|
|
58
|
-
"@turf/bearing": "^7.0.0-alpha.
|
|
59
|
-
"@turf/destination": "^7.0.0-alpha.
|
|
60
|
-
"@turf/distance": "^7.0.0-alpha.
|
|
61
|
-
"@turf/helpers": "^7.0.0-alpha.
|
|
62
|
-
"@turf/invariant": "^7.0.0-alpha.
|
|
63
|
-
"@turf/line-intersect": "^7.0.0-alpha.
|
|
64
|
-
"@turf/meta": "^7.0.0-alpha.
|
|
65
|
-
"tslib": "^2.
|
|
63
|
+
"@turf/bearing": "^7.0.0-alpha.110+1411d63a7",
|
|
64
|
+
"@turf/destination": "^7.0.0-alpha.110+1411d63a7",
|
|
65
|
+
"@turf/distance": "^7.0.0-alpha.110+1411d63a7",
|
|
66
|
+
"@turf/helpers": "^7.0.0-alpha.110+1411d63a7",
|
|
67
|
+
"@turf/invariant": "^7.0.0-alpha.110+1411d63a7",
|
|
68
|
+
"@turf/line-intersect": "^7.0.0-alpha.110+1411d63a7",
|
|
69
|
+
"@turf/meta": "^7.0.0-alpha.110+1411d63a7",
|
|
70
|
+
"tslib": "^2.6.2"
|
|
66
71
|
},
|
|
67
|
-
"gitHead": "
|
|
72
|
+
"gitHead": "1411d63a74c275c9216fe48e9d3cb2d48a359068"
|
|
68
73
|
}
|
package/dist/es/index.js
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import bearing from "@turf/bearing";
|
|
2
|
-
import distance from "@turf/distance";
|
|
3
|
-
import destination from "@turf/destination";
|
|
4
|
-
import lineIntersects from "@turf/line-intersect";
|
|
5
|
-
import { flattenEach } from "@turf/meta";
|
|
6
|
-
import { point, lineString } from "@turf/helpers";
|
|
7
|
-
import { getCoords } from "@turf/invariant";
|
|
8
|
-
/**
|
|
9
|
-
* Takes a {@link Point} and a {@link LineString} and calculates the closest Point on the (Multi)LineString.
|
|
10
|
-
*
|
|
11
|
-
* @name nearestPointOnLine
|
|
12
|
-
* @param {Geometry|Feature<LineString|MultiLineString>} lines lines to snap to
|
|
13
|
-
* @param {Geometry|Feature<Point>|number[]} pt point to snap from
|
|
14
|
-
* @param {Object} [options={}] Optional parameters
|
|
15
|
-
* @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers
|
|
16
|
-
* @returns {Feature<Point>} closest point on the `line` to `point`. The properties object will contain three values: `index`: closest point was found on nth line part, `dist`: distance between pt and the closest point, `location`: distance along the line between start and the closest point.
|
|
17
|
-
* @example
|
|
18
|
-
* var line = turf.lineString([
|
|
19
|
-
* [-77.031669, 38.878605],
|
|
20
|
-
* [-77.029609, 38.881946],
|
|
21
|
-
* [-77.020339, 38.884084],
|
|
22
|
-
* [-77.025661, 38.885821],
|
|
23
|
-
* [-77.021884, 38.889563],
|
|
24
|
-
* [-77.019824, 38.892368]
|
|
25
|
-
* ]);
|
|
26
|
-
* var pt = turf.point([-77.037076, 38.884017]);
|
|
27
|
-
*
|
|
28
|
-
* var snapped = turf.nearestPointOnLine(line, pt, {units: 'miles'});
|
|
29
|
-
*
|
|
30
|
-
* //addToMap
|
|
31
|
-
* var addToMap = [line, pt, snapped];
|
|
32
|
-
* snapped.properties['marker-color'] = '#00f';
|
|
33
|
-
*/
|
|
34
|
-
function nearestPointOnLine(lines, pt, options = {}) {
|
|
35
|
-
if (!lines || !pt) {
|
|
36
|
-
throw new Error("lines and pt are required arguments");
|
|
37
|
-
}
|
|
38
|
-
let closestPt = point([Infinity, Infinity], {
|
|
39
|
-
dist: Infinity,
|
|
40
|
-
index: -1,
|
|
41
|
-
location: -1,
|
|
42
|
-
});
|
|
43
|
-
let length = 0.0;
|
|
44
|
-
flattenEach(lines, function (line) {
|
|
45
|
-
const coords = getCoords(line);
|
|
46
|
-
for (let i = 0; i < coords.length - 1; i++) {
|
|
47
|
-
//start
|
|
48
|
-
const start = point(coords[i]);
|
|
49
|
-
start.properties.dist = distance(pt, start, options);
|
|
50
|
-
//stop
|
|
51
|
-
const stop = point(coords[i + 1]);
|
|
52
|
-
stop.properties.dist = distance(pt, stop, options);
|
|
53
|
-
// sectionLength
|
|
54
|
-
const sectionLength = distance(start, stop, options);
|
|
55
|
-
//perpendicular
|
|
56
|
-
const heightDistance = Math.max(start.properties.dist, stop.properties.dist);
|
|
57
|
-
const direction = bearing(start, stop);
|
|
58
|
-
const perpendicularPt1 = destination(pt, heightDistance, direction + 90, options);
|
|
59
|
-
const perpendicularPt2 = destination(pt, heightDistance, direction - 90, options);
|
|
60
|
-
const intersect = lineIntersects(lineString([
|
|
61
|
-
perpendicularPt1.geometry.coordinates,
|
|
62
|
-
perpendicularPt2.geometry.coordinates,
|
|
63
|
-
]), lineString([start.geometry.coordinates, stop.geometry.coordinates]));
|
|
64
|
-
let intersectPt;
|
|
65
|
-
if (intersect.features.length > 0 && intersect.features[0]) {
|
|
66
|
-
intersectPt = Object.assign(Object.assign({}, intersect.features[0]), { properties: {
|
|
67
|
-
dist: distance(pt, intersect.features[0], options),
|
|
68
|
-
location: length + distance(start, intersect.features[0], options),
|
|
69
|
-
} });
|
|
70
|
-
}
|
|
71
|
-
if (start.properties.dist < closestPt.properties.dist) {
|
|
72
|
-
closestPt = Object.assign(Object.assign({}, start), { properties: Object.assign(Object.assign({}, start.properties), { index: i, location: length }) });
|
|
73
|
-
}
|
|
74
|
-
if (stop.properties.dist < closestPt.properties.dist) {
|
|
75
|
-
closestPt = Object.assign(Object.assign({}, stop), { properties: Object.assign(Object.assign({}, stop.properties), { index: i + 1, location: length + sectionLength }) });
|
|
76
|
-
}
|
|
77
|
-
if (intersectPt &&
|
|
78
|
-
intersectPt.properties.dist < closestPt.properties.dist) {
|
|
79
|
-
closestPt = Object.assign(Object.assign({}, intersectPt), { properties: Object.assign(Object.assign({}, intersectPt.properties), { index: i }) });
|
|
80
|
-
}
|
|
81
|
-
// update length
|
|
82
|
-
length += sectionLength;
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
return closestPt;
|
|
86
|
-
}
|
|
87
|
-
export default nearestPointOnLine;
|
package/dist/es/package.json
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"type":"module"}
|
package/dist/js/index.js
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const tslib_1 = require("tslib");
|
|
4
|
-
const bearing_1 = tslib_1.__importDefault(require("@turf/bearing"));
|
|
5
|
-
const distance_1 = tslib_1.__importDefault(require("@turf/distance"));
|
|
6
|
-
const destination_1 = tslib_1.__importDefault(require("@turf/destination"));
|
|
7
|
-
const line_intersect_1 = tslib_1.__importDefault(require("@turf/line-intersect"));
|
|
8
|
-
const meta_1 = require("@turf/meta");
|
|
9
|
-
const helpers_1 = require("@turf/helpers");
|
|
10
|
-
const invariant_1 = require("@turf/invariant");
|
|
11
|
-
/**
|
|
12
|
-
* Takes a {@link Point} and a {@link LineString} and calculates the closest Point on the (Multi)LineString.
|
|
13
|
-
*
|
|
14
|
-
* @name nearestPointOnLine
|
|
15
|
-
* @param {Geometry|Feature<LineString|MultiLineString>} lines lines to snap to
|
|
16
|
-
* @param {Geometry|Feature<Point>|number[]} pt point to snap from
|
|
17
|
-
* @param {Object} [options={}] Optional parameters
|
|
18
|
-
* @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers
|
|
19
|
-
* @returns {Feature<Point>} closest point on the `line` to `point`. The properties object will contain three values: `index`: closest point was found on nth line part, `dist`: distance between pt and the closest point, `location`: distance along the line between start and the closest point.
|
|
20
|
-
* @example
|
|
21
|
-
* var line = turf.lineString([
|
|
22
|
-
* [-77.031669, 38.878605],
|
|
23
|
-
* [-77.029609, 38.881946],
|
|
24
|
-
* [-77.020339, 38.884084],
|
|
25
|
-
* [-77.025661, 38.885821],
|
|
26
|
-
* [-77.021884, 38.889563],
|
|
27
|
-
* [-77.019824, 38.892368]
|
|
28
|
-
* ]);
|
|
29
|
-
* var pt = turf.point([-77.037076, 38.884017]);
|
|
30
|
-
*
|
|
31
|
-
* var snapped = turf.nearestPointOnLine(line, pt, {units: 'miles'});
|
|
32
|
-
*
|
|
33
|
-
* //addToMap
|
|
34
|
-
* var addToMap = [line, pt, snapped];
|
|
35
|
-
* snapped.properties['marker-color'] = '#00f';
|
|
36
|
-
*/
|
|
37
|
-
function nearestPointOnLine(lines, pt, options = {}) {
|
|
38
|
-
if (!lines || !pt) {
|
|
39
|
-
throw new Error("lines and pt are required arguments");
|
|
40
|
-
}
|
|
41
|
-
let closestPt = helpers_1.point([Infinity, Infinity], {
|
|
42
|
-
dist: Infinity,
|
|
43
|
-
index: -1,
|
|
44
|
-
location: -1,
|
|
45
|
-
});
|
|
46
|
-
let length = 0.0;
|
|
47
|
-
meta_1.flattenEach(lines, function (line) {
|
|
48
|
-
const coords = invariant_1.getCoords(line);
|
|
49
|
-
for (let i = 0; i < coords.length - 1; i++) {
|
|
50
|
-
//start
|
|
51
|
-
const start = helpers_1.point(coords[i]);
|
|
52
|
-
start.properties.dist = distance_1.default(pt, start, options);
|
|
53
|
-
//stop
|
|
54
|
-
const stop = helpers_1.point(coords[i + 1]);
|
|
55
|
-
stop.properties.dist = distance_1.default(pt, stop, options);
|
|
56
|
-
// sectionLength
|
|
57
|
-
const sectionLength = distance_1.default(start, stop, options);
|
|
58
|
-
//perpendicular
|
|
59
|
-
const heightDistance = Math.max(start.properties.dist, stop.properties.dist);
|
|
60
|
-
const direction = bearing_1.default(start, stop);
|
|
61
|
-
const perpendicularPt1 = destination_1.default(pt, heightDistance, direction + 90, options);
|
|
62
|
-
const perpendicularPt2 = destination_1.default(pt, heightDistance, direction - 90, options);
|
|
63
|
-
const intersect = line_intersect_1.default(helpers_1.lineString([
|
|
64
|
-
perpendicularPt1.geometry.coordinates,
|
|
65
|
-
perpendicularPt2.geometry.coordinates,
|
|
66
|
-
]), helpers_1.lineString([start.geometry.coordinates, stop.geometry.coordinates]));
|
|
67
|
-
let intersectPt;
|
|
68
|
-
if (intersect.features.length > 0 && intersect.features[0]) {
|
|
69
|
-
intersectPt = Object.assign(Object.assign({}, intersect.features[0]), { properties: {
|
|
70
|
-
dist: distance_1.default(pt, intersect.features[0], options),
|
|
71
|
-
location: length + distance_1.default(start, intersect.features[0], options),
|
|
72
|
-
} });
|
|
73
|
-
}
|
|
74
|
-
if (start.properties.dist < closestPt.properties.dist) {
|
|
75
|
-
closestPt = Object.assign(Object.assign({}, start), { properties: Object.assign(Object.assign({}, start.properties), { index: i, location: length }) });
|
|
76
|
-
}
|
|
77
|
-
if (stop.properties.dist < closestPt.properties.dist) {
|
|
78
|
-
closestPt = Object.assign(Object.assign({}, stop), { properties: Object.assign(Object.assign({}, stop.properties), { index: i + 1, location: length + sectionLength }) });
|
|
79
|
-
}
|
|
80
|
-
if (intersectPt &&
|
|
81
|
-
intersectPt.properties.dist < closestPt.properties.dist) {
|
|
82
|
-
closestPt = Object.assign(Object.assign({}, intersectPt), { properties: Object.assign(Object.assign({}, intersectPt.properties), { index: i }) });
|
|
83
|
-
}
|
|
84
|
-
// update length
|
|
85
|
-
length += sectionLength;
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
return closestPt;
|
|
89
|
-
}
|
|
90
|
-
exports.default = nearestPointOnLine;
|