V3中的Google地图折线长度

时间:2010-11-14 22:56:34

标签: google-maps

在V3中,Google地图中的Polyline似乎没有长度功能。

是否有人找到了此功能差距的解决方法?

7 个答案:

答案 0 :(得分:16)

<script type="text/javascript"
src="http://maps.google.com/maps/api/js?libraries=geometry&sensor=true"></script>
... var path = poly.getPath(); // or:
var path = polygon.getPath(); 
... = google.maps.geometry.spherical.computeLength(path.getArray())
... = google.maps.geometry.spherical.computeArea(path.getArray())

- &GT;折线的距离,多边形的面积

并在两点之间: computeDistanceBetween()

不要忘记指定几何库(libraries = geometry)

http://code.google.com/apis/maps/documentation/javascript/geometry.html

答案 1 :(得分:5)

这是所需功能的原型 - 希望这有助于进一步:

google.maps.Polygon.prototype.Distance = function() {
   var dist = 0;
   for (var i=1; i < this.getPath().getLength(); i++) {
      dist += this.getPath().getAt(i).distanceFrom(this.getPath().getAt(i-1));
   }
   return dist;
}

google.maps.LatLng.prototype.distanceFrom = function(newLatLng) {
    //var R = 6371; // km (change this constant to get miles)
    var R = 6378100; // meters
    var lat1 = this.lat();
    var lon1 = this.lng();
    var lat2 = newLatLng.lat();
    var lon2 = newLatLng.lng();
    var dLat = (lat2-lat1) * Math.PI / 180;
    var dLon = (lon2-lon1) * Math.PI / 180;
    var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
      Math.cos(lat1 * Math.PI / 180 ) * Math.cos(lat2 * Math.PI / 180 ) *
      Math.sin(dLon/2) * Math.sin(dLon/2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    var d = R * c;
    return d;
}

source

答案 2 :(得分:4)

必须逐段完成。

有关建议的解决方案,请参阅this Google Maps JavaScript API v3 groups帖子。

答案 3 :(得分:2)

我去寻找相同的信息,发现你正在寻找的api调用是在geometry.spherical命名空间中。

以下是我使用的代码:

//Path is the mvc array of lat/lng that makes up the polyline
var path = $scope.courseLine.getPath();

$scope.totalDistance = google.maps.geometry.spherical.computeLength(path);
$scope.totalMiles = ($scope.totalDistance * 0.00062137).toFixed(2) + " mi";
                });

答案 4 :(得分:2)

现在Google Maps Javascript API v3 geometry library中有一种方法可以计算两个google.maps.LatLng个对象之间的距离,以米为单位google.maps.geometry.spherical.computeDistanceBetween

the Google Maps Javascript API v3 geometry library中用于计算折线google.maps.geometry.poly.computeLength长度的方法。

来自Google Maps JavaScript API v3 groups post中引用的Hamish's answer的概念,但使用Google Maps Javascript API v3 geometry library method computeDistanceBetween

google.maps.Polyline.prototype.inKm = function(n) {
  var a = this.getPath(n),
    len = a.getLength(),
    dist = 0;
  for (var i = 0; i < len - 1; i++) {
    dist += google.maps.geometry.spherical.computeDistanceBetween(a.getAt(i), a.getAt(i + 1));
  }
  return dist / 1000;
}

结果是折线的长度(以千米为单位)。可选的 parameter是多路径折线的路径索引。

proof of concept fiddle

使用computeLength:

google.maps.geometry.spherical.computeLength(poly.getPath())/1000

proof of concept fiddle

代码段

var map;
var poly;
var gmarkers = [];

