-1

I've been exploring Google Maps JavaScript API for web and I am getting stuck trying to display directions between the user's current location and a destination.

I am able to display directions between two locations when they are predefined using LatLng(lat, lng). I am also able to find the current location of a user. I just can't seem to do both.

function initMap() {

    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(locationSuccess, locationError);
    }
    else {
        alert("Geolocation not supported");
    }

}

function locationSuccess(position) {

    var directionsService = new google.maps.DirectionsService();
    var directionsDisplay = new google.maps.DirectionsRenderer();
    var trafficLayer = new google.maps.TrafficLayer();

    var myLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
    var LA = new google.maps.LatLng(34.0522, -118.2437);

    var mapOptions = {
        zoom: 8,
        center: {lat: 34.2805, lng: -119.2945}
    };

    var map = new google.maps.Map(document.getElementById('map'), mapOptions);
    directionsDisplay.setMap(map);
    trafficLayer.setMap(map);

    //This will mark the current location if found
    // var myLocationMarker = new google.maps.Marker({
    //     position: myLocation,
    //     map: map,
    //     title: 'Current location'
    // });

    map.setCenter(myLocation);

    var request = {
        origin: myLocation,
        destination: LA,
        travelMode: 'DRIVING'
    };

    directionsService.route(request, function (result, status) {
        if (status == google.maps.DirectionsStatus.OK)
            directionsDisplay.setDirections(result);
    });


}

function locationError() {
    alert("Couldn't get location");
}
iiCloudex
  • 11
  • 1
  • 6
  • possible duplicate of [HTML 5 Geolocation not working with Directions API](https://stackoverflow.com/questions/35756481/html-5-geolocation-not-working-with-directions-api) – geocodezip Feb 02 '19 at 23:10

1 Answers1

0

I'm not sure what the issue was that was preventing you from realising your goals - I tried the code above and it appeared to work - as it was too cold to work in the garage I had a little play and created a small demo; perhaps though you or someone else might find the following useful?

Initially when the call to navigator.getCurrentLocation resolves with the user's location the map loads using the returned position object to form the map centre location. The route to the pre-defined destination is then calculated using the Directions service with a modified options parameter - notably in this instance to hide the default markers. The reason for hiding the markers is because they do not expose any events and thus we cannot bind any listeners to them so we add our own. The added markers allow the route to be dynamically re-calculated ( can also drag the actual route itself )

The text version of the directions is available by clicking on one of the two markers.

The destination is in Birmingham, UK. If you are outwith the UK this might not work immediately without editing this location. Also, a valid API key is required.

<!DOCTYPE html>
<html>
    <head>
        <title>Google Maps: Directions from my location to...</title>
        <meta charset='utf-8' />
        <style>
            body,
            html { height:100%;margin:0;padding:0;box-sizing:border-box; }
            #map { width:100%;height:100vh; margin:auto;float:none; }
            #info{ display:none;padding:0.25rem;margin:1rem;background:white;font-size:0.75rem!important; }
        </style>
        <script>
            let map;
            let marker;
            let infoWindow;
            let oDir;
            let oTraf;
            let oDisp;
            let oReq;
            let destination={ lat:52.477068, lng:-1.911663 };

            const modes={
                walk:'WALKING',
                bike:'BICYCLING',
                car:'DRIVING',
                pub:'TRANSIT'
            };
            const advReqOptions={
                provideRouteAlternatives:true,
                optimizeWaypoints:true,
                avoidFerries:true,
                avoidHighways:false,
                avoidTolls:false
            };



            function initMap(){
                /* utility to add a new marker and assign listeners to it */
                const addmarker=function( pos, type, colour ){
                    marker=new google.maps.Marker({
                        icon:'//maps.google.com/mapfiles/ms/icons/'+colour+'-pushpin.png',
                        type:type,
                        draggable:true,
                        position:pos,
                        map:map
                    });
                    google.maps.event.addListener( marker, 'click', function(e){
                        infoWindow.getContent().style.display='block';
                        infoWindow.setPosition( this.getPosition() );
                        infoWindow.open( map );
                    });
                    google.maps.event.addListener( marker, 'dragend', calculateroute );
                };

                /* callback function when markers are dragged and the route is re-calculated */
                const calculateroute=function(e){
                    oReq={
                        origin:this.type=='start' ? e.latLng : oReq.origin,
                        destination:this.type=='finish' ? e.latLng : oReq.destination,
                        travelMode:modes.car
                    };
                    oDir.route( Object.assign( oReq, advReqOptions ), callback );
                };

                /* process the route response */
                const callback=function(r,s){
                    if( s === 'OK' ) oDisp.setDirections( r );
                    else evtGeoFailure( s );
                }

                /* Main callback invoked when the user's location has been identified */
                const evtGeoSuccess=function(p){
                    /* create the map */
                    let location={
                        lat: parseFloat( p.coords.latitude ),
                        lng: parseFloat( p.coords.longitude )
                    };
                    let options= {
                        zoom: 16,
                        center:location,
                        mapTypeId: google.maps.MapTypeId.ROADMAP
                    };
                    let routeoptions={
                        suppressMarkers:true,
                        draggable:true,
                        map:map
                    };

                    /* create the map object */
                    map = new google.maps.Map( document.getElementById('map'), options );

                    /* add draggable markers to the start and end of pre-defined route */
                    addmarker( location, 'start', 'grn' );
                    addmarker( destination, 'finish', 'red' );

                    /* display the textual directions in an infowindow which opens on marker click */
                    infoWindow = new google.maps.InfoWindow({ maxWidth:450, disableAutoPan:false });
                    infoWindow.setContent( document.getElementById('info') );


                    /* create the objects required for the directions calculations */
                    oDir=new google.maps.DirectionsService();
                    oDisp=new google.maps.DirectionsRenderer( routeoptions );
                    oTraf=new google.maps.TrafficLayer();


                    /* construct the initial request */
                    oReq={
                        origin:location,
                        destination:destination,
                        travelMode:modes.car
                    };

                    /* go get the directions... */
                    oDisp.setMap( map );
                    oTraf.setMap( map );
                    oDisp.setPanel( infoWindow.getContent() );
                    oDir.route( Object.assign( oReq, advReqOptions ), callback );
                };


                const evtGeoFailure=function(e){ console.info( 'you broke the internets: %s', e ) };
                const config={ maximumAge:60000, timeout:5000, enableHighAccuracy:true };

                if( navigator.geolocation ) navigator.geolocation.getCurrentPosition( evtGeoSuccess, evtGeoFailure, config );
            }
        </script>
        <script src='//maps.googleapis.com/maps/api/js?key=<<APIKEY>>&callback=initMap' async defer></script>
    </head>
    <body>
        <div id='map'></div>
        <div id='info'></div>
    </body>
</html>
Professor Abronsius
  • 33,063
  • 5
  • 32
  • 46
  • May I ask how you ran it? I'm a bit new to JavaScript and I'm using the WebStorm IDE from Jet Brains. Also, I am now seeing that I get an OVER_QUERY_LIMIT so maybe I'll have to do some research on that. Thanks again I'll look into what you've posted! – iiCloudex Feb 04 '19 at 23:52
  • copy and paste all of the above code into a new, empty document - add your own APIKey, save as a html file in your document root and point the browser at it... – Professor Abronsius Feb 05 '19 at 07:49