通过谷歌地图上的纬度和经度数组获得距离

时间:2016-07-04 11:05:51

标签: javascript jquery google-maps google-maps-api-3

var path = [
    { "lat": 43.00678, "lng": -89.53743 },
    { "lat": 43.00656, "lng": -89.53732 },
    { "lat": 43.005878, "lng": -89.53797 },
    { "lat": 43.005344, "lng": -89.53684 },
    { "lat": 43.003834, "lng": -89.535400 },
    { "lat": 43.003692, "lng": -89.533834 },
    { "lat": 43.006384, "lng": -89.533796 },
    { "lat": 43.0120328, "lng": -89.533667 },
    { "lat": 43.015931, "lng": -89.533635 },
    { "lat": 43.023030, "lng": -89.5335390 },
    { "lat": 43.032010, "lng": -89.533249 },
    { "lat": 43.040221, "lng": -89.5329596 },
    { "lat": 43.04632176, "lng": -89.5318224 },
    { "lat": 43.052562, "lng": -89.5277883 },
    { "lat": 43.060300, "lng": -89.52759526 },
    { "lat": 43.06401556, "lng": -89.5268978 },
    { "lat": 43.06681381, "lng": -89.5241620 },
    { "lat": 43.0714224, "lng": -89.52499888 },
    { "lat": 43.07468269, "lng": -89.52698371 },
    { "lat": 43.07490213, "lng": -89.53292749 },
    { "lat": 43.076203059, "lng": -89.53269145 },
    { "lat": 43.0765949, "lng": -89.5314576 },
    { "lat": 43.0793377, "lng": -89.53323862 },
    { "lat": 43.0803799, "lng": -89.53454754 },
    { "lat": 43.0835927, "lng": -89.5340754 },
    { "lat": 43.08458789, "lng": -89.5334853 },
    { "lat": 43.0844468, "lng": -89.53403256 },
    { "lat": 43.08445469, "lng": -89.5352985 },
    { "lat": 43.084619242, "lng": -89.5358993791 }
];

这是Javascript数组,我想在谷歌地图上绘制一条折线进行车辆跟踪,找到车辆行程的总距离

1 个答案:

答案 0 :(得分:3)

计算路径总距离的最简单方法是循环路径数组并计算每个点之间的距离 Haversine formula: https://stackoverflow.com/questions/27928/calculate-distance-between-two-latitude-longitude-points-haversine-formulagoogle.maps.geometry.spherical.computeDistanceBetween(latLngA, latLngB);方法并总结结果。 (后一种情况,您必须加载几何库:https://maps.googleapis.com/maps/api/js?libraries=geometry) e.g:

function calcPathLength(path){
    var total = 0;
    for (var i = 0; i < path.length - 1; i++) {
        var pos1 = new google.maps.LatLng(path[i].lat(), path[i].lng());
        var pos2 = new google.maps.LatLng(path[i + 1].lat(), path[i + 1].lng());
        total += google.maps.geometry.spherical.computeDistanceBetween(pos1, pos2);
    };
    return total;
};

这只给出了一个近似的结果,因为两点之间的距离有时太大而且路径不能精确地跟随道路。

解决这个问题的另一种方法是使用Google Maps Roads API snap to roads feature. (https://developers.google.com/maps/documentation/roads/snap)在这种情况下,我们仍然存在点之间距离的问题,因为文档说连续的点对应该在彼此300米之内。我认为我们能做的最好的事情就是在路径上增加更多的积分。 在下面的示例中,我将向您展示如何显示和计算路径的总距离。为了您的目的,我修改了谷歌的Snap to Road演示。请注意,道路API需要API密钥,因此您应该使用密钥替换YOUR_API_KEY。

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <title>Roads API Demo</title>
    <style>
      html, body, #map {
        height: 100%;
        margin: 0px;
        padding: 0px
      }
    </style>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script
      src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
    <script>
var apiKey = 'YOUR_API_KEY'; //Replace it with your key
            //This is the path you provided
var path = [
    { "lat": 43.00678, "lng": -89.53743 },
    { "lat": 43.00656, "lng": -89.53732 },
    { "lat": 43.005878, "lng": -89.53797 },
    { "lat": 43.005344, "lng": -89.53684 },
    { "lat": 43.003834, "lng": -89.535400 },
    { "lat": 43.003692, "lng": -89.533834 },
    { "lat": 43.006384, "lng": -89.533796 },
    { "lat": 43.0120328, "lng": -89.533667 },
    { "lat": 43.015931, "lng": -89.533635 },
    { "lat": 43.023030, "lng": -89.5335390 },
    { "lat": 43.032010, "lng": -89.533249 },
    { "lat": 43.040221, "lng": -89.5329596 },
    { "lat": 43.04632176, "lng": -89.5318224 },
    { "lat": 43.052562, "lng": -89.5277883 },
    { "lat": 43.060300, "lng": -89.52759526 },
    { "lat": 43.06401556, "lng": -89.5268978 },
    { "lat": 43.06681381, "lng": -89.5241620 },
    { "lat": 43.0714224, "lng": -89.52499888 },
    { "lat": 43.07468269, "lng": -89.52698371 },
    { "lat": 43.07490213, "lng": -89.53292749 },
    { "lat": 43.076203059, "lng": -89.53269145 },
    { "lat": 43.0765949, "lng": -89.5314576 },
    { "lat": 43.0793377, "lng": -89.53323862 },
    { "lat": 43.0803799, "lng": -89.53454754 },
    { "lat": 43.0835927, "lng": -89.5340754 },
    { "lat": 43.08458789, "lng": -89.5334853 },
    { "lat": 43.0844468, "lng": -89.53403256 },
    { "lat": 43.08445469, "lng": -89.5352985 },
    { "lat": 43.084619242, "lng": -89.5358993791 }
  ]; 
