WebGIS中通过行列号来换算出多种瓦片的URL 之离线地图

1.前言

在前面我花了两个篇幅来讲解行列号的获取,也解释了为什么要获取行列号。在这一章,我将把常见的几种请求瓦片时的URL样式罗列出来,并且给出大致的解释。

我在这里将地图分为离线地图和在线地图。所谓离线地图,即保存在本地而没有发布的地图。在线地图即发布与网上,可以通过浏览器访问的地图。

2.ArcGIS切图——exploded类型

在前面章节中我已经贴出了exploded类型的切图图片,这里再次给出。

那么如何通过行列号来换算出此瓦片的URL呢。我们首先可以通过观察得出三个结论:

(1)L开头的代表了Level,R开头的代表了row,C开头的代表了Col。

(2)确定这个后,我们再继续观察,可以发现L后的数字是两位字符串,R后的是八位字符串,C后的也是八位字符串。

(3)英文后的数字均是16进制数,然后不足位数的用0补充。

我想大家在知道了这三个结论后,通过行列号来获得离线松散瓦片的地址该不难了吧,我们只需把级别、行列号换算成16进制后,不足位数的再用0补位,最后加上英文标识,于是这个瓦片的地址也便可以额找到了。

3.ArcGIS 切图——bundle类型

这里我也首先贴出这种瓦片类型的样式:

这个瓦片的获取咋一看确实是毫无头绪,因为arcgis的这种紧凑型格式将图片进行了包装,并不能直观的看到图片。ArcGIS号称这种格式目前是不公开解析方法的,并且同样在网上也很难收到对应的解析方法。但是,我的一个很有想法的同事,在去年时花了些时间后已经将这种格式下的瓦片获取方法破解了,并且我们已经成功运用到多个项目中。

这里我就只给出几个提示吧,根据我的这几个提示,我想读者只要再加一把劲一定可以破解的:

(1)同样,L、R、C后的是地图的级别、行号、列号。

(2)R、C后的字符串固定是4位。

(3)R、C后的数字是通过行列号除以128后再转成16进制,然后将不足的位数补零。

(4)Bundle文件中存放的是图片二进制流,BundleX文件中存放的是对应瓦片在Bundle中的地址,是一个索引文件。

(5)然后…..

然后就是如何在索引文件中找到应该读取的地方,获得瓦片在Bundle中所在的地址后,再去Bundle中的相应地址里读取图片。不过,这里补充一下,Bundle中也不是只有瓦片的,它里面还包含了每个瓦片的大小,也就是你读这个瓦片需要读取多少个二进制的数目。

这里再次感谢我的同事的智慧的结晶,否则这篇文章一定是不完整的。

4.非常见瓦片格式——国土局的瓦片

在我们项目中经常可以见到非ArcGIS的瓦片系列,比如超图的、中地的等等。这里我给出某国土局的瓦片格式,其实目前很多国土局自己的瓦片均是这个组织格式。

同样我先给出瓦片的样式图:

大家是不是很奇怪,明明该是三个层次的呀,Level、Row、Col的呀,怎么这个就有四个层次呢。是的,国土局的瓦片中除了这三个参数外,还有一个FileID参数。

这里我直接给出换算公式:

FixedLevel=Level;

FixedRow=Math.floor(Row/4);

FixedCol=Math.floor(Col/4);

FileID=(Row)%4)+ 4*((Col)%4);

其URL的地址就是\FixedLevel\FixedRow\FixedCol\FileID.png。

5.总结

在这一节里我们针对两种常见离线地图格式和一种特殊的离线地图格式进行了解析。从这个解析中我们可以看出,不管是什么地图,行列号都是必须的条件。所以对行列号如何得到还不是很清楚的读者,请将我这个系列中的第二节和第三节再次专心的读一遍,相信你和我一样一定有不一样的收获的。

下一节里,我们将对在线的地图的URL解析进行讲解,在线的地图的URL获取相对简单。我们同样会对符合OGC标准的在线地图以及特殊的在线地图服务进行分析。欢迎持续关注。

ArcGIS Flex API读取自定义瓦片地图

