在最近的一个项目中有个需求,我需要确定从单个点 ? 到由其他两个点(A 和 B)的连线的垂直距离。通常我们可以只使用turf.nearestPointOnLine()
,但是只有当C点位于前两点之间时才有效。
但是点 C 可以在任何位置,不一定在点 A 和 B 之间。因此,需要沿着垂直于由点 A 和 B 创建的假想无限延长的直线来测量距离。这可以通过其他一些 turf 函数方法来完成 - 比如turf.bearing()
、turf.destination()
、turf.lineIntersect()
以及线的斜率。
下面的函数会返回一条延长线,其中两个附加点分别表示两个点的 X轴 和 Y轴 截距, 坐标轴位于点 C。我们有了这条延长线,就可以确定第三个点位于两个新点之间。此时我们可以使用turf.nearestPointOnLine()
,但这往往有一个小但显著的误差范围。为了提高测量的准确性,我们可以使用turf.lineIntersect()
函数。
const lines = turf.featureCollection([]);
const slope = (b[1] - a[1]) / (b[0] - a[0]);
const point1 = [c[0], slope * (c[0] - a[0]) + a[1]];
const point2 = [(c[1] - a[1]) / slope + a[0], c[1]];
const lineArray = [a, b, point1, point2];
lineArray.sort((a, b) => b[0] - a[0]);
lines.features.push(turf.lineString(lineArray));
const bearing1 = turf.bearing(a, b);
const { geometry: p90 } = turf.destination(
turf.point(c),
turf.distance(a, c),
bearing + 90
);
const { geometry: p91 } = turf.destination(
turf.point(c),
turf.distance(a, c),
bearing - 90
);
const perpendicularLine = turf.lineString([p90.coordinates, p91.coordinates]);
lines.features.push(perpendicularLine);
使用 turf.bearing()
我们可以从 C 点到 A 点或 B 点的距离创建一条垂直线,然后在该方位角上加上或减去 90。我们可以使用这个距离,因为除非点 C 与点 A 或 B 正好成 90 度,否则这个距离将始终大于到延长线的垂直距离。
现在我们有了这条垂直线,就可以使用 turf.lineIntersect()
沿着延长线获取目标点,并用它来测量到 C 点的距离。
const intersectingPoint = turf.lineIntersect(
lines.features[0],
lines.features[1]
);
const distance = turf.distance(intersectingPoint.features[0], turf.point(c), {
units: "miles"
});