65.9K
CodeProject 正在变化。 阅读更多。
Home

Resco.Location 库中的 GPS 和基于位置的服务

2011 年 4 月 6 日

CPOL

12分钟阅读

viewsIcon

33467

本文讨论了如何在移动设备上捕获位置信息以及如何将这些信息用于基于位置的服务,例如获取驾车路线、创建自定义地图等。本文还介绍了 Resco.Location 库,该库提供了相应的 W.

本文讨论了如何在移动设备上捕获位置信息以及如何将这些信息用于基于位置的服务,例如获取驾车路线、创建自定义地图等。本文还介绍了 Resco.Location 库,该库为 Windows Mobile 和 Windows Phone 7 平台提供了相应的高级 .NET 类。

引言

如今,移动设备上的 GPS 应用越来越流行,并且具有广泛的应用前景。移动 GPS 服务的流行应用示例包括:

  • 物流 - 跟踪司机、卡车和货物
  • 旅游 - 客户导航至酒店,游客可以跟踪最受欢迎的景点
  • 车队定位 - 跟踪船舶,计算预计到达时间等。
  • 人员跟踪 - 跟踪外勤销售人员的位置等。

现代移动设备通常具有位置感知功能。例如,所有 Windows Phone 7 手机都内置了 GPS 接收器。另一方面,也存在基于位置的服务——网络服务,可以将原始 GPS 信息转换为有用的内容,例如地图、地址、驾车路线等。所有这些服务通常统称为地图服务。

地图服务有各种实现。也许最知名的例子是 Google Maps 和 Bing Maps。地图服务相当复杂,并且使用起来非常不简单。

文章从解释位置基础知识开始 - GPS 坐标及其与地理地图的关系。在下一部分,我们将讨论 Google Maps 与 Bing Maps - 它们的可能性和局限性。在最后一部分,我们将介绍 Resco.Location 库,该库提供了使用 GPS 数据和基于位置服务的高级接口。

该库是Resco MobileForms Toolkit 的一部分,目前支持两个平台 - Windows Mobile 和 Windows Phone 7。

必备组件

目标受众是 C# .NET 程序员。不需要了解 Silverlight。

低级别 GPS 数据

地理坐标系

地理坐标通过两个数字描述地球上的每个位置

  • 纬度衡量从赤道向南极或北极的夹角。(赤道纬度为零。)
  • 经度表示从经过格林威治附近的参考子午线(本初子午线)向东或向西的角度。

在下文中,我们将使用“GPS 坐标”一词代替较长的“纬度/经度坐标系统”。下图(来自维基百科)显示了 GPS 坐标。

image1.png

获取 GPS 坐标

全球定位系统(GPS)是一个全球导航卫星系统,可提供可靠的位置和时间信息。它由美国政府维护,任何拥有 GPS 接收器的人都可以免费访问。

GPS 接收器通过 GPS 卫星发送的信号计算其位置。(使用四颗或更多卫星来计算位置。)GPS 接收器还报告海拔高度,即海平面以上的高度。

除了位置数据,移动电话中的低级别 GPS 软件还可以提供额外信息,例如

  • 航向(WP7 使用内置指南针实现此目的)
  • 速度(根据接收到的 GPS 数据计算得出)
  • 生成信息的盖章

手机上 GPS 信息的可用性

WP7 内置 GPS 接收器。系统 API(GeoCoordinateWatcher 类)允许您选择低精度数据,在这种情况下,将使用来自蜂窝网络的信号而不是 GPS 接收器。

此方法提供的结果不够准确,但更节能。

GPS 和 Resco.Location 库

GpsDevice 类提供了接收 GPS 信息的主要接口。您可以启动/停止数据接收并响应 PositionChanged 事件。WP7 用户会发现此接口与内置的 GeoCoordinateWatcher 类非常相似。确实如此。此类别的目的是统一不同平台上的代码库。

GpsTracking 类可用于获取平滑的折线,该折线描述了在跟踪激活期间的移动。
接收 GPS 信号还不够。您必须以某种方式将其呈现给用户,即在地图上显示或以易于理解的形式描述。这可以通过使用 Resco.Location 库支持的地理服务来完成,正如本文其余部分所讨论的。

基于位置的服务

