Skip to content

Commit cd34656

Browse files
committed
nearest-point-on-line Rename point properties
1 parent 2cf5f71 commit cd34656

File tree

9 files changed

+104
-103
lines changed

9 files changed

+104
-103
lines changed

packages/turf-nearest-point-on-line/index.ts

Lines changed: 28 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { getCoord, getCoords } from "@turf/invariant";
2222
* @param {Geometry|Feature<Point>|number[]} inputPoint Point to snap from
2323
* @param {Object} [options={}] Optional parameters
2424
* @param {Units} [options.units='kilometers'] Supports all valid Turf {@link https://turfjs.org/docs/api/types/Units Units}
25-
* @returns {Feature<Point>} closest point on the `line` to `point`. The properties object will contain four values: `index`: closest point was found on nth line part, `multiFeatureIndex`: closest point was found on the nth line of the `MultiLineString`, `dist`: distance between pt and the closest point, `location`: distance along the line between start and the closest point, `multiFeatureLocation`: distance along the line between start of the `MultiLineString` where closest point was found and the closest point.
25+
* @returns {Feature<Point>} closest point on the `lines` to the `inputPoint`. The point will have the following properties: `lineStringIndex`: closest point was found on the nth LineString (only relevant if input is MultiLineString), `segmentIndex`: closest point was found on nth line segment of the LineString, `totalDistance`: distance along the line from the absolute start of the MultiLineString, `lineDistance`: distance along the line from the start of the LineString where the closest point was found, `segmentDistance`: distance along the line from the start of the line segment where the closest point was found, `pointDistance`: distance to the input point.
2626
* @example
2727
* var line = turf.lineString([
2828
* [-77.031669, 38.878605],
@@ -47,11 +47,12 @@ function nearestPointOnLine<G extends LineString | MultiLineString>(
4747
): Feature<
4848
Point,
4949
{
50-
dist: number;
51-
index: number;
52-
multiFeatureIndex: number;
53-
location: number;
54-
multiFeatureLocation: number;
50+
lineStringIndex: number;
51+
segmentIndex: number;
52+
totalDistance: number;
53+
lineDistance: number;
54+
segmentDistance: number;
55+
pointDistance: number;
5556
[key: string]: any;
5657
}
5758
> {
@@ -61,21 +62,13 @@ function nearestPointOnLine<G extends LineString | MultiLineString>(
6162

6263
const inputPos = getCoord(inputPoint);
6364

64-
let closestPt: Feature<
65-
Point,
66-
{
67-
dist: number;
68-
index: number;
69-
multiFeatureIndex: number;
70-
location: number;
71-
multiFeatureLocation: number;
72-
}
73-
> = point([Infinity, Infinity], {
74-
dist: Infinity,
75-
index: -1,
76-
multiFeatureIndex: -1,
77-
location: -1,
78-
multiFeatureLocation: -1,
65+
let closestPt = point([Infinity, Infinity], {
66+
lineStringIndex: -1,
67+
segmentIndex: -1,
68+
totalDistance: -1,
69+
lineDistance: -1,
70+
segmentDistance: -1,
71+
pointDistance: Infinity,
7972
});
8073

8174
let length = 0.0;
@@ -122,24 +115,20 @@ function nearestPointOnLine<G extends LineString | MultiLineString>(
122115
);
123116
}
124117

125-
const lineLocationDist = distance(start, intersectPos, options);
126-
const intersectPt = point(intersectPos, {
127-
dist: distance(inputPoint, intersectPos, options),
128-
multiFeatureIndex: multiFeatureIndex,
129-
location: length + lineLocationDist,
130-
multiFeatureLocation: multiFeatureLength + lineLocationDist,
131-
});
132-
133-
if (intersectPt.properties.dist < closestPt.properties.dist) {
134-
closestPt = {
135-
...intersectPt,
136-
properties: {
137-
...intersectPt.properties,
138-
// Legacy behaviour where index progresses to next segment # if we
139-
// went with the end point this iteration.
140-
index: wasEnd ? i + 1 : i,
141-
},
142-
};
118+
const pointDistance = distance(inputPoint, intersectPos, options);
119+
120+
if (pointDistance < closestPt.properties.pointDistance) {
121+
const lineLocationDist = distance(start, intersectPos, options);
122+
closestPt = point(intersectPos, {
123+
lineStringIndex: multiFeatureIndex,
124+
// Legacy behaviour where index progresses to next segment
125+
// if we went with the end point this iteration.
126+
segmentIndex: wasEnd ? i + 1 : i,
127+
totalDistance: length + lineLocationDist,
128+
lineDistance: multiFeatureLength + lineLocationDist,
129+
segmentDistance: lineLocationDist,
130+
pointDistance: pointDistance,
131+
});
143132
}
144133

145134
// update length and multiFeatureLength

packages/turf-nearest-point-on-line/test.ts

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,16 @@ test("turf-nearest-point-on-line", (t) => {
3737
for (const { name, filename, geojson } of fixtures) {
3838
const [line, point] = geojson.features;
3939
const onLine = nearestPointOnLine(line, point);
40-
onLine.properties["marker-color"] = "#F0F";
41-
onLine.properties.dist = round(onLine.properties.dist, 6);
42-
onLine.properties.location = round(onLine.properties.location, 6);
43-
onLine.properties.multiFeatureLocation = round(
44-
onLine.properties.multiFeatureLocation,
40+
onLine.geometry.coordinates[0] = round(onLine.geometry.coordinates[0], 6);
41+
onLine.geometry.coordinates[1] = round(onLine.geometry.coordinates[1], 6);
42+
onLine.properties.totalDistance = round(onLine.properties.totalDistance, 6);
43+
onLine.properties.lineDistance = round(onLine.properties.lineDistance, 6);
44+
onLine.properties.segmentDistance = round(
45+
onLine.properties.segmentDistance,
4546
6
4647
);
48+
onLine.properties.pointDistance = round(onLine.properties.pointDistance, 6);
49+
onLine.properties["marker-color"] = "#F0F";
4750
const between = lineString(
4851
[onLine.geometry.coordinates, point.geometry.coordinates],
4952
{ stroke: "#F00", "stroke-width": 6 }
@@ -79,9 +82,9 @@ test("turf-nearest-point-on-line - first point", (t) => {
7982
"pt on start does not move"
8083
);
8184
t.equal(
82-
Number(snapped.properties.location.toFixed(6)),
85+
Number(snapped.properties.totalDistance.toFixed(6)),
8386
0,
84-
"properties.location"
87+
"properties.totalDistance"
8588
);
8689

8790
t.end();
@@ -108,7 +111,7 @@ test("turf-nearest-point-on-line - points behind first point", (t) => {
108111
first.geometry.coordinates,
109112
"pt behind start moves to first vertex"
110113
);
111-
expectedLocation.push(Number(snapped.properties.location.toFixed(6)));
114+
expectedLocation.push(Number(snapped.properties.totalDistance.toFixed(6)));
112115
});
113116

114117
const filepath =
@@ -117,7 +120,7 @@ test("turf-nearest-point-on-line - points behind first point", (t) => {
117120
t.deepEqual(
118121
loadJsonFileSync(filepath),
119122
expectedLocation,
120-
"properties.location"
123+
"properties.totalDistance"
121124
);
122125
t.end();
123126
});
@@ -146,7 +149,7 @@ test("turf-nearest-point-on-line - points in front of last point", (t) => {
146149
last.geometry.coordinates,
147150
"pt behind start moves to last vertex"
148151
);
149-
expectedLocation.push(Number(snapped.properties.location.toFixed(6)));
152+
expectedLocation.push(Number(snapped.properties.totalDistance.toFixed(6)));
150153
});
151154

152155
const filepath =
@@ -155,7 +158,7 @@ test("turf-nearest-point-on-line - points in front of last point", (t) => {
155158
t.deepEqual(
156159
loadJsonFileSync(filepath),
157160
expectedLocation,
158-
"properties.location"
161+
"properties.totalDistance"
159162
);
160163
t.end();
161164
});
@@ -209,7 +212,9 @@ test("turf-nearest-point-on-line - points on joints", (t) => {
209212
"pt on joint stayed in place"
210213
);
211214
if (!expectedLocation[i]) expectedLocation[i] = [];
212-
expectedLocation[i][j] = Number(snapped.properties.location.toFixed(6));
215+
expectedLocation[i][j] = Number(
216+
snapped.properties.totalDistance.toFixed(6)
217+
);
213218
});
214219
});
215220

@@ -218,7 +223,7 @@ test("turf-nearest-point-on-line - points on joints", (t) => {
218223
t.deepEqual(
219224
expectedLocation,
220225
loadJsonFileSync(filepath),
221-
"properties.location"
226+
"properties.totalDistance"
222227
);
223228
t.end();
224229
});
@@ -249,7 +254,7 @@ test("turf-nearest-point-on-line - points on top of line", (t) => {
249254
const snapped = nearestPointOnLine(line, pt, { units: "miles" });
250255
const shift = distance(pt, snapped, { units: "miles" });
251256
t.true(shift < 0.000001, "pt did not shift far");
252-
expectedLocation.push(Number(snapped.properties.location.toFixed(6)));
257+
expectedLocation.push(Number(snapped.properties.totalDistance.toFixed(6)));
253258
}
254259

255260
const filepath =
@@ -258,7 +263,7 @@ test("turf-nearest-point-on-line - points on top of line", (t) => {
258263
t.deepEqual(
259264
expectedLocation,
260265
loadJsonFileSync(filepath),
261-
"properties.location"
266+
"properties.totalDistance"
262267
);
263268
t.end();
264269
});
@@ -324,11 +329,11 @@ test("turf-nearest-point-on-line - check dist and index", (t) => {
324329
const pt = point([-92.110576, 41.040649]);
325330
const snapped = truncate(nearestPointOnLine(line, pt));
326331

327-
t.equal(snapped.properties.index, 8, "properties.index");
332+
t.equal(snapped.properties.segmentIndex, 8, "properties.segmentIndex");
328333
t.equal(
329-
Number(snapped.properties.dist.toFixed(6)),
334+
Number(snapped.properties.pointDistance.toFixed(6)),
330335
0.823802,
331-
"properties.dist"
336+
"properties.pointDistance"
332337
);
333338
t.deepEqual(
334339
snapped.geometry.coordinates,
@@ -346,9 +351,9 @@ test("turf-nearest-point-on-line -- Issue #691", (t) => {
346351
[9, 50],
347352
]);
348353
const pointAlong = along(line1, 10);
349-
const { location } = nearestPointOnLine(line1, pointAlong).properties;
354+
const { totalDistance } = nearestPointOnLine(line1, pointAlong).properties;
350355

351-
t.false(isNaN(location));
356+
t.false(isNaN(totalDistance));
352357
t.end();
353358
});
354359

@@ -396,9 +401,9 @@ test("turf-nearest-point-on-line -- multifeature index", (t) => {
396401
],
397402
]);
398403
t.equal(
399-
nearestPointOnLine(multiLine.geometry, pt).properties.multiFeatureIndex,
404+
nearestPointOnLine(multiLine.geometry, pt).properties.lineStringIndex,
400405
1,
401-
"multiFeatureIndex"
406+
"properties.lineStringIndex"
402407
);
403408
t.end();
404409
});
@@ -422,14 +427,14 @@ test("turf-nearest-point-on-line -- issue 2753 multifeature location", (t) => {
422427
const nearestToB = nearestPointOnLine(multiLine, ptB, { units: "meters" });
423428

424429
t.equal(
425-
Number(nearestToA.properties.multiFeatureLocation.toFixed(6)),
430+
Number(nearestToA.properties.lineDistance.toFixed(6)),
426431
150.296465,
427-
"nearestToA multiFeatureLocation"
432+
"nearestToA lineDistance"
428433
);
429434
t.equal(
430-
Number(nearestToB.properties.multiFeatureLocation.toFixed(6)),
435+
Number(nearestToB.properties.lineDistance.toFixed(6)),
431436
157.738215,
432-
"nearestToB multiFeatureLocation"
437+
"nearestToB lineDistance"
433438
);
434439
t.end();
435440
});
@@ -549,7 +554,7 @@ test("turf-nearest-point-on-line -- issue 2808 redundant point support", (t) =>
549554
const thePoint = point([10.57846, 49.8468386]);
550555

551556
const nearest = nearestPointOnLine(line1, thePoint); // should not throw
552-
t.equal(nearest.properties.dist, 0, "redundant point should not throw");
557+
t.equal(nearest.properties.pointDistance, 0, "redundant point support");
553558

554559
t.end();
555560
});
@@ -563,8 +568,8 @@ test("turf-nearest-point-on-line -- duplicate points on line string shouldn't br
563568
]);
564569
const userPoint = point([-80.191762, 25.885587]);
565570
const nearest = nearestPointOnLine(line, userPoint, { units: "meters" });
566-
t.equal(nearest.properties.dist > 4, true, "dist should be greater than 4");
567-
t.equal(nearest.properties.location, 0, "location should be 0");
571+
t.equal(nearest.properties.pointDistance > 4, true, "pointDistance be > 4");
572+
t.equal(nearest.properties.totalDistance, 0, "totalDistance be 0");
568573
t.end();
569574
});
570575

packages/turf-nearest-point-on-line/test/out/line-northern-latitude-#344.geojson

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,12 @@
3939
{
4040
"type": "Feature",
4141
"properties": {
42-
"dist": 5.959562,
43-
"multiFeatureIndex": 0,
44-
"location": 19.748879,
45-
"multiFeatureLocation": 19.748879,
46-
"index": 1,
42+
"lineStringIndex": 0,
43+
"segmentIndex": 1,
44+
"totalDistance": 19.748879,
45+
"lineDistance": 19.748879,
46+
"segmentDistance": 1.771897,
47+
"pointDistance": 5.959562,
4748
"marker-color": "#F0F"
4849
},
4950
"geometry": {

packages/turf-nearest-point-on-line/test/out/line1.geojson

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,12 @@
3939
{
4040
"type": "Feature",
4141
"properties": {
42-
"dist": 2.556271,
43-
"multiFeatureIndex": 0,
44-
"location": 22.137494,
45-
"multiFeatureLocation": 22.137494,
46-
"index": 1,
42+
"lineStringIndex": 0,
43+
"segmentIndex": 1,
44+
"totalDistance": 22.137494,
45+
"lineDistance": 22.137494,
46+
"segmentDistance": 3.445915,
47+
"pointDistance": 2.556271,
4748
"marker-color": "#F0F"
4849
},
4950
"geometry": {

packages/turf-nearest-point-on-line/test/out/multiLine1.geojson

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,12 @@
6767
{
6868
"type": "Feature",
6969
"properties": {
70-
"dist": 114.725451,
71-
"index": 21,
72-
"multiFeatureIndex": 1,
73-
"location": 9479.011715,
74-
"multiFeatureLocation": 4800.716022,
70+
"lineStringIndex": 1,
71+
"segmentIndex": 21,
72+
"totalDistance": 9479.011715,
73+
"lineDistance": 4800.716022,
74+
"segmentDistance": 173.221741,
75+
"pointDistance": 114.725451,
7576
"marker-color": "#F0F"
7677
},
7778
"geometry": {

packages/turf-nearest-point-on-line/test/out/multiLine2.geojson

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,12 @@
4848
{
4949
"type": "Feature",
5050
"properties": {
51-
"dist": 390.942725,
52-
"index": 0,
53-
"multiFeatureIndex": 1,
54-
"location": 1656.139708,
55-
"multiFeatureLocation": 0,
51+
"lineStringIndex": 1,
52+
"segmentIndex": 0,
53+
"totalDistance": 1656.139708,
54+
"lineDistance": 0,
55+
"segmentDistance": 0,
56+
"pointDistance": 390.942725,
5657
"marker-color": "#F0F"
5758
},
5859
"geometry": {

packages/turf-nearest-point-on-line/test/out/multiLine3.geojson

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,12 @@
5757
{
5858
"type": "Feature",
5959
"properties": {
60-
"dist": 121.937841,
61-
"multiFeatureIndex": 0,
62-
"location": 214.735285,
63-
"multiFeatureLocation": 214.735285,
64-
"index": 0,
60+
"lineStringIndex": 0,
61+
"segmentIndex": 0,
62+
"totalDistance": 214.735285,
63+
"lineDistance": 214.735285,
64+
"segmentDistance": 214.735285,
65+
"pointDistance": 121.937841,
6566
"marker-color": "#F0F"
6667
},
6768
"geometry": {

packages/turf-nearest-point-on-line/test/out/route1.geojson

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4792,11 +4792,12 @@
47924792
{
47934793
"type": "Feature",
47944794
"properties": {
4795-
"dist": 7.876557,
4796-
"multiFeatureIndex": 0,
4797-
"location": 183.46844,
4798-
"multiFeatureLocation": 183.46844,
4799-
"index": 3104,
4795+
"lineStringIndex": 0,
4796+
"segmentIndex": 3104,
4797+
"totalDistance": 183.46844,
4798+
"lineDistance": 183.46844,
4799+
"segmentDistance": 0.044741,
4800+
"pointDistance": 7.876557,
48004801
"marker-color": "#F0F"
48014802
},
48024803
"geometry": {

0 commit comments

Comments
 (0)