Showing posts with label draw polyline on bing maps. Show all posts
Showing posts with label draw polyline on bing maps. Show all posts

Wednesday, 30 July 2014

Adding Polygons and Polylines to Bing Maps Windows 8.1



Introduction


Hi everybody, 


Today I am gonna show you that how to draw complex polygons and polyline on Bing Maps in Windows Store Application. Many of you guys might think that It would be an rocket science but literally it doesn't. 




Objective 

  • To know the difference between polygons and polyline.
  • To know the need and usage of polygons and polyline.
  • To draw complex polygons on certain area of map.
  • To draw polyline between any two points. 


Description

Polygons are different shapes like square, circle, ellipse, triangle or any custom shape while polyline is only a straight line between two specific points. Youy can also form polygon through polyline by drawing multiple polylines end to end but if you want a complex or custom shape don't go for it because it can be easily done using polygon.

Implemention

Before starting let me explain the things which you need to have with you.

1- Visual Studio 2012 or later. (2013 Recommended)
2- Bing Map SDK for Windows 8 or Windows 8.1 

If you don't have download it from given link below

For Windows 8 Visual Studio 2012

For Windows 8.1 Visual Studio 2013
  

3- Bing Map Key (Credential Key)

To access Bing Map you need to create a Bing Map Credential Key. If you already have its good but if you don't have then click the given link below, login to Bing portal with your Microsoft, Hotmail or Outlook account and generate credential key by putting some information they required. 

Note: Don't tell your credential key to anybody as it is important to keep it private. 

If you have all above mentioned things you are easily able to implement Bing Maps in your windows store application. 

Now lets move toward implementing. 

1- Run the Bing Map SDK installer by doing double click on it. 
2- It will take couple of seconds to install. 
3- After installation restart your visual studio if it is already running otherwise run visual studio 2013.
4- Create new windows store (Blank App) Project and name it. 
5- In Solution Explorer right click to reference and add 

1- "Bing Maps for C#, C++ or Visual Basic"  
2- "Microsoft Visual C++ 2013 Runtime Package for windows" 

references as shown in picture below. 























6- After adding you will see a yellow warning sign on both references in solution explorer as shown in picture below. 




















7- Don't worry it is just due to addition of Visual C++ Runtime reference because some reference only allows to debug or build solution only for one architecture, either it is ARM, x86 or x64. 

So to eliminate this warning change platform from "AnyCPU" to "x86" from Build Configuration Manager and see references after closing it as shown in picture below.





















So we have added references successfully. 

8- Now open MainPage.xaml and add Map Control from toolbox and name it "map" or "myMap".





Note: The controls in Bing Map SDK will be automatically added in toolbox. So you can use them directly as explained. 

9- Now the next step is to add two new buttons. One for adding polyline and second for adding complex polygon. So add two buttons and name them polylinebutton and polygonbutton and create their click event handlers.

Your MainPage.xaml will look like this




















Now open MainPage.xaml.cs from solution explorer and see, after creating both buttons click event your MainPage.xaml.cs will look like this



















10- Now create string property to set and get Maps Credential key paste the code given below before constructor in you MainPage class in MainPage.xaml.cs

        
public string MapKey { get; set; }


11- Now set the Bing Maps Credential Key, paste the code given below in MainPage class constructor in MainPage.xaml.cs

// Replace your Bing Maps credential key

MapKey = "<Your-Bing-Maps-Credential-key>"

myMap.Credentials = MapKey;    // Assigning map key to Bing Maps Control

12- Its time to draw polyline between two location points. so first we have two different location points.

13- Create and Initialize the Object of LocationCollection class and add different locations in it statically and add two or three different location points in it. 

14- Paste the code below in constructor to store different location points for polyline

LocationCollection PolylineLocationPoints = new LocationCollection( );

15- Paste the code below in constructor

// Adding different point locations to draw polyline on map


PolylineLocationPoints.Add(new Location(40.798682, -73.968946));

