Search code examples
javascripthtmlgoogle-maps-api-3google-directions-api

main polyline is not being selected on created map


I'm trying to create a simple program where I can display all the available paths from one point to another using google maps and let the user select any one of the path generated.

I wrote a code for that whereas, the alternate polyline paths are being selected and deselected on clicking unselected path. but the main polyline path is displayed in different color and when tried to select it's not triggering the event listener somehow and not being selected.

I am attaching the complete code below without the google map API key, please help me solve this issue.

<!DOCTYPE html>
<html>
<head>
  <title>Show All Possible Routes</title>
  <style>
    #map {
      height: 400px;
      width: 100%;
    }
  </style>
</head>
<body>
  <div id="map"></div>
  <script>
    var map;
    var directionsService;
    var directionsDisplay;
    var polylines = [];
    var mainPolyline = null;

    function initMap() {
      var mapOptions = {
        center: { lat: 23.022594, lng: 72.570681 }, // Center point coordinates
        zoom: 12, // Zoom level
        mapTypeId: google.maps.MapTypeId.ROADMAP // Map type
      };

      map = new google.maps.Map(document.getElementById('map'), mapOptions);
      directionsService = new google.maps.DirectionsService();
      directionsDisplay = new google.maps.DirectionsRenderer({ map: map });

      var origin = new google.maps.LatLng(23.022594, 72.570681); // Origin coordinates
      var destination = new google.maps.LatLng(22.308836, 70.782300); // Destination coordinates

      var waypoints = [
        // Array of LatLng objects representing waypoints (if needed)
        // Example: new google.maps.LatLng(37.7895, -122.4348)
      ];

      var request = {
        origin: origin,
        destination: destination,
        travelMode: google.maps.TravelMode.DRIVING,
        waypoints: waypoints,
        provideRouteAlternatives: true // Request multiple route options
      };

      directionsService.route(request, function(result, status) {
        if (status === google.maps.DirectionsStatus.OK) {
          directionsDisplay.setDirections(result);
          var routes = result.routes;
          for (var i = 0; i < routes.length; i++) {
            var route = routes[i];
            displayRoute(route, i === 0);
          }
        }
      });
    }

    function displayRoute(route, isMainPath) {
      var path = [];
      for (var i = 0; i < route.legs.length; i++) {
        var leg = route.legs[i];
        for (var j = 0; j < leg.steps.length; j++) {
          var step = leg.steps[j];
          var decodedPath = google.maps.geometry.encoding.decodePath(step.polyline.points);
          path = path.concat(decodedPath);
        }
      }

      var polyline = new google.maps.Polyline({
        path: path,
        strokeColor: isMainPath ? '#FF0000' : '#000000',
        strokeOpacity: 0.8,
        strokeWeight: 4,
        clickable: true,
        map: map
      });

      polyline.addListener('click', function() {
        selectRoute(polyline);
      });

      polylines.push(polyline);

      if (isMainPath) {
        mainPolyline = polyline;
      }
    }

    function selectRoute(clickedPolyline) {
      if (mainPolyline) {
        mainPolyline.setOptions({ strokeColor: '#000000', strokeWeight: 4 });
      }
      mainPolyline = clickedPolyline;
      mainPolyline.setOptions({ strokeColor: '#FF0000', strokeWeight: 6 });
    }

    function initGoogleMaps() {
      // Initialize Google Maps API
      var script = document.createElement('script');
      script.src =
        'https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=initMap';
      script.defer = true;
      document.head.appendChild(script);
    }

    // Load Google Maps API asynchronously
    initGoogleMaps();
  </script>
</body>
</html>

Thanks & Regards


Solution

  • The "main polyline path" which is displayed in different color, is the route rendered by the DirectionsRenderer, which doesn't have a click event. If that isn't the behavior you want, don't display it on the map, change:

    directionsDisplay = new google.maps.DirectionsRenderer({ map: map });
    

    to:

    directionsDisplay = new google.maps.DirectionsRenderer();
    

    (or remove it entirely)

    If you still want the map to zoom to the bounds of the first result, then add:

    map.fitBounds(result.routes[0].bounds); // fit the map to the bounds of the first route
    

    to your code that processes the result.

    screenshot of resulting map

    updated working code snippet:

    <!DOCTYPE html>
    <html>
    <head>
      <title>Show All Possible Routes</title>
      <style>
        #map {
          height: 400px;
          width: 100%;
        }
      </style>
    </head>
    <body>
      <div id="map"></div>
      <script>
        var map;
        var directionsService;
        var directionsDisplay;
        var polylines = [];
        var mainPolyline = null;
    
        function initMap() {
          var mapOptions = {
            center: { lat: 23.022594, lng: 72.570681 }, // Center point coordinates
            zoom: 12, // Zoom level
            mapTypeId: google.maps.MapTypeId.ROADMAP // Map type
          };
    
          map = new google.maps.Map(document.getElementById('map'), mapOptions);
          directionsService = new google.maps.DirectionsService();
          // doen't display the directions from the DirectionsRenderer on the map (removed {map: map})
          directionsDisplay = new google.maps.DirectionsRenderer(); 
    
          var origin = new google.maps.LatLng(23.022594, 72.570681); // Origin coordinates
          var destination = new google.maps.LatLng(22.308836, 70.782300); // Destination coordinates
    
          var waypoints = [
            // Array of LatLng objects representing waypoints (if needed)
            // Example: new google.maps.LatLng(37.7895, -122.4348)
          ];
    
          var request = {
            origin: origin,
            destination: destination,
            travelMode: google.maps.TravelMode.DRIVING,
            waypoints: waypoints,
            provideRouteAlternatives: true // Request multiple route options
          };
    
          directionsService.route(request, function(result, status) {
            if (status === google.maps.DirectionsStatus.OK) {
              directionsDisplay.setDirections(result);
              map.fitBounds(result.routes[0].bounds); // fit the map to the bounds of the first route
              var routes = result.routes;
              for (var i = 0; i < routes.length; i++) {
                var route = routes[i];
                displayRoute(route, i === 0);
              }
            }
          });
        }
    
        function displayRoute(route, isMainPath) {
          var path = [];
          for (var i = 0; i < route.legs.length; i++) {
            var leg = route.legs[i];
            for (var j = 0; j < leg.steps.length; j++) {
              var step = leg.steps[j];
              var decodedPath = google.maps.geometry.encoding.decodePath(step.polyline.points);
              path = path.concat(decodedPath);
            }
          }
    
          var polyline = new google.maps.Polyline({
            path: path,
            strokeColor: isMainPath ? '#FF0000' : '#000000',
            strokeOpacity: 0.8,
            strokeWeight: 4,
            clickable: true,
            map: map
          });
    
          polyline.addListener('click', function() {
            selectRoute(polyline);
          });
    
          polylines.push(polyline);
    
          if (isMainPath) {
            mainPolyline = polyline;
          }
        }
    
        function selectRoute(clickedPolyline) {
          if (mainPolyline) {
            mainPolyline.setOptions({ strokeColor: '#000000', strokeWeight: 4 });
          }
          mainPolyline = clickedPolyline;
          mainPolyline.setOptions({ strokeColor: '#FF0000', strokeWeight: 6 });
        }
    
        function initGoogleMaps() {
          // Initialize Google Maps API
          var script = document.createElement('script');
          script.src =
            'https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=places&callback=initMap';
          script.defer = true;
          document.head.appendChild(script);
        }
    
        // Load Google Maps API asynchronously
        initGoogleMaps();
      </script>
    </body>
    </html>