PortlandTiledMapServiceLayer.as

  1. package com.esri.ags.samples
  2. {
  3.  
  4. import com.esri.ags.SpatialReference;
  5. import com.esri.ags.geometry.Extent;
  6. import com.esri.ags.geometry.MapPoint;
  7. import com.esri.ags.layers.supportClasses.LOD;
  8. import com.esri.ags.layers.supportClasses.TileInfo;
  9. import com.esri.ags.layers.TiledMapServiceLayer;
  10.  
  11. import flash.net.URLRequest;
  12.  
  13. /**
  14. * PortlandTiledMapServiceLayer
  15. */
  16. public class PortlandTiledMapServiceLayer extends TiledMapServiceLayer
  17. {
  18. //--------------------------------------------------------------------------
  19. //
  20. // Constructor
  21. //
  22. //--------------------------------------------------------------------------
  23.  
  24. /**
  25. * Creates a new PortlandTiledMapServiceLayer object.
  26. */
  27. public function PortlandTiledMapServiceLayer()
  28. {
  29. super();
  30.  
  31. buildTileInfo(); // to create our hardcoded tileInfo
  32.  
  33. setLoaded(true); // Map will only use loaded layers
  34. }
  35.  
  36. //--------------------------------------------------------------------------
  37. //
  38. // Variables
  39. //
  40. //--------------------------------------------------------------------------
  41.  
  42. private var _tileInfo:TileInfo = new TileInfo(); // see buildTileInfo()
  43. private var _baseURL:String = "http://sampleserver1.arcgisonline.com/arcgiscache/Portland_Portland_ESRI_LandBase_AGO/Portland/_alllayers";
  44.  
  45. //--------------------------------------------------------------------------
  46. //
  47. // Overridden properties
  48. // fullExtent()
  49. // initialExtent()
  50. // spatialReference()
  51. // tileInfo()
  52. // units()
  53. //
  54. //--------------------------------------------------------------------------
  55.  
  56. //----------------------------------
  57. // fullExtent
  58. // - required to calculate the tiles to use
  59. //----------------------------------
  60.  
  61. override public function get fullExtent():Extent
  62. {
  63. return new Extent(-123.596895130725, 44.297575737946, -121.553757125519, 46.3683237161949, new SpatialReference(4326));
  64. }
  65.  
  66. //----------------------------------
  67. // initialExtent
  68. // - needed if Map doesn't have an extent
  69. //----------------------------------
  70.  
  71. override public function get initialExtent():Extent
  72. {
  73. return new Extent(-122.539, 45.500, -122.540, 45.501, new SpatialReference(4326));
  74. }
  75.  
  76. //----------------------------------
  77. // spatialReference
  78. // - needed if Map doesn't have a spatialReference
  79. //----------------------------------
  80.  
  81. override public function get spatialReference():SpatialReference
  82. {
  83. return new SpatialReference(4326);
  84. }
  85.  
  86. //----------------------------------
  87. // tileInfo
  88. //----------------------------------
  89.  
  90. override public function get tileInfo():TileInfo
  91. {
  92. return _tileInfo;
  93. }
  94.  
  95. //----------------------------------
  96. // units
  97. // - needed if Map doesn't have it set
  98. //----------------------------------
  99.  
  100. override public function get units():String
  101. {
  102. return "esriDecimalDegrees";
  103. }
  104.  
  105. //--------------------------------------------------------------------------
  106. //
  107. // Overridden methods
  108. // getTileURL(level:Number, row:Number, col:Number):URLRequest
  109. //
  110. //--------------------------------------------------------------------------
  111.  
  112. override protected function getTileURL(level:Number, row:Number, col:Number):URLRequest
  113. {
  114. // Use virtual cache directory
  115. // This assumes the cache's virtual directory is exposed, which allows you access
  116. // to tile from the Web server via the public cache directory.
  117. // Example of a URL for a tile retrieved from the virtual cache directory:
  118. // http://serverx.esri.com/arcgiscache/dgaerials/Layers/_alllayers/L01/R0000051f/C000004e4.jpg
  119. var url:String = _baseURL
  120. + "/L" + padString(String(level), 2, "0")
  121. + "/R" + padString(row.toString(16), 8, "0")
  122. + "/C" + padString(col.toString(16), 8, "0") + ".png";
  123. return new URLRequest(url);
  124. }
  125.  
  126. //--------------------------------------------------------------------------
  127. //
  128. // Private Methods
  129. //
  130. //--------------------------------------------------------------------------
  131.  
  132. private function buildTileInfo():void
  133. {
  134. _tileInfo.height = 512;
  135. _tileInfo.width = 512;
  136. _tileInfo.origin = new MapPoint(-180, 90);
  137. _tileInfo.spatialReference = new SpatialReference(4326);
  138. _tileInfo.lods =
  139. [
  140. new LOD(0, 0.351562499999999, 147748799.285417),
  141. new LOD(1, 0.17578125, 73874399.6427087),
  142. new LOD(2, 0.0878906250000001, 36937199.8213544),
  143. new LOD(3, 0.0439453125, 18468599.9106772),
  144. new LOD(4, 0.02197265625, 9234299.95533859),
  145. new LOD(5, 0.010986328125, 4617149.97766929),
  146. new LOD(6, 0.0054931640625, 2308574.98883465),
  147. new LOD(7, 0.00274658203124999, 1154287.49441732),
  148. new LOD(8, 0.001373291015625, 577143.747208662),
  149. new LOD(9, 0.0006866455078125, 288571.873604331),
  150. new LOD(10, 0.000343322753906249, 144285.936802165),
  151. new LOD(11, 0.000171661376953125, 72142.9684010827),
  152. new LOD(12, 0.0000858306884765626, 36071.4842005414),
  153. new LOD(13, 0.0000429153442382813, 18035.7421002707),
  154. new LOD(14, 0.0000214576721191406, 9017.87105013534),
  155. new LOD(15, 0.0000107288360595703, 4508.93552506767)
  156. ];
  157. }
  158.  
  159. private function padString(text:String, size:int, ch:String):String
  160. {
  161. while (text.length < size)
  162. {
  163. text = ch + text;
  164. }
  165. return text;
  166. }
  167. }
  168.  
  169. }

