使用 Windows Mobile 6 设备跟踪您的位置






4.59/5 (21投票s)
使用 Windows Mobile 6 设备和一些 Google Map 编程来跟踪您的地理位置。
引言
除了编程乐趣和工作之外,我的爱好之一是长距离徒步旅行。我最喜欢的年度活动是荷兰奈梅亨的“四日行军”。我现在已经参加了五次,这确实非常有趣。
“后勤”人员留下来的人面临的一个问题是知道你在哪里。您每天都会接到几次电话,询问“你在哪里?”和“还有多久到终点?”。嗯,拥有一部带有 GPS 和互联网连接的手机可以轻松解决这个问题。
二进制文件使用
您所需要的是
- 一部带有内置 GPS 设备并能连接互联网的 WM6 智能手机。
- 一台连接到互联网的、位于“家”的 PC。
- 移动电话上安装了 .NET CF 3.5。
- PC 上安装了 .NET 3.5 框架。
- 一个 Google 静态地图 API 密钥(可在此 处免费获得)。
PC 应用程序
我们不会深入探讨 PC 应用程序的细节,因为这不是本文的主题。只要知道该程序托管了一个 WCF Web 服务,能够处理一组坐标。然后将这些坐标用于调用 Google 静态地图 API 以生成坐标所指示位置的地图就足够了。
Web 服务的端点是 http://yourhost:xxx/services/positionservice。
程序运行一次后,它将创建一个名为 AppConfig.xml 的配置文件。在此文件中,您可以输入主机名、端口号和 Google API 密钥等详细信息。
移动应用程序
移动应用程序只是一个 EXE 文件,可以使用 ActiveSync 的常规方法将其放入移动设备。没有安装程序,因此您需要手动完成。安装在设备上后,请运行该程序一次。在您放置 EXE 文件的文件夹中,现在会找到 AppConfig.xml,其中包含配置信息。
使用应用程序
在将用于跟踪您位置的 PC 上,启动 PositionTrackerPC 程序。确保配置文件中的配置正确。您可能需要编辑防火墙设置以打开您将使用的端口,并且可能需要编辑调制解调器中的 NAT 规则才能使其正常工作。我无法帮助您进行配置,因为每个调制解调器/防火墙都不同。因此,现在您的位置跟踪器已准备就绪并在 PC 上运行。
现在,启动移动设备上的位置跟踪程序。同样,请确保输入正确的主机名和端口号。
在第一个选项卡上,您可以输入运行位置跟踪器 PC 应用程序的主机名以及使用的端口号。此外,您在此处输入您的 Google API 密钥(它将在第二个选项卡上使用)。如果您已完成输入配置信息,请务必保存,否则您将不得不重新输入!在文本框中,您可以输入一个备注,该备注也会显示在 PC 应用程序中。除此之外,还会显示一些关于卫星数量和当前位置的 GPS 信息。
按下底部的“发送”按钮将调用您 PC 上的 Web 服务,瞧,您的位置就会显示出来!
在应用程序的第二个选项卡上,作为奖励,您还可以获取您当前位置的地图。如果 GPS 未正常工作或不存在,将显示 **我的** 位置的地图……
移动应用程序的内部
移动应用程序并不复杂,它只是一个简单的窗体,上面有一个选项卡控件,里面包含两个窗体。有三种主要技术,足以解释
- 从移动设备调用 WCF Web 服务。
- 从 GPS 设备获取 GPS 位置。
- 使用找到的 GPS 坐标显示 Google 地图。
调用 WCF Web 服务
还记得 PC 应用程序中的 Web 服务端点
http://yourhost:xxx/services/positionservice
为了本文的缘故,让我们假设它是一个 http://acme.com:8080/services/positionservice。现在,会出现两个问题:Visual Studio 不提供创建 Web 服务引用的工具,并且 .NET 3.5 CF 没有 ChannelFactory<TInterface>
类的实现。
那么,如何才能做到呢?
您必须安装 **.NET Compact Framework 3.5 的 Power Toys**。这些工具包含一个名为 netcfSvcUtil.exe 的命令行工具。此工具允许为您的 Web 服务生成代理,在我们的例子中,它的用法如下
netcfSvcUtil.exe /language:cs http://acme.com:8080/services
此命令将生成两个文件:PositionService.cs 和 CFClientBase.cs。这两个文件都应添加到您的项目中。在 PositionService.cs 中,您必须为 PositionServiceClient
添加一个构造函数,允许传递一个终结点 URI
public PositionServiceClient(string endPointAddress) :
this(CreateDefaultBinding(),
new System.ServiceModel.EndpointAddress(endPointAddress))
{
}
现在,您可以使用从配置信息动态构造的终结点地址来创建 PositionServiceClient
。
//Calling it is now quite easy:
private void sendMenuItem_Click(object sender, EventArgs e)
{
double latitude = 52.031694;
double longitude = 5.165283;
string uri = String.Format("http://{0}:{1}/services/PositionService",
hostTextBox.Text, Convert.ToInt32(portTextBox.Text));
PositionServiceClient client = new PositionServiceClient(uri);
if (_position != null)
{
if (_position.LatitudeValid && _position.LongitudeValid)
{
latitude = _position.Latitude;
longitude = _position.Longitude;
}
}
client.SendPosition(latitude, longitude, remarksTextBox.Text);
MessageBox.Show("Position sent!");
}
从 GPS 设备获取 GPS 位置
使用 Microsoft 提供的类来包装 WM6 中的本机 GPS API,这非常容易。我已将这些类包含在应用程序中,并将命名空间更改为匹配我的应用程序的命名空间。这里没有错误:所有功劳都归功于 Microsoft 提供的这些易于使用的类!
初始化部分在窗体的 Load
处理程序中
private void PositionSenderForm_Load(object sender, EventArgs e)
{
_configuration = AppConfiguration.ApplicationConfiguration();
hostTextBox.Text = _configuration.WebServiceHostName;
portTextBox.Text = _configuration.PortNumber.ToString();
googleAPIKey.Text = _configuration.GoogleMapAPIKey;
if (!_gps.Opened)
{
_gps.Open();
updateDataHandler = new EventHandler(UpdateData);
_gps.LocationChanged += new LocationChangedEventHandler(_gps_LocationChanged);
}
}
调用 Gps.Open
将打开 GPS(如果尚未打开)并开始搜索卫星。如果位置发生变化,将调用一个事件处理程序来更新坐标。就是这么简单!
使用找到的 GPS 坐标显示 Google 地图
最后一部分涉及使用 GPS 坐标显示地图。Google 提供了一个 API,可以通过指定缩放值,获取以一组纬度/经度值为中心的地图像。为此,必须使用以下格式构建一个 URL
String.Format(CultureInfo.InvariantCulture,
"http://maps.google.com/staticmap?center={0}," +
"{1}&size={5}x{6}&markers={0},{1}," +
"greenc&zoom={2}&maptype={3}&key={4}",
_coordinate.Latitude, _coordinate.Longitude,
_zoomLevel, _mapType, _apiKey, _xSize, _ySize);
为此,使用了 MapUrlBuilder
类。
检索图像的代码如下
MapUrlBuilder builder = new MapUrlBuilder();
builder.CenterCoordinate = coordinate;
builder.MapType = "mobile";
builder.ZoomLevel = 15;
builder.XSize = mapPictureBox.ClientRectangle.Width;
builder.YSize = mapPictureBox.ClientRectangle.Height;
builder.GoogleMapsAPIKey = _configuration.GoogleMapAPIKey;
LocationMap map = new LocationMap(builder.MapUrl);
mapPictureBox.Image = map.Map;
LocationMap
类检索图像如下
private Bitmap FromUrl(string url)
{
WebRequest request = HttpWebRequest.Create(url);
WebResponse response = request.GetResponse();
Bitmap bmp = new Bitmap(response.GetResponseStream());
return bmp;
}
有关完整的代码详细信息,我将不得不引用提供的源代码。
关注点
希望我已经为您提供了一些关于构建自己的 WM6 应用程序的见解和工具。我认为这是一个很有潜力的平台,特别是当与其他 .NET 支柱(如 WCF)结合使用时。