• ArcGIS.Server.9.2.DotNet使用Virtual Earth地图图片数据(自带例子 九、二)


    目的:
    1.arcgis server9.2 ADF中把Virtual Earth地图图片数据作为数据源,这样可以直接使用MicroSoft的卫星图片

    准备工作:
    1.参考DeveloperKit\SamplesNET\Server\Web_Applications目录下的Common_CustomDataSourceCSharp.zip。
    完成后的效果图:


    开始:
    1.把Virtual Earth地图图片数据作为地图数据源,和(九、一)例子一样也是需要通过自定义数据源实现了,具体的关于地图数据、地图控件、Data Source、Resource、Functionatily之间的关系地图以及地图从数据到显示的整个过程说明可以参考(九、一)例子,这里不做详细的说明。
    2.新建名为CustomDataSource的ASP.NET Web应用程序,然后添加一个Default_TileMapData.aspx页面用来具体功能的展示。
    3.在CustomDataSource的解决方案中在添加一个名为TiledMapDataSource的类库工程,用来实现自定义DataSource类型和MapResource的功能。同时在CustomDataSource的ASP.NET Web应用程序中添加对这个TiledMapDataSource的类库工程的引用。
    4.同(九、一)例子一样自定义数据源的要在ADF中使用需要在ArcGisServer安装目录的DotNet文件内添加配置文件,关于配置文件的说明可以看(九、一)例子,添加名为ESRI.ArcGIS.ADF.Web.DataSources.TiledMap.config的配置文件,内容如下:

    Code

    5.从上面配置文件看,我们需要实现TiledMapDataSource.GISDataSource、TiledMapDataSource.MapResource这2个类,新建GISDataSource.cs和MapResource.cs两个文件。
    6.TiledMapDataSource.GISDataSource类和(九、一)例子一样了这里不详细说明了,同时也可以参考Common_CustomDataSourceCSharp.zip的源代码,这样需要对在TiledMapDataSource.GISDataSource类中使用到的MapInformation.cs类需要进行说明,与上例不同这次是采用Virtual Earth瓦块图片数据,所以MapInformation.cs类的实现较上例有些不同,主要区别是当MapInformation类实例化时,读取配置了Virtual Earth地图数据的一些配置参数对TileCacheInfo属性进行数据设置,主要是在方法parseConfig()中。
    Virtual Earth地图数据配置参数文件VirtualEarth_original.xml,具体节点说明可以对照parseConfig()方法,内容具体如下:

    Code

    MapInformation类具体的代码和说明如下:

      1namespace TiledMapDataSource
      2{
      3    public class MapInformation : IMapInformation
      4    {
      5        public MapInformation(string dataSourceDefinition, string resourceDefinition)
      6        {
      7            this.dataSourceConfig = dataSourceDefinition;
      8            resourceConfig = resourceDefinition;
      9            //读取对Virtual Earth地图数据的配置定义信心,包括名称、坐标系、图层、各个比例尺等信息
     10            parseConfig();
     11        }

     12
     13        private string dataSourceConfig = string.Empty;
     14        private string resourceConfig = string.Empty;
     15        private SpatialReference defaultSpatialReference = null;
     16        private TileCacheInfo tileCacheInfo = null;
     17        private Envelope defaultExtent, fullExtent;
     18
     19        //IMapInformation成员
     20        public string DataFrame
     21        {
     22            get return "(default)"; }
     23        }

     24        //IMapInformation成员
     25        public SpatialReference DefaultSpatialReference
     26        {
     27            get return defaultSpatialReference; }
     28        }

     29        //IMapInformation成员
     30        public Envelope DefaultExtent
     31        {
     32            get
     33            {
     34                return defaultExtent;
     35            }

     36        }

     37        //IMapInformation成员
     38        public Envelope FullExtent
     39        {
     40            get
     41            {
     42                return fullExtent;
     43            }

     44        }

     45        //IMapInformation成员
     46        public ESRI.ArcGIS.ADF.Web.DataSources.TileCacheInfo TileCacheInfo
     47        {
     48            get return tileCacheInfo; }
     49            set { tileCacheInfo = new TileCacheInfo(value); }
     50        }

     51
     52        private void parseConfig()
     53        {
     54            //读取xml文档
     55            XmlDocument doc = new XmlDocument();
     56            doc.Load(dataSourceConfig);
     57            XmlNode root = doc.DocumentElement;
     58            //读取TileCacheInfo节点
     59            XmlNodeList tileCacheInfoNodes = root.SelectNodes("TileCacheInfo");
     60            if (tileCacheInfoNodes == null || tileCacheInfoNodes.Count < 1)
     61            {
     62                throw new Exception("Could not find configuration for resource " + resourceConfig);
     63            }
       
     64
     65            XmlNode tileCacheNode = null;
     66            System.Collections.Generic.Dictionary<intstring> tileUrls = new Dictionary<intstring>();
     67            System.Collections.Generic.Dictionary<stringstring> layers = new Dictionary<stringstring>();
     68
     69            //如果Name节点为resourceConfig
     70            for (int t = 0; t < tileCacheInfoNodes.Count; ++t)
     71            {   
     72                if (tileCacheInfoNodes[t].Attributes["Name"].InnerText == resourceConfig)
     73                {
     74                    tileCacheNode = tileCacheInfoNodes[t];
     75                    break;
     76                }

     77            }

     78            //获取第一个节点
     79            if (tileCacheNode == null)
     80            {
     81                tileCacheNode = tileCacheInfoNodes[0];
     82            }

     83            //获取SpatialReference节点内容,坐标系统定义字符串
     84            string srtext = tileCacheNode.Attributes["SpatialReference"].InnerText;
     85            int srid;
     86            //设置defaultSpatialReference
     87            if (Int32.TryParse(srtext, out srid))
     88            {
     89                defaultSpatialReference = new SpatialReference(srid);
     90            }

     91            else
     92            {
     93                defaultSpatialReference = new SpatialReference(srtext);
     94            }

     95
     96            //获取图片解像度
     97            int dpi = Convert.ToInt32(tileCacheNode.Attributes["DPI"].InnerText);
     98            //瓦块图的高
     99            int height = Convert.ToInt32(tileCacheNode.Attributes["Height"].InnerText);
    100            //瓦块图的宽
    101            int width = Convert.ToInt32(tileCacheNode.Attributes["Width"].InnerText);
    102            //原点坐标
    103            string[] originCoords = tileCacheNode.Attributes["TileOrigin"].InnerText.Split(new char[] ',' });
    104            //最小x坐标
    105            double xmin = Convert.ToDouble(originCoords[0]);
    106            //最小y坐标
    107            double ymin = Convert.ToDouble(originCoords[1]);
    108            //原点
    109            Point origin = new Point(xmin, ymin);
    110
    111            //全图范围
    112            XmlNode extentNode = tileCacheNode.SelectSingleNode("FullExtent");
    113            xmin = Convert.ToDouble(extentNode.Attributes["XMin"].InnerText);
    114            ymin = Convert.ToDouble(extentNode.Attributes["YMin"].InnerText);
    115            double xmax = Convert.ToDouble(extentNode.Attributes["XMax"].InnerText);
    116            double ymax = Convert.ToDouble(extentNode.Attributes["YMax"].InnerText);
    117            fullExtent = new Envelope(xmin, ymin, xmax, ymax);
    118            fullExtent.SpatialReference = defaultSpatialReference;
    119
    120            //默认显示范围
    121            extentNode = tileCacheNode.SelectSingleNode("DefaultExtent");
    122            xmin = Convert.ToDouble(extentNode.Attributes["XMin"].InnerText);
    123            ymin = Convert.ToDouble(extentNode.Attributes["YMin"].InnerText);
    124            xmax = Convert.ToDouble(extentNode.Attributes["XMax"].InnerText);
    125            ymax = Convert.ToDouble(extentNode.Attributes["YMax"].InnerText);
    126            defaultExtent = new Envelope(xmin, ymin, xmax, ymax);
    127            defaultExtent.SpatialReference = defaultSpatialReference;
    128
    129            //获取图层id和名称
    130            XmlNode layersNode = tileCacheNode.SelectSingleNode("Layers");
    131            if (layersNode != null)
    132            {
    133                XmlNodeList layerNodes = layersNode.SelectNodes("Layer");
    134                if (layerNodes != null)
    135                {
    136                    for (int l = 0; l < layerNodes.Count; ++l)
    137                    {
    138                        string layerId = layerNodes[l].Attributes["LayerID"].InnerText;
    139                        string layerName = layerNodes[l].Attributes["Name"].InnerText;
    140                        layers.Add(layerId, layerName);
    141                    }

    142                }

    143            }

    144 
    145            //获取各个比例尺的信息
    146            System.Collections.Generic.List<LodInfo> lodInfos = new List<LodInfo>();
    147            System.Collections.Generic.Dictionary<intint> levels = new Dictionary<intint>();
    148            XmlNode lodInfoNode = tileCacheNode.SelectSingleNode("LodInfos");
    149            XmlNodeList lodInfoNodes = lodInfoNode.SelectNodes("LodInfo");
    150            for (int l = 0; l < lodInfoNodes.Count; ++l)
    151            {
    152                int levelid = Convert.ToInt32(lodInfoNodes[l].Attributes["LevelID"].InnerText);
    153                levels.Add(l, levelid);
    154                //瓦片图行数量
    155                int rows = Convert.ToInt32(lodInfoNodes[l].Attributes["Rows"].InnerText);
    156                //瓦片图列数量
    157                int columns = Convert.ToInt32(lodInfoNodes[l].Attributes["Columns"].InnerText);
    158                //瓦片图路径
    159                string tileUrl = lodInfoNodes[l].Attributes["TileUrl"].InnerText;
    160                //瓦片图地理宽度
    161                double tilewidth = Convert.ToDouble(lodInfoNodes[l].Attributes["TileExtentWidth"].InnerText);
    162                //瓦片图地理高度
    163                double tileheight = Convert.ToDouble(lodInfoNodes[l].Attributes["TileExtentHeight"].InnerText);
    164                //比例尺
    165                double scale = Convert.ToDouble(lodInfoNodes[l].Attributes["Scale"].InnerText);
    166                //分辨率
    167                double resolution = Convert.ToDouble(lodInfoNodes[l].Attributes["Resolution"].InnerText);
    168                LodInfo lodInfo = new LodInfo(levelid, resolution, scale, columns, rows, tilewidth, tileheight);
    169                lodInfos.Add(lodInfo);
    170                tileUrls.Add(levelid, tileUrl);
    171            }

    172
    173            //设置TileCacheInfo
    174            tileCacheInfo = new TileCacheInfo(width, height,dpi, origin, lodInfos.ToArray());
    175            tileCacheInfo.TileUrls = tileUrls;
    176            tileCacheInfo.Layers = layers;
    177            tileCacheInfo.Levels = levels;
    178
    179            //获取Virtual Earth瓦块图片路径处理类的Assembly和名称
    180            XmlNode urlGenNode = tileCacheNode.SelectSingleNode("TileUrlGenerator");
    181            if (urlGenNode != null)
    182            {
    183                tileCacheInfo.TileUrlGeneratorAssembly =urlGenNode.Attributes["Assembly"].InnerText;
    184                tileCacheInfo.TileUrlGeneratorClass =urlGenNode.Attributes["Class"].InnerText;
    185            }

    186
    187        }

    188    }

    189}

    190
    TileCacheInfo.cs类代码:
     1namespace TiledMapDataSource
     2{
     3    public class TileCacheInfo : ESRI.ArcGIS.ADF.Web.DataSources.TileCacheInfo
     4    {
     5        public TileCacheInfo(int width, int height, int dpi, Point origin, LodInfo[] lodInfos): base(width, height, dpi, origin, lodInfos)
     6        { }
     7        public TileCacheInfo(ESRI.ArcGIS.ADF.Web.DataSources.TileCacheInfo tci): base(tci.Width, tci.Height, tci.Dpi, tci.Origin, tci.LodInfos)
     8        { }
     9        internal System.Collections.Generic.Dictionary<intint> Levels = new Dictionary<intint>();
    10        internal System.Collections.Generic.Dictionary<intstring> TileUrls = new Dictionary<intstring>();
    11        internal System.Collections.Generic.Dictionary<stringstring> Layers = new Dictionary<stringstring>();
    12        internal string TileUrlGeneratorAssembly;
    13        internal string TileUrlGeneratorClass;
    14    }

    15}

    16

    7.MapResource类和(九、一)例子差不多了这里不详细说明了,具体的可以看Common_CustomDataSourceCSharp.zip的源代码,与上例不同的地方是这个Resource实现了TileFunctionality,因为本来的Virtual Earth地图数据源是切成小块的瓦块图,所以需要实现TileFunctionality,关于TileFunctionality的具体代码和说明如下:

      1namespace TiledMapDataSource
      2{
      3    class TileFunctionality : ITileFunctionality
      4    {
      5        ITileFunctionality 成员
     65
     66        IGISFunctionality 成员
    133
    134        private MapFunctionality GetMapFunctionality(string name)
    135        {
    136            MapFunctionality mapFunctionality = resource.Functionalities.Find(name) as MapFunctionality;
    137            return mapFunctionality;
    138        }

    139
    140        private object getInstanceOfType(string assemblyName, string type)
    141        {
    142            object o = null;
    143            try
    144            {
    145                System.Reflection.Assembly assembly = System.Reflection.Assembly.Load(assemblyName);
    146                o = assembly.CreateInstance(type);
    147            }

    148            catch (Exception e)
    149            {
    150                string mess = e.Message;
    151            }

    152            return o;
    153        }

    154    }

    155}

    156

    8.在TileFunctionality类中有用到ITileUrlGenerator接口,新建ITileUrlGenerator.cs文件,代码如下:

    1namespace TiledMapDataSource
    2{
    3    public interface ITileUrlGenerator
    4    {
    5        //获取瓦块图路径的的方法
    6        string GetTileUrl(long column, long row, int level, string defaultUrl, Dictionary<stringbool> layerVisibility);
    7    }

    8}

    9.在TileFunctionality类中有用到VirtualEarthTileUrlGenerator类,它实现了ITileUrlGenerator接口。VirtualEarthTileUrlGenerator方法是获取Virtual Earth的图片,所以有必要对VirtualEarth的图片算法进行了解,看如下的参考资料:
    卫星图和微软普通地图瓦片算法是一样的,区别在于卫星图要是a或者h开头,而微普通地图则是r开头,服务器地址不同下面举例:
    http://a1.ortho.tiles.virtualearth.net/tiles/a1322111.jpeg?g=1 这是不带label的微软卫星图
    http://h1.ortho.tiles.virtualearth.net/tiles/h1322111.jpeg?g=1 这是带label(如显示省份、地市)的微软卫星图
    http://r1.tiles.ditu.live.com/tiles/r1322111.png?g=1 这微软普通地图
    看到http://后面,红色的a、h、r分别代表不带label卫星图、带label卫星图、微软普通地图。
    10.有了上面的资料后就能知道如何取地图图片了,新建VirtualEarthTileUrlGenerator.cs文件,代码如下:

     1namespace TiledMapDataSource
     2{
     3    public class VirtualEarthTileUrlGenerator : ITileUrlGenerator
     4    {
     5        ITileUrlGenerator Members
    13
    14        //获取瓦块图路径,参数:瓦块列值,瓦块的行值,比例等级,可视图层
    15        private string GetUrl(int column, int row, int level, Dictionary<stringbool> layerVisibility)
    16        {
    17            string mapType = null;
    18            string mapExtension = null;
    19            //如果同时包括Road图层和Aerial图层
    20            if (layerVisibility["r"&& layerVisibility["a"])
    21            {
    22                mapType = "h";
    23                mapExtension = ".jpeg";
    24            }

    25            //只包括Road图层
    26            else if (layerVisibility["r"])
    27            {
    28                mapType = "r";
    29                mapExtension = ".png";
    30            }

    31            //只包括Aerial图层
    32            else if (layerVisibility["a"])
    33            {
    34                mapType = "a";
    35                mapExtension = ".jpeg";
    36            }

    37            else
    38            {
    39                return null;
    40            }

    41
    42            string quadKey = TileToQuadKey(column, row, level);
    43
    44            string url = String.Concat(new object[] "http://", mapType, quadKey[quadKey.Length - 1], ".ortho.tiles.virtualearth.net/tiles/", mapType, quadKey, mapExtension, "?g="1 });
    45            return url;
    46        }

    47
    48        //Virtual Earth图片名称的算法
    49        private static string TileToQuadKey(int tx, int ty, int zl)
    50        {
    51            string quad = "";
    52            for (int i = zl; i > 0; i--)
    53            {
    54                int mask = 1 << (i - 1);
    55                int cell = 0;
    56                if ((tx & mask) != 0)
    57                {
    58                    cell++;
    59                }

    60                if ((ty & mask) != 0)
    61                {
    62                    cell += 2;
    63                }

    64                quad += cell;
    65            }

    66            return quad;
    67        }

    68    }

    69}

    11.剩下的MapFunctionality.cs和MapTocFunctionality.cs和上例类似比较简单了不做详细解释,具体参考Common_CustomDataSourceCSharp.zip的源代码。

    12.这样自定义数据源完成了,接下在就是测试这个数据源,在CustomDataSource的ASP.NET Web应用程序的Default_TileMapData.aspx页面中添加Map1、MapResourceManager1、Toc13个控件,然后做相应的设置,具体设置可以参考前面的文章。
    13.接下来在MapResourceManager1中在Server Resource上面在新增加名为Virtual Earth,在弹出的Map Resource Definition Editor中Type:选择TiledMap就是上面添加到DotNet文件内的ESRI.ArcGIS.ADF.Web.DataSources.TiledMap.config中定义的名字,在Data Source:输入上面的那个xml的地址,如:D:\VirtualEarth_original.xml,然后确定就完成了设置。这里的Data Source为了方便是输入的方式了,最好的做法可以参考Common_CustomDataSourceCSharp.zip样例为它做一个xml文件选择界面,具体的参考CustomDataSource_CSharp\REXMLDataSource_CSharp\Design\DataSourceDefinitionEditorFormREXML.cs,是一个Winform的选择节目,只有在config文件配置一下,就可以在
    Map Resource Definition Editor中调用自己定制的编辑器。
    14.运行查看效果,这样成功的把Virtual Earth的卫星图片显示在我们的页面中了。

     

  • 相关阅读:
    【Blog怎么玩】如何修改博客地址栏logo—怎样查找和制作ico文件
    【Blog怎么玩】怎么给博客添加支付宝/微信打赏按钮—tctip打赏插件开源
    【免费开源网站】利用乐云xzc.cn结合百度网盘来收作业
    【数字信号处理不挂科-笔记】第三讲-离散傅立叶变换
    【数字信号处理不挂科-笔记】第一讲-离散时间信号与系统
    【Blog怎么玩】学长教你怎么在博客里播放音乐+krc转lrc(krc2lrc)
    【南工程开源计划-通信网】南工程通信09级A卷-通信网
    【南工程开源计划-通信网】南工程通信07级A卷-通信网
    【南工程开源计划-通信网】南工程通卓15级B卷-电力系统通信网期末考试
    【南工程开源计划-通信网】南工程通卓17级A卷-通信网期末考试
  • 原文地址:https://www.cnblogs.com/hll2008/p/1281479.html
Copyright © 2020-2023  润新知