qq70191 发表于 2015-5-23 10:33:18

windows 8 metro 关于定位

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);
}
}
}

  
  
页: [1]
查看完整版本: windows 8 metro 关于定位