Titanium Community Questions & Answer Archive

We felt that 6+ years of knowledge should not die so this is the Titanium Community Questions & Answer Archive

Mobile Map route from google server

Hello. I am trying to make a map that will display a route that is not stored on the phone, but one that is received from a service.

I have some experience at this using this link witch if put in the address bar will generate a .kml file, that containes at the end the coordinates of the route.

I've tried making a xhr in Titanium and making a GET request to that link, but if I try to take the responseXML or Text, I stumble upon a html page.

Can someone please point me in the right direction?
Thanks in advance.

— asked October 28th 2010 by Vali Filip
  • get
  • map
  • route
  • xhr
0 Comments

5 Answers

  • I've got this working by adding a parameter "output=kml" to the link, and if someone is interested, here is the code:

    data = [];
        var url = "http://maps.google.com/?saddr=" 
                + origin + "&daddr=" 
                + destination + "&doflg=ptk&hl=en&output=kml"
        xhr = Titanium.Network.createHTTPClient();
        xhr.open('GET',url);
        Ti.API.info('>>> go get data for Rgeocode! ...URL: '+url);
        xhr.onload = function(){
            // Now parse the XML 
            var xml = this.responseXML;
             var points = [];
            var coords = xml.documentElement.getElementsByTagName("LineString");
            for(var cc=0; cc < coords.length; cc++) {
                var line = coords.item(cc);
                var str = line.firstChild.text.split(" ");
                for(dd = 0; dd < str.length; dd++) {
                    var loc = str[dd].split(',');
                    if(loc[0] && loc[1]) {
                        points.push({latitude: loc[1], 
                             longitude: loc[0]});
                    }
                }
            }
            var route = {
                    name:"boston",
                    points:points,
                    color:"red",
                    width:4
                };
    
            // add a route
            map.addRoute(route);
        };    
        xhr.send();
    
    — answered October 28th 2010 by Vali Filip
    permalink
    4 Comments
    • Works great, thanks.

      — commented December 23rd 2010 by Justin Toth
    • This works but the map doesnt show up until user moves the map, zoom in or zoom out. Any idea why this is happening.
      My code is

      var win=Titanium.UI.currentWindow;
      Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_BEST;
      
       var origin1 = Titanium.UI.createSearchBar({
              barColor:'#000', 
              showCancel:true,
              height:40,
              top:0,
              });
      
              win.add(origin1);
      
              var dest1 = Titanium.UI.createSearchBar({
              barColor:'#000', 
              showCancel:true,
              height:40,
              top:40,
              });
      
              win.add(dest1);
      
           dest1.addEventListener('return',function(){    
           addr=origin1.value;
               Titanium.Geolocation.forwardGeocoder(addr,function(evt)
              {
      
              var latitude=evt.latitude;
              var longitude=evt.longitude;
               var boston={latitude:latitude, longitude:longitude,latitudeDelta:0.1, longitudeDelta:0.1};
      
               var anno = Ti.Map.createAnnotation({
               latitude:latitude,
                longitude:longitude,
                pincolor:Ti.Map.ANNOTATION_GREEN,
                animate:true,
              });
      
               var mapview = Titanium.Map.createView({
                  mapType: Titanium.Map.STANDARD_TYPE,
                     region: boston,
                  animate:true,
                  //regionFit:false,
                  regionFit:true,
                  userLocation:true,
                  top:90,
                  height:301,
                  annotations:[anno]
              });
      
      
      
              dest1.addEventListener('cancel',function(){
                  dest1.blur();
              });
      
      
              zoomout = Titanium.UI.createButton({
                  title:'-',
                  style:Titanium.UI.iPhone.SystemButtonStyle.BORDERED,
                  //top:390,
              });
              win.setToolbar([zoomout]);
      
      
               zoomout.addEventListener('click',function() {
                  mapview.zoom(-1);
              });
      
      
              dest1.blur();
              var origin=origin1.value;
              var destination=dest1.value;
              data = [];
              var url = "http://maps.google.com/?saddr=" 
                  + origin + "&daddr=" 
                  + destination + "&doflg=ptk&hl=en&output=kml";
              xhr = Titanium.Network.createHTTPClient();
              xhr.open('GET',url);
                  Ti.API.info('URL: '+url);
              xhr.onload = function(){
              // Now parse the XML 
              var xml = this.responseXML;
              var points = [];
              var coords = xml.documentElement.getElementsByTagName("LineString");
              for(var cc=0; cc < coords.length; cc++) {
                  var line = coords.item(cc);
                  var str = line.firstChild.text.split(" ");
                  for(dd = 0; dd < str.length; dd++) {
                      var loc = str[dd].split(',');
                      if(loc[0] && loc[1]) {
                          points.push({latitude: loc[1], 
                               longitude: loc[0]});
                      }
                  }
              }
      
      
              var route = {
                      name:"boston",
                      points:points,
                      color:"blue",
                      width:2
                      };
      
              // add a route
              mapview.addRoute(route);
      
          };  
          xhr.send();
        win.add(mapview);
      
        });
      });
      

      — commented July 26th 2011 by nWorks Technologies
    • I added your code to a gist in github giving you credit.
      git://gist.github.com/1351119.git
      If you want me to remove it publicly just tell me. I think this is very interesting and I think it's worth making it available to as many people as possible.

      Regards,
      Jose

      — commented November 9th 2011 by Itinerarium Itinerarium
    • the code is very useful,but my problem is i want route from user current location to a static location. how can i make this possible?

      — commented May 22nd 2013 by devyani p
  • I have updated the code, as the route was not very accurate. Now it's decoding the polylines and adding all their points to the point array:

    The first part of the onload should be replaced with this:

    var xml = this.responseXML, points = [], steps = xml.documentElement.getElementsByTagName("step"), totalSteps = steps.length;
    
                        for(var i = 0; i < totalSteps; i++) {
                            var polylineString = steps.item(i).getElementsByTagName("polyline").item(0).getElementsByTagName("points").item(0).text,
                            decodedPolyline = decodeLine(polylineString);
    
                            for (var j = 0; j < decodedPolyline.length; j++) {
                                if (decodedPolyline[j] != null) {
                                    points.push({
                                        latitude : decodedPolyline[j][0],
                                        longitude : decodedPolyline[j][1]
                                    });
                                }
                            }                    
                        }
    

    And the decoding function:

    function decodeLine(encoded) {
              var len = encoded.length;
              var index = 0;
              var array = [];
              var lat = 0;
              var lng = 0;
    
              while (index < len) {
                var b;
                var shift = 0;
                var result = 0;
                do {
                  b = encoded.charCodeAt(index++) - 63;
                  result |= (b & 0x1f) << shift;
                  shift += 5;
                } while (b >= 0x20);
                var dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
                lat += dlat;
    
                shift = 0;
                result = 0;
                do {
                  b = encoded.charCodeAt(index++) - 63;
                  result |= (b & 0x1f) << shift;
                  shift += 5;
                } while (b >= 0x20);
                var dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
                lng += dlng;
    
                array.push([lat * 1e-5, lng * 1e-5]);
              }
    
              return array;
            }
    
    — answered January 10th 2012 by Manuel Pedrera
    permalink
    4 Comments
    • // show route hack after pulling from google map xml

      setTimeout(function () { mapView.regionFit = true; }, 700);//hack to get route to show
      

      — commented January 10th 2012 by Aizil Akmar Omar
    • xml.documentElement.getElementsByTagName("step")
      

      This line returns a list with undefined elements.

      — commented March 13th 2012 by Lucian Pacurar
    • xml.documentElement.getElementsByTagName("route").item(0).getElementsByTagName('leg').item(0).getElementsByTagName("step")
      

      It looks like another Titanium bug. The code above seems to work :)

      — commented March 13th 2012 by Lucian Pacurar
    • Great code, you helped me so much with your function DecodeLine.

      — commented May 8th 2014 by Lucas Caramelo
  • After trying both code snippets, I got the HTTPClient with empty responseXML property. Then I decided to go on my own and I ended up with this code. Note that the URL format is different, and I have added annotations aswell as a travel mode to the settings.

    Ti.Geolocation.getCurrentPosition(function(evt) {
                    var origin = String(evt.coords.latitude + ',' + evt.coords.longitude),
                    travelMode = 'walking',
                    destination = String(yourLatitude + ',' + yourLongitude),
                    url = "http://maps.google.com/maps/api/directions/xml?mode="
                            + travelMode + "&origin="
                            + origin + "&destination="
                            + destination +"&sensor=false";
                    xhr = Titanium.Network.createHTTPClient();
                    xhr.open('GET',url);
    
                    Ti.API.info('>>> go get data for Rgeocode! ...URL: ' + url);
    
                    xhr.onload = function(e){
                        var xml = this.responseXML,
                        points = [],
                        steps = xml.documentElement.getElementsByTagName("step"),
                        totalSteps = steps.length;
    
                        for (var i=0; i < totalSteps; i++) {
                            var startLocation = steps.item(i).getElementsByTagName("start_location");
                            startLatitude = startLocation.item(0).getElementsByTagName("lat").item(0).text,
                            startLongitude = startLocation.item(0).getElementsByTagName("lng").item(0).text;    
    
                            points.push({latitude:startLatitude, longitude:startLongitude});                
                        }
    
                        // Get last point and add it to the array, as we are only parsing <start_location>
                        var finalLocation = steps.item(totalSteps - 1).getElementsByTagName("end_location"),
                        finalLatitude = finalLocation.item(0).getElementsByTagName("lat").item(0).text,
                        finalLongitude = finalLocation.item(0).getElementsByTagName("lng").item(0).text;
    
                        points.push({latitude:finalLatitude, longitude:finalLongitude});
    
                        // Create route and annotations
                        var route = {
                            name:"bonVoyage",
                            points:points,
                            color:"blue",
                            width:6
                           }, startAnnotation = Ti.Map.createAnnotation({
                               pincolor: Ti.Map.ANNOTATION_RED,
                               latitude: points[0].latitude,
                               longitude: points[0].longitude,
                               title: 'Current location'
                           }), endAnnotation = Ti.Map.createAnnotation({
                               pincolor: Ti.Map.ANNOTATION_RED,
                               latitude: points[points.length - 1].latitude,
                               longitude: points[points.length - 1].longitude,
                               title: 'Destination'
                           });
    
                        // Add elements
                        mapView.addRoute(route);
                        mapView.addAnnotation(startAnnotation);
                        mapView.addAnnotation(endAnnotation);
                    };  
    
                    xhr.send();        
                });
    

    Also note that you have to set your destination coords, and have a mapView object created beforehand.

    By the way, there is a bug in 1.7.x SDK that makes the route dissapear when you reach certain level of zoom, aswell as while you scroll the map. With 1.8.0, the scrolling part is still present but the zoom works ok.

    — answered November 15th 2011 by Manuel Pedrera
    permalink
    1 Comment
    • See last post to get updated code.

      — commented January 10th 2012 by Manuel Pedrera
  • So this basically adds a route overlay to your existing mapview? Right now I'm having to hack it and open up the native app which works, but looks unprofessional.

    — answered November 9th 2010 by Josh Lewis
    permalink
    1 Comment
    • Yes, that is exactly what happens.

      — commented November 9th 2010 by Vali Filip
  • ha

    — answered August 22nd 2012 by kim huat
    permalink
    0 Comments
The ownership of individual contributions to this community generated content is retained by the authors of their contributions.
All trademarks remain the property of the respective owner.