咳咳,有点激动,刚刚还发了一条微博缓和一下气氛。
好的,因为现在手头有个项目需要用到地图和定位,祖哥就下圣旨让我去看看wp上有哪些地图的api,还特意提醒我说wp自带的那个Map控件会有偏移。
1. WP8自带的Map控件
好嘛,你说有偏移,我就查了一下嘛,然后发现说那玩意会偏移的论坛都是101112年的嘛。好嘛,那万一fix掉了呢?
嗯,抱着不装南墙不回头的心态,我开始用上了wp自带的map控件。
在Xaml里加一行xmlns声明:
xmlns:maps="clr-namespace:Microsoft.Phone.Maps.Controls;assembly=Microsoft.Phone.Maps"
还必须检查 WMAppManifest.xml 文件中的 ID_Cap_Map 功能以使用该控件。
<maps:Map />
太简单?
<maps:Map
x:Name="LittleMap"
HorizontalAlignment="Left"
Margin="10,10,0,0"
VerticalAlignment="Top"
Height="587"
Width="436"
Center="30,120"
ZoomLevel="13"
Pitch="30" />
差不多了- - 好吧说一下比较复杂的那个 Center是地图要显示的中心点,ZoomLevel是缩放等级,数值越大表示精度越高,一共有1-20个等级,Pitch是倾斜度,表示的是你的视线和地面的夹角。
怎样定位呢? 直接来!大家可以随便弄一个button或者在ApplicationBar上弄一个,然后在click函数里(在click函数前加上async关键字)
Geoposition geoposition;
geoposition = await new Geolocator().GetGeopositionAsync();
LittleMap.SetView(geoposition.Coordinate.ToGeoCoordinate(), 13);
首先声明一个Geoposition变量,然后调用异步方法GetGeopositionAsync来获得此时的地理位置,然后调用SetView方法,设置当前显示的界面的中心点,以及缩放度,当然还有别的参数,大家可以随便玩玩。不知道为什么这个获取地理位置的函数特别耗时,要等一段比较明显的时间之后地图的视角才会变到我现在所处的位置。而且!!!!!
这个方法的偏移量很大,不,是灰常大!让人难以接受,我一开始都没找到我单位在哪= = 雅蠛蝶,不好不好。。。
还有一些Map的显示Mode啊什么的大家随便玩玩,反正这个偏移量是伤到我了。
P.S. 这个地图的查询功能还是比较好玩的,大家有兴趣的话可以去MSDN相关页面看一看。
P.P.S 有的网站说需要申请啥Key 然后在Map的一个CredentialsProvider属性上赋值。但是我一没找到那个属性,二不知道申请过Key 之后有啥用(除非你想用Here地图的Launcher API 后面说!)
2.添加Toolkit里关于Map的附加功能
虽然偏移量(不行还得再吐槽一次为什么不能把便宜修好了然后再玩呢?)是有的,但是还是不能阻止我们去继续增加一些小玩意的决心。在Silverlight Toolkit for Windows Phone里有一些针对Map的扩展比较有意思。首先大家先去下载一下这个Toolkit,里面有下载的步骤。安装完成之后我们在xaml里添加一个命名空间:
xmlns:maptk="clr-namespace:Microsoft.Phone.Maps.Toolkit;assembly=Microsoft.Phone.Controls.Toolkit"
然后重头戏来啦,既然是针对map的扩展,那一定是要放在map里面的,然后就有了下面这段代码:
<maps:Map
x:Name="LittleMap"
HorizontalAlignment="Left"
Margin="10,10,0,0"
VerticalAlignment="Top"
Height="587"
Width="436"
Center="30,120"
ZoomLevel="13"
Pitch="30">
<maptk:MapExtensions.Children>
<maptk:UserLocationMarker
x:Name="UserLocationMarker"
Visibility="Collapsed" />
</maptk:MapExtensions.Children>
</maps:Map>
注意中间<maptk:MapExtensions.Children>和〈/maptk:MapExtensions.Children>之间的东西,他是Toolkit里的一些关于Map的控件,用于在Map上作出一个标记。从代码中我们可以看出只给它起了一个名字,然后设置为不可见。
然后我们在cs代码中写道:
Geoposition geoposition;
geoposition = await new Geolocator().GetGeopositionAsync();
this.UserLocationMarker = (UserLocationMarker)this.FindName("UserLocationMarker");
this.UserLocationMarker.GeoCoordinate = geoposition.Coordinate.ToGeoCoordinate();
this.UserLocationMarker.Visibility = System.Windows.Visibility.Visible;
LittleMap.SetView(UserLocationMarker.GeoCoordinate, 13);
在我们上面得到地理位置的代码中添加了三行关于UserLocationMarker的代码,首先根据名字找到这个控件的示例,然后把坐标赋给控件,最后设置为可见,再次定位的时候就可以看到一个标记了。好了,关于Toolkit里面的控件还有许多可以玩的,还有兴趣的话可以看看 Toolkit的Sample,然后点击左边的PhoneToolkitSample8->Samples->MapsSample看看,里面有关于收藏啊显示路线啊什么的其他功能。
3.Here Launcher API
用Lumia的同志们应该都听过Here地图啊Here公交啊什么的,然后Nokia出了一个api,是关于调用这些应用的。比如你想在应用中让用户查询地图的某些功能,可以直接转过去。
好吧,在这个里面要用到之前申请的Application Key 或者说是 ID ,否则就等着Vs报 InvalidOperationException的错吧。
我们可以先在MainPage的构造函数里写一句话
Microsoft.Phone.Maps.MapsSettings.ApplicationContext.ApplicationId = "AkHsf3IMADTUAd7V71u_OH2j-hb54Nh4LtZQmfy8TClnXzd6CopCxmTpgvU3EJuh";
这个ID是真的可以用的!大家拿去玩,反正再过90天这个就不能用了。。。。如果大家拷贝之后发现不能用,看一下这篇文章的发布日期到你看到的日期是不是过了90天。。。 然后可以随便来一个Button写个click函数
var showmap = new ExploremapsShowMapTask
{
ViewPort = new LocationRectangle(new GeoCoordinate(60.35, 24.60), new GeoCoordinate(60.25, 24.80))
};
showmap.Show();
使用前提是你得有Here地图这个应用,否则先去下一个吧~
其他的Launcher大家可以参照Nokia的文档 。这个得要Here应用下载到手机里之后才起作用,没啥意思。
4.高德地图API
好东西!由于这位仁兄向国家申请了某些东西,可以没有偏移地得到地理位置信息!废话不多说,上图!不对- - 上攻略!
首先大家进入这个API的主页,申请一个Key先,一个账号可以申请10个key。然后进入WindowsPhone API,点击左边的相关下载,2.0的开发包是一定要下载的,然后非常重要的一个是开发指南,但是主页上只有一个v1.1的开发指南,坑爹!那到哪去找v2.0的呢?
先点击左边的常见问题,然后看到一大串,然后下面有一个问题:
Q: 我怎么开始使用高德地图Windows Phone API?
void amap_Loaded(object sender, RoutedEventArgs e)
{
this.Dispatcher.BeginInvoke(() => amap.AddMarker(new AMapMarkerOptions
{
IconUri = new Uri("Images/AZURE.png", UriKind.Relative),
Position = amap.Center
}));
}
其他的话,大家随便玩吧。我没有去试往地图里添加点线面体这些东西,所以有可能还有别的问题大家仔细思考一下吧~
AMapGeolocator mylocation = new AMapGeolocator();
this.UserLocationMarker = (UserLocationMarker)this.FindName("UserLocationMarker");
mylocation.PositionChanged += mylocation_PositionChanged;
在响应函数里:
this.Dispatcher.BeginInvoke(() =>
{
this.UserLocationMarker.GeoCoordinate = new System.Device.Location.GeoCoordinate(args.LngLat.latitude,
args.LngLat.longitude);
this.UserLocationMarker.Visibility = System.Windows.Visibility.Visible;
LittleMap.SetView(UserLocationMarker.GeoCoordinate, 13);
});
直接使用args的经纬度来设置Marker的位置,然后调用SetView去显示。完事!