青梅猪马
百度空间 | 百度首页 
 
文章列表
 
2009年11月17日 星期二 13:50

       和传统GIS客户端架构有所不同,BMSLMapMode的方式来控制Map的一些特征,比如更换地图瓦片数据,限定缩放级别,固定平移范围;甚至是控制鼠标键盘事件导航地图的方式,以及地理坐标与像素坐标的映射等。

         Map有属性曰Mode,类型为MapModeMapMode有子类FlatMapModeFlatMapMode有子类MercatorModeMercatorMode有两个子类RoadModeAerialMode。(关系简单,不再图示)

         MercatorMode设置了Web Mercator投影的相关投影,RoadModeAerialMode分别定了Bing Maps的数据类型,以及导航控件等。比如把MapMode设置为空的MercatorMode,即可清除Bing Maps数据,替换其中的TileSource,即可更换底图数据。

         若要限制显示范围,则要定制自己的MapMode,比如从RoadMode继承,覆盖GetZoomRange限制缩放级别,覆盖ConstrainView限制平移范围。


        下文的示例,大致限定在中国经纬度范围内,缩放级别限定在310之间,并把底图数据改变为Google卫星地图以及它的地图注记数据(即那些汉字标绘),如何自定义TileSource请参考《BMSL中使用Google 地图》。

    public class ChinaMode : RoadMode
    {
        private Range<double> validLatitudeRange = new Range<double>(3.92, 53.51);
        private Range<double> validLongitudeRange = new Range<double>(73.60, 135.01);

        public ChinaMode()
            : base()
        {
            var tileLayer = (MapTileLayer)this.Content;
            tileLayer.TileSources.Clear();
            tileLayer.TileSources.Add(new GoogleSatelliteTileSource());
            tileLayer.TileSources.Add(new GoogleLabelTileSource());
        }

        protected override Range<double> GetZoomRange(Location center)
        {
            return new Range<double>(3, 10);
        }

        public override bool ConstrainView(Location center, ref double zoomLevel, ref double heading, ref double pitch)
        {
            bool isChanged = base.ConstrainView(center, ref zoomLevel, ref heading, ref pitch);
            double newLatitude = center.Latitude;
            double newLongitude = center.Longitude;
            if (center.Longitude > validLongitudeRange.To)
            {
                newLongitude = validLongitudeRange.To;
            }
            else if (center.Longitude < validLongitudeRange.From)
            {
                newLongitude = validLongitudeRange.From;
            }

            if (center.Latitude > validLatitudeRange.To)
            {
                newLatitude = validLatitudeRange.To;
            }
            else if (center.Latitude < validLatitudeRange.From)
            {
                newLatitude = validLatitudeRange.From;
            }

            if (newLatitude != center.Latitude || newLongitude != center.Longitude)
            {
                center.Latitude = newLatitude;
                center.Longitude = newLongitude;
                isChanged = true;
            }

            Range<double> range = GetZoomRange(center);
            if (zoomLevel > range.To)
            {
                zoomLevel = range.To;
                isChanged = true;
            }
            else if (zoomLevel < range.From)
            {
                zoomLevel = range.From;
                isChanged = true;
            }

            return isChanged;
        }

    }

         定义好之后,调用起来很方便。

XAML<m:Map x:Name="myMap" CredentialsProvider="Your Key" /> C#

            myMap.Mode = new ChinaMode();

            myMap.SetView(new Location(37.5, 104.3), 4);

            myMap.MapForeground.TemplateApplied += (s, e) =>

            {

                myMap.MapForeground.NavigationBar.TemplateApplied += (sender, eventArgs) =>

                    {

                        myMap.MapForeground.NavigationBar.HorizontalPanel.Children.Clear();

                    };

            };

         限定显示范围内,导航条中的缩放条会自动根据所设置的级别变化,但需要手工屏蔽它自带的RoadAerial的按钮。上述C#后面的代码作用即此,请注意图中左上角的导航条变化。

 
