青梅猪马

by LionGG, a GIS Major

 

BMSL:Map Mode解析

       和传统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#后面的代码作用即此,请注意图中左上角的导航条变化。示例结果图示: http://hi.baidu.com/liongg/blog/item/5724d42a1d048291033bf620.html 

posted on 2009-11-17 22:43  狮兄  阅读(1727)  评论(2编辑  收藏  举报

导航