silverlight   发布时间:2022-05-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了基于DeepZoom技术的Bing Maps客户端实现研究大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

概述

  目前基于Silverlight技术的Web GIS客户端实现,包括微软Bing Maps Silverlight Control,以及开源的Web GIS客户端组件DeepEarth项目,核心都是采用Silverlight中的DeepZoom技术实现。可能您已经知道DeepZoom技术以MultiScaleIR_277_11845@age控件为核心,其内部有一个MultiScaleTilesource类型的源属性,

  目前基于Silverlight技术的Web GIS客户端实现,包括微软Bing Maps Silverlight Control,以及开源的Web GIS客户端组件DeepEarth项目,核心都是采用Silverlight中的DeepZoom技术实现。可能您已经知道DeepZoom技术以MultiScaleIR_277_11845@age控件为核心,其内部有@L_905_2@multiScaleTilesource类型的源属性,主要用于设置MultiScaleIR_277_11845@age控件所要呈现的数据源,可以通过学习Deep Zoom Composer快速上手。

 

  通过Deep Zoom Composer创建基于图片的Silverlight项目,可以@L_675_6@一个基于MultiScaleIR_277_11845@age控件的图片查看应用,完全实现了图片的平铺,以及平滑、缩放以及拖拽等功能特性。 实际上基于Silverlight的Web GIS客户端实现也是通MultiScaleIR_277_11845@age控件来实现,核心就在于通过MultiScaleTilesource属性针对不同的Web GIS地图瓦片数据(Image Tiles)提供商为MultiScaleIR_277_11845@age控件实现一个数据源。

 

  对于微软的Bing Maps,则需要通过了解Bing Maps Tile System,然后针对其图片映射系统发布出的地图服务编写MultiScaleIR_277_11845@age控件的数据源实现就行了。在实现前还需要借助http嗅探器工具抓获到Bing Maps的Tiles路径,如下路径格式:

   街道地图:http: // r{0}.ortho.tiles.virtualearth.net/tiles/r{1}.png?g=203
   卫星地图:http: // h{0}.ortho.tiles.virtualearth.net/tiles/h{1}.jpeg?g=203

 

  有了上面的Bing Maps的Tiles路径,接下来就可以基于这两个路径为MultiScaleIR_277_11845@age控件编写数据源的实现(既MultiScaleTilesource)了,如下代码块:

public   abstract   class  BingMapsTilesource : MultiScaleTilesource
{
    
protected  BingMapsTilesource()
        : 
base ( int .MaxValue,  int .MaxValue,  0x100 0 )
    { }
}

 

  通过上面代码块的Tilesource的编程模板可以看出,BingMapsTilesource继承与DeepZoom的核心类MultiScaleTilesource,其加载图片数据的算法由MultiScaleTilesource的实例方法GetTileLayers()完成。因此要想实现按照自己的前面获取到的Bing Maps的Tiles路径去获取Bing Maps的地图数据,就应该重写该方法的实现,让其更改加载数据的方式。

      

基于DeepZoom技术的Bing Maps客户端实现研究

///   <sumMary>
///  图层Tile算法
///   </sumMary>
///   <param NAME="tileLevel"> 缩放级别 </param>
///   <param NAME="tilePositionX"> X坐标 </param>
///   <param NAME="tilePositionY"> Y坐标 </param>
///   <param NAME="tileImageLayersources"> 图层源集合 </param>
protected   override   void  GetTileLayers( int  tileLevel,  int  tilePositionX,  int  tilePositionY, IList < object >  tileImageLayersources)
{
    
int  zoom  =  tileLevel  -   8 ;
    
if  (zoom  >   0 )
    {
        
String  QuadKey  =  TileXYToQuadKey(tilePositionX, tilePositionY, zoom);
        
String  veLink  =   String .Format(UriFormat, new   object [] { QuadKeY[QuadKey.Length  -   1 ], QuadKey });
        var veUri 
=   new  Uri(veLink);
        tileImageLayersources.Add(veUri);
    }
}

 

   上面代码段中实现了按照Bing Maps的Tiles路径格式去计算完整的地图数据地址,然后将其加入到图层源列表中,需要主要的是这里用到了Bing Maps Tile System中的一个方法TileXYToQuadKey(),该放松实现将图层的X,Y坐标值转化为Bing Maps的Tile QuadKey参数值,也就是Tile地址(http://h{0}.ortho.tiles.virtualearth.net/tiles/h{1}.jpeg?g=203)中的第二个参数值。则BingMapsTileSource类完整代码如下:

namespace  BingMapsClient.Tilesources
{
    
public   abstract   class  BingMapsTilesource : MultiScaleTilesource
    {
        
protected  BingMapsTilesource()
            : 
base ( int .MaxValue,  0 )
        { }

        
///   <sumMary>
        
///  地图的Tile映射地址
        
///   </sumMary>
         public   abstract   String  UriFormat {  get ; }

        
///   <sumMary>
        
///  转换X,Y坐标值为地图的QuadKey参数值
        
///   </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)
        {
            var 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();
        }

        
///   <sumMary>
        
///  图层Tile算法
        
///   </sumMary>
        
///   <param NAME="tileLevel"> 缩放级别 </param>
        
///   <param NAME="tilePositionX"> X坐标 </param>
        
///   <param NAME="tilePositionY"> Y坐标 </param>
        
///   <param NAME="tileImageLayersources"> 图层源集合 </param>
         protected   override   void  GetTileLayers( int  tileLevel, IList < object >  tileImageLayersources)
        {
            
int  zoom  =  tileLevel  -   8 ;
            
if  (zoom  >   0 )
            {
                
String  QuadKey  =  TileXYToQuadKey(tilePositionX, zoom);
                
String  veLink  =   String .Format(UriFormat, QuadKey });
                var veUri 
=   new  Uri(veLink);
                tileImageLayersources.Add(veUri);
            }
        }
    }
}

 

  以上只是定义了一个基于Bing Maps的Tiles地址的通用Tilesource模型,需要改变的就是Tile地址,既然UrlFormat属性。如果需要分别实现加载街道地图和卫星地图的Tilesource,只需要制定相应的Tile地址就OK了。如下实现代码