2009年11月15日 星期日 16:01

       BMSL V1除包含CTP版的诸如DeepZoom等所有特性外,基于Silverlight3构建,支持OOBBlend设计时,并利用Bing Maps Key的方式授权。值得一提的新功能有:

       Map Mode的扩展性增强,比如新增的Fading Labels功能,即来源于此。

       内置PushpinBinding:原来没有默认的地理标记,最基本的添加个地理要素也需要自定义个形状,在Earthware等人的呼吁下,终于默认提供了,并提供MapItemsControl支持批量地物绑定,俺觉得后者有些多余。

       Bing Maps Web Service:对相关类,属性,方法进行一系列包装,可以更加方便的再BMSL中使用。

       国际支持:通过设置Mapculture属性,可以使用某地区本地的瓦片数据。

       可嵌入性:无需懂得编程,按照给定URL的参数规范,设定相应的值,嵌入到原来的程序中,即可显示地图。此功能目前有限,仅支持添加pushpin等简单用途。

脚本API:对那些不愿意使用VS等开发工具的同学们来说是个顶级好消息,利用相关API的脚本接口,在JavaScript里完成相关开发程序。

      

       Embeddable MapsScriptable API其实是微软自己开发的在线应用程序,通过特定的URL参数和脚本接口,来让普通用户使用。在线程序网址,也即使用Embeddable Maps特性时的URL前缀:http://dev.virtualearth.net/embeddedMap/v1/silverlight ;其中的XAP,也即使用Scriptable API必需引用的XAP源:http://dev.virtualearth.net/silverlight/mapcontrol/v1/Microsoft.Maps.MapControl.xap

        把该XAP下载解压缩反编译,可以发现程序集Microsoft.Maps.MapControl.Scripting.dll中的ScriptableMapMap继承,ScriptableMapLayerMapLayer继承,开放相应接口,共同构成Scriptable API。而在App类的Application_Startup中,根据规范的URL参数,来载入相应的地图数据,从而支持了Embeddable Map功能。
        

       基本来说,新特性就上述这么点东西。对比EarthWaretop-10-wish-list还差得老远,比如模块的重新设计,KML/GeoRSS的内置支持,Clustering,绘制工具,导航控件自定义风格能够更容易等等。因此估计他们和我一样不免失望。

         但同时Embeddable MapsScriptable API功能的支持方法,也提醒我们,不要总想着依赖基础商给我们定制太多的东西,很多好玩的,我们自己,或者说更靠近用户的开发商,可以自己去玩玩。

 
2009年11月14日 星期六 10:32

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的控制,把Map的Mode由默认的RoadMode(AerialMode)设置为空,即他们的父类MercatorMode。在BMSL中,Mode的能耐挺大,后续专文介绍。现在用Fiddler一看,便只有Goolge Maps的数据了。

但是,虽然我们只用了Google Maps的数据,却仍然需要Bing Maps的验证密钥CredentialsProvider={YourKey},能不能去掉它?CredentialsProvider是Map的属性,那不用这个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,呵呵。

 
2009年11月11日 星期三 11:19

Bing Maps Silverlight Control自从3月发布CTP版后,8个月不见动静,甚至沦落到在论坛里已经有人问这个项目是不是死掉了。终于,跳过Beta直接就发布正式版。参见官方报道1官方报道2视频新闻等。同时,Bing Maps彻底翻新,增加了诸多新特性,比如:Draggable Routes,缩放条样式更新,和Silverlight Control一致,必应版(中国版)截至目前尚未更新。

        

因为盼得太久,所以看到邮件通知和RSS更新相关新闻,迫不及待统统转一圈浏览个遍。带着太大的希望,期待着太多的惊喜,最后终得来的是落差,和CTP版相比,尽管有诸多新特性,仍没见震撼性更新,甚至一些bug都不曾消除。

    

下面播报一些相关链接,新特性介绍将另篇文章,原来打算写一系列进阶学习性的文章,如此看来,作罢。入门学习请看iSDK,微软必应地图大中华区业务拓展经理acnChen博士的博客也有一系列文章介绍。

     

