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

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.59/5 (21投票s)

2008 年 12 月 29 日

CPOL

5分钟阅读

viewsIcon

137424

downloadIcon

3281

使用 Windows Mobile 6 设备和一些 Google Map 编程来跟踪您的地理位置。

MobilePositionTracker/positiontrackermobile.JPG

引言

除了编程乐趣和工作之外,我的爱好之一是长距离徒步旅行。我最喜欢的年度活动是荷兰奈梅亨的“四日行军”。我现在已经参加了五次,这确实非常有趣。

“后勤”人员留下来的人面临的一个问题是知道你在哪里。您每天都会接到几次电话,询问“你在哪里?”和“还有多久到终点?”。嗯,拥有一部带有 GPS 和互联网连接的手机可以轻松解决这个问题。

二进制文件使用

您所需要的是

  1. 一部带有内置 GPS 设备并能连接互联网的 WM6 智能手机。
  2. 一台连接到互联网的、位于“家”的 PC。
  3. 移动电话上安装了 .NET CF 3.5。
  4. PC 上安装了 .NET 3.5 框架。
  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 服务,瞧,您的位置就会显示出来!

MobilePositionTracker/positiontrackingPC.JPG

在应用程序的第二个选项卡上,作为奖励,您还可以获取您当前位置的地图。如果 GPS 未正常工作或不存在,将显示 **我的** 位置的地图……

移动应用程序的内部

移动应用程序并不复杂,它只是一个简单的窗体,上面有一个选项卡控件,里面包含两个窗体。有三种主要技术,足以解释

  1. 从移动设备调用 WCF Web 服务。
  2. 从 GPS 设备获取 GPS 位置。
  3. 使用找到的 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.csCFClientBase.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)结合使用时。

© . All rights reserved.