var map;
var snappedCoordinates = [];
var extendedPath = [];
var startMarker;
var endMarker;
var startIcon = 'https://mts.googleapis.com/maps/vt/icon/name=icons/spotlight/spotlight-waypoint-a.png&text=A&psize=16&font=fonts/Roboto-Regular.ttf&color=ff333333&ax=44&ay=48&scale=1';
var endIcon = 'https://mts.googleapis.com/maps/vt/icon/name=icons/spotlight/spotlight-waypoint-b.png&text=B&psize=16&font=fonts/Roboto-Regular.ttf&color=ff333333&ax=44&ay=48&scale=1';
var infowindow;
function initialize() {
  var mapOptions = {
    zoom: 12,
    center: {lat: 43.040221, lng: -89.5329596}
  };
  map = new google.maps.Map(document.getElementById('map'), mapOptions);
  startMarker = new google.maps.Marker({
    map: map,
    position: new google.maps.LatLng(path[0].lat, path[0].lng),
    icon: startIcon
  });
  endMarker = new google.maps.Marker({
    map: map,
    position: new google.maps.LatLng(path[path.length - 1].lat, path[path.length - 1].lng),
    icon: endIcon
  })
  infowindow = new google.maps.InfoWindow({content: ''});
  extendedPath = getExtendedPath(path); //Let's extend the original path
  runSnapToRoad(extendedPath);
}
function getExtendedPath(path) {
  var extPath = path;
  var newPath = [];
  while (pointsTooFar(extPath)){  //We do it while all the distance between points are less then 250 meters
      newPath = [];
      for (var i = 0; i < extPath.length - 1; i++) {
        var pos1 = new google.maps.LatLng(extPath[i].lat, extPath[i].lng);
        var pos2 = new google.maps.LatLng(extPath[i + 1].lat, extPath[i + 1].lng);
        var dist = google.maps.geometry.spherical.computeDistanceBetween(pos1, pos2);
        newPath.push(extPath[i]);
        if (dist > 250) {  //If the distance between two points is greater than 250 metres we add an intermediate point 
           var insPos = { "lat": (extPath[i].lat + extPath[i + 1].lat)/2, "lng": (extPath[i].lng + extPath[i + 1].lng)/2 };
            newPath.push(insPos);
        }
      }
      newPath.push(extPath[extPath.length-1]);
      extPath = newPath;
  }
  return extPath;
}

function pointsTooFar(pointPath){
  var tooFar = false;
  for (var i = 0; i < pointPath.length - 1; i++) {
    var pos1 = new google.maps.LatLng(pointPath[i].lat, pointPath[i].lng);
    var pos2 = new google.maps.LatLng(pointPath[i + 1].lat, pointPath[i + 1].lng);
    var dist = google.maps.geometry.spherical.computeDistanceBetween(pos1, pos2);
    if (dist > 250){
        tooFar = true;
        break;
    };
  }; 
  return tooFar;
}

// Snap a user-created polyline to roads and draw the snapped path
function runSnapToRoad(path) {
  var pathValues = [];
  for (var i = 0; i < path.length; i++) {
    pathValues.push((new google.maps.LatLng(path[i].lat, path[i].lng)).toUrlValue());
  }
  $.get('https://roads.googleapis.com/v1/snapToRoads', {
    interpolate: true,
    key: apiKey,
    path: pathValues.join('|')
  }, function(data) {
    processSnapToRoadResponse(data);
    drawSnappedPolyline();
    calcPathLength(snappedCoordinates);
  });
}

// Store snapped polyline returned by the snap-to-road service.
function processSnapToRoadResponse(data) {
  snappedCoordinates = [];
  for (var i = 0; i < data.snappedPoints.length; i++) {
    var latlng = new google.maps.LatLng(
        data.snappedPoints[i].location.latitude,
        data.snappedPoints[i].location.longitude);
    snappedCoordinates.push(latlng);
  }
}

// Draws the snapped polyline (after processing snap-to-road response).
function drawSnappedPolyline() {
  var snappedPolyline = new google.maps.Polyline({
    path: snappedCoordinates,
    strokeColor: '#00B3FD',
    strokeOpacity: 0.6,
    strokeWeight: 5
  });
  snappedPolyline.setMap(map);
}

function calcPathLength(cPath){
    var total = 0;
    for (var i = 0; i < cPath.length - 1; i++) {
        var pos1 = new google.maps.LatLng(cPath[i].lat(), cPath[i].lng());
        var pos2 = new google.maps.LatLng(cPath[i + 1].lat(), cPath[i + 1].lng());
        total += google.maps.geometry.spherical.computeDistanceBetween(pos1, pos2);
        console.log(google.maps.geometry.spherical.computeDistanceBetween(pos1, pos2).toFixed(0));
    };
    infowindow.setContent('<h4>Total length of the path: ' + (total / 1609.34).toFixed(1) + ' miles</h4>');
    infowindow.open(map, endMarker);
};

$(window).load(initialize);

    </script>
  </head>
  <body>
    <div id="map"></div>
  </body>
</html>

希望这有帮助。