Skip to content

Commit e5091a9

Browse files
committed
Compute multiFeatureLocation in addition to location property in @turf/nearest-point-on-line
1 parent b53f6d1 commit e5091a9

File tree

2 files changed

+60
-5
lines changed

2 files changed

+60
-5
lines changed

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

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { getCoord, getCoords } from "@turf/invariant";
1818
* @param {Geometry|Feature<Point>|number[]} pt point to snap from
1919
* @param {Object} [options={}] Optional parameters
2020
* @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers
21-
* @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.
21+
* @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.
2222
* @example
2323
* var line = turf.lineString([
2424
* [-77.031669, 38.878605],
@@ -47,6 +47,7 @@ function nearestPointOnLine<G extends LineString | MultiLineString>(
4747
index: number;
4848
multiFeatureIndex: number;
4949
location: number;
50+
multiFeatureLocation: number;
5051
[key: string]: any;
5152
}
5253
> {
@@ -58,18 +59,33 @@ function nearestPointOnLine<G extends LineString | MultiLineString>(
5859

5960
let closestPt: Feature<
6061
Point,
61-
{ dist: number; index: number; multiFeatureIndex: number; location: number }
62+
{
63+
dist: number;
64+
index: number;
65+
multiFeatureIndex: number;
66+
location: number;
67+
multiFeatureLocation: number;
68+
}
6269
> = point([Infinity, Infinity], {
6370
dist: Infinity,
6471
index: -1,
6572
multiFeatureIndex: -1,
6673
location: -1,
74+
multiFeatureLocation: -1,
6775
});
6876

6977
let length = 0.0;
78+
let multiFeatureLength = 0.0;
79+
let currentMultiFeatureIndex = -1;
7080
flattenEach(
7181
lines,
7282
function (line: any, _featureIndex: number, multiFeatureIndex: number) {
83+
//reset multiFeatureLength at each changed multiFeatureIndex
84+
if (currentMultiFeatureIndex !== multiFeatureIndex) {
85+
currentMultiFeatureIndex = multiFeatureIndex;
86+
multiFeatureLength = 0.0;
87+
}
88+
7389
const coords: any = getCoords(line);
7490

7591
for (let i = 0; i < coords.length - 1; i++) {
@@ -107,15 +123,22 @@ function nearestPointOnLine<G extends LineString | MultiLineString>(
107123
let intersectPt:
108124
| Feature<
109125
Point,
110-
{ dist: number; multiFeatureIndex: number; location: number }
126+
{
127+
dist: number;
128+
multiFeatureIndex: number;
129+
location: number;
130+
multiFeatureLocation: number;
131+
}
111132
>
112133
| undefined;
113134

114135
if (intersectPos) {
136+
const lineLocationDist = distance(start, intersectPos, options);
115137
intersectPt = point(intersectPos, {
116138
dist: distance(pt, intersectPos, options),
117139
multiFeatureIndex: multiFeatureIndex,
118-
location: length + distance(start, intersectPos, options),
140+
location: length + lineLocationDist,
141+
multiFeatureLocation: multiFeatureLength + lineLocationDist,
119142
});
120143
}
121144

@@ -134,8 +157,9 @@ function nearestPointOnLine<G extends LineString | MultiLineString>(
134157
};
135158
}
136159

137-
// update length
160+
// update length and multiFeatureLength
138161
length += sectionLength;
162+
multiFeatureLength += sectionLength;
139163
}
140164
}
141165
);

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,37 @@ test("turf-nearest-point-on-line -- multifeature index", (t) => {
398398
t.end();
399399
});
400400

401+
test("turf-nearest-point-on-line -- issue 2753 multifeature location", (t) => {
402+
const multiLine = multiLineString([
403+
[
404+
[-122.3125, 47.6632],
405+
[-122.3102, 47.6646],
406+
],
407+
[
408+
[-122.3116, 47.6623],
409+
[-122.3091, 47.6636],
410+
],
411+
]);
412+
413+
const ptA = point([-122.3106, 47.6638], { name: "A" });
414+
const ptB = point([-122.3102, 47.6634], { name: "B" });
415+
416+
const nearestToA = nearestPointOnLine(multiLine, ptA, { units: "meters" });
417+
const nearestToB = nearestPointOnLine(multiLine, ptB, { units: "meters" });
418+
419+
t.equal(
420+
Number(nearestToA.properties.multiFeatureLocation.toFixed(6)),
421+
150.293316,
422+
"nearestToA multiFeatureLocation"
423+
);
424+
t.equal(
425+
Number(nearestToB.properties.multiFeatureLocation.toFixed(6)),
426+
157.736676,
427+
"nearestToB multiFeatureLocation"
428+
);
429+
t.end();
430+
});
431+
401432
test("turf-nearest-point-on-line -- issue 1514", (t) => {
402433
const pt = point([-40.01, 56]);
403434
const line = lineString([

0 commit comments

Comments
 (0)