PolylineLocationPoints.Add(new Location(40.797253, -73.965963));

PolylineLocationPoints.Add(new Location(40.804757, -73.932297));

Now we need to do the following to add polyline in maps. 

Create and Initialize object of Map Polyline class to create polyline and set its properties like width, color and location points. 
Create and Initialize the object of Map Shape Layer class to add all shapes (polygons,polylines) which you want to add on maps to it. 
Add Map Shape Layer to maps as its shape layer.
Set the view of Map and zoom to location where shape is added. 


16- Add some code written below  in polyline button click event to draw polyline after clicking the button. Paste the code given below in it. 




MapPolyline line = new MapPolyline();    // Initializing Polyline Object



line.Color = Colors.Orange;                   // Setting its color to Orange



// Assigning Location Points Collection

            
line.Locations = PolylineLocationPoints;  

line.Width = 5;                                    // Assigning width of polyline. 

// Initializing object of Map Shape Layer to add different shapes (polygons, polylines) on map.
            
MapShapeLayer layer = new MapShapeLayer();   
            
layer.Shapes.Add(line);                          // Adding Line to Map Shape Layer.

// Adding Map Shape Layer holding all shapes in Map            

myMap.ShapeLayers.Add(layer);              

// Setting Map View to the location points where we draw polyline.

myMap.SetView(new Location(40.800744, -73.952842),myMap.MaxZoomLevel);  

Now your code in MainPage.xaml.cs will look like this 


17- Now clean the solution and build it from build menu and run it on local machine. After application launching application click the Add Polyline button and see that you map will move toward the points where you have added the polyline. Location points are represented as point A,B and C in screenshot below. 



18- Now add some more code to draw polygons on the map, most of the code is similar to the above code. 

19- Again create and initialize new object of location collection class for polygon and add some location points in it as we did above. 

20-Add the code below before constructor of the MainPage.xaml.cs class.

LocationCollection PolygonLocationPoints = new LocationCollection( );

Add the code below within in the constructor


// Adding two different location points for polygon



PolygonLocationPoints.Add(new Location(40.808785, -73.936352));

PolygonLocationPoints.Add(new Location(40.804270, -73.937404));



21- Now same as above add some code in Add Polygon button Click Event to add polygon on maps.

Create and Initialize the object of Map Polygon class to create polygon and set its properties like visibility, Fill Color and Location Points. 
Create and Initialize the object of Map Shape Layer class to add all shapes (polygons,polylines) which you want to add on maps to it. 
Add Map Shape Layer to maps as its shape layer.
Set the view of Map and zoom to location where shape is added.


MapPolygon polygon= new MapPolygon();     // Initializing Polygon Object



polygon.FillColor = Colors.Red;                   // Setting its color to Red



// Assigning Location Points Collection

            

polygon.Locations = PolygonLocationPoints; 



// Assigning visibility of polygon. 



polygon.Visibility = true;  
                         
// Initializing object of Map Shape Layer to add different shapes (polygons, polylines) on map.
            
MapShapeLayer layer = new MapShapeLayer();   
            
layer.Shapes.Add(polygon);            // Adding polygon to Map Shape Layer.

// Adding Map Shape Layer holding all shapes in Map            

myMap.ShapeLayers.Add(layer);              

// Setting Map View to the location points where we draw polyline.

myMap.SetView(new Location(40.800744, -73.952842),myMap.MaxZoomLevel);


Now you code in MainPage.xaml.cs will look like this



22- Now again clean the solution and rebuild it from build menu and run it on local machine. After application launch click both button one by one and you will see the polyline and polygon on your Bing Maps. 


So we have added polyline and polygon to our Bing Maps successfully.

If you have any issue or confusion regarding this topic kindly inform me in comments so I will be able to help you. Sample project is also available to download.






Windows Mobile Professional


Tuesday, 3 June 2014

