Windows Phone 下开发 LBS 应用

一、LBS的概念

1、基本概念

基于位置的服务(Location Based Service,LBS),它是通过电信移动运营商的无线电通讯网络(如GSM网、CDMA网)或外部定位方式(如GPS)获取移动终端用户的位置信息(地理坐标,或大地坐标),在GIS(Geographic Information System,地理信息系统)平台的支持下,为用户提供相应服务的一种增值业务。

它包括两层含义:首先是确定移动设备或用户所在的地理位置;其次是提供与位置相关的各类信息服务。意指与定位相关的各类服务系统,简称"定位服务",另外一种叫法为MPS-Mobile Position Services, 也称为"移动定位服务"系统。如找到手机用户的当前地理位置,然后在上海市6340平方公里范围内寻找手机用户当前位置处1公里范围内的宾馆、影院、图书馆、加油站等的名称和地址。所以说LBS就是要借助互联网或无线网络,在固定用户或移动用户之间,完成定位和服务两大功能。


2、LBS系统的主要构成

总体上看LBS由移动通信网络和计算机网络结合而成,两个网络之间通过网关实现交互。移动终端通过移动通信网络发出请求,经过网关传递给LBS服务平台;服务平台根据用户请求和用户当前位置进行处理。并将结果通过网关返回给用户。

其中移动终端可以是移动电话、个人数字助理(Personal Digital Assistant, PDA)、手持计算机(Pocket PC),也可以是通过Internet通讯的台式计算机(desktop PC)。服务平台主要包括WEB服务器(Web Server)、定位服务器(Location Server)和LDAP(Lightweight Directory Access Protocol)服务器。


二、开发LBS App

1、地图控件

1.1、Windows Phone中的地图控件

Windows Phone 8提供了用来显示地图的Map控件,该控件是Windows Phone SDK的一部分,在使用控件之前,必须选定WMAppmanifest.xml中的ID_Cap_Map功能。

如果直接从工具箱中拖放地图控件,则会自动添加Microsoft.Phone.Map程序集的引用,如果通过编写XAML添加控件,还需要将xmlns声明添加到phone:PhoneApplicationPage元素。

xmlns:maps="clr-namespace:Microsoft.Phone.Maps.Controls;assembly=Microsoft.Phone.Maps"

有关向 Windows Phone 8 项目添加 Map 控件的更多信息,请参见如何将地图控件添加到 Windows Phone 8 中的页面中

以下代码示例演示了如何使用 XAML 创建要在您的 Windows Phone 8 应用中显示的 Map 控件。

<!--ContentPanel - place additional content here-->

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">

    <maps:Map />

</Grid>

以下代码示例演示了如何使用代码创建要在您的 Windows Phone 8 应用中显示的 Map 控件。

public MainPage()

{

   InitializeComponent();

   Map MyMap = new Map();

   ContentPanel.Children.Add(MyMap);

}

地图显示后,您首先要做的事情之一就是设置地图的中心和缩放。

可以使用控件的 Center 属性来设置 Map 控件的中心。要使用 XAML 设置属性,请将一个(纬度,经度)对分配给 Center 属性。以下代码示例演示了如何使用 XAML 设置 Map 的中心。

<!--ContentPanel - place additional content here-->

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">

   <maps:Map x:Name="MyMap" Center="47.6097, -122.3331" />

</Grid>

以下代码示例演示了如何使用C#代码设置 Map  的中心。

// Constructor

public MainPage()

