【Silverlight】Bing Maps开发应用与技巧四:自定义MapMode实现地图访问限制

  在某些情况下可能会出现只需要访问(加载)某块区域的地图显示,也可能需要对地图的缩放级别进行限制,或者只能让地图在5--10级之间进行深度缩放。要实现这些功能就需要通过自定义MapMode来实现了。本篇将为您介绍如何通过自定义MapMode来实现地图访问限制的常用方法与技巧。

 

  首先需要了解下Bing Maps Silverlight Control的地图投影模式(MapMode)的架构模型,所有的地图投影模式都是根据投影抽象基类(MapMode)扩展而来。比如二维平面地图投影模式(FlatMapMode)、三维立体地图投影模式(MapMode3D:此投影模式目前尚未使用,为以后的扩展而保留)以及空地图投影模式(NullMode)等。如下图:

        

  如上图所示,其中的墨卡托投影模式(MercatorMode),通过继承于平面地图投影模式(FlatMapMode)对下提供基于墨卡托投影的地图空间映射模型,其下分别实现了加载卫星地图的卫星投影模式(AerialMode)和街道地图的街道投影模式(RoadMode),分别用于实现加载微软卫星地图和街道地图。

 

  如本篇前面提到的实现地图的访问范围和深度缩放级别限制,从上面对Bing Maps Silverlight Control的地图投影模式架构设计的整体分析,可知要实现访问限制可以从MercatorMode基类开始,MercatorMode提供了基于墨卡托投影的地理空间坐标系的完整地图投影模式实现,要自定义的平面地图投影模式则可以直接通过扩展MercatorMode来实现。比如下自定义模式用于加载中国地区的地图瓦片:

///   <summary>
///  自定义地图投影模式
///   </summary>
public   class  ChinaMode : MercatorMode
{
}

 

  通过MercatorMode继承过来有分别处理地图加载范围(ConstrainView)和地图深度缩放级别(GetZoomrange)的两个方法。实际上我们要在地图访问上做一些范围的限制主要就是通过重写这两个方法的具体实现。如下代码块演示了加载经度从70--140范围的地图,且地图缩放级别只能是在3--10级之间进行缩放。

 

///   <summary>
///  自定义地图投影模式
///   </summary>
public   class  ChinaMode : MercatorMode
{
    
///   <summary>
    
///  纬度范围
    
///   </summary>
     public  Range < double >  LatitudeRange  =   new  Range < double > ( - 50.0 50.0 );
    
///   <summary>
    
///  经度范围(70-140刚好就是中国地图区域)
    
///   </summary>
     public  Range < double >  LongitudeRange  =   new  Range < double > ( 70.0 140.0 );
    
///   <summary>
    
///  深度缩放范围(3-10级)
    
///   </summary>
     public  Range < double >  MapZoomrange  =   new  Range < double > ( 3.0 10.0 );

    
///   <summary>
    
///  
    
///   </summary>
    
///   <param name="center"> 地图中心地理坐标 </param>
    
///   <param name="zoomLevel"> 地图缩放级别 </param>
    
///   <param name="heading"> 定向视图标题 </param>
    
///   <param name="pitch"></param>
    
///   <returns> 是否有值更改 </returns>
     public   override   bool  ConstrainView(Location center,  ref   double  zoomLevel,  ref   double  heading ref   double  pitch)
    {
        
return   base .ConstrainView(center,  ref  zoomLevel,  ref  heading ref  pitch);
    }

    
///   <summary>
    
///  确定地图深度缩放范围
    
///   </summary>
    
///   <param name="center"></param>
    
///   <returns></returns>
     protected   override  Range < double >  GetZoomrange(Location center)
    {
        //只能访问3-10级地图
        
return   this .MapZoomrange;
    }

    
///   <summary>
    
///  重写鼠标中键滚轮操作行为
    
///   </summary>
    
///   <param name="e"></param>
     public   override   void  OnMouseWheel(MapMouseWheelEventArgs e)
    {
        
if  ((e.WheelDelta  >   0.0 &&  ( this .ZoomLevel  >=   this .MapZoomrange.To))
        {
            e.Handled 
=   true ;
        }
        
else
        {
            
base .OnMouseWheel(e);
        }
    }

    
///   <summary>
    
///  重写鼠标拖放地图行为
    
///   </summary>
    
///   <param name="e"></param>
     public   override   void  OnMouseDragBox(MapMouseDragEventArgs e)
    {
        
if  ((( this .TargetBoundingRectangle.East  <=   this .LongitudeRange.To)
            
&&  ( this .TargetBoundingRectangle.West  >=   this .LongitudeRange.From)))
        {
            e.Handled 
=   true ;
        }
        
else
        {
            e.Handled 
=   false ;
        }
    }
}

 

   通过以上方式自定义的地图投影模式,使用和内置的投影模式一样的简单,可以直接在XAML代码里配置,也可以在后台代码里动态指定。详细如下代码片段:

< m:Map  x:Name ="map"  Margin ="0,0"  CredentialsProvider =" {StaticResource MyCredentials} "
        MouseClick
="map_MouseClick"
        ScaleVisibility
="Visible"
        copyrightVisibility
="Collapsed" >
    
< m:Map.Mode >
        
<!-- 使用自定义的地图投影模式 -->
        
< mode:ChinaMode ></ mode:ChinaMode >
    
</ m:Map.Mode >
</ m:Map >

 

  后台代码中动态指定和Bing Maps Silverlight Control中内置的投影模式使用方式是完全一样的,直接将投影模式的实例赋值给Map控件的Mode属性

public  MainPage()
{
    InitializeComponent();
    
this .Loaded  +=  (o, e)  =>
        {
            
this .map.Mode  =   new  ChinaMode();
            map.ZoomLevel
= 5 ;
        };
}

 

        

 

相关文章

如何在Silverlight4(XAML)中绑定IsEnabled属性?我试过简单的...
我正在编写我的第一个vb.net应用程序(但我也会在这里标记c#,...
ProcessFile()是在UIThread上运行还是在单独的线程上运行.如...
我从同行那里听说,对sharepoint的了解对职业生涯有益.我们不...
我正在尝试保存一个类我的类对象的集合.我收到一个错误说明:...
我需要根据Silverlight中的某些配置值设置给定控件的Style.我...