GoogleMaps Polyline Length in V3

后端 未结 7 1185
半阙折子戏
半阙折子戏 2020-12-10 23:30

There doesn\'t seem to be a length funciton for the Polyline in Google Maps anymore in V3.

Has anyone found a workaround for this functionality gap?

相关标签:
7条回答
  • 2020-12-10 23:47

    I went looking for the same information and found that the api call you're looking for is in the geometry.spherical namespace.

    Here's the code I'm using:

    //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";
                    });
    
    0 讨论(0)
  • 2020-12-10 23:50

    There is now a method in the Google Maps Javascript API v3 geometry library to compute the distance between two google.maps.LatLng objects in meters google.maps.geometry.spherical.computeDistanceBetween.

    And a method in the Google Maps Javascript API v3 geometry library to compute the length of a polyline google.maps.geometry.poly.computeLength.

    Concept from the Google Maps JavaScript API v3 groups post referenced in Hamish's answer, but using the 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;
    }
    

    The result is the length of the polyline in kilometers. The optional parameter is the path index of multi path polylines.

    proof of concept fiddle

    Using computeLength:

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

    proof of concept fiddle

    code snippet:

    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&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
    <label>polyline length (km):</label>
    <input id="length" type="text" />
    <div id="map_canvas" style="border: 2px solid #3872ac;"></div>

    0 讨论(0)
  • 2020-12-10 23:51

    It has to be done segment by segment.

    See this Google Maps JavaScript API v3 groups post for a suggested solution.

    0 讨论(0)
  • 2020-12-10 23:51

    Get the distance between the 2 LatLngs it connects using the haversine formula

    0 讨论(0)
  • 2020-12-10 23:59

    If you got the polyline from DirectionsService, check distance and duration in DirectionsLeg.

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

    0 讨论(0)
  • 2020-12-11 00:01
    <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())
    

    --> distance for polyline, area for polygon

    and between two points: computeDistanceBetween()

    Don't forget to specify the geometry library (libraries=geometry)

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

    0 讨论(0)
提交回复
热议问题