Windows Phone 8 Learning Note (8) Positioning map navigation

Source: Internet
Author: User
Windows phone 8 no longer uses its own bing map. The new map control can specify the mapping mode, view, and so on. The positioning error of the bing map is relatively large, and it seems ideal to test the new map in the simulator. This section mainly explains the use of location services and new map controls.

Quick navigation:
I. Location Services
Map and navigation

Mobile phone location services can be used to develop applications that utilize the geographic location of mobile phones. We can monitor the whereabouts of mobile phones through the application, and can be used for navigation with maps. The location service can obtain the geographic location of the mobile phone in time, can also continuously track the mobile phone movement, and can also run in the background. Get current position immediately

We can get the current position in one operation. The following code demonstrates the implementation method.

[C #]

private async void OneShotLocation_Click (object sender, RoutedEventArgs e)

{

// Geographic access service

Geolocator geolocator = new Geolocator ();

// definition accuracy in meters

geolocator.DesiredAccuracyInMeters = 1;

try

{

// Start getting the latitude and longitude of the current position

Geoposition geoposition = await geolocator.GetGeopositionAsync ();

LatitudeTextBlock.Text = "Longitude:" + geoposition.Coordinate.Latitude.ToString ("0.00");

LongitudeTextBlock.Text = "Latitude:" + geoposition.Coordinate.Longitude.ToString ("0.00");

}

catch (Exception ex)

{

if ((uint) ex.HResult == 0x80004004)

{

StatusTextBlock.Text = "System settings have turned off location services.";

}

}

} 2. Keep track of location information

If the continuous tracking of the mobile phone position is enabled, when the mobile phone moves beyond the set distance, a position change event will be triggered. At this time, we can calculate the mobile phone's movement trajectory, speed direction, etc. through the environmental information. Here's how to keep track.

[C #]

Geolocator geolocator = null;

bool tracking = false;

private void TrackLocation_Click (object sender, RoutedEventArgs e)

{

if (! tracking)

{

// Geographic access service

geolocator = new Geolocator ();

// precision level

geolocator.DesiredAccuracy = PositionAccuracy.High;

// How many meters exceeds to trigger a position change event

geolocator.MovementThreshold = 100;

// When the function status changes

geolocator.StatusChanged + = geolocator_StatusChanged;

// When the position changes

geolocator.PositionChanged + = geolocator_PositionChanged;

tracking = true;

TrackLocationButton.Content = "Stop tracking";

}

else

{

geolocator.PositionChanged-= geolocator_PositionChanged;

geolocator.StatusChanged-= geolocator_StatusChanged;

geolocator = null;

tracking = false;

TrackLocationButton.Content = "Tracking Location";

StatusTextBlock.Text = "Stop";

}

}

void geolocator_StatusChanged (Geolocator sender, StatusChangedEventArgs args)

{

string status = "";

switch (args.Status)

{

case PositionStatus.Disabled:

status = "Location service settings are disabled";

break;

case PositionStatus.Initializing:

status = "Initializing";

break;

case PositionStatus.NoData:

status = "no data";

break;

case PositionStatus.Ready:

status = "ready";

break;

case PositionStatus.NotAvailable:

status = "unavailable";

break;

case PositionStatus.NotInitialized:

break;

}

Dispatcher.BeginInvoke (() =>

{

StatusTextBlock.Text = status;

});

}

void geolocator_PositionChanged (Geolocator sender, PositionChangedEventArgs args)

{

Dispatcher.BeginInvoke (() =>

{

LatitudeTextBlock.Text = "Longitude:" + args.Position.Coordinate.Latitude.ToString ("0.00");

LongitudeTextBlock.Text = "Latitude:" + args.Position.Coordinate.Longitude.ToString ("0.00");

});

} 3. Continuous tracking in the background

Location tracking can be run as a service in the background. At this time we do not need to update the UI. In order for our application to run as a service, we need to right-click to open the manifest file and choose to use an XML text editor. Replace the DefaultTask node with the following information:

[XML]

      <DefaultTask Name = "_ default" NavigationPage = "MainPage.xaml">
        <BackgroundExecution>
          <ExecutionType Name = "LocationTracking" />
        </ BackgroundExecution>
      </ DefaultTask>
Then we need to register for the RunningInBackground event, open App.xaml and add the event Application_RunningInBackground, the code is as follows:

[XAML]

        <!-Objects needed to handle application lifetime events->
        <shell: PhoneApplicationService
            Launching = "Application_Launching" Closing = "Application_Closing"
            Activated = "Application_Activated" Deactivated = "Application_Deactivated"
            RunningInBackground = "Application_RunningInBackground" />
Add static variables RunningInBackground and Geolocator in App.xaml.cs. RunningInBackground is true when Application_RunningInBackground event, RunningInBackground is false when Application_Activated event. code show as below:

[C #]

// Determine if the application is running in the background
public static bool RunningInBackground {get; set;}
// Provide access to the current geographic location
public static Geolocator Geolocator {get; set;}

// Code executed when the application is activated (in the foreground)
// This code is not executed when the application is first launched
private void Application_Activated (object sender, ActivatedEventArgs e)
{
    RunningInBackground = false;
}

private void Application_RunningInBackground (object sender, RunningInBackgroundEventArgs args)
{
    RunningInBackground = true;
}
Add the following code to the mainpage:

[C #]

protected override void OnNavigatedTo (System.Windows.Navigation.NavigationEventArgs e)
{
    if (App.Geolocator == null)
    {
        App.Geolocator = new Geolocator ();
        App.Geolocator.DesiredAccuracy = PositionAccuracy.High;
        App.Geolocator.MovementThreshold = 100;
        App.Geolocator.PositionChanged + = geolocator_PositionChanged;
    }
}

void geolocator_PositionChanged (Geolocator sender, PositionChangedEventArgs args)
{
    if (! App.RunningInBackground)
    {
        Dispatcher.BeginInvoke (() =>
        {
            LatitudeTextBlock.Text = "Longitude:" + args.Position.Coordinate.Latitude.ToString ("0.00");
            LongitudeTextBlock.Text = "Latitude:" + args.Position.Coordinate.Longitude.ToString ("0.00");
        });
    }
    else
    {
        Microsoft.Phone.Shell.ShellToast toast = new Microsoft.Phone.Shell.ShellToast ();
        toast.Content = args.Position.Coordinate.Latitude.ToString ("0.00") + "," + args.Position.Coordinate.Longitude.ToString ("0.00");
        toast.Title = "Position:";
        toast.NavigationUri = new Uri ("/ Page1.xaml", UriKind.Relative);
        toast.Show ();

    }
}
Maps and navigation
To use the new map control, you need to register first, at phone: Pho
neApplicationPage registration logo.

[XAML]

xmlns: maps = "clr-namespace: Microsoft.Phone.Maps.Controls; assembly = Microsoft.Phone.Maps"
    
1. Introduce the map control
Add the following code in XAML to introduce the control. We see that Center is the latitude and longitude of the center point of the current map; ZoomLevel is the zoom level; LandmarksEnabled property is set to true to display landmarks on the Map control; PedestrianFeaturesEnabled is set to true to display the pedestrian street structure.

[XAML]

        <!-ContentPanel-place additional content here->
        <Grid x: Name = "ContentPanel" Grid.Row = "1" Margin = "12,0,12,0">
            <!-Map controls->
            <maps: Map x: Name = "MyMap" Center = "30.5473, 114.2922" ZoomLevel = "10" LandmarksEnabled = "true" PedestrianFeaturesEnabled = "true" />
            <Button Foreground = "Red" Content = "specified position" HorizontalAlignment = "Left" Margin = "295,530,0,0" VerticalAlignment = "Top" Click = "Button_Click_1" Width = "151" />
            <Button Foreground = "Red" Content = "drawing mode" HorizontalAlignment = "Left" Margin = "10,530,0,0" VerticalAlignment = "Top" Click = "Button_Click_2" />
            <Button Foreground = "Red" Content = "color mode" HorizontalAlignment = "Left" Margin = "134,530,0,0" VerticalAlignment = "Top" Click = "Button_Click_3" />
            <Button Foreground = "Red" Content = "My Position" HorizontalAlignment = "Left" Margin = "10,602,0,0" VerticalAlignment = "Top" Click = "Button_Click_4" />
        </ Grid>
2. Set the drawing mode
There are four options in the mapping mode, as follows:
Road: Shows the normal default 2D map.
Aerial: Display aerial map.
Hybrid: Aerial survey view showing maps overlapping roads and labels.
Terrain: Displays natural terrain images for displayed highland and water structures, such as mountains and rivers.

Let ’s see how to switch.

[C #]

// Toggle drawing mode
private void Button_Click_2 (object sender, RoutedEventArgs e)
{
    switch (MyMap.CartographicMode)
    {
        case MapCartographicMode.Aerial:
            MyMap.CartographicMode = MapCartographicMode.Hybrid;
            break;
        case MapCartographicMode.Hybrid:
            MyMap.CartographicMode = MapCartographicMode.Road;
            break;
        case MapCartographicMode.Road:
            MyMap.CartographicMode = MapCartographicMode.Terrain;
            break;
        case MapCartographicMode.Terrain:
            MyMap.CartographicMode = MapCartographicMode.Aerial;
            break;
    }
}
3. Set the color mode
Color is divided into light and dark, let's see how to achieve it.

[C #]

// Switch color mode
private void Button_Click_3 (object sender, RoutedEventArgs e)
{
    if (MyMap.ColorMode == MapColorMode.Light)
        MyMap.ColorMode = MapColorMode.Dark;
    else MyMap.ColorMode = MapColorMode.Light;
}
4. Specify the new perspective position
We can programmatically switch the position of the view to the new latitude and longitude, and can specify the transition effect when switching, here is the parabolic way.

[C #]

private void Button_Click_1 (object sender, RoutedEventArgs e)
{
    // In a parabolic way, position the perspective over the central lake of the Optics Valley Software Park.
    MyMap.SetView (new GeoCoordinate (30.476724, 114.406563), 16, MapAnimationKind.Parabolic);
}
5. Locate and mark my location
Position the map to my current location. At this time, you need to use the positioning function. The types of latitude and longitude instances obtained through the positioning function are different. You need to do a conversion in advance. The conversion class CoordinateConverter is as follows.

[C #]

public static class CoordinateConverter
{
    /// <summary>
    /// Convert the positioning position to the map position
    /// </ summary>
    /// <param name = "geocoordinate"> </ param>
    /// <returns> </ returns>
    public static GeoCoordinate ConvertGeocoordinate (Geocoordinate geocoordinate)
    {
        return new GeoCoordinate
            (
            geocoordinate.Latitude,
            geocoordinate.Longitude,
            geocoordinate.Altitude ?? Double.NaN,
            geocoordinate.Accuracy,
            geocoordinate.AltitudeAccuracy ?? Double.NaN,
            geocoordinate.Speed ?? Double.NaN,
            geocoordinate.Heading ?? Double.NaN
            );
    }
}
Then, we need to draw a small square on the map to mark my current location and position the map here.

[C #]

// Add other controls to the map to identify my current location
private async void Button_Click_4 (object sender, RoutedEventArgs e)
{
    // Get my geographic location
    Geolocator myGeolocator = new Geolocator ();
    // precision
    myGeolocator.DesiredAccuracyInMeters = 1;
    Geoposition myGeoposition = await myGeolocator.GetGeopositionAsync ();
    Geocoordinate myGeocoordinate = myGeoposition.Coordinate;
    // Convert latitude and longitude GeoCoordinate
    GeoCoordinate myGeoCoordinate = CoordinateConverter.ConvertGeocoordinate (myGeocoordinate);

    //MessageBox.Show (myGeoCoordinate.ToString ());

    // Locate the map to my location
    MyMap.SetView (myGeoCoordinate, 16, MapAnimationKind.Parabolic);

    // Draw a square and render it on my current location on the map
    Rectangle MyRectangle = new Rectangle ();
    MyRectangle.Fill = new SolidColorBrush (Colors.Black);
    MyRectangle.Height = 20;
    MyRectangle.Width = 20;

    MapOverlay MyOverlay = new MapOverlay ();
    MyOverlay.Content = MyRectangle;
    MyOverlay.GeoCoordinate = myGeoCoordinate;
    MyOverlay.PositionOrigin = new Point (0, 0.5);

    MapLayer MyLayer = new MapLayer ();
    MyLayer.Add (MyOverlay);
    MyMap.Layers.Add (MyLayer);

}
6. Get driving directions
We can also implement navigation through positioning and maps. The following demonstrates how to drive from my current location (Optical Valley Software Park) to a designated location (Optical Valley Venture Street).

[XAML]

    <phone: PhoneApplicationPage.Resources>
        <DataTemplate x: Key = "RouteListTemplate">
            <TextBlock Text = "{Binding}" FontSize = "{StaticResource PhoneFontSizeMedium}" Margin = "5,5,0,0" />
        </ DataTemplate>
    </phone:PhoneApplicationPage.Resources>
    <!-LayoutRoot is the root grid containing all page content->
        <Grid x: Name = "LayoutRoot" Background = "Transparent">
            <Grid.RowDefinitions>
                <RowDefinition Height = "auto" />
                <RowDefinition Height = "*" />
                <RowDefinition Height = "auto" />
                <RowDefinition Height = "*" />
            </ Gri
d.RowDefinitions>
            <TextBlock Text = "Map Navigation" Grid.Row = "0" FontSize = "{StaticResource PhoneFontSizeLarge}" Margin = "0,0,0,20" />
            <maps: Map x: Name = "MyMap" Grid.Row = "1" Center = "30.476724, 114.406563" ZoomLevel = "13" />
            <TextBlock Text = "Driving directions" Grid.Row = "2" FontSize = "{StaticResource PhoneFontSizeLarge}" Margin = "0,10,0,20" />
            <phone: LongListSelector x: Name = "RouteLLS" Grid.Row = "3" Background = "Transparent" ItemTemplate = "{StaticResource RouteListTemplate}" LayoutMode = "List"
      IsGroupingEnabled = "False" />
    </ Grid>
[C #]

    public partial class Page1: PhoneApplicationPage
    {
        public Page1 ()
        {
            InitializeComponent ();
            this.GetCoordinates ();
        }

        RouteQuery MyQuery = null;
        GeocodeQuery Mygeocodequery = null;

        List <GeoCoordinate> MyCoordinates = new List <GeoCoordinate> ();

        private async void GetCoordinates ()
        {
            Geolocator MyGeolocator = new Geolocator ();
            MyGeolocator.DesiredAccuracyInMeters = 5;
            Geoposition MyGeoPosition = null;
            try
            {
                MyGeoPosition = await MyGeolocator.GetGeopositionAsync (TimeSpan.FromMinutes (1), TimeSpan.FromSeconds (10));
            }
            catch (UnauthorizedAccessException)
            {
                MessageBox.Show ("Location service is turned off by system settings.");
            }
            catch (Exception ex)
            {
            }
            MyCoordinates.Add (new GeoCoordinate (MyGeoPosition.Coordinate.Latitude, MyGeoPosition.Coordinate.Longitude));



            Mygeocodequery = new GeocodeQuery ();
            Mygeocodequery.SearchTerm = "Optical Valley Venture Street";
            Mygeocodequery.GeoCoordinate = new GeoCoordinate (MyGeoPosition.Coordinate.Latitude, MyGeoPosition.Coordinate.Longitude);

            Mygeocodequery.QueryCompleted + = Mygeocodequery_QueryCompleted;
            Mygeocodequery.QueryAsync ();


        }
        void Mygeocodequery_QueryCompleted (object sender, QueryCompletedEventArgs <IList <MapLocation >> e)
        {
            if (e.Error == null)
            {
                MyQuery = new RouteQuery ();
                MyCoordinates.Add (e.Result [0] .GeoCoordinate);
                MyQuery.Waypoints = MyCoordinates;
                MyQuery.QueryCompleted + = MyQuery_QueryCompleted;
                MyQuery.QueryAsync ();
                Mygeocodequery.Dispose ();
            }
        }

        void MyQuery_QueryCompleted (object sender, QueryCompletedEventArgs <Route> e)
        {
            if (e.Error == null)
            {
                // Get specific itinerary
                Route MyRoute = e.Result;
                MapRoute MyMapRoute = new MapRoute (MyRoute);
                MyMap.AddRoute (MyMapRoute);
                List <string> RouteList = new List <string> ();
                foreach (RouteLeg leg in MyRoute.Legs)
                {
                    foreach (RouteManeuver maneuver in leg.Maneuvers)
                    {
                        RouteList.Add (maneuver.InstructionText);
                    }
                }

                RouteLLS.ItemsSource = RouteList;
                MyQuery.Dispose ();
            }
        }

    }
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.