Introduction.

We continue our path to geolocation services enlightenment.

Before we start, let's review what was covered in previous articles.   We took a look at placeholders - how to define, create and then superimpose these on the NokiaMap control.   We started with installation of the Phone Toolkit. We went on to cover creation of a pushpin.  Pushpins can be used for both the user's location and points of interest. Finally, there was a brief overview of the UserLocationMarker control which is also part of Phone Toolkit.



In this article, we will see how to calculate and view a route on the map before moving on to managing privacy policy of the user's location. We will cover:

  • Introduction to RouteQuery Class 
  • Implementation of RouteQuery in a test project
  • Test the application
  • Privacy policy
  • Conclusion
  • Other Resources

Remember to use the services of geolocation and maps; you must enable the capability ID_CAP_LOCATION and ID_CAP_MAP, discussed in previous articles. Be found in the file WMAppManifest.xml the Features section.

 

Introduction to the RouteQuery Class



In an application that makes use of geolocation services and in this case a NokiaMaps control , you cannot miss the opportunity to track and view a route within that control.  Windows Phone Silverlight provides us developers with the RouteQuery class for this purpose  Using RouteQuery it is possible to draw and display a path from a starting position to an arrival. Now let's see the main methods, properties and events that expose this class.

Properties:

  • TravelMode
  • RouteOptimization
  • Waypoints 

TravelMode: This is the way in which we view the map, we can choose between two available values of TravelMode enumerator. Driving when we are travelling by car or walking.  It also indicates whether a route is suitable if we walk.

RouteOptimization: in this case, we have the opportunity to choose between two values enumerator RouteOptimization MinimizeTime with which the route calculation is performed based on time or MinimizeDistance if we run the route calculation based on distance.

Waypoints: it is a collection of type GeoCoordinate, accounting or points of the route displayed on the map. It can enter all the necessary points, which will then be displayed in the order they were entered.

Methods:

  • QueryAsync()

QueryAsync(): This method simply performs the calculation of the points on the property Waypoints.

Events:

  • QueryCompleted

QueryCompleted: this event, will be performed at the time when the method QueryAsync () completes the calculation for tracing the route on the map. Will return an object of type MapRoute with all the necessary data to show the location on the control NokiaMaps.

 

Implementation of the RouteQuery class in a test project

After this brief introduction, let's see how you can view a route from a starting point (our position) to a point of arrival. First we take over the project that we used in the second part on the control NokiaMaps. Find the complete example at this link. We open the project, explore solutions we place the cursor on the project name, right mouse button and choose "Add" and immediately after "New Item". From templates available select "Page vertical Windows Phone" and call it RouteTravel. Remaining in file.xaml insert the following code to define the graphical interface. The two namespaces needed to make use of the monitoring and control NokiaMaps Pushpin.
xmlns:Controls="clr-namespace:Microsoft.Phone.Maps.Controls;assembly=Microsoft.Phone.Maps"           
xmlns:toolkit="clr-namespace:Microsoft.Phone.Maps.Toolkit;assembly=Microsoft.Phone.Controls.Toolkit"

The remaining part of code to the graphical interface:

<!--LayoutRoot è la griglia radice in cui viene inserito tutto il contenuto della pagina-->
<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
 
    <!--TitlePanel contiene il nome dell'applicazione e il titolo della pagina-->
    <StackPanel Grid.Row="0" Margin="12,17,0,28">
        <TextBlock Text="GeoPositionSample" Style="{StaticResource PhoneTextNormalStyle}"/>
        <TextBlock Text="Route travel" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
    </StackPanel>
 
    <!--ContentPanel - inserire ulteriore contenuto qui-->
    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>              
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
 
        <Grid Grid.Row="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
           
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>                   
            </Grid.ColumnDefinitions>
           
            <TextBlock Grid.Row="0" Grid.Column="0" Text="From" VerticalAlignment="Center"/>
            <TextBox x:Name="tbxFrom" Text="My Position" IsEnabled="False" TextAlignment="Center" Grid.Row="0" Grid.Column="2" Width="400"/>
 
            <TextBlock Grid.Row="1" Grid.Column="0" Text="To" VerticalAlignment="Center"/>
            <TextBox x:Name="tbxTo" Grid.Row="1" Grid.Column="2" Width="400"/>              
        </Grid>
        
        <StackPanel Grid.Row="1">
            <Controls:Map x:Name="mapLocation" Height="442" Width="480">
                <toolkit:MapExtensions.Children>
                    <toolkit:Pushpin x:Name="myPushPinStart" Content="your are here" Visibility="Collapsed"/>                      
                    <toolkit:Pushpin x:Name="myPushPinEnd" Content="destination" Visibility="Collapsed"/>
                </toolkit:MapExtensions.Children>
            </Controls:Map>
        </StackPanel>
 
        <Button Grid.Row="2" x:Name="btnFindCoordinate" Content="Find Route" Tap="btnFindCoordinate_Tap"/>
    </Grid>
