Search code examples
javascripthtmlgoogle-mapsgoogle-maps-api-3kml

How to draw a route between two markers in Google Maps API?


I have a requirement where, onclick, I have to draw a route in between two markers when I select. I have successfully uploaded a KML file on Google MAPS API, so the markers are clearly visible on Google MAPS API.

When I select a two markers onclick, there should be a route drawn between the selected markers. I was able to draw a static route between the two points but the line which was getting drawn was not following the route. Please guide. Also please find the code which I have tried. Thanks in advance.

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Transit layer</title>
<style>
html,body,#map-canvas {
    height: 100%;
    margin: 0px;
    padding: 0px
}
</style>
<link href="/maps/documentation/javascript/examples/default.css" rel="stylesheet"      type="text/css" />
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript"   src="http://geoxml3.googlecode.com/svn/branches/polys/geoxml3.js"></script>
<script> function initialize() 
{   
    var myLatlng = new google.maps.LatLng(0, -180);   
    var mapOptions = 
        {     
            zoom: 13,     
            center: myLatlng,     
            mapTypeId: google.maps.MapTypeId.ROADMAP  
        }    

     var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);    
     var transitLayer = new google.maps.TransitLayer();   
     transitLayer.setMap(map); 


    var geoXml = new geoXML3.parser({map: map, singleInfoWindow: true});
     geoXml.parse('kmload.kml'); 
     var geoXml1 = new geoXML3.parser({map: map, singleInfoWindow: true});
     geoXml1.parse('lines.kml'); 


     var coordinates = [     
                           new google.maps.LatLng(18.9800, 73.1000),     
                           new google.maps.LatLng(19.0361, 73.0617)];  

     google.maps.event.addListener(map, "click", function (e) 
      {  
                 var trainpath = new google.maps.Polyline({     
                 path: coordinates,    
                 geodesic: true,     
                 strokeColor: '#FF0000',     
                 strokeOpacity: 1.0,     
                 strokeWeight: 2   
                 });    
                trainpath.setMap(map);
      });



     }  
google.maps.event.addDomListener(window, 'load', initialize); 
    </script>
</head>
<body>
<div id="map-canvas"></div>
</body>
</html>

Solution

  • example

    add a custom "createMarker" function to geoxml3 which adds a function to the marker's click listener to trigger the directions service.

    // global variables
    var directions = {};
    var directionsDisplay = new google.maps.DirectionsRenderer();
    var directionsService = new google.maps.DirectionsService();
    
    // geoxml3 configuration
    var geoXml = new geoXML3.parser({
        map: map,
        createMarker: createMarker,
        singleInfoWindow: true
    });
    
    // handle the directions service
    function processMarkerClick(latLng) {
        if (!directions.start) {
            directions.start = latLng;
        }
        else if (!directions.end) {
            directions.end = latLng;
            directionsService.route({
                origin:directions.start,
                destination: directions.end,
                travelMode: google.maps.TravelMode.DRIVING
            },
            function(result, status) {
                if (status == google.maps.DirectionsStatus.OK) {
                    directionsDisplay.setDirections(result);
                    directionsDisplay.setMap(map);
    
                }
                else {
                    alert("Directions Request failed:" +status);
                }
                directions.start = null;
                directions.end = null;
            });
        }
    }
    
    // custom createMarker function to add hook for the directions service 
    // (modified from the version in the geoxml3 source)
    var createMarker = function (placemark, doc) {
        // create a Marker to the map from a placemark KML object
    
        // Load basic marker properties
        var markerOptions = geoXML3.combineOptions(geoXml.options.markerOptions, {
            map:      geoXml.options.map,
            position: new google.maps.LatLng(placemark.Point.coordinates[0].lat, placemark.Point.coordinates[0].lng),
            title:    placemark.name,
            zIndex:   Math.round(placemark.Point.coordinates[0].lat * -100000)<<5,
            icon:     placemark.style.icon,
            shadow:   placemark.style.shadow 
        });
    
        // Create the marker on the map
        var marker = new google.maps.Marker(markerOptions);
        if (!!doc) {
            doc.markers.push(marker);
        }
    
        // Set up and create the infowindow if it is not suppressed
        if (!geoXml.options.suppressInfoWindows) {
            var infoWindowOptions = geoXML3.combineOptions(geoXml.options.infoWindowOptions, {
                content: '<div class="geoxml3_infowindow"><h3>' +
                         placemark.name + 
                         '</h3><div>' + 
                         placemark.description + 
                         '</div></div>',
                pixelOffset: new google.maps.Size(0, 2)
            });
    
            if (geoXml.options.infoWindow) {
                marker.infoWindow = geoXml.options.infoWindow;
            }
            else {
                marker.infoWindow = new google.maps.InfoWindow(infoWindowOptions);
            }
            marker.infoWindowOptions = infoWindowOptions;
    
            // Infowindow-opening event handler
            google.maps.event.addListener(marker, 'click', function() {
                processMarkerClick(marker.getPosition());
                this.infoWindow.close();
                marker.infoWindow.setOptions(this.infoWindowOptions);
                this.infoWindow.open(this.map, this);
            });
        }
        placemark.marker = marker;
        return marker;
    };