2017-08-28 96 views
-2

我渲染谷歌地圖的數據,看起來像這樣一個折線:獲取從緯度/經度點沿折線距離

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

當鼠標懸停在折線,我可以得到lat/lng座標我想根據這些座標獲得沿線的距離。

我還沒有找到一個簡單的方法來做到這一點與地圖API。我想要沿着折線從開始到任意點的距離;我發現的大多數答案只是兩點之間的距離(最短),而不是沿着預定義的路線。

我的另一個想法是使用D3(我用它來繪製一些相關的圖表)來平分數據並獲得距離。然而,我不知道如何基於兩個數據點(lat + lng)平分。

有關如何完成我想要做的任何建議?

編輯:在我的數據中,distance是在給定座標處行進的累積距離。

+0

的[計算在給定時間地理位置(可能的複製https://stackoverflow.com/questions/ 25562799 /按給定時間計算地理位置) – geocodezip

+0

我對Google Maps API不熟悉,但如何確定此距離?它有一個方向(下一點)嗎?如果多段線上的懸停位置位於兩點的中間,並且您不知道沿路徑分佈的地形如何,則必須將最後一點與光標之間的距離和近似值加起來。 – LEI

+0

如果你看看我對鏈接問題的回答,它會使用第三方庫函數'GetPointAtDistance'來做到這一點。 – geocodezip

回答

0

我猜我希望Google地圖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; 
    } 
    

將其組合在一起以找到從折線開始到懸停的點的累積距離:

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); 
}); 
+0

我不認爲這會讓你從*開始到沿着折線*的任意點。它會讓你從一開始到多線上已有的點之一,對吧?如果你的光標在兩點之間的一半,你會失去這個距離,不是嗎? –

+0

這是真的,但對我的目的而言(+/- 30英尺)就足夠了。如有必要,我可以增加折線密度以提高精度。 – ericgio

0

如果您的數據集只是一個lat/lng列表,你可以使用this answer根據Haversine formula(在地球表面的最短距離)來計算每個點之間的差距。

+0

雖然我不希望兩點之間的距離最短。我想要在兩點之間沿着多段線*的距離*,即:從起點到多段線上任意一點的距離的累積距離。這通常不是最短的距離。 – ericgio

+0

是不是[polyline](https://developers.google.com/maps/documentation/javascript/examples/polyline-simple)只是一個段的列表?然後你的光標應該在一行,你會做*每個點之間的長度的總和,直到被徘徊*,但也許我誤解了一些東西?請回答編輯您的問題更多的細節,演示鏈接將是很好的。 – LEI

+0

實際上,儘管使用了Maps的'computeDistanceBetween'方法,這或多或少是我最終做的。 – ericgio

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 

這與Google的810英里路線非常接近,並非都是直線。

+0

你分解它的方式是有道理的,但希望不要添加另一個第三方庫。我發佈了一個關於我如何使用Maps API和普通JS實現的答案。 – ericgio

相關問題