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

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.74/5 (48投票s)

2011 年 2 月 3 日

CPOL

3分钟阅读

viewsIcon

183456

downloadIcon

6109

本文介绍了如何使用Microsoft随Windows Phone 7开发者工具提供的地图控件来使用Google地图。

main.PNG

引言

微软最近推出了必应地图,它是谷歌地图的直接竞争对手。 必应地图相对较新,与谷歌地图相比,数据量和地图深度当然较少,谷歌地图在该领域已经存在了相当长的时间。 开发人员经常希望将谷歌地图整合到他们的 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 开发人员工具中提供的必应地图控件(感谢微软提供的地图控件的灵活性和通用性)。

hybrid.PNG physical.PNG wateroverlay.PNG

street.PNG satellite.PNG

关注点

将来,我计划提供一个更详细的教程,其中包含谷歌地图提供的所有功能,包括方向和路线。

使用必应地图控件的 Windows Phone 7 谷歌地图 - CodeProject - 代码之家
© . All rights reserved.