{

   InitializeComponent();

   Map MyMap = new Map();

   MyMap.Center = new GeoCoordinate(47.6097, -122.3331);

   ContentPanel.Children.Add(MyMap);

使用 ZoomLevel 属性设置您要用来显示地图的初始分辨率。ZoomLevel 接受从 1 到 20 的值,其中 1 对应于完全放大地图,并且缩放级别越高,放大所采用的分辨率也更高。以下代码示例演示如何在 XAML 和C#代码中使用ZoomLevel 属性设置地图的缩放。

<!--ContentPanel - place additional content here-->

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">

   <maps:Map x:Name="MyMap" Center="47.6097, -122.3331" ZoomLevel="10"/>

</Grid>

public MainPage()

{

   InitializeComponent();

   Map MyMap = new Map();

   //Set the Map center by using Center property

   MyMap.Center = new GeoCoordinate(47.6097, -122.3331);

   //Set the map zoom by using ZoomLevel property

   MyMap.ZoomLevel = 10;

   ContentPanel.Children.Add(MyMap);

}

地图控件的 Center 属性要求来自 System.Device.Location  命名空间的 GeoCoordinate 的类型的值。如果您正在使用 Windows.Devices.Geolocation 命名空间的位置服务,您需要将 转换为  System.Device.Location.GeoCoordinate 值以与地图控件结合使用。

地图应用中一个常用的方案是:从地图中某个位置移动到另一个位置,或者从一个视图移动到另一个视图。每当平移、缩放、旋转或倾斜导致地图的位置发生更改时,都将定义新的地图视图。SetView() 方法用于定义地图视图,该方法可包含如下参数:视图的中心、缩放级别、行进方向、间距、LocationRectangle 和用于从一个视图转到另一个视图的动画。下面详细介绍了 SetView() 方法的参数。

  • center:使用此参数以传递地图视图的中心。它由 GeoCoordinate 对象定义。
  • zoomLevel:此参数表示地图上可用的各种详图级别。它可接受从 1 至 20 的值。可用的最大详图级别由您正在放大的位置所决定。与其他区域相比,某些区域还可以进一步放大。缩放级别越高表示地图中视图的缩放程度也更高。缩放级别为 1 表示最大缩小级别的视图。
  • heading:此参数指定地图上标记的“前进”航向。将使用值介于 0 到 360 之间的几何度数表示该参数,以指示地图要旋转的度数。例如,0 或 360 表示北方,90 表示西方,180 表示南方以及 270 表示东方。下图详细描述了行进方向。
  • pitch:此参数指定地图要倾斜的度数。它由介于 0 到 180 之间的值表示,以指示地图要倾斜的度数。
  • boundingRectangle:此参数表示一个包含 Map 对象。
  • animationKind:使用此参数设置当视图更改时您想要看到的动画。可以在 MapAnimationKind 枚举中找到可用的动画设置。
  • 如果您将 None 传递为animationKind 参数,则地图将捕捉到新的视图而不是对视图更改进行动画处理。

设置地图的中心和缩放级别后,您可能想要设置地图的制图模式。制图模式将定义 Map  控件上坐标系的显示以及坐标系从屏幕坐标到世界坐标的转换。您可以使用 Map 控件的 属性设置地图的制图模式。此属性接受  MapCartographicMode 枚举中的值。以下类型的制图模式在 MapCartographicMode 枚举中受支持。

  • Road 显示正常的默认二维地图。
  • Aerial 显示航测图。
  • Hybrid 显示与道路和标签重叠的地图的“航测”视图。
  • Terrain 为显示的高地和水域构造(例如高山和河流)显示自然地形图像。

可通过使用 ColorMode 属性,以浅色或深色模式来显示地图。此属性可接受的值 Light 或 Dark 枚举中进行指定。默认值为 Light。

您也可以在地图上显示其他元素,例如地标和步行街构造。

  • 地标。 将 LandmarksEnabled 属性设置为 true 以在 Map 控件上显示地标。仅当 ZoomLevel 属性被设置为 16 或更高的值时,地标才在地图上可见。
  • 步行街构造。 在 Map 控件上将 PedestrianFeaturesEnabled 设置为 true,以显示步行街构造(如公共楼梯)。仅当 ZoomLevel 属性被设置为 16 或更高的值时,步行街功能才在地图上可见。

更多信息,请参见:


1.2、Windows 8应用商店应用中的地图控件

Bing Maps for Windows Store apps为Windows Store应用程序提供了地图方面很好的用户体验,开发者可以使用Bing Maps地图控件为Windows Store应用程序加入最新的路线图、鸟瞰图和低角度高清晰图像。

Bing Maps API

Bing Maps AJAX控件7.0版

Bing Maps AJAX控件7.0版是最新版本的Bing Maps Javascript API,将AJAX地图控件与Bing Maps REST服务Bing空间数据服务相结合,并使用最新的图像和定位功能来创建功能强大的Web站点和移动应用。请参见Bing Maps AJAX控件7.0版交互式SDK

Windows Store应用程序的Bing Maps

Windows Store应用程序的Bing Maps控件为Windows Store应用程序集成了最新的路线图、鸟瞰图以及低角度高分辨率图像

Bing Maps REST服务

Bing Maps REST服务使用REST URL来执行下述任务:创建地图图钉、地理编码地址、检索图像元数据或者计算路径。

Bing空间数据服务

Bing空间数据服务使用REST URL进行地理编码以及解码大量空间数据集合并创建查询数据源,数据源包含一个用户定义的实体类型,其中包含了空间数据集。你可以创建一组商店的数据源,然后在其中查找附近商店的位置。

Bing Maps WPF控件

Bing Maps WPF控件SDK让开发者将Bing地图整合到富Windows Presentation Foundation(WPF)应用程序中,使用“软件+服务”的方式,您的使用Bing云计算架构的WPF应用程序可以使用Bing Maps WPF控件获取最新的Bing地图图像,该控件同时也支持Microsoft Surface的触摸界面,可以创建丰富的触摸功能的应用程序。要开始使用Bing Maps WPF控件,请下载Bing Maps Windows Presentation Foundation控件SDK

新建一个Windows Store应用程序,添加命名空间xmlns:bm="using:Bing.Maps",将一下XAML代码放入Tag标签内,并用你的Bing Maps Key替换INSERT_YOUR_BING_MAPS_KEY占位符。

执行程序,地图控件就会出现。同Windows Phone中的地图控件一样,Windows Store应用程序中的地图控件也可以通过设置各种参数对其进行更加精细化的设置。

详细用法,请参见代码示例


2、获取定位信息

只有地图控件是不能完成功能的,必须通过位置传感器获取到定位信息,才可以在地图控件上面显示出来当前位置,然后进行LBS应用程序的下一步操作。


2.1、Windows Phone中获取当前位置

1.  在 Visual Studio 中创建新的 Windows Phone 应用。

  1. 在“解决方案资源管理器”中,展开“属性”文件夹,然后双击 WMAppManifest.xml。
  2. 在清单设计器的“功能”选项卡上,选中“ID_CAP_LOCATION”旁边的复选框。
  3. 在 MainPage.xaml 中,将下列 XAML 代码粘贴到现有的名为 ContentPanel 的 Grid 元素上。此代码定义一个将启动位置 API 的按钮,以及一些文本块来显示维度、经度和应用的状态。

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">

<StackPanel>

<Button x:Name="OneShotLocationButton" Click="OneShotLocation_Click" Content="get one-shot location"/>

<TextBlock x:Name="LatitudeTextBlock"/>

<TextBlock x:Name="LongitudeTextBlock"/>

<TextBlock x:Name="StatusTextBlock"/>

</StackPanel>

</Grid>

  1. 在 MainPage.xaml.cs 文件的顶部添加以下 using 语句。

using System.Threading.Tasks;

using Windows.Devices.Geolocation;

  1. 添加同意提示以允许用户选择不让您的应用访问其位置。所有应用在使用位置 API 之前,应取得用户同意。本例检查 MainPage 类的 OnNavigatedTo(NavigationEventArgs) 方法中的用户同意,只要应用启动,就会调用它。代码首先检查 ApplicationSettings 字典,以了解是否存在“LocationConsent”密钥。如果发现该密钥,则意味着用户已经选择或退出位置,因此该方法立即返回。如果未发现该密钥,那么将显示 MessageBox,寻求用户同意。MessageBox 操作的结果受到检查,指示用户同意状态的布尔值存储在 ApplicationSettings 中的“LocationConsent”密钥内。在应用尝试访问用户位置之前,此密钥将受到检查。

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)