function initialize() {
  map = new google.maps.Map(
    document.getElementById("map_canvas"), {
      center: new google.maps.LatLng(37.4419, -122.1419),
      zoom: 11,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });
  google.maps.event.addListener(map, 'click', addLatLng);
  var polyCoord = [
    new google.maps.LatLng(41.86, 8.73),
    new google.maps.LatLng(41.88, 8.75)
  ];
  var bounds = new google.maps.LatLngBounds();
  bounds.extend(polyCoord[0]);
  bounds.extend(polyCoord[1]);
  map.fitBounds(bounds);
  google.maps.event.addListenerOnce(map, 'bounds_changed', function() {
    map.setZoom(map.getZoom() - 2);
  });
  // Polyline
  poly = new google.maps.Polyline({
    path: polyCoord
  });
  poly.binder = new MVCArrayBinder(poly.getPath());
  var marker0 = new google.maps.Marker({
    position: event.latLng,
    title: '#0',
    map: map,
    icon: {
      path: 'M256,320c-70.688,0-128-57.312-128-128c0-70.687,57.313-128,128-128c70.688,0,128,57.313,128,128C384,262.688,326.688,320,256,320z',
      fillColor: 'white',
      fillOpacity: 1,
      scale: 0.025,
      strokeColor: 'black',
      strokeWeight: 1,
      strokeOpacity: 1,
      anchor: new google.maps.Point(200, 200)
    },
    draggable: true
  });
  marker0.bindTo('position', poly.binder, (0).toString());
  google.maps.event.addListener(marker0, 'dragend', updateLength);
  gmarkers.push(marker0);
  var marker1 = new google.maps.Marker({
    position: event.latLng,
    title: '#1',
    map: map,
    icon: {
      path: 'M256,320c-70.688,0-128-57.312-128-128c0-70.687,57.313-128,128-128c70.688,0,128,57.313,128,128C384,262.688,326.688,320,256,320z',
      fillColor: 'white',
      fillOpacity: 1,
      scale: 0.025,
      strokeColor: 'black',
      strokeWeight: 1,
      strokeOpacity: 1,
      anchor: new google.maps.Point(200, 200)
    },
    draggable: true
  });
  marker1.bindTo('position', poly.binder, (1).toString());
  google.maps.event.addListener(marker1, 'dragend', updateLength);
  gmarkers.push(marker1);
  poly.setMap(map);
  updateLength();
}

function updateLength() {
  document.getElementById('length').value = (google.maps.geometry.spherical.computeLength(poly.getPath()) / 1000).toFixed(2);
};
google.maps.event.addDomListener(window, "load", initialize);

/**
 * Handles click events on a map, and adds a new point to the Polyline.
 * @param {MouseEvent} mouseEvent
 */
function addLatLng(event) {
  var path = poly.getPath();
  path.push(event.latLng);
  var len = path.getLength();
  var marker = new google.maps.Marker({
    position: event.latLng,
    title: '#' + len,
    map: map,
    icon: {
      path: 'M256,320c-70.688,0-128-57.312-128-128c0-70.687,57.313-128,128-128c70.688,0,128,57.313,128,128C384,262.688,326.688,320,256,320z',
      fillColor: 'white',
      fillOpacity: 1,
      scale: 0.025,
      strokeColor: 'black',
      strokeWeight: 1,
      strokeOpacity: 1,
      anchor: new google.maps.Point(200, 200)
    },
    draggable: true
  });
  gmarkers.push(marker);
  marker.bindTo('position', poly.binder, (len - 1).toString());
  google.maps.event.addListener(marker, 'dragend', updateLength);
  document.getElementById('length').value = poly.inKm().toFixed(2);
}

/*
 * Use bindTo to allow dynamic drag of markers to refresh poly.
 */

function MVCArrayBinder(mvcArray) {
  this.array_ = mvcArray;
}
MVCArrayBinder.prototype = new google.maps.MVCObject();
MVCArrayBinder.prototype.get = function(key) {
  if (!isNaN(parseInt(key))) {
    return this.array_.getAt(parseInt(key));
  } else {
    this.array_.get(key);
  }
}
MVCArrayBinder.prototype.set = function(key, val) {
  if (!isNaN(parseInt(key))) {
    this.array_.setAt(parseInt(key), val);
  } else {
    this.array_.set(key, val);
  }
}
html,
body,
#map_canvas {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
<label>polyline length (km):</label>
<input id="length" type="text" />
<div id="map_canvas" style="border: 2px solid #3872ac;"></div>

答案 5 :(得分:0)

使用haversine formula

获取它连接的2个LatLng之间的距离

答案 6 :(得分:0)

如果您从DirectionsService获得折线,请检查DirectionsLeg中的距离和持续时间。

https://developers.google.com/maps/documentation/javascript/reference#DirectionsLeg

相关问题