| 
 | 
	
 
 
1、概述 
 
 
-   地理定位的方式有四种:wifi, ip地址, 手机基站, GPS。
 
 
 -   win8内置了wifi, ip地址两种方式,wifi定位的精度在350米左右,ip地址的精度在25千米。
 
 
 -   win8定位服务不提供朝向,高度,速度,地址等数据。
 
 
 -   当需要用定位服务时,需要显式地提醒用户,并在window8的隐私设置里打开定位服务。
 
 
 - 在应用能力里打开位置服务。
 
 
  
2、指导方针 
 
 
-   只调用一次定位的请求,用getGeopostionAsync()方法。
 
 
 -   设置轨迹数据变化阈值,通过设置MovementThreshold属性,当在此值的范围之外变化时,才触发PositionChanged事件,比如城市间的天气变化。
 
 
 -   设置位置数据报告频率,通过设置ReportInterval属性,为0时,则实时变化。注意:有些设备设置此属性可能无用。
 
 
 -   设置精度,通过设置DesiredAccuracy属性,当精度为高时,才会调用GPS。
 
 
 -   启动延迟,可能会有2秒,注意不要阻塞UI。
 
 
 -   后台运行,当应用挂起时,数据不会更新,所以考虑后台运行。
 
 
 - 捕获StatusChanged事件,了解位置服务可用状态。
 
 - 当用户禁止了位置服务时,调用getGeopostionAsync()会报异常,LocationStatus值是disable,这时需要提醒用户去开启位置服务。
 
 - 当状态不可用时,应该清除缓存数据。
 
 - 当用户重新开启位置功能时,不会有任何事件产生,只有依靠程序请求数据来得到这个事件。
 
 - 当应用从挂起到激活时,应当重新获取位置数据。
 
 - 提供一个刷新按钮让用户去重新获取位置数据。
 
 - 建议提示"Your location is currently turned off. Change your settings through the Settings charm to turn it back on.”
 
 - 如果位置不是重要信息,就用通知就行,如果位置是重要信息,比如地图,就用flyout.
 
 
  
3、C#示例 
  获取位置数据 
 
 
 
using System; 
using System.Collection.Generic; 
using System.Linq; 
using System.Threading.Tasks; 
using Windows.Foundation; 
using Windows.UI.DirectUI; 
using Windows.UI.DirectUI.Controls; 
using Windows.UI.DirectUI.Data; 
using Windows.Devices.Geolocation; 
namespace GeolocationSample 
{ 
partial class MainPage 
{ 
Geolocator geo = null; 
public MainPage() 
{ 
InitializeComponent(); 
} 
private async void button1_Click( 
object sender, RoutedEventArgs e) 
{ 
if (geo == null) 
{ 
geo = new Geolocator(); 
} 
IGeoposition pos = await geo.GetGeopositionAsync();             
textblockLatitude.Text = "Latitude: " + pos.Coordinate.Latitude.ToString(); 
textblockLongitude.Text = "Longitude: " + pos.Coordinate.Longitude.ToString(); 
textblockAccuracy.Text = "Accuracy: " + pos.Coordinate.Accuracy.ToString(); 
} 
} 
} 
 
   
  获取位置变化情况数据 
 
 
 
using System; 
using System.Collection.Generic; 
using System.Linq; 
using System.Threading.Tasks; 
using Windows.Foundation; 
using Windows.UI.Core; 
using Windows.UI.DirectUI; 
using Windows.UI.DirectUI.Controls; 
using Windows.UI.DirectUI.Data; 
using Windows.Devices.Geolocation; 
namespace GeolocationEventsSample 
{ 
partial class MainPage 
{ 
private Geolocator geo = null; 
private CoreDispatcher _cd; 
public MainPage() 
{ 
InitializeComponent(); 
_cd = Window.Current.CoreWindow.Dispatcher; 
} 
private void button1_Click(object sender, RoutedEventArgs e) 
{ 
if (geo == null) 
{ 
geo = new Geolocator(); 
} 
if (geo != null) 
{ 
geo.PositionChanged +=  
new TypedEventHandler(geo_PositionChanged); 
} 
} 
private void button2_Click(object sender, RoutedEventArgs e) 
{ 
if (geo != null) 
{ 
geo.PositionChanged -= new TypedEventHandler (geo_PositionChanged); 
} 
} 
private void geo_PositionChanged(Geolocator sender, PositionChangedEventArgs e) 
{ 
_cd.InvokeAsync(CoreDispatcherPriority.Normal, (s, a) => 
{ 
IGeoposition pos = (a.Context as IPositionChangedEventArgs).Position; 
textLatitude.Text = "Latitude: " + pos.Coordinate.Latitude.ToString(); 
textLongitude.Text = "Longitude: " + pos.Coordinate.Longitude.ToString(); 
textAccuracy.Text = "Accuracy: " + pos.Coordinate.Accuracy.ToString(); 
}, this, e); 
} 
} 
} 
 
   
  设置位置数据变化阈值 
 
 
 
 
