谷歌方向路线 - 中点标记

时间:2018-06-13 18:59:07

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

如何在渲染路线的中间添加可点击标记,然后显示包含自定义数据的信息窗口,因为信息窗口无法直接添加到路线渲染器?

 function loadRoute0() {
  var request0 = {
    origin: new google.maps.LatLng(46.56300788, 15.62779705),
    destination: new google.maps.LatLng(46.55953332, 15.62616729),
    travelMode: google.maps.TravelMode.WALKING
  };

  directionsService.route(request0, function(result, status) {
    if (status == google.maps.DirectionsStatus.OK) {
      var renderer = new google.maps.DirectionsRenderer({
        polylineOptions: {
          strokeColor: "#00FF00"
        },
        suppressMarkers: true,
        map: map
      });
      renderer.setDirections(result);
    }
  });
 }

我读到我们可以使用step,但我不确定如何实现它。

 marker.setPosition(myRoute.steps[i].start_location);

1 个答案:

答案 0 :(得分:1)

计算路线的中点:

  1. 捕获从路线服务返回的整个路线
  2. polyline.setPath([]);
    var route = result.routes[0];
    
    var path = result.routes[0].overview_path;
    var legs = result.routes[0].legs;
    for (i = 0; i < legs.length; i++) {
      var steps = legs[i].steps;
      for (j = 0; j < steps.length; j++) {
        var nextSegment = steps[j].path;
        for (k = 0; k < nextSegment.length; k++) {
          polyline.getPath().push(nextSegment[k]);
        }
      }
    }
    
    1. 计算其长度
    2. function computeTotalDistance(result) {
        totalDist = 0;
        totalTime = 0;
        var myroute = result.routes[0];
        for (i = 0; i < myroute.legs.length; i++) {
          totalDist += myroute.legs[i].distance.value;
          totalTime += myroute.legs[i].duration.value;
        }
        putMarkerOnRoute(50);
      
        totalDist = totalDist / 1000.
        document.getElementById("total").innerHTML = "total distance is: " + totalDist + " km<br>total time is: " + (totalTime / 60).toFixed(2) + " minutes";
      }
      
      1. 找到该长度的50%(这样做的一个选择是使用epoly库中的GetPointAtDistance函数,移植到v3 API。
      2. function putMarkerOnRoute(percentage) {
          var distance = (percentage / 100) * totalDist;
          var time = ((percentage / 100) * totalTime / 60).toFixed(2);
          if (!marker) {
            marker = createMarker(polyline.GetPointAtDistance(distance), "time: " + time, "marker");
          } else {
            marker.setPosition(polyline.GetPointAtDistance(distance));
            marker.setTitle("time:" + time);
          }
        }
        

        proof of concept fiddle

        screenshot of resulting map

        代码段

        function loadRoute0() {
          var request0 = {
            origin: new google.maps.LatLng(46.56300788, 15.62779705),
            destination: new google.maps.LatLng(46.55953332, 15.62616729),
            travelMode: google.maps.TravelMode.WALKING
          };
        
          directionsService.route(request0, function(result, status) {
            if (status == google.maps.DirectionsStatus.OK) {
              var renderer = new google.maps.DirectionsRenderer({
                polylineOptions: {
                  strokeColor: "#00FF00"
                },
                suppressMarkers: true,
                map: map
              });
              renderer.setDirections(result);
              polyline.setPath([]);
              var route = result.routes[0];
        
              var path = result.routes[0].overview_path;
              var legs = result.routes[0].legs;
              for (i = 0; i < legs.length; i++) {
                var steps = legs[i].steps;
                for (j = 0; j < steps.length; j++) {
                  var nextSegment = steps[j].path;
                  for (k = 0; k < nextSegment.length; k++) {
                    polyline.getPath().push(nextSegment[k]);
                  }
                }
              }
              computeTotalDistance(result);
            }
          });
        }
        var directionsService, map, marker, polyline, infowindow;
        
        function initialize() {
          map = new google.maps.Map(
            document.getElementById("map_canvas"), {
              center: new google.maps.LatLng(37.4419, -122.1419),
              zoom: 13,
              mapTypeId: google.maps.MapTypeId.ROADMAP
            });
          polyline = new google.maps.Polyline({
            path: [],
            strokeColor: '#FF0000',
            strokeWeight: 3
          });
          infowindow = new google.maps.InfoWindow();
          directionsService = new google.maps.DirectionsService();
          loadRoute0();
        }
        google.maps.event.addDomListener(window, "load", initialize);
        var totalDist = 0;
        var totalTime = 0;
        
        function computeTotalDistance(result) {
          totalDist = 0;
          totalTime = 0;
          var myroute = result.routes[0];
          for (i = 0; i < myroute.legs.length; i++) {
            totalDist += myroute.legs[i].distance.value;
            totalTime += myroute.legs[i].duration.value;
          }
          putMarkerOnRoute(50);
        
          totalDist = totalDist / 1000.
          document.getElementById("total").innerHTML = "total distance is: " + totalDist + " km<br>total time is: " + (totalTime / 60).toFixed(2) + " minutes";
        }
        
        function putMarkerOnRoute(percentage) {
          var distance = (percentage / 100) * totalDist;
          var time = ((percentage / 100) * totalTime / 60).toFixed(2);
          if (!marker) {
            marker = createMarker(polyline.GetPointAtDistance(distance), "time: " + time, "midpoint");
          } else {
            marker.setPosition(polyline.GetPointAtDistance(distance));
            marker.setTitle("time:" + time);
          }
          google.maps.event.trigger(marker, 'click');
        }
        
        function createMarker(latlng, label, html) {
          var contentString = '<b>' + label + '</b><br>' + html;
          var marker = new google.maps.Marker({
            position: latlng,
            map: map,
            title: label,
            zIndex: Math.round(latlng.lat() * -100000) << 5
          });
          marker.myname = label;
        
          google.maps.event.addListener(marker, 'click', function() {
            infowindow.setContent(contentString + "<br>" + marker.getPosition().toUrlValue(6));
            infowindow.open(map, marker);
          });
          return marker;
        }
        // modified from epoly http://econym.org.uk/gmap/epoly.htm
        // (ported to v3)
        // === A method which returns a GLatLng of a point a given distance along the path ===
        // === Returns null if the path is shorter than the specified distance ===
        google.maps.Polyline.prototype.GetPointAtDistance = function(metres) {
          // some awkward special cases
          if (metres == 0) return this.getPath().getAt(0);
          if (metres < 0) return null;
          if (this.getPath().getLength() < 2) return null;
          var dist = 0;
          var olddist = 0;
          for (var i = 1;
            (i < this.getPath().getLength() && dist < metres); i++) {
            olddist = dist;
            dist += google.maps.geometry.spherical.computeDistanceBetween(this.getPath().getAt(i), this.getPath().getAt(i - 1));
          }
          if (dist < metres) {
            return null;
          }
          var p1 = this.getPath().getAt(i - 2);
          var p2 = this.getPath().getAt(i - 1);
          var m = (metres - olddist) / (dist - olddist);
          return new google.maps.LatLng(p1.lat() + (p2.lat() - p1.lat()) * m, p1.lng() + (p2.lng() - p1.lng()) * m);
        }
        html,
        body {
          height: 100%;
          width: 100%;
          margin: 0px;
          padding: 0px;
        }
        
        #map_canvas {
          height: 90%;
          width: 100%;
        }
        <script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
        <div id="total"></div>
        <div id="map_canvas"></div>