</Grid>

If everything has been entered correctly, this will be the appearance of the screen RouteTravel:





Image 1.1 The screen Route travel.

Now open the file MyPosition.cs, and insert the following code:

public static void FindRoute(string position, List<double> startposition, Map maps)
{
    var locator = new Geolocator();
    var geocodequery = new GeocodeQuery();
    var coordinate = new List<GeoCoordinate>();
    var map = maps;
 
    if (!locator.LocationStatus.Equals(PositionStatus.Disabled))
    {
        try
        {
            geocodequery.GeoCoordinate = new GeoCoordinate(0, 0);
            geocodequery.SearchTerm = position;
            geocodequery.QueryAsync();
            geocodequery.QueryCompleted += (sender, args) =>
            {
                if (!args.Result.Equals(null))
                {
                    var result = args.Result.FirstOrDefault();
                    coordinate.Add(new GeoCoordinate(startposition[0],startposition[1]));
                    coordinate.Add(new GeoCoordinate(result.GeoCoordinate.Latitude,result.GeoCoordinate.Longitude));
                    var midLatitude = coordinate.Average(a => a.Latitude);
                    var midLongitude = coordinate.Average(b => b.Longitude);
                    map.Center = new GeoCoordinate(midLatitude, midLongitude);
                    map.ZoomLevel = 12;
 
                    RouteQuery query = new RouteQuery();
                    query.TravelMode = TravelMode.Driving;
                    query.RouteOptimization = RouteOptimization.MinimizeTime;
                    query.Waypoints = coordinate;
 
                    query.QueryCompleted +=(senderone,argsone)=>
                        {
                            var route = new MapRoute(argsone.Result);
                            map.AddRoute(route);
 
                            var startpushpin = (Pushpin)maps.FindName("myPushPinStart");
                            startpushpin.GeoCoordinate = new GeoCoordinate(startposition[0], startposition[1]);
                            startpushpin.Visibility = System.Windows.Visibility.Visible;
 
                            var endpushpin = (Pushpin)maps.FindName("myPushPinEnd");
                            endpushpin.GeoCoordinate = new GeoCoordinate(coordinate[1].Latitude, coordinate[1].Longitude);
                            endpushpin.Visibility = System.Windows.Visibility.Visible;                                  
                        };
 
                    query.QueryAsync();
                }
            };
        }
 
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, AppResources.ApplicationTitle, MessageBoxButton.OK);
        }
    }
 
    else
    {
        MessageBox.Show("Service Geolocation not enabled!", AppResources.ApplicationTitle, MessageBoxButton.OK);
    }
}

Analyze the code, and have created a method that requires three parameters, the first of type string that corresponds to the final destination, we're going to enter into the TextBox screen RouteTravel. The second and a collection of type double that represents the coordinates of our current position, the last we have already seen in the previous article, it is a variable of type Maps, which does nothing but change control NokiaMaps we screen and we spend as a reference to the method FindRoute. The additional pieces of code are:

coordinate.Add(new GeoCoordinate(startposition[0],startposition[1]));
coordinate.Add(new GeoCoordinate(result.GeoCoordinate.Latitude,result.GeoCoordinate.Longitude)); 

We value the collection coordinates type GeoCoordinate, with the latitude and longitude contained in the collection StartPosition of type double, if we remember are the coordinates of our current position, and the second line of code does is add the coordinates of the place from us chosen, or the destination, all when the method QueryAsync () class GeocodeQuery finished the conversion from address to coordinates, and then signing the event QueryCompleted get all the necessary data. While the novelty starts from this code.

RouteQuery query = new RouteQuery();
query.TravelMode = TravelMode.Driving;
query.RouteOptimization = RouteOptimization.MinimizeTime;
query.Waypoints = coordinate;

We declare a new object RouteQuery, we value the properties TravelMode on Driving, RouteOptimization on MinimizeTime and finally we value the property Waypoints with coordinate's collection. After that, we subscribe to the event QueryCompleted exposed by the class RouteQuery.

query.QueryCompleted +=(senderone,argsone)=>
    {
        var route = new MapRoute(argsone.Result);
        map.AddRoute(route);
        var startpushpin = (Pushpin)maps.FindName("myPushPinStart");
        startpushpin.GeoCoordinate = new GeoCoordinate(startposition[0], startposition[1]);
        startpushpin.Visibility = System.Windows.Visibility.Visible;
        var endpushpin = (Pushpin)maps.FindName("myPushPinEnd");
        endpushpin.GeoCoordinate = new GeoCoordinate(coordinate[1].Latitude, coordinate[1].Longitude);
        endpushpin.Visibility = System.Windows.Visibility.Visible;                                  
    };
 
query.QueryAsync();

Here enters a new class, MapRoute, which provides everything you need to draw the route on the map, and then this class exposes many other properties that will deepen in the next article, for now we need to know what was said before. In order to view the route on the map, and needed this instruction code:

