Skip to content

Commit 1f0c122

Browse files
committed
Compute multiFeatureLocation in addition to location property in @turf/nearest-point-on-line
Fix unit tests
1 parent bac370a commit 1f0c122

File tree

9 files changed

+65
-4
lines changed

9 files changed

+65
-4
lines changed

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

Lines changed: 23 additions & 4 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[]} pt 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.
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.
2626
* @example
2727
* var line = turf.lineString([
2828
* [-77.031669, 38.878605],
@@ -51,6 +51,7 @@ function nearestPointOnLine<G extends LineString | MultiLineString>(
5151
index: number;
5252
multiFeatureIndex: number;
5353
location: number;
54+
multiFeatureLocation: number;
5455
[key: string]: any;
5556
}
5657
> {
@@ -62,18 +63,33 @@ function nearestPointOnLine<G extends LineString | MultiLineString>(
6263

6364
let closestPt: Feature<
6465
Point,
65-
{ dist: number; index: number; multiFeatureIndex: number; location: number }
66+
{
67+
dist: number;
68+
index: number;
69+
multiFeatureIndex: number;
70+
location: number;
71+
multiFeatureLocation: number;
72+
}
6673
> = point([Infinity, Infinity], {
6774
dist: Infinity,
6875
index: -1,
6976
multiFeatureIndex: -1,
7077
location: -1,
78+
multiFeatureLocation: -1,
7179
});
7280

7381
let length = 0.0;
82+
let multiFeatureLength = 0.0;
83+
let currentMultiFeatureIndex = -1;
7484
flattenEach(
7585
lines,
7686
function (line: any, _featureIndex: number, multiFeatureIndex: number) {
87+
//reset multiFeatureLength at each changed multiFeatureIndex
88+
if (currentMultiFeatureIndex !== multiFeatureIndex) {
89+
currentMultiFeatureIndex = multiFeatureIndex;
90+
multiFeatureLength = 0.0;
91+
}
92+
7793
const coords: any = getCoords(line);
7894

7995
for (let i = 0; i < coords.length - 1; i++) {
@@ -106,10 +122,12 @@ function nearestPointOnLine<G extends LineString | MultiLineString>(
106122
);
107123
}
108124

125+
const lineLocationDist = distance(start, intersectPos, options);
109126
const intersectPt = point(intersectPos, {
110127
dist: distance(pt, intersectPos, options),
111128
multiFeatureIndex: multiFeatureIndex,
112-
location: length + distance(start, intersectPos, options),
129+
location: length + lineLocationDist,
130+
multiFeatureLocation: multiFeatureLength + lineLocationDist,
113131
});
114132

115133
if (intersectPt.properties.dist < closestPt.properties.dist) {
@@ -124,8 +142,9 @@ function nearestPointOnLine<G extends LineString | MultiLineString>(
124142
};
125143
}
126144

127-
// update length
145+
// update length and multiFeatureLength
128146
length += sectionLength;
147+
multiFeatureLength += sectionLength;
129148
}
130149
}
131150
);

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ test("turf-nearest-point-on-line", (t) => {
4040
onLine.properties["marker-color"] = "#F0F";
4141
onLine.properties.dist = round(onLine.properties.dist, 6);
4242
onLine.properties.location = round(onLine.properties.location, 6);
43+
onLine.properties.multiFeatureLocation = round(
44+
onLine.properties.multiFeatureLocation,
45+
6
46+
);
4347
const between = lineString(
4448
[onLine.geometry.coordinates, point.geometry.coordinates],
4549
{ stroke: "#F00", "stroke-width": 6 }
@@ -399,6 +403,37 @@ test("turf-nearest-point-on-line -- multifeature index", (t) => {
399403
t.end();
400404
});
401405

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

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"dist": 5.959562,
4343
"multiFeatureIndex": 0,
4444
"location": 19.748879,
45+
"multiFeatureLocation": 19.748879,
4546
"index": 1,
4647
"marker-color": "#F0F"
4748
},

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"dist": 2.556271,
4343
"multiFeatureIndex": 0,
4444
"location": 22.137494,
45+
"multiFeatureLocation": 22.137494,
4546
"index": 1,
4647
"marker-color": "#F0F"
4748
},

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
"index": 21,
7272
"multiFeatureIndex": 1,
7373
"location": 9479.011715,
74+
"multiFeatureLocation": 4800.716022,
7475
"marker-color": "#F0F"
7576
},
7677
"geometry": {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
"index": 0,
5353
"multiFeatureIndex": 1,
5454
"location": 1656.139708,
55+
"multiFeatureLocation": 0,
5556
"marker-color": "#F0F"
5657
},
5758
"geometry": {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
"dist": 121.937841,
6161
"multiFeatureIndex": 0,
6262
"location": 214.735285,
63+
"multiFeatureLocation": 214.735285,
6364
"index": 0,
6465
"marker-color": "#F0F"
6566
},

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4795,6 +4795,7 @@
47954795
"dist": 7.876557,
47964796
"multiFeatureIndex": 0,
47974797
"location": 183.46844,
4798+
"multiFeatureLocation": 183.46844,
47984799
"index": 3104,
47994800
"marker-color": "#F0F"
48004801
},

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3799,6 +3799,7 @@
37993799
"dist": 19.22738,
38003800
"multiFeatureIndex": 0,
38013801
"location": 303.639629,
3802+
"multiFeatureLocation": 303.639629,
38023803
"index": 1185,
38033804
"marker-color": "#F0F"
38043805
},

0 commit comments

Comments
 (0)