James Lee
James Lee

Reputation: 23

Google Maps api V3 Ferry detection

I wondering if there is a way to get the api to inform me when a ferry is taken. I know you can change avoidFerries: between true and false, but when set as true I need a way of knowing the ferry has been taken so I can override if necessary via an external button. I just need a way of getting gMaps to tell me one has been taken. Any suggestions would be greatly appreciated.

Regards.

Upvotes: 2

Views: 2194

Answers (1)

Dr.Molle
Dr.Molle

Reputation: 117334

You must parse the steps of a route.

When a step takes a ferry it depends on the TravelMode how to detect it.

For TRANSIT you have to check:

    step.transit.line.vehicle.type==='FERRY'

for other TravelModes it would be:

    step.maneuver==='ferry' 

A function to detect it may look like this:

 /**
    * @param route object DirectionsRoute
    * @return array with steps where a ferry has been taken
    **/
  function get_ferries(route){
     var f=[],section;
     for(var leg=0;leg<route.legs.length;++leg){
        for(var step=0;step<route.legs[leg].steps.length;++step){
           section  = route.legs[leg].steps[step];
           if(
                section.maneuver==='ferry'  
                  ||
                (
                  section.transit
                    &&
                  section.transit.line
                    &&
                  section.transit.line.vehicle
                    &&
                  section.transit.line.vehicle.type==='FERRY'  
                )
             ){
               f.push(section);
             }
        } 
     }
     return f;
  }

Demo:

function initMap() {
  var goo       = google.maps,
      service   = new goo.DirectionsService,
      map       = new goo.Map(document.getElementById('map'), {
                    zoom: 0,
                    center: {lat: 0, lng: 0},
                    noClear:true
                  }),
      renderer  = new goo.DirectionsRenderer({suppressMarkers:true,map:map,polylineOptions:{strokeWeight:3,zIndex:100}}),
      ctrl      = document.getElementById('ctrl'),
      sMode     = ctrl.querySelector('select[name="mode"]'),
      sRoute    = ctrl.querySelector('select[name="route"]')
      sFerry    = ctrl.querySelector('select[name="ferries"]')
      calcRoute = function(){
                    var mode          = goo.TravelMode[sMode.value],
                        avoidFerries  = !!parseInt(sFerry.value),
                        route         = sRoute.options[sRoute.selectedIndex],
                        origin        = route.getAttribute('data-origin'),
                        destination   = route.getAttribute('data-destination');
                        map.data.forEach(function(f){
                          map.data.remove(f);
                        });
                        service.route({
                                        origin      : origin,
                                        destination : destination,
                                        travelMode  : mode,
                                        avoidFerries: avoidFerries
                                      }, function(response, status) {
                          renderer.setDirections(response);
                          if (status !== goo.DirectionsStatus.OK) {
                            alert('Directions request failed due to ' + status);
                          }
                        });

                  };
                  
      map.data.setStyle({
        strokeColor:  'tomato',
        strokeWeight:  5,
        strokeOpacity:  1,
        zIndex:1000,
        icon: 'https://maps.gstatic.com/mapfiles/transit/iw2/6/ferry.png'
      });
      map.controls[google.maps.ControlPosition.TOP_CENTER].push(ctrl);
      goo.event.addDomListener(sMode,   'change',  calcRoute);
      goo.event.addDomListener(sRoute,  'change',  calcRoute);
      goo.event.addDomListener(sFerry,  'change',  calcRoute);
      goo.event.addListener(renderer,'directions_changed',function(){
         var r= this.getDirections(),
             i= this.getRouteIndex();
          if(r && r.routes && r.routes[i]){
            var ferries=get_ferries(r.routes[i]);
            if(ferries.length){
            
              alert('Ferries:'+ ferries.length);
              for(var f=0;f<ferries.length;++f){
                map.data.add({geometry:ferries[f].start_location})
                map.data.add({geometry:new goo.Data.LineString(ferries[f].path)})
              }
              
            }          
          }
      });
      function get_ferries(route){
         var f=[],section;
         for(var leg=0;leg<route.legs.length;++leg){
            for(var step=0;step<route.legs[leg].steps.length;++step){
               section  = route.legs[leg].steps[step];
               if(
                    section.maneuver==='ferry'  
                      ||
                    (
                      section.transit
                        &&
                      section.transit.line
                        &&
                      section.transit.line.vehicle
                        &&
                      section.transit.line.vehicle.type==='FERRY'  
                    )
                 ){
                   f.push(section);
                 }
            } 
         }
         return f;
      }
      calcRoute();
}
html,
body,
#map {
  height: 100%;
  margin: 0;
  padding: 0;
}
    <div id="map">
      <div id="ctrl">
        <select name="route">
          <option data-origin="Rostock,DE" data-destination="Bornholm,DK">Rostock-Bornholm</option>
          <option data-origin="Rotterdam,NL" data-destination="Ipswich,UK">Rotterdam-Ipswich</option>
          <option data-origin="Manhattan,US" data-destination="Ellis Island,US">Manhattan-Ellis Island</option>
        </select>
        <select name="mode">
          <option value="DRIVING">Driving</option>
          <option value="TRANSIT">Transit</option>
          <option value="WALKING">Walking</option>
          <option value="BICYCLING">Bicycling</option>
        </select>
        <select name="ferries">
          <option value="0">avoidFerries:no</option>
          <option value="1">avoidFerries:yes</option>
        </select>
      </div>
    </div>
    <script src="https://maps.googleapis.com/maps/api/js?v=3&callback=initMap"  async defer></script>

Upvotes: 5

Related Questions