Tiago Mendes
Tiago Mendes

Reputation: 5156

Google maps API Draw driving route and if fail draw straight line

I am trying to use google map API to draw driving routes but when it fails like for example he can have a route that pass over the sea (ex: China to Japan) and when it fail I need that he make straight line replacement of driving route.

The problem is that when API fail to find valid work around and teller "Hey if you fail I gonna just pick up destination value and draw a straight line to next point"I can't because of the callback function when it fails directionResult is empty.

route(request:DirectionsRequest, callback:function(DirectionsResult, DirectionsStatus))

This is what I am trying to do. This example if was working well it should drive the 3 spots in China then straight line to South Korea, then other straight line to other spot in Korea (in South Korea is not working driving mode) and then other straight line to Japan and from there just driving drawing.

<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>

<script type="text/javascript">
var markers = [
        {
            "title": 'China1',
            "lat": '33.007',
            "lng": '120.504',
            "description": '1.'
        }
    ,
        {
            "title": 'China2',
            "lat": '32.304',
            "lng": '118.549',
            "description": '2'
        }
    ,
        {
            "title": 'China3',
            "lat": '38.161',
            "lng": '117.557',
            "description": '3'
        }
        ,
        {
            "title": 'SouthKorea1',
            "lat": '37.55',
            "lng": '126.989',
            "description": '4'
        }
        ,
        {
            "title": 'SouthKorea2',
            "lat": '35.91',
            "lng": '127.269',
            "description": '5'
        }
    ,
        {
            "title": 'Japan1',
            "lat": '34.17996',
            "lng": '131.5234',
            "description": '6'
        }
    ,
        {
            "title": 'Japan3',
            "lat": '35.0058',
            "lng": '132.3381',
            "description": '7'
        }
    ,
        {
            "title": 'Japan4',
            "lat": '35.06253',
            "lng": '134.0060087',
            "description": '8'
        }
    ,
        {
            "title": 'Japan5',
            "lat": '34.69974',
            "lng": '135.42779',
            "description": '9'
        }
    ,
        {
            "title": 'Japan6',
            "lat": '38.270',
            "lng": '140.866',
            "description": '10'
        }
];
window.onload = function () {
    var mapOptions = {
        center: new google.maps.LatLng(markers[0].lat, markers[0].lng),
        zoom: 10,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    var map = new google.maps.Map(document.getElementById("dvMap"), mapOptions);
    var infoWindow = new google.maps.InfoWindow();
    var lat_lng = new Array();
    var latlngbounds = new google.maps.LatLngBounds(); //criar um rectagulo com o tamanho maximo com todos pontos
    for (var i = 0; i < markers.length; i++) {
        var data = markers[i];
        var myLatlng = new google.maps.LatLng(data.lat, data.lng);
        lat_lng.push(myLatlng);
        var marker = new google.maps.Marker({
            position: myLatlng,
            map: map,
            title: data.title
        });
        latlngbounds.extend(marker.position); //extender os limites do rectagulo para os pontos
        (function (marker, data) {
            google.maps.event.addListener(marker, "click", function (e) {
                infoWindow.setContent(data.description);
                infoWindow.open(map, marker);
            });
        })(marker, data);
    }
    map.setCenter(latlngbounds.getCenter());
    map.fitBounds(latlngbounds); //definir limites

    //***********ROUTING****************//

    //Initialize the Path Array
    var path = new google.maps.MVCArray();

    //Initialize the Direction Service
    var service = new google.maps.DirectionsService(); //Serviço para computar direccoes entre 2 sitios

    //Set the Path Stroke Color
    var poly = new google.maps.Polyline({ map: map, strokeColor: '#235c23' });

    //Loop and Draw Path Route between the Points on MAP
    for (var i = 0; i < lat_lng.length; i++) {
        //if ((i) < lat_lng.length) {
            var src = lat_lng[i];
            var des = lat_lng[i + 1];
            poly.setPath(path); //add the ways to the polyine 
            service.route({
                origin: src,
                destination: des,
                travelMode: google.maps.DirectionsTravelMode.DRIVING
            }, function (result, status) {
                //alert(status);
                if (status == google.maps.DirectionsStatus.OK) {
                    len = result.routes[0].overview_path.length;
                    for (var j = 0; j < len; j++) {
                        path.push(result.routes[0].overview_path[j]);
                    }
                }else{
                    //if i could pass the value of  "var i" was easy
                    //path.push(src); //add points to the plyline

                }   
            });
        //}
    }
}
</script>

<div id="dvMap" style="width: 800px; height: 500px">
</div>

Here is Running Example

Desired Result (This is print screen from geocodezip answer, I added the image to those who came the first time to this question to understand what I wanted at the time.) desired result

Any help would be greatly appreciated :)

Upvotes: 2

Views: 1871

Answers (1)

Dr.Molle
Dr.Molle

Reputation: 117334

What you need is called "closures", use this as callback-function for route()

(function(i,s,d){
   return function (result, status) {

           if (status == google.maps.DirectionsStatus.OK) {
             len = result.routes[0].overview_path.length;
             for (var j = 0; j < len; j++) {
                path.push(result.routes[0].overview_path[j]);
             }
           }
           else{
                path.push(s); //add points to the plyline
           }    
}}(i,src,des))

The problem with your attempt is clear, the variables i, des and src will be modified inside the loop.

What the function-call above will do:

It returns another function(the callback). As arguments the variables will be passed. The names of the expected arguments are i, s and d, you now have 3 new variables which may be used inside the returned, inner function too(and which not will be affected by the loop).

Demo: http://jsfiddle.net/doktormolle/a93ntv0L/6/

But there is another issue: You always push the latLngs onto the path, but you can't expect that the results arrive in the desired order(it's running asynchronously). You better fill an array with the segments(of course ordered), and when you got all results populate path

Upvotes: 4

Related Questions