customtiled.mxml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
  3. xmlns:s="library://ns.adobe.com/flex/spark"
  4. xmlns:mx="library://ns.adobe.com/flex/mx"
  5. xmlns:esri="http://www.esri.com/2008/ags"
  6. xmlns:samples="com.esri.ags.samples.*"
  7. pageTitle="Extending TiledMapServiceLayer in Flex API">
  8. <!--
  9. @@includeFiles com/esri/ags/samples/PortlandTiledMapServiceLayer.as
  10.  
  11. This sample shows how tiles can be used without the REST endpoint.
  12.  
  13. The ArcGIS API for Flex allows for extending the API
  14. to access layer types not included as part of the API.
  15. In this example, tiled layers (TiledMapServiceLayer) is extended
  16. to access tiles created in 9.2 or above and made accessible
  17. in the standard virtual directory.
  18.  
  19. Steps involved:
  20. 1. Creating new ActionScript class that extends TiledMapServiceLayer.
  21. 2. Hardcoding some of the configuration settings:
  22. fullExtent, initialExtent, spatialReference, tileInfo, and units.
  23. 3. Overriding the protected function getTileURL() to obtain the appropriate
  24. tiles and place them accurately on the map.
  25. 4. Using the extended class with MXML or ActionScript :)
  26. -->
  27.  
  28. <esri:Map id="myMap">
  29. <samples:PortlandTiledMapServiceLayer id="virtualTiles" fadeInFrameCount="12"/>
  30. </esri:Map>
  31.  
  32. <s:Label width="85%"
  33. backgroundColor="0xFFFF00"
  34. color="0x000000"
  35. fontSize="14"
  36. fontWeight="bold"
  37. horizontalCenter="0"
  38. paddingBottom="10"
  39. paddingLeft="10"
  40. paddingRight="10"
  41. paddingTop="10"
  42. text="By extending TiledMapServiceLayer, this application can access tiles from an ArcGIS 9.2 (or above) virtual directory. This specific service is in the {virtualTiles.spatialReference.wkid} spatialReference and has {virtualTiles.tileInfo.lods.length} scale levels."/>
  43. </s:Application>