[Solved] Easiest way to Draw Route on Bing Map in Windows Store Application




INTRODUCTION



Hi everybody, 

Today I am going to show you the easiest way to draw route between two location points using Bing Maps Route API. It might be little bit lengthy for you but I am pretty sure that you will feel easy to implement it. 

But before starting let me explain the things which you need to have with you.

1- Visual Studio 2012 or later. (2013 Recommended)
2- Bing Map SDK for Windows 8 or Windows 8.1 

If you don't have download it from given link below

For Windows 8 Visual Studio 2012

For Windows 8.1 Visual Studio 2013
  

3- Bing Map Key (Credential Key)

To access Bing Map you need to create a Bing Map Credential Key. If you already have its good but if you don't have then click the given link below, login to Bing portal with your Microsoft, Hotmail or Outlook account and generate credential key by putting some information they required. 

Note: Don't tell your credential key to anybody as it is important to keep it private. 

If you have all above mentioned things you are easily able to implement Bing Maps in your windows store application. 

Now lets move toward implementing. 

1- Run the Bing Map SDK installer by doing double click on it. 
2- It will take couple of seconds to install. 
3- After installation restart your visual studio if it is already running otherwise run visual studio 2013.
4- Create new windows store (Blank App) Project and name it. 
5- In Solution Explorer right click to reference and add 

1- "Bing Maps for C#, C++ or Visual Basic"  
2- "Microsoft Visual C++ 2013 Runtime Package for windows" 

references as shown in picture below. 























6- After adding you will see a yellow warning sign on both references in solution explorer as shown in picture below. 




















7- Don't worry it is just due to addition of Visual C++ Runtime reference because some reference only allows to debug or build solution only for one architecture, either it is ARM, x86 or x64. 

So to eliminate this warning change platform from "AnyCPU" to "x86" from Build Configuration Manager and see references after closing it as shown in picture below.





















So we have added references successfully. 

8- Now open MainPage.xaml and add Map Control from toolbox and name it "map" or "myMap".





Note: The controls in Bing Map SDK will be automatically added in toolbox. So you can use them directly as explained. 

9- In above picture you see that I have left blank space at right side. It is just to add some additional controls like button to perform actions. So add button from tool box set its content to "Draw Route" and name to "drawroute" 
and create its "Click Event"

10- Now copy your Bing Map Credential Key as its the time to provide it to Bing Map control. 

So open MainPage.xaml.cs and paste the code below in its constructor

// Replace your key with it. 

map.Credentials = "<Your-Bing-Map-Key>";

Now your constructor will look like this.

 public MainPage()
 {
   
     this.InitializeComponent();

     // Replace your key with it.

     map.Credentials = "samplekeyforblog123123123";


 }

11- Build the solution and run it. You will see maps with a button on right side. 

12- Now its time to use Bing Map Route API to draw route between two points. Below is the given link of Bing Map Restful API which takes the latitude,longitude of both locations and credential key as parameter and return data in form of XML or JSON at end point. 

http://dev.virtualearth.net/REST/V1/Routes?wp.0=latitude1,longitude1&wp.1=latitude2,longitude2&key=Your_Bing_Maps_Key

13 - Now we have send request to above URL using HttpClient and get response from it.

So for that purpose I am going to create a method or function in which I will write code and at the end will call it on Button Click Event which we have created already. It is your choice to make function or not. 


First to make request we need points of two different locations so I am taking points of two different location in New York 

Paste the code given below in your MainPage.xaml.cs class and resolve HttpClient object by right clicking on it. 


string point1 = "40.782946,-73.965369";
string point2 = "40.727586,-73.992433";


public async void TraceRoute()
{

   try
   {
        string reqURL = "http://dev.virtualearth.net/REST/V1/Routes?wp.0=" + point1   + "&wp.1=" + point2 +"&key=Your_Bing_Maps_Key";


        HttpClient client = new HttpClient( );

        HttpResponseMessage response = await client.GetAsync(reqURL);

        var jsonResponse = await response.Content.ReadAsStringAsync( );
   }
   catch(Exception ex) 
   {
        Debug.WriteLine(ex.ToString());
   }
  
   finally
   {


   }


}