{

if (IsolatedStorageSettings.ApplicationSettings.Contains("LocationConsent"))

{

// User has opted in or out of Location

return;

}

else

{

MessageBoxResult result = 

MessageBox.Show("This app accesses your phone's location. Is that ok?", "Location",MessageBoxButton.OKCancel);

if (result == MessageBoxResult.OK)

{

IsolatedStorageSettings.ApplicationSettings["LocationConsent"] = true;

}else

{

IsolatedStorageSettings.ApplicationSettings["LocationConsent"] = false;

}

IsolatedStorageSettings.ApplicationSettings.Save();

}

}

  1. 将下列处理程序粘贴到用于按钮单击事件的 MainPage.xaml.cs 中。该方法首先检查 ApplicationSettings 字典中用户同意的状态。如果值为 false,则该方法立即退出。一旦确定用户同意,则该方法初始化 Geolocator 对象,并设置 DesiredAccuracyInMeters 属性。随后,将调用 GetGeopositionAsync 方法。此方法尝试获取手机的当前位置。此为异步操作,因此在获取位置时不会阻止 UI 线程。您可以使用 await 操作符将代码置于异步调用之后,将在调用完成后执行。这需要该处理程序方法被申明为 async。因为可以确保使用 await 发起的调用返回在调用开始的线程上,而且 await 调用从 UI 线程发起,因此代码可以在调用返回时,直接访问并修改 UI。