WebGIS中通过行列号来换算出多种瓦片的URL 之离线地图(转载)的更多相关文章

  1. 从底层谈WebGIS 原理设计与实现(四):WebGIS中通过行列号来换算出多种瓦片的URL 之离线地图

    从底层谈WebGIS 原理设计与实现(四):WebGIS中通过行列号来换算出多种瓦片的URL 之离线地图 作者:naaoveGI…    文章来源:naaoveGIS    点击数:1759    更 ...

  2. (四)WebGIS中通过行列号来换算出多种瓦片的URL 之离线地图

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.前言 在前面我花了两个篇幅来讲解行列号的获取,也解释了为什么要获取行 ...

  3. 从底层谈WebGIS 原理设计与实现(五):WebGIS中通过行列号来换算出多种瓦片的URL 之在线地图

    从底层谈WebGIS 原理设计与实现(五):WebGIS中通过行列号来换算出多种瓦片的URL 之在线地图 作者:naaoveGI…    文章来源:naaoveGIS    点击数:2063    更 ...

  4. 【总结整理】webGIS学习thinkGIS(四)WebGIS中通过行列号来换算出多种瓦片的URL 之离线地

    http://www.thinkgis.cn/topic/541a5319da8db186fd06e097 1.前言 在前面我花了两个篇幅来讲解行列号的获取,也解释了为什么要获取行列号.在这一章,我将 ...

  5. (五)WebGIS中通过行列号来换算出多种瓦片的URL 之在线地图

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.前言 这篇文章里,我主要针对OGC标准中的WMS.WMTS以及Ar ...

  6. WebGIS中自定义互联网地图局部注记的一种方案

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.    前言 实际项目中我们经常会遇到这样一种场景:地图底图可能是互 ...

  7. (八)WebGIS中栅格图层的设计

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.    前言 我们在上一章里了解到WebGIS中栅格图层的本质—— ...

  8. 从底层谈WebGIS 原理设计与实现(三):WebGIS前端地图显示之根据地理范围换算出瓦片行列号的原理(转载)

    从底层谈WebGIS 原理设计与实现(三):WebGIS前端地图显示之根据地理范围换算出瓦片行列号的原理 1.前言   在上一节中我们知道了屏幕上一像素等于实际中多少单位长度(米或经纬度)的换算方法, ...

  9. (三)WebGIS前端地图显示之根据地理范围换算出瓦片行列号的原理(核心)

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.前言 在上一节中我们知道了屏幕上一像素等于实际中多少单位长度(米或 ...

随机推荐

  1. 快速部署Python应用:Nginx+uWSGI配置详解

    在PHP里,最方便的就是deployment了,只要把php文件丢到支持PHP的路径里面,然后访问那个路径就能使用了:无论给主机添加多少PHP应用,只要把目录改好就没你的事了,完全不用关心php-cg ...

  2. space 管理

    输入:表空间名字 输出:表空间下的一个文件即退出 /tmp/.sql select name from v$database; set serveroutput on; declare i1 varc ...

  3. [jQueryUI] – Chosen:select下拉选择框美化插件及问题

    Chosen 是一个支持jquery的select下拉框美化插件,它能让丑陋的.很长的select选择框变的更好看.更方便.不仅如此,它更扩展了select,增加了自动筛选的功能.它可对列表进行分组, ...

  4. 设置span 宽度的完美解决方案

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. iOS的基本图形绘制

    绘图的步骤: 1.获取上下文 2.创建路径(描述路径) 3.把路径添加到上下文 4.渲染上下文 通常在- (void)drawRect:(CGRect)rect这个方法里面绘制图形 为什么要再draw ...

  6. 转:web_custom_request应用示例

    LoadRunner提供的web_custom_request函数可以用于实现参数的动态生成.在LoadRunner中,web_reg_save_param和custom_request都常于处理参数 ...

  7. docker rancher 体验 (未完待续.....)

    docker rancher 体验 官方 githubhttps://github.com/rancher/rancher 环境说明: 10.6.0.14010.6.0.18710.6.0.188 修 ...

  8. 基于Verilog HDL 的数字电压表设计

    本次实验是在“基于Verilog HDL的ADC0809CCN数据采样”实验上进一步改进,利用ADC0809采集到的8位数据,进行BCD编码,以供查表方式相加进行显示,本次实验用三位数码管. ADC0 ...

  9. flex4 list 自动适应高度

    <s:List width="100%"> <s:layout> <s:VerticalLayout useVirtualLayout="f ...

  10. HDU 5166 Missing number 简单数论

    Missing number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) [ ...