Add Markers Along a Route

2019-01-26 01:49发布

问题:

I am trying to create several markers along a route from google maps directions. I have already looked into waypoints as an option but based on my understanding of the documentation on it, it creates the route from point A to point B and passes through the waypoints that you set in order to get from point A to point B. I don't want my route to be calculated based on predetermined waypoints. I want a predetermined start and end point, with my waypoints calculated based on a distance on the map. For instance, a marker created every so many miles along the route. Would waypoints do this? If so, any examples of where that has been done?

Any suggestions?

回答1:

As Andrew told waypoints wouldn't do it.

You don't have predefined points for the route(like the eaxmple), so what you can do is:

A direction consists of points defined by route->overview_path, what defines the polyline for the route.

So you may walk this path, calculate the distance between two path-points using google.maps.geometry.spherical.computeDistanceBetween() and create the marker when the desired distance has been reached.

Here is an implementation of the suggestion: http://jsfiddle.net/doktormolle/eNzFb/


<edit>

Please Note: this answer is obsolete. You better use the built-in IconSequence instead.



回答2:

No. Waypoints determine the path of the route, as you found. You want to put "waypoints" along the route whichever path is determined.

It is possible, and Larry has an example at http://www.geocodezip.com/v3_polyline_example_kmmarkers.html



回答3:

Example that places markers every 1 mile along a route returned from the directions service:

http://www.geocodezip.com/v3_kmMarkersFromDirections.html

code snippet:

var directionDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
var polyline = null;
var gmarkers = [];
var infowindow = new google.maps.InfoWindow();

function initMap() {
  var directionsService = new google.maps.DirectionsService;
  var directionsDisplay = new google.maps.DirectionsRenderer;
  map = new google.maps.Map(document.getElementById('map'), {
    zoom: 7,
    center: {
      lat: 41.85,
      lng: -87.65
    }
  });
  polyline = new google.maps.Polyline({
    path: [],
    strokeColor: '#FF0000',
    strokeWeight: 3
  });


  directionsDisplay.setMap(map);
  calculateAndDisplayRoute(directionsService, directionsDisplay);
  var onChangeHandler = function() {
    calculateAndDisplayRoute(directionsService, directionsDisplay);
  };
  document.getElementById('btn').addEventListener('click', onChangeHandler);
}

function calculateAndDisplayRoute(directionsService, directionsDisplay) {
  directionsService.route({
    origin: document.getElementById('start').value,
    destination: document.getElementById('end').value,
    travelMode: 'DRIVING'
  }, function(response, status) {
    if (status == google.maps.DirectionsStatus.OK) {
      polyline.setPath([]);
      var bounds = new google.maps.LatLngBounds();
      startLocation = new Object();
      endLocation = new Object();
      directionsDisplay.setDirections(response);
      var route = response.routes[0];
      // For each route, display summary information.
      var path = response.routes[0].overview_path;
      var legs = response.routes[0].legs;
      for (i = 0; i < legs.length; i++) {
        if (i == 0) {
          startLocation.latlng = legs[i].start_location;
          startLocation.address = legs[i].start_address;
          // marker = google.maps.Marker({map:map,position: startLocation.latlng});
          marker = createMarker(legs[i].start_location, "start", legs[i].start_address, "green");
        }
        endLocation.latlng = legs[i].end_location;
        endLocation.address = legs[i].end_address;
        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]);
            bounds.extend(nextSegment[k]);
          }
        }
      }

      polyline.setMap(map);
      for (var i = 0; i < gmarkers.length; i++) {
        gmarkers[i].setMap(null);
      }
      gmarkers = [];
      var points = polyline.GetPointsAtDistance(1000);
      for (var i = 0; i < points.length; i++) {
        var marker = new google.maps.Marker({
          map: map,
          position: points[i],
          title: i + 1 + " mile"
        });
        marker.addListener('click', openInfoWindow);
      }

    } else {
      alert("directions response " + status);
    }
  });


  /*  function(response, status) {
      if (status === 'OK') {
        directionsDisplay.setDirections(response);
      } else {
        window.alert('Directions request failed due to ' + status);
      }
    }); */
}
google.maps.event.addDomListener(window, 'load', initMap);

function createMarker(latlng, label, html, color) {
  // alert("createMarker("+latlng+","+label+","+html+","+color+")");
  var contentString = '<b>' + label + '</b><br>' + html;
  var marker = new google.maps.Marker({
    position: latlng,
    // draggable: true, 
    map: map,
    icon: getMarkerImage(color),
    title: label,
    zIndex: Math.round(latlng.lat() * -100000) << 5
  });
  marker.myname = label;
  gmarkers.push(marker);

  google.maps.event.addListener(marker, 'click', function() {
    infowindow.setContent(contentString);
    infowindow.open(map, marker);
  });
  return marker;
}
var icons = new Array();
icons["red"] = {
  url: "http://maps.google.com/mapfiles/ms/micons/red.png"
};

function getMarkerImage(iconColor) {
  if ((typeof(iconColor) == "undefined") || (iconColor == null)) {
    iconColor = "red";
  }
  if (!icons[iconColor]) {
    icons[iconColor] = {
      url: "http://maps.google.com/mapfiles/ms/micons/" + iconColor + ".png"
    };
  }
  return icons[iconColor];

}

function openInfoWindow() {
  var contentString = this.getTitle() + "<br>" + this.getPosition().toUrlValue(6);
  infowindow.setContent(contentString);
  infowindow.open(map, this);
}

// === A method which returns an array of GLatLngs of points a given interval along the path ===
google.maps.Polyline.prototype.GetPointsAtDistance = function(metres) {
  var next = metres;
  var points = [];
  // some awkward special cases
  if (metres <= 0) return points;
  var dist = 0;
  var olddist = 0;
  for (var i = 1;
    (i < this.getPath().getLength()); i++) {
    olddist = dist;
    dist += google.maps.geometry.spherical.computeDistanceBetween(this.getPath().getAt(i), this.getPath().getAt(i - 1));
    while (dist > next) {
      var p1 = this.getPath().getAt(i - 1);
      var p2 = this.getPath().getAt(i);
      var m = (next - olddist) / (dist - olddist);
      points.push(new google.maps.LatLng(p1.lat() + (p2.lat() - p1.lat()) * m, p1.lng() + (p2.lng() - p1.lng()) * m));
      next += metres;
    }
  }
  return points;
}
/* Always set the map height explicitly to define the size of the div
 * element that contains the map. */

html,
body,
#map {
  height: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}

#floating-panel {
  position: absolute;
  top: 10px;
  left: 25%;
  z-index: 5;
  background-color: #fff;
  padding: 5px;
  border: 1px solid #999;
  text-align: center;
  font-family: 'Roboto', 'sans-serif';
  line-height: 30px;
  padding-left: 10px;
}
<div id="floating-panel">
  <b>Start: </b>
  <input id="start" value="New York, NY" />
  <b>End: </b>
  <input id="end" value="Newark, NJ" />
  <input id="btn" value="Get Directions" type="button" />
</div>
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js"></script>