从lat / lng点获取折线的距离

时间:2017-08-28 18:01:09

标签: javascript google-maps d3.js

我正在Google地图上渲染折线,其数据如下所示:

data = [
  {
    distance: 3.45,
    lat: 37.37112776376307,
    lng: -122.13909476995468,
  },
  ...
];

将鼠标悬停在折线上时,我可以获得lat / lng坐标,我希望根据这些坐标获得沿线的距离。

我还没有找到一种使用Maps API执行此操作的简单方法。我希望从起点到任意点的距离沿着折线;大多数答案我发现只是处理两点之间的(最短)距离,而不是沿着预定义的路线。

我的另一个想法是使用D3(我用来绘制一些相关的图表)来平分数据并获得距离。但是,我无法弄清楚如何基于两个数据点(lat + lng)进行二等分。

关于如何完成我想要做的事情的任何建议?

编辑:在我的数据中,distance是在给定坐标处行进的累积距离。

3 个答案:

答案 0 :(得分:1)

您可以使用Turf库执行此操作(以及更多内容)。

使用草坪,您可以将问题分解为一些较小的问题 -

  • 找到离光标最近的行的确切位置
  • 从头到尾创建折线
  • 测量折线的长度。

例如,这里是从芝加哥到缅因州波特兰的几个城市的路线,我们想知道离锡拉丘兹和波士顿之间的线路附近的斯克内克塔迪有多远,但不在我们的路线上:

const turf = require('@turf/helpers')
const lineSlice = require('@turf/line-slice')
const pointOnLine = require('@turf/point-on-line')
const lineDistance = require('@turf/line-distance')

var route = turf.lineString([
[-87.627453, 41.853555], // Chicago
[-87.389126, 41.587682], // Gary IN
[-81.674692, 41.420385], // Clevland
[-76.077655, 42.988040], // Syracuse
[-71.066601, 42.323782], // Boston
[-70.277662, 43.627106]  // Portland, ME
]);

var Schenectady = turf.point([-73.899115, 42.815089]); //Schenectady

var snapped = pointOnLine(route, Schenectady, 'miles');
var sliced = lineSlice(route.geometry.coordinates[0], snapped, route);
var length = lineDistance(sliced, 'miles');

console.log(length) // => 736.8317888716095

这与谷歌的810英里路线非常吻合,这并非所有直线路线。

答案 1 :(得分:1)

我想我希望Maps API有一个方法

polyLine.computeDistanceBetween(point1, point2);

但似乎并非如此。

我最终解决了与@Mark_M如上所述相似的问题:

  1. Find the point on the polyline closest to the hovered point

    function getIndexOfNearestPoint(path, hoveredPoint) {
      let index = -1;
      let minDistance = 1000;
    
      path.forEach((pointOnPath, idx) => {
        const dist = window.google.maps.geometry.spherical.computeDistanceBetween(
          hoveredPoint,
          pointOnPath
        );
    
        if (dist < minDistance){
          minDistance = dist;
          index = idx;
        }
      });
    
      return index;
    }
    
  2. 计算折线上2个点之间的距离

    function getDistanceAlongPath(path, startIndex, endIndex) {
      let distance = 0;
      for (let ii = startIndex; ii < endIndex; ii++) {
        distance += window.google.maps.geometry.spherical.computeDistanceBetween(
          path[ii],
          path[ii + 1]
        );
      }
      return distance;
    }
    
  3. 将它们放在一起以找到从折线起点到悬停点的累积距离:

    polyline.addListener('mousemove', e => {
      const path = polyline.getPath().getArray();
      const hoveredPoint = e.latLng;
      const startIndex = 0;
    
      const endIndex = getIndexOfNearestPoint(path, hoveredPoint);
      const distance = getDistanceAlongPath(path, startIndex, endIndex);
    });
    

答案 2 :(得分:0)

如果您的数据集只是lat/lng的列表,则可以使用this answer根据Haversine formula计算每个点之间的差距(地球上的最短距离&#39;表面)。