Now we need to add JSON parser to parse the JSON in response. You can use any parser but I would suggest you to use Newtonsoft JSON library. 

So open Nuget Package manager by right clicking on project in solution explorer and selecting Manage Nuget Packages... 

Select JSON and install it. You will see reference of Netwonsoft.Json will be added to reference automatically. as show in picture below



Now you can parse JSON using Parser but we need classes of C# against the classes of JSON so we can convert them and store them in C# classes.

So instead of writing code for classes manually we will use JSON to C# classes generator. Below is the link of online generator. 

http://www.json2csharp.com 

Just paste the link with proper parameters and click generate as shown in picture below. 


 As I already told you that credential key is private so I have erased it using blue ink. So enter the proper link and click generate. It will generate classes of C# with respect to JSON classes coming in response. But it will be uneditable .

So here is the picture of generated classes. 



Now click copy button and you will see that you will be able to copy all code. 








Now add new class named "RootObject.cs" by right clicking on project in solution explorer and add new class. 

After creating class paste all the code in it.

Now your RootObject Class will look like the code below. 


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BingMapRouteSample
{
    public class ActualEnd
    {
        public string type { get; set; }
        public List<double> coordinates { get; set; }
    }

    public class ActualStart
    {
        public string type { get; set; }
        public List<double> coordinates { get; set; }
    }

    public class Detail
    {
        public int compassDegrees { get; set; }
        public List<int> endPathIndices { get; set; }
        public List<string> locationCodes { get; set; }
        public string maneuverType { get; set; }
        public string mode { get; set; }
        public List<string> names { get; set; }
        public string roadType { get; set; }
        public List<int> startPathIndices { get; set; }
    }

    public class Instruction
    {
        public object formattedText { get; set; }
        public string maneuverType { get; set; }
        public string text { get; set; }
    }

    public class ManeuverPoint
    {
        public string type { get; set; }
        public List<double> coordinates { get; set; }
    }

    public class Warning
    {
        public string origin { get; set; }
        public string severity { get; set; }
        public string text { get; set; }
        public string to { get; set; }
        public string warningType { get; set; }
    }

    public class Hint
    {
        public object hintType { get; set; }
        public string text { get; set; }
    }

    public class ItineraryItem
    {
        public string compassDirection { get; set; }
        public List<Detail> details { get; set; }
        public string exit { get; set; }
        public string iconType { get; set; }
        public Instruction instruction { get; set; }
        public ManeuverPoint maneuverPoint { get; set; }
        public string sideOfStreet { get; set; }
        public string tollZone { get; set; }
        public string towardsRoadName { get; set; }
        public string transitTerminus { get; set; }
        public double travelDistance { get; set; }
        public int travelDuration { get; set; }
        public string travelMode { get; set; }
        public List<string> signs { get; set; }
        public List<Warning> warnings { get; set; }
        public List<Hint> hints { get; set; }
    }

    public class EndWaypoint
    {
        public string type { get; set; }
        public List<double> coordinates { get; set; }
        public string description { get; set; }
        public bool isVia { get; set; }
        public string locationIdentifier { get; set; }
        public int routePathIndex { get; set; }
    }

    public class StartWaypoint
    {
        public string type { get; set; }
        public List<double> coordinates { get; set; }
        public string description { get; set; }
        public bool isVia { get; set; }
        public string locationIdentifier { get; set; }
        public int routePathIndex { get; set; }
    }

    public class RouteSubLeg
    {
        public EndWaypoint endWaypoint { get; set; }
        public StartWaypoint startWaypoint { get; set; }
        public double travelDistance { get; set; }
        public int travelDuration { get; set; }
    }

    public class RouteLeg
    {
        public ActualEnd actualEnd { get; set; }
        public ActualStart actualStart { get; set; }
        public List<object> alternateVias { get; set; }
        public int cost { get; set; }
        public string description { get; set; }
        public List<ItineraryItem> itineraryItems { get; set; }
        public string routeRegion { get; set; }
        public List<RouteSubLeg> routeSubLegs { get; set; }
        public double travelDistance { get; set; }
        public int travelDuration { get; set; }
    }

    public class Resource
    {
        public string __type { get; set; }
        public List<double> bbox { get; set; }
        public string id { get; set; }
        public string distanceUnit { get; set; }
        public string durationUnit { get; set; }
        public List<RouteLeg> routeLegs { get; set; }
        public double travelDistance { get; set; }
        public int travelDuration { get; set; }
        public int travelDurationTraffic { get; set; }
    }

    public class ResourceSet
    {
        public int estimatedTotal { get; set; }
        public List<Resource> resources { get; set; }
    }

    public class RootObject
    {
        public string authenticationResultCode { get; set; }
        public string brandLogoUri { get; set; }
        public string copyright { get; set; }
        public List<ResourceSet> resourceSets { get; set; }
        public int statusCode { get; set; }
        public string statusDescription { get; set; }
        public string traceId { get; set; }
    }

}





