GPS 坐标和地图

地球表面近似为一个椭球体。我们都知道的地图是地球表面的平面投影。地图通常使用 UTM(通用横轴墨卡托)坐标系。UTM 不是单一的地图投影,而是一系列投影,每个投影都适用于局部区域。有六十个这样的区域,并且这些区域部分重叠。

GPS 和 UTM 坐标之间的转换仅是近似的,并且误差在区域边界处会增加。不同的 UTM 区域使用不同的 GPS/UTM 转换公式。

要吸取的教训

在不知道地图是如何构造的情况下,您无法在地图上精确显示 GPS 点。(即,它属于哪个 UTM 区域。)

作者在尝试构建 GPS 跟踪系统时获得了个人经验 - 在城市地图上显示移动汽车的 GPS 坐标。使用错误的 UTM 公式,汽车会平行于道路行驶,而误差远大于 GPS 接收器的精度。

稍后讨论的 Google 和 Bing 地图服务提供了一个部分解决方案:它们不仅提供地图,还会在地图上绘制兴趣点。换句话说,它们为您解决了复杂的 UTM/GPS 转换问题。

这对于路线规划甚至低刷新率的 GPS 跟踪等应用程序来说已经足够了。但是,如果您需要实时 GPS 跟踪,或者需要最大程度地减少网络流量(地图是图像),那么您别无选择,只能深入研究复杂的 UTM 主题。

Web 地图服务

这些服务通过网络提供地图及相关数据(例如 GIS 数据,例如水文数据,土地评估...)。

您应该注意与 Web 地图相关的缺点/问题

  • 互联网和 Web 服务器的可靠性。
  • Web 地图需要相对较高的带宽。
  • 有限的屏幕空间
  • 许多 Web 地图质量较差(因地区而异)
  • 版权和隐私问题

有很多 Web 地图服务,通常提供非常不同的服务;您可以在此处找到一个不错的比较:http://en.wikipedia.org/wiki/Comparison_of_web_map_services

Resco.Location 库支持的 Web 地图服务

目前,Resco.Location 库支持 Bing Maps 和 Google Maps 服务。稍后可能会添加其他提供商,例如 Yahoo 或 OpenStreetMap。

您必须选择提供商(Google 或 Bing),然后开始使用高级 .Net 类。除了细微差异外,两个提供商都提供相同的服务。

就地图而言,Resco.Location 只提供静态地图。这些地图以光栅图像(png/jpg/gif)形式提供,并且可以与其他信息结合 - 标记(下图显示了位于四个位置的标记)或突出显示的路线。

image2.png