public class  BingMapsroadTilesource : BingMapsTilesource
{
    
public override String
 UriFormat
    {
        
get { return "http://r{0}.ortho.tiles.virtualearth.net/tiles/r{1}.png?g=203"
; }
    }
}

public class
 BingMapSAErialTilesource : BingMapsTilesource
{
    
public override String
 UriFormat
    {
        
get { return "http://h{0}.ortho.tiles.virtualearth.net/tiles/h{1}.jpeg?g=203"
; }
    }
}

 

  接下来看看如果将上面的工作成果应用到Silverlight中,在XAML中实现如下布局,主要也就是使用@L_905_2@multiScaleIR_277_11845@age控件。

 

<Grid x:Name="LayoutRoot" BACkground="White">
    
<@H_266_539@multiScaleIR_277_11845@age Height="600" x:Name="msi" Width="600"/>
</Grid>

 

    msi.source  =   new  BingMapsroadTilesource();

 

  现在就是操作MultiScaleIR_277_11845@age控件了,所谓操作其实也就是动态的获取或设置MultiScaleIR_277_11845@age控件的某些属性以及调用某些方法。以下是MultiScaleIR_277_11845@age控件比较常用的属性或方法

  source:即DeepZoomComposer导出的文件(单个文件为Info.bin,集合为Items.bin)

  SubImages:子图片,如果DeepZoomComposer导出的为集合的话,其将集合中每个元素作为@L_905_2@multiScaleSubImage对象存储在这个集合中。对子图片的操作就全靠它了。

  UsingSprings:是否启用其认动画(就是那中很飘逸的感觉,取消则比较生硬了)

  Viewport: 视口位置(可以简单理解成眼睛所在位置,有过3D编程经验的比较容易理解)

  ViewportWidth:视口宽度,视口越宽看到的东西越到(感觉上离图片越远,或图片缩小了)

  ViewportOrigin:视窗内显示图像的左上角坐标位置。

  AspectRatio:宽高比。

  ElementToLogicPoint():从元素坐标(物理坐标)转换为逻辑坐标 (元素坐标则是我们平时所说的普通坐标,逻辑坐标则是指元素左上角为0,0点,右下角为1,1点而言的相对坐标)

  LogictoElementPoint():与上述相反。

  ZoomAboutLogicPoint(double, double, doublE)按逻辑坐标缩放,第一个参数指定缩放增量,后两个参数指定缩放中心。

  @H_79_817@motionFinished事件:动画结束(或者说当你操作图片或子图后其运动结束)

 

   比如说现在需要处理鼠标移动的事件,需要虑两种情况,如果鼠标是拖拽的需要将地图拖动在放下的时候进行重新定位,如果只是简单的移动则不需要进行地图定位,这就需要通过获取视窗大小(ViewportWidth)以及当前所在视窗内的坐标点(Point)来计算出新的坐标点,然后进行重定位实现。

private  Point currentPosition;
private  Point dragOffset;
private   bool  mouseIsDragging;

this .MouseMove  +=   delegate ( object  sender, MouseEventArgs E)
{
    
if  (mouseIsDragging)
    {
        var newOrigin 
=   new  Point();
        newOrigin.X 
=  currentPosition.X  -
                        (((e.GetPosition(msi).X 
-  dragOffset.X)  /  msi.ActualWidth)  *  msi.ViewportWidth);
        newOrigin.Y 
=  currentPosition.Y  -
                        (((e.GetPosition(msi).Y 
-  dragOffset.Y)  /  msi.ActualHeight)  *  msi.ViewportWidth);
        msi.ViewportOrigin 
=  newOrigin;
    }
};

 

      

基于DeepZoom技术的Bing Maps客户端实现研究

 

  本篇暂且介绍到这里,通过本篇的介绍,基本上实现了一个基于微软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/

      SilverlightShow:http://www.silverlightshow.net/items/Virtual-earth-deep-zooming.aspx

  DeepZoom:http://blogs.msdn.com/silverlight_sdk/archive/2008/11/18/using-viewportorigin-and-viewportwidth-in-deep-zoom.aspx

  【Silverlight】Bing Maps系列文章

  http://cn.bing.com/ditu/  

 

  

基于DeepZoom技术的Bing Maps客户端实现研究

大佬总结

以上是大佬教程为你收集整理的基于DeepZoom技术的Bing Maps客户端实现研究全部内容,希望文章能够帮你解决基于DeepZoom技术的Bing Maps客户端实现研究所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。