整个位置操作都包装在 try 块中,以防止引发任何异常。如果在开发时引发 UnauthorizedAccessException 异常,可能意味着您的应用清单中未包含 ID_CAP_LOCATION。如果在已经部署应用之后发生这种情况,则可能意味着用户已在手机“设置”中禁用了此应用的位置。

```

private async void OneShotLocation_Click(object sender, RoutedEventArgs e)

{

if ((bool)IsolatedStorageSettings.ApplicationSettings["LocationConsent"] != true)

{

// The user has opted out of Location.

return;

}

Geolocator geolocator = new Geolocator();

geolocator.DesiredAccuracyInMeters = 50;

try

{

Geoposition geoposition = await geolocator.GetGeopositionAsync(

maximumAge: TimeSpan.FromMinutes(5),

timeout: TimeSpan.FromSeconds(10)

);

LatitudeTextBlock.Text = geoposition.Coordinate.Latitude.ToString("0.00");

LongitudeTextBlock.Text = geoposition.Coordinate.Longitude.ToString("0.00");

}

catch (Exception ex)

{

if ((uint)ex.HResult == 0x80004004)

{

// the application does not have the right capability or the location master switch is off

StatusTextBlock.Text = "location  is disabled in phone settings.";

}

//else

{

// something else happened acquring the location

}

}

}

```

2.2、Windows 8中获取当前位置

  1. 打开 Microsoft Visual Studio 2012
  2. 创建一个新项目
    创建新项目,从Visual C# > Windows 应用商店项目类型中选择一个“应用程序”。
  3. 在应用中插入 C# 代码
    打开你的项目的 MainPage.xaml.cs 文件并将现有的代码替换为下面的代码。

me

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;

  1. ```
    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();
    }
    Geoposition 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();
    }
    }
    }

你将需要用你的应用的类名称替换上面的代码片段中的类名称。例如,如果你创建了一个名为“Application1”的项目,则需要将:

  1. namespace GeolocationSample

替换为

  1. namespace Application1
    ```
  2. 在应用中插入 XAML 代码
    打开名为 MainPage.xaml 的文件,然后将下面的 XML 复制到此文件中(替换原来的内容)。

<UserControl x:Class="GeolocationSample.MainPage"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

mc:Ignorable="d"

d:DesignHeight="768" d:DesignWidth="1366">

<Grid x:Name="LayoutRoot" Background="Gray">

<Button Content="Get Location Async" Click="button1_Click" Height="23" 

HorizontalAlignment="Left" Margin="12,180,0,0" Name="button3" VerticalAlignment="Top" Width="120" />

<TextBlock Margin="14,220,0,0" Text="Latitude" Name="textLatitude" />

<TextBlock Margin="14,260,0,0" Text="Longitude" Name="textLongitude" />

<TextBlock Margin="14,300,0,0" Text="Accuracy" Name="textAccuracy" />

</Grid>

</UserControl> 

  1. 你将需要用你的应用的类名称替换上面的代码片段中类名称的第一部分。例如,如果你创建了一个名为“Application1”的项目,则需要将:

<UserControl x:Class="GeolocationSample.MainPage"

  1. 替换为