除了核心功能(地图)之外,Google 和 Bing 还提供其他服务。Resco.Location 库支持其中两项服务

  1. 路线规划确定给定位置之间的路线。路线规划是为驾驶/步行/骑自行车设计的,并且可以进行优化以最大程度地减少成本/交通/距离。您可以选择性地提供在路线中要访问的位置 - 所谓的航点。路线规划可以以文本形式(一系列指令,例如“左转”)或视觉形式(在地图上显示路线)提供。
  2. 地理编码是将市民地址(例如“221B Baker Street, London”(是的,福尔摩斯)和地理坐标(例如本例中的)相互转换的过程。
       纬度:51.523700;经度:-0.158600

虽然市民地址更适合报告,但通过放置标记等方式可以轻松地在地图上显示 GPS 点。

不要尝试自己操作地图(例如,通过绘制标记) - 您会遇到各种问题

  • 地图信息的可靠性
  • GPS/UTM 转换错误
  • 法律问题

地图 API 非常强大,可以为您做很多事情。(即使是快速交互式 GPS 跟踪之类的事情也不包括在内。)

地图 API 的使用条件

即使服务乍看起来是免费的,但并非如此。Google 和 Microsoft 都施加了限制、条件和付费服务。

使用 Google Maps Web 服务

Resco.Location 涵盖 3 项服务

  • Google Static Maps API(下载地图图像)
  • Google Geocoding API(GPS 地址与市民地址之间的翻译)
  • Google Directions API(请求路线方向)

未涵盖海拔和地点 API。已弃用的服务也不受支持 - 例如,Google Geocoding V2 API。
以下限制适用于(普通用户)

  • 每位查看者每天 1000 个唯一的(不同的)图像请求。
  • 地理编码 API:每天 2500 个请求
  • Directions API:每天 2500 个请求,最多 8 个中间航点

此外

  • 地图只能在浏览器内容中显示(不允许在浏览器外部使用静态地图。)
  • Directions/Geocoding 结果只能用于显示与 Google 地图相关的结果;禁止无关用途。
  • Directions API 会生成版权信息,必须以某种方式显示给用户。

还有另一个正式标准

请求(地图/地理编码/地理路线)被编码到一个 URL 中,该 URL 被发送到相应的 Web 服务。这些 URL 限制为 2048 个字符(在 URL 编码之前)。例如,在请求过多标记时,您很容易超出此限制。

Google Maps API Premier

您可以购买 Google Maps API Premier,享受多项优势

  • 服务级别协议提供 99.9% 的正常运行时间保证
  • 价格基于地图查看次数,起价为 10 美元/年。
  • Https 支持(Resco.Location 不支持)

Premier API 限制(可购买更高的限制。)

  • 地理编码 API:每天 100,000 个请求
  • Directions API:每天 100,000 个请求,每次请求最多 23 个航点
  • 地图:允许在查看器外部显示图像

购买 Google Maps API Premier 后,您将收到一个Google API 密钥,该密钥需要与所有请求一起使用。(请参阅 ServiceSettings 类。)

使用 Bing Maps Web 服务

Bing Maps API 代表了许多接口。其中之一 - Bing Maps REST Services - 在 Resco.Location 库中使用。(另一个有趣的例子是 Bing Maps Silverlight 控件,例如在 Windows Phone 7 上可用。)

您必须拥有 Bing Maps 开发人员帐户才能为您的应用程序获取Bing Maps 密钥。此密钥包含在每个位置/路线/地图请求中,并由 Microsoft 用于计算事务。(请参阅 ServiceSettings 类。)

Microsoft 对免费事务施加了非常宽松的限制,即

  • 每天 50,000 笔交易
  • 每年 500,000 笔交易

此外

  • 您必须显示 Bing 徽标和版权。
  • 禁止“实时”导航
  • 您不得将 Bing Maps 与其他地图平台集成(即,只使用 Bing 或 Google,但不能同时使用两者)

(Bing Maps 的完整使用条款(http://www.microsoft.com/maps/product/terms.html)过于复杂,无法在此处复制。)
可以协商更高的限制和更宽松的条件。

Resco.Location 库

接下来,我们将介绍 Resco.Location 库中实现的主要类。提供的类描述非常简略 - 编写得易于您了解所提供的功能。所有不必要的信息都已删除。(例如,省略了 public 关键字,属性仅按名称列出等。)

服务实现方案

所有服务类(GeoCode、GeoRoute、GeoMap)都遵循相同的方案

  • 它们允许用户设置请求
  • 请求被转换为 URL
  • URL 被发送到相应的 Web 服务
  • 服务响应被解析并转换为用户可理解的形式

所有服务类都实现了基于事件的异步模式,允许多个并发调用。同步模式仅在 WM 平台实现。

这是用于所有服务类的模式

class SomeService
{
	// 1. Members defining the request are service-dependent
	...
 
	// 2. Async request; parameters are service-dependent
    	void GetXXXAsync( ...parameters..., object userState)
 
	// 3. Event signaling request completion (success or failure)
    	event EventHandler<GetXXXCompletedEventArgs> GetXXXCompleted;
 
	// Synchronous interface is supported on WM platform only
	#if !SILVERLIGHT
		GeoPoint GetXXX(...parameters...)
	#endif
}
 
class GetXXXCompletedEventArgs : AsyncCompletedEventArgs
{
	// Definition of the properties containing the result (Address, Route...)
	// Note you cannot access results when Error!=null (an exception is thrown)
	....
 
	// Getters inherited from System.ComponentModel.AsyncCompletedEventArgs
	bool Cancelled			// Returns false (Cancel unsupported)
	Exception Error			// Error information; null on successful termination
	Object UserState		// Object passed to the async call
}

命名空间 Resco.Location

该命名空间包含其他更专业命名空间使用的基本类。

// Helper class providing distance conversions
struct GeoDistance
{
    GeoDistance(double meters)
 
    double Meters, Kilometers, Feet, Yards, Miles, NauticalMiles	// Conversion properties
    operators <, <=, >, >=, ==, !=, +, -, *, /
    string ToString()		// Uses format from ServiceSettings.DefaultUnitSystem
}
 
// GPS point with string conversions and distance computation
class GeoPoint
{
    GeoPoint(GeoPoint p)
    GeoPoint(double lat, lon)
 
    double Latitude, Longitude		// point coordinates
 
    GeoPoint Move(lat, lon)			// this += [lon,lat]
    GeoDistance GetDistanceTo(GeoPoint other)	// (Approximate) distance between GPS points
 
    // String conversions support common formats such as 40:26:46.302N, 
    // 40°26'21"N, 79d 58' 36" W, 40.446195N
    GeoPoint(string str)
    GeoPoint(string lat, string lon)
    string ToString( eGPSFormat fmt, string delimiter)	// a number of formats available
}
 
// GPS rectangle
class GeoArea
{
    GeoArea( GeoPoint southWest, northEast)		// More constructors available
 
    GeoPoint SouthWest, NorthEast
    GeoDistance Width/Height				// Average dimensions
    GeoPoint CenterPoint
 
    bool IsEnclosing( point | area)			// Tests
    void EnlargeArea( point | area)			// Enlarge area by including point
                                                         // or another area
    void InflateArea( ... )				// various arguments
}
 
// Polyline supporting string conversions (string format is used in web requests)
class GeoPolyline
{
    GeoPolyline( string polyline )
    GeoPolyline( IEnumerable points )
 
    string Polyline			// encoded polyline
    List<GeoPoint> Points		// polyline
    GeoDistance Length		// polyline length
}

命名空间 Resco.Location.GPS

该命名空间提供处理 GPS 接收器的类。API 以 Windows Phone 7 中内置的 GPS 类为模型。

// GPS point
// (WP7 equivalent: GeoPosition<GeoCoordinate>)
class GeoPosition : GeoPoint
{
    DateTime TimeStamp					// local device time
    double Altitude, Course, Speed, HorizontalAccuracy, VerticalAccuracy
}
 
// API for working with GPS receiver
// (WP7 equivalent: GeoCoordinateWatcher)
class GpsDevice : IDisposable
{
    // Getters:
    GeoPosition Position				// The most recent position
    GeoPositionStatus Status		// Service status: Disabled/Ready/Initializing/NoData
 
    // Events:
    PositionChanged			// delivers GeoPosition
    StatusChanged			// delivers GeoPositionStatus
 
    static GpsDevice Create()	// Constructor
 
    // WP7 only: Constructor reusing existing GeoCoordinateWatcher
    static GpsDevice Create(GeoCoordinateWatcher watcher, bool dispose)
 
    bool Start();
    void Stop();
 
    bool WaitForLocation(int timeout)	// Synchronous wait for new position
}
 
// Implements GPS position tracking, i.e. remembers smoothed polyline describing
// your movement during the time the tracking was active.
class GpsTracking : IDisposable
{
    // Constructor can reuse existing device or create a new one
    GpsTracking()
    GpsTracking(GpsDevice device, bool dispose)
 
    // Setup conditions for remembering points
    TimeSpan MinimalTimeDifference	// Min. time period between remembered points; Default = 10 sec
    GeoDistance MinimalDistance	// Min. distance between remembered points; Default = 50m
    double RouteAccuracy		// 0..1; default=0.98; hustota zapamatanych bodov
 
    bool Start()
    void Stop()
 
    // Remembered points (getters)
    List<GeoPosition> TrackList	// Source points
    GeoPolyline Polyline		// Constructs polyline from current TrackList
 
    // Events
    TrackListChanged		// Occurs when the TrackList changes
    StatusChanged			// Occurs when service status changes
}

命名空间 Resco.Services

命名空间包含由各个服务使用的面向服务的类。

enum eServiceProvider			// Default, Google, Bing
 
// Class describing civic address
class Address
{
    Address(string country, string city, string street, string streetNum)
    string StreetNumber, Street, City, Region, Country, CountryCode, PostalCode
    string ToString()		// "Dunajska 12, Bratislava[, region], Slovakia"
}
 
// Basic exception type used for all service-oriented classes. 
// It has public members at present.
class ServiceRequestException : Exception
 
// Global settings for all service-oriented classes.
// Implements Singleton pattern; i.e. only one global instance of ServiceSettings exists.
class ServiceSettings
{
    static ServiceSettings Instance 	     // Use to set global settings
 
    // API keys used in service requests
    string BingApiKeyl		     // Condition for using Bing Maps
    string GoogleApiKeyl		     // Set if you have Google Maps API Premier
 
    // Other global settings. 
    // Provider and units be overriden by individual service classes. 
    // (Wheerever it makes sense.)
    eServiceProvider DefaultProvider	      // Default=Bing.
    eUnitSystems DefaultUnitSystem	     // Default=Metric. Used also by GeoDistance.ToString().
    string Language
}

命名空间 Resco.Services.GeoCode

GeoCode 类提供 GPS 位置与市民地址之间的翻译。每个翻译方向代表一个单独的请求。

class GeoCode
{
    // 1) Request setup
    eServiceProvider ServiceProvider	// Default: ServiceSettings.DefaultProvider
 
    // 2a) Request for translation GeoPoint -> Address
    void GetAddressAsync(GeoPoint location, object userState)
 
    // 3a) Wait for completion event
    event EventHandler<GetAddressCompletedEventArgs> GetAddressCompleted;
 
    // 4a) Results are provides by GetLocationCompletedEventArgs object with these getters:
        GeoPoint Location			// Translation result
        GeoArea ViewPoint			// Optional: null if Location describes the
                                                // result sufficiently
        eGeoPrecision LocationPrecision	// Unknown, Precise, Interpolated, GeoCenter, Aproximated
 
    // 2b) Request for opposite translation Address -> GeoPoint
    void GetLocationAsync(Address address, object userState)
 
    // 3b) Wait for completion event
    event EventHandler<GetLocationCompletedEventArgs> GetLocationCompleted;
 
    // 4b) Results are provided by GetAddressCompletedEventArgs object with these getters:
         Address Address			// Translation result
         eGeoPrecision LocationPrecision	// Unknown, Precise, Interpolated, GeoCenter, Aproximated
         GeoArea ViewPoint			// Optional: Used when the address represents areal object 
         string FormattedAddress		// Optional: Formatted address provided by the web service
         string EntityType			// address, route, street
 
    // Synchronous interface (WM platform only) provides only partial results:
    Address GetAddress(GeoPoint location)
    GeoPoint GetLocation(Address address)
}

命名空间 Resco.Services.GeoRoute

GeoRoute 类提供路线规划服务的高级 API。其余类用于描述路线规划结果。

enum eTravelModes		// Driving, Walking, Bicycling
 
// Result of the routing request
class GeoRouteResult
{
    List<GeoRouteLeg> RouteLegs
    string Copyrights		// Copyright information; need to be presented!
}
 
// GeoRouteResult consists of GeoRouteLeg's representing portion of
// a route between two waypoints.
class GeoRouteLeg
{
    string StartAddress, EndAddress
    GeoRouteSummary Summary
    GeoPoint EndLocation
    GeoPolyline Polyline
    List<ItineraryItem> ItineraryItems
}
 
// GeoRouteLeg consists of ItineraryItem's representing one step of a route.
class ItineraryItem
{
    eCompassDirection Direction	// Unknown(-1), East(0), SouthEast(45), South ... NorthEast(315)
    eTravelModes TravelMode
    eIconType IconType		// None, Airline, Auto, Bus, Ferry, Train, Walk, Other 
    GeoRouteSummary Summary
    GeoPolyline Polyline
    string Instructions
}
 
// Summary information for ItineraryItem, such as total distance and time
class GeoRouteSummary
{
    GeoPoint StartLocation
    GeoDistance Distance
    TimeSpan Duration
    GeoArea Bounds
}
 
class GeoRoute
{
    // 1) Request setup
    RouteOptions
    {
    eWayType AvoidWayType			// Ignore (default), AvoidTolls, AvoidHighways
	eTravelModes TravelMode		// Default = eTravelModes.Driving
	eUnitSystems Units			// Default = GeoDistance.DefaultUnitSystem
	eRouteOptimization Optimization	// MinimizeTime (default), MinimizeDistance…
 
	// Bing only:
	// Set to include GPS coordinates into the result. Needed to display GeoRouteResult on a map.
	bool RequirePathPoints			// Default=false
    }
    eServiceProvider ServiceProvider;
 
    // 2) Request for routing between src and dst locations with optional way points
    void GetRouteAsync( Address src, Address dst, object userState, params Address[] waypoints)
    void GetRouteAsync( GeoPoint src, GeoPoint dst, object userState, params GeoPoint[] waypoints)
 
    // 3) Wait for completion event
    event EventHandler<GetRouteCompletedEventArgs> GetRouteCompleted
 
    // 4) The results are provided by GetRouteCompletedEventArgs object with a single getter:
	GeoRouteResult Route
 
    // Synchronous interface (WM platform only):
    GeoRouteResult GetRoute(Address src, Address dst, params Address[] waypoints)
    GeoRouteResult GetRoute(GeoPoint src, GeoPoint dst, params GeoPoint[] waypoints)
}

命名空间 Resco.Services.Map

GeoMap 类提供下载静态地图图像的高级 API。其余类用于描述补充地图内容。

请注意,Google 和 Bing 地图的设置之间存在显著差异。

// Represents highlighted line on a map.
// One of the most common applications is to highlight the routing result.
class GeoMapPath
{
    // Construct path from a result of a routing request (can be used for both Google/Bing)
    GeoMapPath(GeoRouteResult route)
 
    // Google can highlight any polyline and offers additional setup parameters:
    Color  RouteColor			// Route color either as a 24-bit or 32-bit alpha value
    Color  MapFill				// Used to fill polygonal area
    int    RouteWeight			// Path thickness in pixels; Default=3
 
    GeoMapPath(GeoPolyline polyline)
}
 
// Marker is a graphical symbol that is placed at given locations.
class GeoMapMarkers
{
    // Create Google markers
    // Label = 1 character string
    // Size = one enum values Default/Mid (Can contain label), Small/Tiny (ignore label)
    // Locations = Address or GeoPoint instances
    GeoMapMarkers( Color col, size, label, params locations[] )
    string IconUrl				// Optional URL of the custom icon (png/jpg/gif)
 
    // Create Bing markers
    // Label = string with at most 2 characters
    // MarkerType = one of 36 icons available (http://msdn.microsoft.com/en-us/library/ff701719.aspx") (default=1)
    // Locations = Address or GeoPoint instances
    GeoMapMarkers( int markerType, label, params locations[] )
}
 
class GeoMap
{
    // 1) Request setup
    eServiceProvider ServiceProvider
    List<GeoMapMarkers>  Markers		// Optional markers shown on the map
    GeoMapPath Path			// Optional highlighted path
 
    Options				// Specify either Center+Zoom or ViewPoint area
    {
        Size ImageSize		// [pix]; Bing max. 800x834, Google max. 640x640; Default = screen size
        eImgFormat Format			// enum: Png, Png32, Gif, Jpg; Default=Png
        eMapType MapType			// enum: Roadmap, Satellite, Hybrid, Terrain; Default=Roadmap
        object Center				// GeoPoint or Address object
        int Zoom				// 1-22 for Bing, 0-21 for Google; default=12
        GeoArea ViewPoint			// Area shown on the map
    }
 
    // 2) Request for static image
    void DownloadMapAsync(object userState)
 
    // 3) Wait for completion event
    event EventHandler<DownloadMapCompletedEventArgs> DownloadMapCompleted;
 
    // 4) The results are provided by DownloadMapCompletedEventArgs object with these getters:
    	Stream ImageStream
    	ImageSource Image		// WP7 only
    	Bitmap Image			// WM only
 
    // Extra services
    string URL			// Translates current setup into an URL that can
                                      // be passed to the browser
    void ShowInBrowser()		// Calls system browser to display URL property
 
    // Synchronous interface (WM platform only):
    Stream DownloadMap()
}

如何实现 GPS 跟踪 – 示例代码

下面我们将演示如何构建一个 WP7 应用程序,该应用程序可以跟踪您的移动并在地??图上显示跟踪的路线。代码非常简化,即省略了所有检查等。

最简单的 MainPage.xaml 包含

  • GPS 状态和最后接收到的位置的 TextBlocks
  • 用于在地??图上显示跟踪路线的按钮
<phone:PhoneApplicationPage>
    <StackPanel Margin="12,0,12,0">
        <TextBlock x:Name="statusText" />
        <TextBlock x:Name="positionText" />
        <Button Content="Show Map" Click="btnShowMap"/>
    </StackPanel>
</phone:PhoneApplicationPage>

MainPage.cs 代码中包含的内容

  • GPS 提供程序的设置。我们选择 Google,因为我们想在地图上显示跟踪结果(即通用折线)。Bing 无法做到这一点。
  • GpsTracking 对象的设置
  • 页面加载时开始 GPS 跟踪,页面卸载时停止
  • 状态和位置变化显示在 UI 中
  • 按下 [显示地图] 按钮时会显示显示跟踪路线的地图。
public partial class MainPage : PhoneApplicationPage
{
    GpsTracking gpsTracking = new GpsTracking()
    {
        // We consider 1 signal per second and ignore positions within 10m accuracy.
        MinimalDistance = new GeoDistance(10),
        MinimalTimeDifference = new TimeSpan(0, 0, 1)
    };
 
    // Constructor
    public MainPage()
    {
        ServiceSettings.Instance.DefaultProvider = eServiceProvider.Google;
        //ServiceSettings.Instance.GoogleApiKey = "???";	// If you purchased Google Maps API Premier
 
        InitializeComponent();
 
        // Start/stop tracking when the page loads/unloads
        this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        this.Unloaded += new RoutedEventHandler(MainPage_Unloaded);
 
        // Define event handlers
        gpsTracking.StatusChanged += new EventHandler<StatusChangedEventArgs>(gpsTracking_StatusChanged);
        gpsTracking.TrackListChanged += new EventHandler(gpsTracking_TrackListChanged);
    }
 
    void MainPage_Unloaded(object sender, RoutedEventArgs e)
    {
        gpsTracking.Start();
    }
 
    void MainPage_Unloaded(object sender, RoutedEventArgs e)
    {
        gpsTracking.Stop();
        gpsTracking.Dispose();
    }
 
    // Update position TextBlock when Position arrives
    void gpsTracking_TrackListChanged(object sender, EventArgs e)
    {
        var list = gpsTracking.TrackList;
        string txt = list.Count > 0 ? list[list.Count - 1].ToString() : "NoData";
        positionText.Text = txt;        // WP7: GPS events are fired on the UI thread
    }
 
    // Update status TextBlock when status changes
    void gpsTracking_StatusChanged(object sender, StatusChangedEventArgs e)
    {
        statusText.Text = e.Status.ToString();
    }
 
    // Show the tracking results on the map
    private void btnShowMap(object sender, RoutedEventArgs e)
    {
        gpsTracking.Stop();
        var map = new GeoMap() { Path = new GeoMapPath(gpsTracking.Polyline) };
        map.ShowInBrowser();
    }
}

关于 Resco.Location 库

该库是Resco MobileForms Toolkit 的一部分,可从 http://www.resco.net/developer/mobileformstoolkit 下载。示例代码可从同一位置下载。

该工具包支持四种平台 - Windows Phone 7、Windows Mobile、Android 和 iOS。在撰写本文时,Location 库可在 Windows Phone 7 和 Windows Mobile 平台上使用。

关于作者

Jan Slodicka。编程超过 30 年。涵盖了多个桌面平台和编程语言。自 2003 年以来一直为 Resco 从事移动技术工作——Palm OS、Windows Mobile,现在是 Windows Phone 7。

您可以通过 `jano at resco.net` 或通过 Resco 论坛联系我。

Resco MobileForms Toolkit - Windows Phone 7 Edition 可从 http://www.resco.net/developer/mobilelighttoolkit 下载。该工具包包含一组有用的控件,可简化 Windows Phone 7 编程。除了 WP7,还有 Windows Mobile、Android 和 iOS 版本。

Resco 是一家拥有悠久移动编程传统的公司,涵盖许多平台,以及面向最终用户和开发者的应用程序工具。

© . All rights reserved.