與眾不同 windows phone (44) - 8.0 位置和地圖
作者:webabcd
介紹
與眾不同 windows phone 8.0 之 位置和地圖
- 位置(GPS) - Location API
- 諾基亞地圖
示例
1、演示新 Location API 的應用
GPS/Demo.xaml
<phone:PhoneApplicationPage x:Class="Demo.GPS.Demo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" mc:Ignorable="d" shell:SystemTray.IsVisible="True"> <Grid x:Name="LayoutRoot"> <StackPanel> <TextBlock Name="lblMsg" TextWrapping="Wrap" /> <Button x:Name="btnDemo" Content="通過 GPS 獲取當前位置" Click="btnDemo_Click" /> </StackPanel> </Grid> </phone:PhoneApplicationPage>
GPS/Demo.xaml.cs
/* * 演示新 Location API 的應用 * * wp7 時代的 Location API 也是支持的(能不用就別用了),參見:http://www.cnblogs.com/webabcd/archive/2012/08/09/2629636.html * * * 注: * 1、需要在 manifest 中增加配置 <Capability Name="ID_CAP_LOCATION" /> * 2、在獲取位置數據之前,需要提供隱私策略並得到用戶的允許 * 3、目前 wp 機器的位置提供程序都是 GPS */ using System; using System.Windows; using Microsoft.Phone.Controls; using Windows.Devices.Geolocation; namespace Demo.GPS { public partial class Demo : PhoneApplicationPage { // 新的 Location API Geolocator geolocator; public Demo() { InitializeComponent(); } protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) { geolocator = new Geolocator(); // 期望的精度級別(PositionAccuracy.Default 或 PositionAccuracy.High) geolocator.DesiredAccuracy = PositionAccuracy.High; // 期望的數據精度(米) geolocator.DesiredAccuracyInMeters = 50; // 移動距離超過此值后,觸發 PositionChanged 事件 geolocator.MovementThreshold = 100; // 在兩次位置更新的時間點中間,請求位置數據的最小間隔(毫秒) geolocator.ReportInterval = 0; // 位置更新時觸發的事件 geolocator.PositionChanged += geolocator_PositionChanged; // 位置服務的狀態發生改變時觸發的事件 geolocator.StatusChanged += geolocator_StatusChanged; base.OnNavigatedTo(e); } protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e) { geolocator.PositionChanged -= geolocator_PositionChanged; geolocator.StatusChanged -= geolocator_StatusChanged; geolocator = null; base.OnNavigatedFrom(e); } private async void btnDemo_Click(object sender, RoutedEventArgs e) { try { // 獲取位置信息 Geoposition geoposition = await geolocator.GetGeopositionAsync(); lblMsg.Text = "位置精度(米): " + geoposition.Coordinate.Accuracy.ToString(); lblMsg.Text += Environment.NewLine; lblMsg.Text += "海拔精度(米): " + geoposition.Coordinate.AltitudeAccuracy.ToString(); lblMsg.Text += Environment.NewLine; lblMsg.Text += "緯度: " + geoposition.Coordinate.Latitude.ToString("0.00"); lblMsg.Text += Environment.NewLine; lblMsg.Text += "經度: " + geoposition.Coordinate.Longitude.ToString("0.00"); lblMsg.Text += Environment.NewLine; lblMsg.Text += "海拔(米): " + geoposition.Coordinate.Altitude.ToString(); lblMsg.Text += Environment.NewLine; lblMsg.Text += "行進方向(相對於正北的度數): " + geoposition.Coordinate.Heading.ToString(); lblMsg.Text += Environment.NewLine; lblMsg.Text += "行進速度(米/秒): " + geoposition.Coordinate.Speed.ToString(); lblMsg.Text += Environment.NewLine; lblMsg.Text += "確定位置的時間(UTC0): " + geoposition.Coordinate.Timestamp.ToString("yyyy-MM-dd hh:mm:ss"); lblMsg.Text += Environment.NewLine; lblMsg.Text += "數據源(Satellite, WiFi, Cellular): " + geoposition.Coordinate.PositionSource.ToString(); lblMsg.Text += Environment.NewLine; lblMsg.Text += "衛星的位置精度衰減: " + geoposition.Coordinate.SatelliteData.PositionDilutionOfPrecision.ToString(); lblMsg.Text += Environment.NewLine; lblMsg.Text += "衛星的水平精度衰減: " + geoposition.Coordinate.SatelliteData.HorizontalDilutionOfPrecision.ToString(); lblMsg.Text += Environment.NewLine; lblMsg.Text += "衛星的垂直精度衰減: " + geoposition.Coordinate.SatelliteData.VerticalDilutionOfPrecision.ToString(); lblMsg.Text += Environment.NewLine; lblMsg.Text += Environment.NewLine; if (geoposition.CivicAddress != null) { lblMsg.Text = "國家名稱: " + geoposition.CivicAddress.Country; lblMsg.Text += Environment.NewLine; lblMsg.Text = "省名稱: " + geoposition.CivicAddress.State; lblMsg.Text += Environment.NewLine; lblMsg.Text = "城市名稱: " + geoposition.CivicAddress.City; lblMsg.Text += Environment.NewLine; lblMsg.Text = "郵編: " + geoposition.CivicAddress.PostalCode; lblMsg.Text += Environment.NewLine; lblMsg.Text = "確定位置的時間(UTC0): " + geoposition.CivicAddress.Timestamp; } } catch (Exception ex) { if ((uint)ex.HResult == 0x80004004) { lblMsg.Text = "定位服務當前是關閉狀態,請打開它"; } else { lblMsg.Text = ex.ToString(); } } } // 位置服務的狀態變化了 void geolocator_StatusChanged(Geolocator sender, StatusChangedEventArgs args) { // 獲取位置服務的狀態 PositionStatus status = geolocator.LocationStatus; // 獲取位置服務的狀態 status = args.Status; switch (args.Status) { case PositionStatus.Disabled: // 位置提供程序已禁用,即用戶尚未授予應用程序訪問位置的權限 break; case PositionStatus.Initializing: // 初始化中 break; case PositionStatus.NoData: // 無有效數據 break; case PositionStatus.Ready: // 已經准備好了相關數據 break; case PositionStatus.NotAvailable: // 位置服務傳感器不可用 break; case PositionStatus.NotInitialized: // 尚未初始化 break; } } // 位置變化了 void geolocator_PositionChanged(Geolocator sender, PositionChangedEventArgs args) { this.Dispatcher.BeginInvoke(delegate() { Geoposition geoposition = args.Position; lblMsg.Text = "緯度: " + geoposition.Coordinate.Latitude.ToString("0.00"); lblMsg.Text += Environment.NewLine; lblMsg.Text += "經度: " + geoposition.Coordinate.Longitude.ToString("0.00"); }); } } }
2、演示諾基亞地圖的應用
Map/Demo.xaml
<phone:PhoneApplicationPage x:Class="Demo.Map.Demo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" mc:Ignorable="d" shell:SystemTray.IsVisible="True" xmlns:maps="clr-namespace:Microsoft.Phone.Maps.Controls;assembly=Microsoft.Phone.Maps"> <Grid x:Name="LayoutRoot" Background="Transparent"> <StackPanel> <!-- Microsoft.Phone.Maps.Controls.Map - 諾基亞地圖 CenterChanged - 地圖的中心點發生變化時觸發的事件 --> <maps:Map x:Name="map" Width="480" Height="440" CenterChanged="map_CenterChanged" /> <StackPanel Orientation="Horizontal"> <Button Name="btnRoad" Content="道路圖" Click="btnRoad_Click" /> <Button Name="btnAerial" Content="衛星圖" Click="btnAerial_Click" /> </StackPanel> <StackPanel Orientation="Horizontal"> <Button Name="btnHybrid" Content="衛星圖疊加道路圖" Click="btnHybrid_Click" /> <Button Name="btnTerrain" Content="自然地形疊加道路圖" Click="btnTerrain_Click" /> </StackPanel> <StackPanel Orientation="Horizontal"> <Button Name="btnZoomIn" Content="放大" Click="btnZoomIn_Click" /> <Button Name="btnZoomOut" Content="縮小" Click="btnZoomOut_Click" /> </StackPanel> <StackPanel Orientation="Horizontal"> <Button Name="btnMoveTop" Content="上移" Click="btnMoveTop_Click" /> <Button Name="btnMoveBottom" Content="下移" Click="btnMoveBottom_Click" /> <Button Name="btnMoveLeft" Content="左移" Click="btnMoveLeft_Click" /> <Button Name="btnMoveRight" Content="右移" Click="btnMoveRight_Click" /> </StackPanel> <TextBlock Name="lblMsg" /> </StackPanel> </Grid> </phone:PhoneApplicationPage>
Map/Demo.xaml.cs
/* * 演示諾基亞地圖的應用 * * * 本例僅用於說明諾基亞地圖的基本使用方式,更多的內容,如:路線繪制,圖釘等功能請參見 Microsoft.Phone.Maps.Controls.Map 控件文檔和 Windows Phone Toolkit 文檔 * * * 注: * 1、需要在 manifest 中增加配置 <Capability Name="ID_CAP_MAP" /> * 2、相關的 Launcher 參見本項目的 Launchers 文件夾內的地圖相關的演示 * 3、Bing 地圖雖然仍可用,但是能不用就別用了 * 4、關於 pin 之類的地圖擴展,請使用 Windows Phone Toolkit,參見 http://phone.codeplex.com/ * * * 另:與地圖相關的協議說明如下,你的 app 如果支持這些協議將會在用戶請求時啟動(只有你一個 app 支持時)或出現在啟動列表中(多個 app 支持時) * 1、駕車到指定地點:ms-drive-to:?destination.latitude=<latitude>&destination.longitude=<longitude>&destination.name=<name> * 2、散步到指定地點:ms-walk-to:?destination.latitude=<latitude>&destination.longitude<longitude>&destination.name=<name> */ using System.Windows; using Microsoft.Phone.Controls; using System.Device.Location; using Microsoft.Phone.Maps.Controls; namespace Demo.Map { public partial class Demo : PhoneApplicationPage { // 地圖的中心點,經緯度坐標 private GeoCoordinate _center; // ZoomLevel: 1 - 最小, 20 - 最大 private double _zoomLevel = 16; // Heading: 0 到 360 之間的任意數字。例:上為正北則為0,上為正西則為90,上為正南則為180,上為正東則為270 private double _heading = 0; // Pitch: 0 到 180 之間的任意數字,代表地圖繞 X 軸傾斜的角度(以實現 3D 效果) private double _pitch = 15; public Demo() { InitializeComponent(); this.Loaded += Demo_Loaded; } void Demo_Loaded(object sender, RoutedEventArgs e) { map.LandmarksEnabled = true; // 是否顯示地標(ZoomLevel 16 級以上才會顯示) map.PedestrianFeaturesEnabled = true; // 是否顯示步行街(ZoomLevel 16 級以上才會顯示) map.ColorMode = MapColorMode.Light; // 顏色模式(Light 或 Dark) _center = new GeoCoordinate(39.909, 116.397); // map.Center = _center; // map.ZoomLevel = _zoomLevel; // map.Heading = _heading; // map.Pitch = _pitch; // SetView() - 通過指定的 Center, ZoomLevel, Heading, Pitch, MapAnimationKind 參數來顯示地圖 // MapAnimationKind - 代表地圖過渡時的動畫效果。None:無動畫;Linear:線性動畫;Parabolic:拋物線動畫 map.SetView(_center, _zoomLevel, _heading, _pitch, MapAnimationKind.Parabolic); } private void btnRoad_Click(object sender, RoutedEventArgs e) { // 道路地圖 map.CartographicMode = MapCartographicMode.Road; } private void btnAerial_Click(object sender, RoutedEventArgs e) { // 衛星地圖 map.CartographicMode = MapCartographicMode.Aerial; } private void btnHybrid_Click(object sender, RoutedEventArgs e) { // 衛星地圖上疊加道路地圖 map.CartographicMode = MapCartographicMode.Hybrid; } private void btnTerrain_Click(object sender, RoutedEventArgs e) { // 自然地形地圖上疊加道路地圖 map.CartographicMode = MapCartographicMode.Terrain; } private void btnZoomIn_Click(object sender, RoutedEventArgs e) { // 放大地圖 map.SetView(_center, ++_zoomLevel, _heading, _pitch, MapAnimationKind.Linear); } private void btnZoomOut_Click(object sender, RoutedEventArgs e) { // 縮小地圖 map.SetView(_center, --_zoomLevel, _heading, _pitch, MapAnimationKind.Linear); } private void btnMoveTop_Click(object sender, RoutedEventArgs e) { // 上移地圖,可以看到地圖切換時線性過渡的效果(MapAnimationKind.Linear) _center = new GeoCoordinate(map.Center.Latitude + 0.1, map.Center.Longitude); map.SetView(_center, _zoomLevel, _heading, _pitch, MapAnimationKind.Linear); } private void btnMoveBottom_Click(object sender, RoutedEventArgs e) { // 下移地圖,可以看到地圖切換時線性過渡的效果(MapAnimationKind.Linear) _center = new GeoCoordinate(map.Center.Latitude -0.1, map.Center.Longitude); map.SetView(_center, _zoomLevel, _heading, _pitch, MapAnimationKind.Linear); } private void btnMoveLeft_Click(object sender, RoutedEventArgs e) { // 左移地圖,可以看到地圖切換時拋物線過渡的效果(MapAnimationKind.Parabolic) _center = new GeoCoordinate(map.Center.Latitude, map.Center.Longitude - 0.1); map.SetView(_center, _zoomLevel, _heading, _pitch, MapAnimationKind.Parabolic); } private void btnMoveRight_Click(object sender, RoutedEventArgs e) { // 右移地圖,可以看到地圖切換時拋物線過渡的效果(MapAnimationKind.Parabolic) _center = new GeoCoordinate(map.Center.Latitude, map.Center.Longitude + 0.1); map.SetView(_center, _zoomLevel, _heading, _pitch, MapAnimationKind.Parabolic); } private void map_CenterChanged(object sender, MapCenterChangedEventArgs e) { // CenterChanged - 中心點發生變化時觸發的事件 // 類似的事件還有:CartographicModeChanged, HeadingChanged, PitchChanged, ZoomLevelChanged, ViewChanging, ViewChanged 等等 lblMsg.Text = string.Format("經度:{0},緯度{1}", map.Center.Longitude, map.Center.Latitude); } } }
OK
[源碼下載]