<UserControl x:Class="Application1.MainPage"

  1. 生成应用
    选择“生成”>“生成解决方案”以生成项目。
  2. 测试应用
    1. 在“调试”菜单上,单击“开始调试”测试该解决方案。
    2. 首次运行该示例时,你会收到一个提示,询问是否可以让应用使用你的位置数据。选择“允许”选项。
    3. 单击“获取位置”按钮获取当前的位置。
  1. 注意  如果位置数据未显示,则检查以下内容:
    • 确保已启用对位置的访问权限,方法是在解决方案资源管理器中打开 package.appxmanifest 并在“功能”选项卡中选中“位置”。
    • 如果管理员已禁用定位服务,则你的应用将无法访问用户的位置。在桌面控制面板中,打开“更改位置设置”并检查是否已选中“打开 Windows 位置平台”。

前面的示例说明,只需编写少量代码即可在应用中集成地理位置功能。

应用会在 button1_Click 方法中发出获取地理位置信息的异步请求。这通过下面一行实现:

Geoposition 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();

以下新值将写入项目 XAML 中的三个 TextBlock 中。

<TextBlock Margin="14,220,0,0" Text="Latitude" Name="textLatitude" />

<TextBlock Margin="14,260,0,0" Text="Longitude" Name="textLongitude" />

<TextBlock Margin="14,300,0,0" Text="Accuracy" Name="textAccuracy" /> 


3、LBS服务

获取到用户当前位置之后,LBS服务就可以为用户提供相应的服务了,其中LBS的主要服务模式有以下几种。


3.1、签到(Check-In)模式

主要是以Foursquare为主,还有一些国外同类服务还有Gowalla、Whrrl等,而国内则有:嘀咕、玩转四方、街旁、开开、多乐趣、在哪等几十家。

该模式的基本特点如下:

  1. 用户需要主动签到(Check-In)以记录自己所在的位置
  2. 通过积分、勋章以及领主等荣誉激励用户 Check-In,满足用户的虚荣感
  3. 通过与商家合作,对获得的特定积分或勋章的用户提供优惠或折扣的奖励,同时也是对商家品牌的营销
  4. 通过绑定用户的其它社会化工具,以同步分享用户的地理位置信息
  5. 通过鼓励用户对地点(商店、餐厅等)进行评价以产生优质内容

该模式的最大挑战在于要培养用户每到一个地点就会签到(Check-In)的习惯。而它的商业模式也是比较明显,可以很好地为商户或品牌进行各种形式的营销与推广。而国内比较活跃的街旁网现阶段则更多地与各种音乐会、展览等文艺活动合作,慢慢向年轻人群推广与渗透,积累用户。


3.2、游戏模式

国外的代表是Mytown,国内则是16Fun。主旨是游戏人生,可以让用户利用手机购买现实地理位置里的虚拟房产与道具,并进行消费与互动等将现实和虚拟真正进行融合的一种模式。这种模式的特点是更具趣味性,可玩性与互动性更强,比Check-In模式更具粘性,但是由于需要对现实中的房产等地点进行虚拟化设计,开发成本较高,并且由于地域性过强导致覆盖速度不可能很快。在商业模式方面,除了借鉴Check-In模式的联合商家营销外,还可提供增值服务,以及类似第二人生(Second

Life)的植入广告等。


3.3、生活服务模式

  1. 周边生活服务的搜索:
    以点评网或者生活信息类网站与地理位置服务结合的模式,代表 大众点评网、*的“折扣王”等。主要体验在于工具性的实用特质,问题在于信息量的积累和覆盖面需要比较广泛。
  2. 与旅游的结合:
    旅游具有明显的移动特性和地理属性,LBS和旅游的结合是十分切合的。分享攻略和心得体现了一定的社交性质,代表是游玩网。
  3. 会员卡与票务模式:
    实现一卡制,捆绑多种会员卡的信息,同时电子化的会员卡能记录消费习惯和信息,充分的使用户感受到简捷的形式和大量的优惠信息聚合。代表是国内的“Mokard(M卡)”、还有票务类型的Eventbee。这些移动互联网化的应用正在慢慢渗透到生活服务的方方面面,使我们的生活更加便利与时尚。


3.4、社交模式

  1. 地点交友,即时通讯:不同的用户因为在同一时间处于同一地理位置构建用户关键,代表是兜兜友。
  2. 以地理位置为基础的小型社区: 地理位置为基础的小型社区,代表是“区区小事”。


上一篇:C#编码简单性之语义篇(如何编写简短的C#代码,随时更新)


下一篇:[iPhone开发之控件的使用]UIActionSheet的各种属性、方法及代理的使用