使用Bing Map控件在Windows Phone 7上使用Google Maps






4.74/5 (48投票s)
本文介绍了如何使用Microsoft随Windows Phone 7开发者工具提供的地图控件来使用Google地图。

引言
微软最近推出了必应地图,它是谷歌地图的直接竞争对手。 必应地图相对较新,与谷歌地图相比,数据量和地图深度当然较少,谷歌地图在该领域已经存在了相当长的时间。 开发人员经常希望将谷歌地图整合到他们的 Windows Phone 应用程序中,这似乎是不可能的,因为微软提供的地图控件与必应地图兼容。
但我们不知道的是,地图控件非常灵活,我们可以在其上显示几乎任何地图(感谢微软为我们提供了这种灵活性)。 因此,在这种方式下,我们不仅限于只显示必应地图,我们也可以使用其他任何地图,例如本文中介绍的谷歌地图。
背景
基本上,地图控件附带了必应地图的默认图像,我们只需要提供来自必应网站的开发者凭据,就可以使用必应地图了。 地图控件已经内置了所有基本功能,例如缩放和导航到地图。 我们所需要做的只是放置控件,提供凭据,然后我们就可以开始使用了。
Using the Code
对于谷歌地图,我们需要首先了解地图控件的工作方式,它基本上会不断调用一个方法 Uri GetUri(int x, int y, int zoomLevel)
,该方法返回一个 Uri,其中包含要显示的图块图像。 图块是 256x256 的图像,由其在网格中的 X 和 Y 位置定义,该网格形成了特定缩放级别的世界地图。
Uri GetUri(int x, int y, int zoomLevel)
我们所要做的就是编写一个从 Microsoft.Phone.Controls.Maps.TileSource
继承的类,该类包含一个重写方法 Uri GetUri(int x, int y, int zoomLevel)
,它将显示我们的自定义图块,在我们的例子中是谷歌地图图块。
首先,我们需要定义一个 Enum
,其中包含谷歌地图支持的所有地图模式。 我们稍后将在检查地图模式时使用这个 Enum
。
public enum GoogleTileTypes
{
Hybrid,
Physical,
Street,
Satellite,
WaterOverlay
}
接下来,我们开始编写上面讨论的类,该类将包含 Uri GetUri(int x, int y, int zoomLevel)
以及我们为方便起见创建的一些实用方法。
public class GoogleTile : Microsoft.Phone.Controls.Maps.TileSource
{
private int _server;
private char _mapmode;
private GoogleTileTypes _tiletypes;
public GoogleTileTypes TileTypes
{
get { return _tiletypes; }
set
{
_tiletypes = value;
MapMode = MapModeConverter(value);
}
}
public char MapMode
{
get { return _mapmode; }
set { _mapmode = value; }
}
public int Server
{
get { return _server; }
set { _server = value; }
}
public GoogleTile()
{
UriFormat = @"http://mt{0}.google.com/vt/lyrs={1}&z={2}&x={3}&y={4}";
Server = 0;
}
public override Uri GetUri(int x, int y, int zoomLevel)
{
if (zoomLevel > 0)
{
var Url = string.Format(UriFormat, Server, MapMode, zoomLevel, x, y);
return new Uri(Url);
}
return null;
}
private char MapModeConverter(GoogleTileTypes tiletype)
{
switch (tiletype)
{
case GoogleTileTypes.Hybrid:
{
return 'y';
}
case GoogleTileTypes.Physical:
{
return 't';
}
case GoogleTileTypes.Satellite:
{
return 's';
}
case GoogleTileTypes.Street:
{
return 'm';
}
case GoogleTileTypes.WaterOverlay:
{
return 'r';
}
}
return ' ';
}
}
我们使用以下 URL 作为我们的谷歌图块源
UriFormat = @"http://mt{0}.google.com/vt/lyrs={1}&z={2}&x={3}&y={4}";
我们有以下参数
- {0} 指的是服务器编号,我们将其保持为 1
- {1} 指的是地图模式的字符代码
- {2} 指的是地图的缩放级别
- {3} 指的是地图的 x 坐标
- {4} 指的是地图的 y 坐标
现在,我们开始 XAML 部分,在这里我们实际定义了地图控件及其图层。 首先,我们需要以下两个命名空间到 MainPage.xaml
xmlns:GoogleTileSource="clr-namespace:googlemaps;assembly=googlemaps"
xmlns:MSPCMCore="clr-namespace:Microsoft.Phone.Controls.Maps.Core;
assembly=Microsoft.Phone.Controls.Maps"
我们将地图模式保持为墨卡托投影,它告诉控件不要为地图加载任何默认图像。 接下来,我们在地图控件上放置图层,谷歌地图的图块将在其上显示。 我们使用了 5 个图层,因为我们希望根据用户对 RadioButton
的选择来更改地图的模式。 也可以通过使用不同的图层的 Opacity
属性来同时显示多个图层。 如果您想保持 Mode static
,则只需要一个图层。 每个图层都有其图块源,在这种情况下是 GoogleTile
类。
<Microsoft_Phone_Controls_Maps:Map Name="googlemap" Margin="0,161,0,0"
CopyrightVisibility="Collapsed" LogoVisibility="Collapsed"
ScaleVisibility="Visible" CredentialsProvider=
"ApBXPZf5IR94SLXE8nh5FYsb5WHKrH1XPY7428-EqQudseivcWhCROIJvGmtnkAV">
<Microsoft_Phone_Controls_Maps:Map.Mode>
<MSPCMCore:MercatorMode/>
</Microsoft_Phone_Controls_Maps:Map.Mode>
<Microsoft_Phone_Controls_Maps:MapTileLayer Name="street" Margin="0,0,0,32">
<Microsoft_Phone_Controls_Maps:MapTileLayer.TileSources>
<GoogleTileSource:GoogleTile TileTypes="Street"/>
</Microsoft_Phone_Controls_Maps:MapTileLayer.TileSources>
</Microsoft_Phone_Controls_Maps:MapTileLayer>
<Microsoft_Phone_Controls_Maps:MapTileLayer Visibility="Collapsed"
Name="wateroverlay" Margin="0,0,0,32">
<Microsoft_Phone_Controls_Maps:MapTileLayer.TileSources>
<GoogleTileSource:GoogleTile TileTypes="WaterOverlay"/>
</Microsoft_Phone_Controls_Maps:MapTileLayer.TileSources>
</Microsoft_Phone_Controls_Maps:MapTileLayer>
<Microsoft_Phone_Controls_Maps:MapTileLayer Visibility="Collapsed"
Name="hybrid" Margin="0,0,0,32">
<Microsoft_Phone_Controls_Maps:MapTileLayer.TileSources>
<GoogleTileSource:GoogleTile TileTypes="Hybrid"/>
</Microsoft_Phone_Controls_Maps:MapTileLayer.TileSources>
</Microsoft_Phone_Controls_Maps:MapTileLayer>
<Microsoft_Phone_Controls_Maps:MapTileLayer Visibility="Collapsed"
Name="satellite" Margin="0,0,0,32">
<Microsoft_Phone_Controls_Maps:MapTileLayer.TileSources>
<GoogleTileSource:GoogleTile TileTypes="Satellite"/>
</Microsoft_Phone_Controls_Maps:MapTileLayer.TileSources>
</Microsoft_Phone_Controls_Maps:MapTileLayer>
<Microsoft_Phone_Controls_Maps:MapTileLayer Visibility="Collapsed"
Name="physical" Margin="0,0,0,32">
<Microsoft_Phone_Controls_Maps:MapTileLayer.TileSources>
<GoogleTileSource:GoogleTile TileTypes="Physical"/>
</Microsoft_Phone_Controls_Maps:MapTileLayer.TileSources>
</Microsoft_Phone_Controls_Maps:MapTileLayer>
</Microsoft_Phone_Controls_Maps:Map>
最后,为了向用户提供一些更改模式和放大/缩小的基本功能,我们连接了一些事件处理程序。
private void Button_Click(object sender, RoutedEventArgs e)
{
if (h.IsChecked == true)
{
hybrid.Visibility = Visibility.Visible;
satellite.Visibility = Visibility.Collapsed;
street.Visibility = Visibility.Collapsed;
physical.Visibility = Visibility.Collapsed;
wateroverlay.Visibility = Visibility.Collapsed;
}
else if (st.IsChecked == true)
{
hybrid.Visibility = Visibility.Collapsed;
satellite.Visibility = Visibility.Collapsed;
street.Visibility = Visibility.Visible;
physical.Visibility = Visibility.Collapsed;
wateroverlay.Visibility = Visibility.Collapsed;
}
else if (sl.IsChecked == true)
{
hybrid.Visibility = Visibility.Collapsed;
satellite.Visibility = Visibility.Visible;
street.Visibility = Visibility.Collapsed;
physical.Visibility = Visibility.Collapsed;
wateroverlay.Visibility = Visibility.Collapsed;
}
else if (p.IsChecked == true)
{
hybrid.Visibility = Visibility.Collapsed;
satellite.Visibility = Visibility.Collapsed;
street.Visibility = Visibility.Collapsed;
physical.Visibility = Visibility.Visible;
wateroverlay.Visibility = Visibility.Collapsed;
}
else
{
hybrid.Visibility = Visibility.Collapsed;
satellite.Visibility = Visibility.Collapsed;
street.Visibility = Visibility.Collapsed;
physical.Visibility = Visibility.Collapsed;
wateroverlay.Visibility = Visibility.Visible;
}
}
private void ButtonZoomIn_Click(object sender, System.Windows.RoutedEventArgs e)
{
googlemap.ZoomLevel++;
}
private void ButtonZoomOut_Click(object sender, System.Windows.RoutedEventArgs e)
{
googlemap.ZoomLevel--;
}
因此,我们准备好使用几行代码开始,现在我们能够使用谷歌地图和微软在 Windows Phone 开发人员工具中提供的必应地图控件(感谢微软提供的地图控件的灵活性和通用性)。
关注点
将来,我计划提供一个更详细的教程,其中包含谷歌地图提供的所有功能,包括方向和路线。