How to add markers on Google Maps polylines based on distance along the line?

后端 未结 5 1674
小蘑菇
小蘑菇 2020-12-02 07:12

I am trying to create a Google Map where the user can plot the route he walked/ran/bicycled and see how long he ran. The GPolyline class with it’s getLeng

5条回答
  •  萌比男神i
    2020-12-02 08:10

    I have used Martin Zeitler method to work with Google Map V3 and its working fine.

     function init() {
           var mapOptions = {
                zoom: 15,
                center: new google.maps.LatLng(-6.208437004433984, 106.84543132781982),
                suppressInfoWindows: true,
                         };
    
            // Get all html elements for map
            var mapElement = document.getElementById('map1');
    
            // Create the Google Map using elements
            map = new google.maps.Map(mapElement, mapOptions);
    
            var nextMarkerAt = 0;     // Counter for the marker checkpoints.
            var nextPoint = null;     // The point where to place the next marker.
    
    
            while (true) {
    
                var routePoints = [ new google.maps.LatLng(47.656, -122.360),
                                    new google.maps.LatLng(47.656, -122.343),
                                    new google.maps.LatLng(47.690, -122.310),
                                    new google.maps.LatLng(47.690, -122.270)];
    
                    nextPoint = moveAlongPath(routePoints, nextMarkerAt);
    
                if (nextPoint) {
                  //Adding marker from localhost
                    MarkerIcon = "http://192.168.1.1/star.png";
                    var marker = new google.maps.Marker
                        ({position: nextPoint,
                            map: map,
                            icon: MarkerIcon
                        });
                    // Add +1000 meters for the next checkpoint.
                    nextMarkerAt +=1000;
    
                }
                else {
                    // moveAlongPath returned null, so there are no more check points.
                    break;
                }
            }
     }
    
    
       Number.prototype.toRad = function () {
            return this * Math.PI / 180;
        }
    
        Number.prototype.toDeg = function () {
            return this * 180 / Math.PI;
        }
    
        function moveAlongPath(point, distance, index) {
            index = index || 0;  // Set index to 0 by default.
    
            var routePoints = [];
    
            for (var i = 0; i < point.length; i++) {
                routePoints.push(point[i]);
            }
    
            if (index < routePoints.length) {
                // There is still at least one point further from this point.
    
                // Construct a GPolyline to use the getLength() method.
                var polyline = new google.maps.Polyline({
                    path: [routePoints[index], routePoints[index + 1]],
                    strokeColor: '#FF0000',
                    strokeOpacity: 0.8,
                    strokeWeight: 2,
                    fillColor: '#FF0000',
                    fillOpacity: 0.35
                });
    
                // Get the distance from this point to the next point in the polyline.
                var distanceToNextPoint = polyline.Distance();
    
                if (distance <= distanceToNextPoint) {
                    // distanceToNextPoint is within this point and the next.
                    // Return the destination point with moveTowards().
                    return moveTowards(routePoints, distance,index);
                }
                else {
                    // The destination is further from the next point. Subtract
                    // distanceToNextPoint from distance and continue recursively.
                    return moveAlongPath(routePoints,
                        distance - distanceToNextPoint,
                        index + 1);
                }
            }
            else {
                // There are no further points. The distance exceeds the length
                // of the full path. Return null.
                return null;
            }
        }
    
        function moveTowards(point, distance,index) {
    
            var lat1 = point[index].lat.toRad();
            var lon1 = point[index].lng.toRad();
            var lat2 = point[index+1].lat.toRad();
            var lon2 = point[index+1].lng.toRad();
            var dLon = (point[index + 1].lng - point[index].lng).toRad();
    
            // Find the bearing from this point to the next.
            var brng = Math.atan2(Math.sin(dLon) * Math.cos(lat2),
                Math.cos(lat1) * Math.sin(lat2) -
                Math.sin(lat1) * Math.cos(lat2) *
                Math.cos(dLon));
    
            var angDist = distance / 6371000;  // Earth's radius.
    
            // Calculate the destination point, given the source and bearing.
            lat2 = Math.asin(Math.sin(lat1) * Math.cos(angDist) +
                Math.cos(lat1) * Math.sin(angDist) *
                Math.cos(brng));
    
            lon2 = lon1 + Math.atan2(Math.sin(brng) * Math.sin(angDist) *
                Math.cos(lat1),
                Math.cos(angDist) - Math.sin(lat1) *
                Math.sin(lat2));
    
            if (isNaN(lat2) || isNaN(lon2)) return null;
    
    
    
            return new google.maps.LatLng(lat2.toDeg(), lon2.toDeg());
        }
    
        google.maps.Polyline.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;
        }
    

提交回复
热议问题