using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using Windows.Foundation; 
using Windows.Foundation.Collections; 
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; 
using Windows.UI.Core; 
using Windows.Devices.Geolocation; 
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 
namespace GeolocationAdjustDistance 
{ 
///  
/// An empty page that can be used on its own or navigated to within a Frame. 
///  
public sealed partial class BlankPage : Page 
{ 
private Geolocator geo = null; 
private CoreDispatcher _cd; 
private double prevLatitude = -1; 
private double prevLongitude = -1; 
private double totalDistance = 0; 
public BlankPage() 
{ 
this.InitializeComponent(); 
_cd = Window.Current.CoreWindow.Dispatcher; 
} 
///  
/// Invoked when this page is about to be displayed in a Frame. 
///  
/// Event data that describes how this page was reached.  The Parameter 
/// property is typically used to configure the page. 
protected override void OnNavigatedTo(NavigationEventArgs e) 
{ 
} 
private void Button_Click_1(object sender, RoutedEventArgs e) 
{ 
if (geo == null) 
{ 
geo = new Geolocator(); 
} 
if (geo != null) 
{ 
geo.PositionChanged += new TypedEventHandler(geo_PositionChanged); 
geo.StatusChanged += new TypedEventHandler(geo_StatusChanged); 
geo.MovementThreshold = float.Parse(tbThreshold.Text); 
tbThreshold.IsEnabled = false; 
TextBox1.Text = "Tracking Started " +  
"(Time, Latitude, Longitude, Distance)\n"; 
} 
} 
private void Button_Click_2(object sender, RoutedEventArgs e) 
{ 
if (geo != null) 
{ 
geo.PositionChanged -= new TypedEventHandler(geo_PositionChanged); 
geo.StatusChanged -= new TypedEventHandler(geo_StatusChanged); 
TextBox1.Text += "\nTracking Stopped.\n" + 
"Total Distance recorded: " + 
totalDistance.ToString("F2") + " m\n"; 
tbThreshold.IsEnabled = true; 
} 
} 
private double CalculateDistance(double prevLat, double prevLong, double currLat, double currLong) 
{ 
const double degreesToRadians = (Math.PI / 180.0); 
const double earthRadius = 6371; // kilometers 
// convert latitude and longitude values to radians 
var prevRadLat = prevLat * degreesToRadians; 
var prevRadLong = prevLong * degreesToRadians; 
var currRadLat = currLat * degreesToRadians; 
var currRadLong = currLong * degreesToRadians; 
// calculate radian delta between each position. 
var radDeltaLat = currRadLat - prevRadLat; 
var radDeltaLong = currRadLong - prevRadLong; 
// calculate distance 
var expr1 = (Math.Sin(radDeltaLat / 2.0) * 
Math.Sin(radDeltaLat / 2.0)) + 
(Math.Cos(prevRadLat) *  
Math.Cos(currRadLat) * 
Math.Sin(radDeltaLong / 2.0) *  
Math.Sin(radDeltaLong / 2.0)); 
var expr2 = 2.0 * Math.Atan2(Math.Sqrt(expr1),  
Math.Sqrt(1 - expr1)); 
var distance = (earthRadius * expr2);  
return distance * 1000;  // return results as meters 
} 
void geo_PositionChanged(Geolocator sender, PositionChangedEventArgs args) 
{ 
_cd.InvokeAsync(CoreDispatcherPriority.Normal, (s, a) => 
{ 
Geoposition pos = (a.Context as IPositionChangedEventArgs).Position; 
double updateDistance = 0; 
// Calculate distance; 
if ( ( prevLatitude == -1 ) || ( prevLongitude == -1 ) )  
{ 
updateDistance = 0; 
} else { 
updateDistance = CalculateDistance( prevLatitude, prevLongitude,  
pos.Coordinate.Latitude, pos.Coordinate.Longitude ); 
} 
// Update tracking 
prevLatitude = pos.Coordinate.Latitude; 
prevLongitude = pos.Coordinate.Longitude; 
totalDistance += updateDistance; 
// display the results. 
TextBox1.Text += "Position Update: " + 
pos.Coordinate.Timestamp.ToString("T") + ", " + 
pos.Coordinate.Latitude.ToString("F3") + ", " + 
pos.Coordinate.Longitude.ToString("F3") + ", " + 
updateDistance.ToString("F2") + " m\n"; 
}, this, args); 
} 
void geo_StatusChanged(Geolocator sender, StatusChangedEventArgs args) 
{ 
var newStatus = args.Status; 
var strStatus = ""; 
switch (newStatus) 
{ 
case PositionStatus.Ready:  
strStatus = "Location is available."; 
break; 
case PositionStatus.Initializing: 
strStatus = "Geolocation service is initializing."; 
break; 
case PositionStatus.NoData: 
strStatus = "Location service data is not available."; 
break; 
case PositionStatus.Disabled: 
strStatus = "Location services are disabled. Use the " + 
"Settings charm to enable them."; 
break; 
case PositionStatus.NotInitialized: 
strStatus = "Location status is not initialized because " + 
"the app has not yet requested location data."; 
break; 
case PositionStatus.NotAvailable: 
strStatus = "Location services are not supported on your system."; 
break; 
default: 
strStatus = "Unknown PositionStatus value (" +  
newStatus.ToString() + ")."; 
break; 
} 
_cd.InvokeAsync(CoreDispatcherPriority.Normal, (s, a) => 
{ 
TextBox1.Text += strStatus + "\n"; 
}, this, args); 
} 
} 
} 
 
   
   |   
 
 
 
 | 
  
 |