Bing Maps Account Center注册账号申请密钥使用相关服务,申请>>

安装包:和Silverlight Toolkit一样,是个MSI安装包,里面含有相关DLL下载>>

收费情况:总体上很优惠,对EducatorsNot-for-Profits都免费,详情>>

交互式SDK:入门学习就从这里开始,iSDK>>

在线帮助文档:有许多专题介绍,进阶材料,MSDN>>

Bing Maps Control论坛:提问或者看看别人的问题,灌水>>

    

附带两个Bug,通过isdk的示例都可以发现。真不好意思,一发布就来砸场子,希望下个版本能够解决,通过acnChen反映到开发团队。

     

用滚轮缩放地图时,导航条的滑块上下抖动,视觉效果不好。我自己试图去解决这个Bug,但若让滑块不抖动,则会出现不能点击导航杆放缩,只能拖动滑块缩放。但我相信微软的工程师应该比我厉害吧……11月13日更新,这个应该是根据中心点位置实时计算缩放级别而造成的,不应该是BUG。倒是地图放在 一个大小确定的Grid中,平移时会发现在国际日期变更线处明显闪动。

     

iSDK"Add a shape layer"为例,当地图放大到倒数第4级时,三角形是正常的;但再放大一个级别,三角形的填充就反了。如图所示,俺故意选取了湖泊陆地交界的区域更容易看,填充到三角形外围了;继续放大可能就又对了,将出现随机填充的情况。我向别人咨询过,据说是Windows 裁剪的问题,在GIS中是个老问题,有较为成熟的解决方案。


 
2009年11月10日 星期二 10:55

问题描述:当向地图上加载大数量Marker或者Pushpin时,会出现彼此覆盖和加载速度过慢的问题,解决方案就是Marker Cluster或者叫Pushpin Clustering

              

GoogleMaps的解决方案:《Handling Large Amounts of Markers in Google Maps》详细论述并比较了Google Maps上目前的7种解决方案。若果非得挑选一种,那就是Google Geo今年4月在官方博客中提到的MarkerClusterer,作者是中国的工程师Xiaoxi Wu,而且已经开源,放到gmaps-utility-library中了。

         

          

              

Bing Maps的解决方案:微软于去年9月发布6.2版时官方支持,称之为Pushpin Clustering。在交互式iSDKCustomize Shape下有个 Pushpin cluster ,同时有两篇文章介绍如何使用如何自定义。之前也有非官方的替代方案,不再介绍。

     


      

ESRI的解决方案:ESRIFlex API中提供了解决方案,据说非常之受欢迎,Silverlight API也提供了类似的功能。

           

还有一些其他公司的解决方案,比如IDVUMapperMaptimize 似乎专业做这个的。


      

 
     
 
 
关于我
 

订阅博客的RSS地址: RSS

遵循的创作共享协议: CCL

作者和博客详尽介绍: About

文章分类与专题介绍: Topic

A GIS Major @ NJU & CAS

   
 
What's New
 
   
 
文章分类
 
 
 
 
Gis(56)
 
 
 
 
 
 
 
     
 
日历
 
     
 
最新评论
 
文章评论|照片评论


不错
 

写的挺详细的,不错
 

这个问题产品部门已经file了,希望下一版本能够解决
 

学习了。我这也是这个原因
 

你真速度
 
http://labs.metacarta.com/wms/vmap0?&LAYERS=basic&REQUEST=GetMap&SERVICE=WMS&...
 
http://labs.metacarta.com/wms/vmap0?&LAYERS=basic&REQUEST=GetMap&SERVICE=WMS&...
 
啊~看到我们的艾老师~
 
你是哪个部门的?
 
     
 
最近访客
 
 

kitboys

linux_k

vincentarea

股市有春天

Dayed_

qianyepiao

不羁311

hu221188
     
 
玩GIS的
 
 
 
 
 
 
     
 
订阅我的空间
 
已有人次访问本空间
 
订阅RSS  什么是RSS?

您也想拥有这样的空间?请点此申请。
     


©2009 Baidu