在Bing Maps开发中,由于各种应用功能的不同,更多的时候用户可能需要将自己的一部分图片数据作为地图数据用来呈现在Bing Maps中,要实现这一功能就首先需要了解Bing Maps的TileSystem的相关算法,然后在对图片进行切片为Bing Maps TileSystem算法所对应的图片格式和命名等,以此来实现发布自己的图片数据,并通过自定义TileSource来实现加载自定义发布的地图数据。
 
  微软提供有专门用来切片源图片的工具MapCruncher,可以通过 http://research.microsoft.com/en-us/um/redmond/projects/mapcruncher/下载并安装此工具就可以自定义图片切片生成Bing Maps Tile System规律的相同大小不同文件名地图图片。首先需要准备一张源图片,这里我就随便找一张图片来做演示,如下:
        
 
  接下来就使用MapCruncher来进行图片切片生成,关于如何使用MapCruncher工具请访问 http://research.microsoft.com/en-us/um/redmond/projects/mapcruncher/tutorial/version3.0docs/index.htm,这里需要对上面提供的源图片进行切片,在MapCruncher中进行描点后就可以生成切片图了,如下图所示:
    
 
  如上图通过点击"Render"就可以根据该工具的向导完成图片的切片生成我们需要的地图图片,如下图为部署在IIS 中的目录地图图片结构:    
    
 
  到这里对于地图图片的准备工作就完成了,通过MapCruncher这个工具生成了地图格式的图片并部署在IIS中。如上图所示,可以通过: http://localhost/Maps%7Bquadkey%7D.png 来访问这些地图图片。
 
  接下来就可以根据 http://localhost/Maps/ { quadkey} .png 这样的Tile System映射地址来自定义TileSource实现对自己部署的地图图片的加载算法,详细实现如下:
public   class  CustomTileSource : LocationRectTileSource
{
    
private   const   string  baseUrl  =   " http://localhost/Maps/{0}.png " ;

    
public  CustomTileSource()
        : 
base (baseUrl,  new  LocationRect( new  Location( 60 60 ),  new  Location( 13 140 )),
            
new  Range < double > ( 1 17 ))
    { }

    
///   <summary>
    
///  重写Tile算法
    
///   </summary>
    
///   <param name="x"></param>
    
///   <param name="y"></param>
    
///   <param name="zoomLevel"></param>
    
///   <returns></returns>
     public   override  Uri GetUri( int  x,  int  y,  int  zoomLevel)
    {
        
return   new  Uri( string .Format( this .UriFormat, TileXYToQuadKey(x, y, zoomLevel)), UriKind.RelativeOrAbsolute);
    }

    
///   <summary>
    
///  坐标转换
    
///   </summary>
    
///   <param name="tileX"></param>
    
///   <param name="tileY"></param>
    
///   <param name="levelOfDetail"></param>
    
///   <returns></returns>
     private   static   string  TileXYToQuadKey( int  tileX,  int  tileY,  int  levelOfDetail)
    {
        StringBuilder quadKey 
=   new  StringBuilder();
        
for  ( int  i  =  levelOfDetail; i  >   0 ; i -- )
        {
            
char  digit  =   ' 0 ' ;
            
int  mask  =   1   <<  (i  -   1 );
            
if  ((tileX  &  mask)  !=   0 )
            {
                digit
++ ;
            }
            
if  ((tileY  &  mask)  !=   0 )
            {
                digit
++ ;
                digit
++ ;
            }
            quadKey.Append(digit);
        }
        
return  quadKey.ToString();
    }
}
 
  
  在Silverlight端可以进行如下定义,来完成加载自己部署的地图数据。
< m:Map  x:Name ="map"  Margin ="0,0,0,0"  CredentialsProvider =" {StaticResource MyCredentials} "  
       ScaleVisibility
="Visible"
       CopyrightVisibility
="Collapsed" >
    
< m:MapTileLayer  x:Name ="CustomMapTileLayer" ></ m:MapTileLayer >
</ m:Map >
 
 
  名为CustomMapTileLayer的MapTileLayer则专门负责加载呈现自定义部署的地图图片数据,通过设置MapTileLayer的TileSources来应用上面自定义的TileSource算法,详细实现如下代码块:
public  MainPage()
{
    InitializeComponent();
    
this .Loaded  +=  (o, e)  =>
        {
            
this .CustomMapTileLayer.TileSources.Add( new  CustomTileSource());
            
this .map.Mode  =   new  MercatorMode();
            map.ZoomLevel 
=   5 ;
        };
}
 
   这里需要注意一点就是设置了地图的Mode属性为MercatorMode,用于限制地图控件只加载自定义的地图图层,也就是不加载Bing Maps默认的地图底板图层。最终的运行效果如下图所示:
      
 
 
   推荐资源:
  Bing Maps Tile System: http://msdn.microsoft.com/en-us/library/bb259689.aspx
  MapCruncher: http://research.microsoft.com/en-us/um/redmond/projects/mapcruncher/
   【Silverlight】Bing Maps学习系列(八):使用Bing Maps Silverlight Control加载自己部署的Google Maps
   Bing Maps进阶系列八:在Bing Maps中集成OpenStreetMap地图