So now your RootObject Class is ready to get data coming in the form of JSON from Bing Maps Route API.

Now come again in MainPage.xaml.cs and after this line declare and Initialize the List of ResourceSet  and ItineraryItem Class present in RootObject.cs before the constructor of MainPage

List<ResourceSet> resourceSet = new List<ResourceSet>( );

List<ItineraryItem> items = new List<ItineraryItem>( );
       
Declare List of Location Class which will hold the location points 

List<Location> loc = new List<Location>( );

Reslove "Location" it by right clicking on it. 

Declare the Object or Resource class

Resource resource;

Now come to TraceRoute Method/Function and paste given code below 

// Parsing JSON Response


 var rootObject = JsonConvert.DeserializeObject<RootObject>(jsonResponse);


 foreach (ResourceSet set in rootObject.resourceSets)
 {
        resourceSet.Add(set);

                
 }

loc.Clear();
            
resource = resourceSet[0].resources[0];
            
items = resource.routeLegs[0].itineraryItems;
            
// Colleting location points to draw route got in response. 

 foreach(ItineraryItem item in items)
            
 {

     loc.Add(new Location() { Latitude = item.maneuverPoint.coordinates[0],        Longitude = item.maneuverPoint.coordinates[1] });
                
            
 }

// Declaring Object of MapPolyline to Draw Route

            MapPolyline line;
            line = new MapPolyline();

// Defining color to Polyline that is Red you can give any color to it. 


            line.Color = Colors.Red;

// Defining width of Polyline so it can easily be visible to naked eye. 
            
            line.Width = 5;

// Giving Collection of location points to Map Polyline     

            foreach(Location l in loc)

            {
                line.Locations.Add(l);
            }
            
// Defining Map Shape layer Object to add Polyline shape to it. 

            MapShapeLayer shapeLayer = new MapShapeLayer();

// Adding line to Shape Layer 

            shapeLayer.Shapes.Add(line);

// Adding Shape Layer to Map

            map.ShapeLayers.Add(shapeLayer);

// Calculating Mid between both location to set center of Map
            int mid;
            
            if(loc.Count%2==0)
            {
                mid = loc.Count / 2;
            }
            else
            {
                mid = (loc.Count + 1) / 2; 
            }

            map.Center = loc[mid];

            map.ZoomLevel = 14;

//------------------------------------------------------------------------------------------------------

Now your MainPage.xaml Class will look like this.  

using Bing.Maps;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238

