青梅猪马

by LionGG, a GIS Major

 

在BMSL中使用Google 地图

BMSL,即Bing Maps Silverlight Control的简称,入门请看帮助文档和iSDK,比如申请Key之类,否则会出现“Invalidate Credentials ”的警告。看题目貌似我又来砸场子了,其实不是。遥想当年,Google Maps刚刚诞生之时,并无相应的API。不久就有人Hack之,于是Google就顺势推出API,自此风靡……此外,这也并非全部是我的原创,关注BMSL这么久,各种文章看得也不少(参考文献就不列了),自此算是总结性的进阶教程。

 

言归正传,首先,正规性的用自己的数据继承TileSource,比如我们利用Google地图的瓦片数据:

    public class GoogleMapsTileSource : TileSource

    {

        public GoogleMapsTileSource()

            : base("http://mt{0}.google.com/vt/lyrs=m@107&hl=en&x={1}&y={2}&z={3}&s=Ga")

        {

        }

 

        public override Uri GetUri(int x, int y, int zoomLevel)

        {

            int num = ((x & 1) << 1) | (y & 1);

            return new Uri(string.Format(this.UriFormat, num, x, y, zoomLevel));

        }

}

然后,将其作为MapTileLayer的属性,加到Map中即可。XAML形式:

        <m:Map CredentialsProvider={YourKey}>

            <m:Map.Children>

                <m:MapTileLayer>

                    <m:MapTileLayer.TileSources>

                        <local:GoogleMapsTileSource />

                    </m:MapTileLayer.TileSources>

                </m:MapTileLayer>

            </m:Map.Children>

    </m:Map>

 

如此这般,即可得到Google Maps的简易Silverlight版本,但若用Fiddler等工具查看就会发现,上述程序后台仍旧下载了Bing Maps的数据。其实是因为在Bing Maps上覆盖了一层Google Maps的数据,后面的一层看不到而已。于是再进一步,去掉Bing Maps的数据。

        <m:Map CredentialsProvider={YourKey}>

            <m:Map.Mode>

                <mCore:MercatorMode />

            </m:Map.Mode>

            <m:Map.Children>

                <m:MapTileLayer>

                    <m:MapTileLayer.TileSources>

                        <local:GoogleMapsTileSource />

                    </m:MapTileLayer.TileSources>

                </m:MapTileLayer>

            </m:Map.Children>

    </m:Map>

也即加入了Mode的控制,把MapMode由默认的RoadModeAerialMode)设置为空,即他们的父类MercatorMode。在BMSL中,Mode的能耐挺大,后续专文介绍。现在用Fiddler一看,便只有Goolge Maps的数据了。

 

但是,虽然我们只用了Google Maps的数据,却仍然需要Bing Maps的验证密钥CredentialsProvider={YourKey},能不能去掉它?CredentialsProviderMap的属性,那不用这个Map类,即可忽略这个类的属性。于是我们想到从当前Map的父类MapCore去继承,写出一个自己的Map。如下,注意MapMode又出现了。

    public class GoogleMaps : MapCore

    {

        public GoogleMaps()

            : base()

        {

            Mode = new GoogleMapsMode();

        }

    }

 

    public class GoogleMapsMode : RoadMode

    {

        public GoogleMapsMode()

            : base()

        {

            var tileLayer = (MapTileLayer)this.Content;

            tileLayer.TileSources.Clear();

            tileLayer.TileSources.Add(new GoogleMapsTileSource());

        }

}

XAML的关键语句一行即可。

<local:GoogleMaps />

 

    至此,本文基本结束。上述方法造成默认的导航等控件消失,不过没关系,我博客里多次提到的DeepEarth等项目提供了不少,而且自定义也未尝不可。同时,再扩展下,可利用Google Maps的卫星影像,地形地图等等。PS:本文仅作学习之用,勿要商用,要不然微软和谷歌会一起来打你PP,呵呵。

示意图:http://hi.baidu.com/liongg/blog/item/f81a632775c25a09918f9d42.html 

posted on 2009-11-14 11:02  狮兄  阅读(1726)  评论(8编辑  收藏  举报

导航