GoogleMaps Polyline Length in V3

后端 未结 7 1200
半阙折子戏
半阙折子戏 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: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
    }
    
    
    
    

提交回复
热议问题