namespace BingMapRouteSample
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {

        List<ResourceSet> resourceSet = new List<ResourceSet>();
        Resource resource;
        List<ItineraryItem> items = new List<ItineraryItem>();
        List<Location> loc = new List<Location>();
        public MainPage()
        {
            this.InitializeComponent();
            map.Credentials = "Your_Bing_Maps_Key";
            progress.Visibility = Visibility.Collapsed;
            
        }

        string point1 = "40.782946,-73.965369";
        string point2 = "40.727586,-73.992433";
       

        public async void TraceRoute()
        {
            try
            {

           
            string reqURL = "http://dev.virtualearth.net/REST/V1/Routes?wp.0=" + point1 + "&wp.1=" + point2 + "&key=Your_Bing_Maps_Key";


            HttpClient client = new HttpClient();

            HttpResponseMessage response = await client.GetAsync(reqURL);

            var jsonResponse = await response.Content.ReadAsStringAsync();

            // Parsing JSON Response

            var rootObject = JsonConvert.DeserializeObject<RootObject>(jsonResponse);


            foreach (ResourceSet set in rootObject.resourceSets)
           {
                   resourceSet.Add(set);

                
           }

            loc.Clear();

            resource = resourceSet[0].resources[0];

            items = resource.routeLegs[0].itineraryItems;

            // Colleting location points to draw route got in response. 

            foreach (ItineraryItem item in items)
            {

                loc.Add(new Location() { Latitude = item.maneuverPoint.coordinates[0], Longitude = item.maneuverPoint.coordinates[1] });


            }

            // Declaring Object of MapPolyline to Draw Route

            MapPolyline line;
            line = new MapPolyline();

            // Defining color to Polyline that is Red you can give any color to it. 


            line.Color = Colors.Red;

            // Defining width of Polyline so it can easily be visible to naked eye. 

            line.Width = 5;

            // Giving Collection of location points to Map Polyline     

            foreach (Location l in loc)
            {
                line.Locations.Add(l);
            }

            // Defining Map Shape layer Object to add Polyline shape to it. 

            MapShapeLayer shapeLayer = new MapShapeLayer();

            // Adding line to Shape Layer 

            shapeLayer.Shapes.Add(line);

            // Adding Shape Layer to Map

            map.ShapeLayers.Add(shapeLayer);

            // Calculating Mid between both location to set center of Map
            int mid;

            if (loc.Count % 2 == 0)
            {
                mid = loc.Count / 2;
            }
            else
            {
                mid = (loc.Count + 1) / 2;
            }

            map.Center = loc[mid];
            map.ZoomLevel = 14;


            }
            catch (Exception)
            {

                Debug.WriteLine(ex.ToString( ));
               
            }
            finally
            {

                drawroute.isEnabled = true;
                progress.Visibility = Visibility.Collapsed;

            }
        }


        private void drawroute_Click(object sender, RoutedEventArgs e)
        {

                drawroute.isEnabled = false;
                progress.Visibility = Visibility.Visible;

               TraceRoute( );

        }
    }
}

Now there is only one thing remaining. You need to add progress ring to check response (Its Optional) and call TraceRoute method/function in drawroute button click event.

Now rebuild the solution and run it. 

You will see the screen like this. 























Click the Draw Route button it will take couple of seconds and draw route between two location points which you we have assigned to it. 

The location points in this sample are of New York Central Park and Merchant House Museum respectively.

After getting response from ROUTE API you will see the result like this. 























So now you are done with drawing driving route path on Bing Maps from one location to another. 

There are many other things which can easily be done via Bing Map ROUTE API, Location API, and etc etc. 

Some of the key features are below 

1- You can easily put your current location by using GeoLocation Class.
2- You can easily add push pins to starting and ending points. 
3- You can easily find the alternative route if there is traffic on suggested route. 
4- You can easily find the distance and estimated time to reach between two location points.

All above mentioned features will be covered in depth from beginner to advance level in future.

If there is any query you can simply email me or write comment I will follow up with you. 

Download sample from here  

Thanks

BR, 
Mudassir






Windows Mobile Professional