map.AddRoute(route);

Recalling the method exposed by the control NokiaMaps, and passing as a parameter an object of type MapRoute. While this piece of code:

var startpushpin = (Pushpin)maps.FindName("myPushPinStart");
startpushpin.GeoCoordinate = new GeoCoordinate(startposition[0], startposition[1]);
startpushpin.Visibility = System.Windows.Visibility.Visible;
 
var endpushpin = (Pushpin)maps.FindName("myPushPinEnd");
endpushpin.GeoCoordinate = new GeoCoordinate(coordinate[1].Latitude, coordinate[1].Longitude);
endpushpin.Visibility = System.Windows.Visibility.Visible;

There must be already familiar, does nothing but add two controls pushpin on the map, the first enhanced with the coordinates of our position, in other words "myPushPinStart", and one with the coordinates obtained after the execution of the method QueryAsync () exposed by RouteQuery class, talk about the control "myPushPinEnd". Finally it remains to recall as previously mentioned the method QueryAsync () so as to obtain all the information needed to use then the control NokiaMaps.

query.QueryAsync();

Now open the file RouteTravel.xaml.cs, where we will implement the method FindRoute () just described. What and manage the event and tap the Button btnFindCoordinate, where we will call the method, insert the following code.

private async void btnFindCoordinate_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            var startPosition = await MyPosition.GetPosition();          
            MyPosition.FindRoute(tbxTo.Text, startPosition, mapLocation);
        }

We analyze the above code. The first statement does is call the method asynchronously GetPosition () that you find in the class MyPosition, which returns a collection of type double that will contain our current position in latitude and longitude. The second statement, however, implements the method FindRoute (), passing three parameters, the Text property of the TextBox tbxTo, which corresponds to the destination that we will enter while running the application, the second parameter, and the collection of type double containing the latitude and longitude of our position, and the last not more than the reference control MapLocation we pass to the method so that you can then view the route on the map. After this activity, and needed one more thing, we open the file MainPage.xaml, and insert the following code immediately below the button btnMultiplePushPin:

<Button x:Name="btnRouteTravel" Content="Route travel" Tap="btnRouteTravel_Tap"/>

F7 key, we access the file MainPage.xaml.cs, where we're going to put the management of the event Tap the button btnRouteTravel.

private void btnRouteTravel_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            NavigationService.Navigate(new Uri("/RouteTravel.xaml", UriKind.Relative));
        }




Test the application.

We included everything you need to view a route on NokiaMaps control, and time to try it out. F5 key, and so we start debugging. This will be the home screen of the application after adding the new button btnRouteTravel.





Image 1.2 The initial screen with the new button Route travel.

We perform a tap on the last button and we will be led to the following screen.





Image 1.3 The screen Route travel while running the application.

The screen consists of two TextBlock controls with values "Form" that is our position, "To" where we will enter the destination you want to view, control NokiaMaps on which will track the path that we display, and finally a button called "Find route "that the tap will execute the code that we saw earlier. Now we type a location in the TextBox beside the word "To" as shown in the figure.





Image 1.4 The screen Route travel with the destination "Caselle Torinese."

After entering the destination, we tap on the button Find Route, and if everything is done correctly, here is what will be the result on the map.





Image 1.5 The screen Route travel with the path displayed on the map.

Privacy policy.

One very important thing, if we decide to make use of the maps in our application and in general of geolocation services, and indeed the user's privacy. And good to know, that the data related to the user's location are sensitive information that, if used improperly, can lead to having problems of no small importance. My advice from a personal point of view and the following:

  • Provide a screen (I do not mean the information on the application) that is dedicated only to describe the application that makes use of geolocation services and / or maps, describing that data collected are used only for the operation of the application and that no are in no way saved and stored or distributed to third parties.
  • Always provide a button on the screen that gives the option to disable geolocation services, leading the user to the correct screen shown in the figure. 





Image 1.6 The Position screen in Setup.

It is true that the user will be warned by a screen where is asked to accept the conditions laid down on the use of the position, if you decide to download an application from the store that makes use of the services of Geolocation, however expect this feature, because it requires little time and date the user the ability to turn on and off at any time geolocation services.



Conclusion.

In this article, it was explained the operation of the class RouteQuery, what are the main methods, properties and events that this class exhibits, we saw how to implement them and later view a route on the map from our location to the final destination, implementing a new class called MapRoute that we will see and describe in the next article. Finally, and was made a brief overview of what and privacy policy, in other words about things you need to bear in mind when we make use of the services of geolocation or maps in our application. In the next article, we will see the class MapRoute, its methods and properties, and finally what to do to post on the store application that makes use of the maps.



See Also



Another important place to find a huge amount of Windows Phone related articles is the TechNet Wiki itself. The best entry point is Windows Phone Resources on the TechNet Wiki.



Other Resources

Finding and Mapping a Route in Windows Phone 8