Xamarin iOS Draw Route between two Geo-location in Google map using Direction api

In brief : Drawing path between two intended location using google direction api over google map in xamarin iOS.


In Detail: If you are done with google map integration and looking for the implementation of the drawing route between two points then you are in the rite place.
Compare to native iOS map even google map has the advantage in cross-platform implementation like in zoom level,night-mode and extended google services [https://developers.google.com/maps/documentation/ios-sdk/views] etc.
Findout the details about google map components like marker,polyline,path in Drawing path between two points in xamarin android.

In steps: 
1.Integrate google map, it is pretty simple and shown in great detail in xamarin component document page.

2.Enable direction api in google developer console and get the api key generated[follow the step2 in Draw path in xamarin android]

3.Mark the source and destination 
Here i will consider two random location you can also consider implementing location autocomplete textview.
To mark on the map need to convert the location into its geo co-ordinates[lat,long]. this can be done by using google geocoding api.


//Code snippet to mark source and destination points
Location SourceLocation{get;set;}
Location DestinationLocation{get;set;}
//mark source point
strGeoCodeURL =string.Format ("https://maps.googleapis.com/maps/api/geocode/json?address={0}&key={1}",strSource,"ApiKeygeoeshere");
string strHttpResponse= await FnHttpRequest (strGeoCodeURL);
GeoCodeJSONClass objGeoCodeJSONClass = JsonConvert.DeserializeObject<GeoCodeJSONClass> (strHttpResponse);
//find GeoCodeJSONClass below in this page
if(objGeoCodeJSONClass!=null && objGeoCodeJSONClass.status=="OK")
{
SourceLocation=new Location(){lat=objGeoCodeJSONClass.results[0].geometry.location.lat,lng=objGeoCodeJSONClass.results[0].geometry.location.lng};
MarkOnMap (SourceLocation,"Start",UIImage.FromBundle("Images/MarkerSource"),false);
}
//mark destination point
strGeoCodeURL =string.Format ("https://maps.googleapis.com/maps/api/geocode/json?address={0}&key={1}",strDestination,"apiKeygeoeshere");
string strHttpResponse = await FnHttpRequest ( strGeoCodeURL );
var objGeoCodeJSONClass = JsonConvert.DeserializeObject<GeoCodeJSONClass> (strHttpResponse);
if ( objGeoCodeJSONClass != null && objGeoCodeJSONClass.status == "OK" )
{
DestinationLocation = new Location () { lat = objGeoCodeJSONClass.results [0].geometry.location.lat, lng = objGeoCodeJSONClass.results [0].geometry.location.lng };
MarkOnMap ( DestinationLocation , "End" , UIImage.FromBundle ( "Images/MarkerDest" ) , false );
}
void MarkOnMap(Location location,string strTitle,UIImage imgIcon,bool isFlat)
{
var marker = new Marker ();
marker.Flat = isFlat;
marker.Position = new CLLocationCoordinate2D ( location.lat , location.lng );
marker.Map = mapView;
marker.Title = strTitle;
marker.Icon=imgIcon;
marker.Draggable=false;
marker.AppearAnimation=MarkerAnimation.Pop;
}
//HttpWebRequest common method
static async Task<string> FnHttpRequest(string strURL)
{
WebClient client = new WebClient ();
string strResult;
try
{
strResult=await client.DownloadStringTaskAsync (new Uri(strURL));
}
catch
{
strResult="Exception";
}
finally
{
client.Dispose ();
client = null;
}
return strResult;
}
4.Make an Http REST request to google direcetion api and parse the json response

//rest request to google direction api
internal static string strGoogleDirectionUrl="https://maps.googleapis.com/maps/api/directions/json?origin=src_locn&destination=dest_lcn&key=keyGoesHere";
string strJSONDirectionResponse = await FnHttpRequest(strGoogleDirectionUrl);
var objRoutes = JsonConvert.DeserializeObject<GoogleDirectionClass> ( jSonData );
//find GoogleDirectionClass below in this page

5.Draw path connecting the polyline points.
Google direction response may contain more then route. Direction api returns polyline points in the encoded format, decode it to draw the line and include it to map.  



//Draw line by connecting polyline points
UIColor pathColor = UIColor.Red;
int intRoutesCount=objRoutes.routes.Count;
//available routes may be more then one
for ( int intCounter = 0 ; intCounter < intRoutesCount ; intCounter++ )
{
var path = Google.Maps.Path.FromEncodedPath ( objRoutes.routes [intCounter].overview_polyline.points );
var line = Google.Maps.Polyline.FromPath ( path );
line.StrokeWidth = 3f;
line.StrokeColor = UIColor.Red;
line.Geodesic = true; //more curved path
line.Map = mapView;
}
JSON class's
Google GeoCode JSON Class:

//Google GeoCode class
public class AddressComponent
{
public string long_name { get; set; }
public string short_name { get; set; }
public List<string> types { get; set; }
}
public class Northeast
{
public double lat { get; set; }
public double lng { get; set; }
}
public class Southwest
{
public double lat { get; set; }
public double lng { get; set; }
}
public class Bounds
{
public Northeast northeast { get; set; }
public Southwest southwest { get; set; }
}
public class Location
{
public double lat { get; set; }
public double lng { get; set; }
}
public class Northeast2
{
public double lat { get; set; }
public double lng { get; set; }
}
public class Southwest2
{
public double lat { get; set; }
public double lng { get; set; }
}
public class Viewport
{
public Northeast2 northeast { get; set; }
public Southwest2 southwest { get; set; }
}
public class Geometry
{
public Bounds bounds { get; set; }
public Location location { get; set; }
public string location_type { get; set; }
public Viewport viewport { get; set; }
}
public class Result
{
public List<AddressComponent> address_components { get; set; }
public string formatted_address { get; set; }
public Geometry geometry { get; set; }
public string place_id { get; set; }
public List<string> types { get; set; }
}
public class GeoCodeJSONClass
{
public List<Result> results { get; set; }
public string status { get; set; }
}
Google Direction JSON Class:

//GoogleDirectionClass.cs
public class GeocodedWaypoint
{
public string geocoder_status { get; set; }
public string place_id { get; set; }
public List<string> types { get; set; }
}
public class Northeast
{
public double lat { get; set; }
public double lng { get; set; }
}
public class Southwest
{
public double lat { get; set; }
public double lng { get; set; }
}
public class Bounds
{
public Northeast northeast { get; set; }
public Southwest southwest { get; set; }
}
public class Distance
{
public string text { get; set; }
public int value { get; set; }
}
public class Duration
{
public string text { get; set; }
public int value { get; set; }
}
public class EndLocation
{
public double lat { get; set; }
public double lng { get; set; }
}
public class StartLocation
{
public double lat { get; set; }
public double lng { get; set; }
}
public class Distance2
{
public string text { get; set; }
public int value { get; set; }
}
public class Duration2
{
public string text { get; set; }
public int value { get; set; }
}
public class EndLocation2
{
public double lat { get; set; }
public double lng { get; set; }
}
public class Polyline
{
public string points { get; set; }
}
public class StartLocation2
{
public double lat { get; set; }
public double lng { get; set; }
}
public class Traffic
{
public List<object> users { get; set; }
public int usercount { get; set; }
public double avgspeed { get; set; }
public int status { get; set; }
}
public class Step
{
public Distance2 distance { get; set; }
public Duration2 duration { get; set; }
public EndLocation2 end_location { get; set; }
public string html_instructions { get; set; }
public Polyline polyline { get; set; }
public StartLocation2 start_location { get; set; }
public string travel_mode { get; set; }
public Traffic traffic { get; set; }
public string maneuver { get; set; }
}
public class Leg
{
public Distance distance { get; set; }
public Duration duration { get; set; }
public string end_address { get; set; }
public EndLocation end_location { get; set; }
public string start_address { get; set; }
public StartLocation start_location { get; set; }
public List<Step> steps { get; set; }
public List<object> via_waypoint { get; set; }
public int priority { get; set; }
}
public class OverviewPolyline
{
public string points { get; set; }
}
public class Route
{
public Bounds bounds { get; set; }
public string copyrights { get; set; }
public List<Leg> legs { get; set; }
public OverviewPolyline overview_polyline { get; set; }
public string summary { get; set; }
public List<object> warnings { get; set; }
public List<object> waypoint_order { get; set; }
}
public class GoogleDirectionClass
{
public List<GeocodedWaypoint> geocoded_waypoints { get; set; }
public List<Route> routes { get; set; }
public string status { get; set; }
}
This is how we can draw route in xamarin iOS application. Please write your thoughts/suggestion or better way of doing this if any...
Thanks for your time here and come back again to explore exciting stuffs. :) 

3 comments:

  1. What's up to all, the contents existing at
    this website are actually awesome for people experience, well,
    keep up the good work fellows.

    my blog post - ice mold ()

    ReplyDelete
  2. awesome thank u so much
    your tutorials are really helpful

    ReplyDelete