若转发请于分明处标明出处,若转发请于显著处标明出处

小说版权由小编李晓晖和博客园共有,若转发请于鲜明处标明出处:http://www.cnblogs.com/naaoveGIS/

小说版权由小编李晓晖和和讯共有,若转发请于分明处标明出处:http://www.cnblogs.com/naaoveGIS/

小说版权由小编李晓晖和微博共有,若转发请于显然处标明出处:http://www.cnblogs.com/naaoveGIS/

1.前言

下周利用夜晚在家时间研商了下怎么着行使AE来开垦切图工具。最初的想法是直接调用GP服务,利用CreateMapServerCache 、ManageMapServerCacheTiles 和吉优processor 那样多少个类来做。但是那些思路有个了不起的弊病就是必须先揭橥地图服务。于是接下去又立即转移思路,想能或无法通过瓦片选址算法以及AE的有的细粒度类来兑现这些职能。在经过了多个夜晚的算法编写和法力编写后,整个工具基本成型,个中囊括了对算法的优化以及壹些实际难点的消除。那里跟大家大致分享下。

1.前言

上周利用上午在家时间研商了下什么利用AE来开采切图工具。最初的想法是直接调用GP服务,利用CreateMapServerCache 、ManageMapServerCacheTiles 和吉优processor 那样八个类来做。但是这些思路有个了不起的流弊正是必须先发表地图服务。于是接下去又及时调换思路,想能不能够通过瓦片选址算法以及AE的1些细粒度类来贯彻这么些职能。在通过了四个早晨的算法编写和效率编写后,整个工具基本成型,其中包蕴了对算法的优化以及一些具体难点的化解。那里跟大家大约分享下。

1.前言

在上一节中大家领略了屏幕上一像素等于实际中有个别单位长度(米或经纬度)的折算方法,而知道这一个规律后,接下去大家要怎么用它吧?它和大家前端展现地图有怎么着关联呢?那一节,笔者会尽量详细的将那五个难点逐壹次答。说1个题外话,那一多元的文章作者都会少给代码,多画流程图或许UML图来跟大家交换,壹来便于未有过多GIS和编制程序基础的人读懂,2来使我们不局限于某种代码的兑现而更关切于原理。

二.切图的基本原理和贯彻

万一对瓦片和瓦片寻址的相干算法不纯熟的情侣,请参考作者写的从底层商讨WebGIS的法则类别:http://www.cnblogs.com/naaoveGIS/category/600559.html

那里笔者向来给出所涉及到的多少个公式。

2.切图的基本原理和落实

即使对瓦片和瓦片寻址的相干算法不熟习的情侣,请参考我写的从最底层研商WebGIS的原理体系:http://www.cnblogs.com/naaoveGIS/category/600559.html

那里作者一向给出所涉及到的多少个公式。

2.影象金字塔简介

我们事先反复提到了印象金字塔这么些概念,然而尚未对其做1个大致的介绍,那里作者将以此概念补充一下。

二.壹Resolution转换公式

resolution=scale*inch2centimeter/dpi。个中scale是地图比例尺,inch二centimeter为英寸转毫米的参数,dpi为壹英寸所包涵的像素。

二.壹Resolution转移公式

resolution=scale*inch贰centimeter/dpi。个中scale是地图比例尺,inch贰centimeter为英寸转毫米的参数,dpi为1英寸所包涵的像素。

2.一 为啥要出现印象金字塔那个概念

现行反革命,作者只要大家的服务器上有1个1G的形象,须求将其在前端实行彰显。我们古板的做法正是首先将服务器中的一G形象下载到前端,然后浏览器加载渲染出图。但是大家想想,首先客户端下载一G的影象需求的时光必然是个漫长的经过,其次浏览器加载这么大的文书也多半会促成其崩溃。而最关键的一个题材是,大家的急需仅仅是浏览全图中的某二个区域下的某多少个等第,今后却将全图下载完成了,而那等同还造成了数额的不安全性(下载到本地),同时大家的每贰重放大和压缩以及拖拽都将会使浏览器花上丰裕长的时日去渲染。

可知,守旧的方式是不符合实际须要的。到后来,又有了新的缓解办法,比如arcgis的IMS版本中建议了动态出图的定义。也正是近年来端发出的央浼里含有了亟需体现的限定、呈现窗口的分寸等参数后,后台动态的在原有数据中切出三个相符供给的瓦片,然后将那几个数额再次回到给前台,并且在服务器中对那么些瓦片做缓存。

不过,那一个方法前端出图依然一点也不快,并且使地图服务器的压力过大。终于,大家的形象金字塔化解方案出现了。

二.二行列号获取公式

若果,地图切图的原点是(originX,oringinY),地图的瓦片大小是tileSize,地图荧屏上壹像素代表的实际距离是resolution。计算坐标点(x,y)所在的瓦片的队列号的公式是:

col  = floor((originX- x)/( tileSize*resolution))

row = floor((oringinY – y)/( tileSize*resolution))

2.二行列号获取公式

借使,地图切图的原点是(originX,oringinY),地图的瓦片大小是tileSize,地图显示屏上1像素代表的其实距离是resolution。总计坐标点(x,y)所在的瓦片的队列号的公式是:

col  = floor((originX- x)/( tileSize*resolution))

row = floor((oringinY – y)/( tileSize*resolution))

2.2原理

形象金字塔正是,大家第三将原本印象根据用户的急需,比如用户须求彰显多少种比例尺下的数码,需求出示的是原有影象中的哪个区域的多少,将本来印象依照那几个供给进行剪切和提取。如图:

 图片 1

最低层就是我们领到和剪切出的比例尺最小的一流的瓦片,而最上层的则是比例尺最大的一流的瓦片。大家精心侦察能够发现那样的3个规律:比例尺越小的等第瓦片数据越少,反之则越大。而那么些规律造成的结果就是:比例尺越小的等级切图的速度越快,同时,同样大小的瓦片所富含的影象范围越多。

当我们创设好了影象金子塔后,前端再请求地图时,则将只是在切好的瓦片缓存中,找到相应等第里对应的瓦片就能够。然后在前端将那么些请求到的瓦片拼接出来,便足以拿走用户要求的等级下的可视范围内的瓦片了。

二.三AGS瓦片的表征

本工具的靶子是切出与AGS瓦片相同格式的瓦片。AGS的瓦片具有以下特点(在http://www.cnblogs.com/naaoveGIS/p/3903270.html自作者做了详细的教学):

(a).L伊始的意味了Level,XC60起首的意味了row,C开头的表示了Col。

(b). L后的数字是两位字符串,帕杰罗后的是7位字符串,C后的也是陆位字符串。

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

二.三AGS瓦片的风味

本工具的靶子是切出与AGS瓦片相同格式的瓦片。AGS的瓦片具有以下特点(在http://www.cnblogs.com/naaoveGIS/p/3903270.html自个儿做了详实的执教):

(a).L开端的意味了Level,LAND初始的表示了row,C开首的表示了Col。

(b). L后的数字是两位字符串,中华V后的是八人字符串,C后的也是四人字符串。

(c).英文后的数字均是1陆进制数,然后不足位数的用0补充。

三.瓦片队列号的折算原理

2.三基于上述公式流程

  
大家率先得到用户输入的切图品级数组levelScaleArr,瓦片大小(imgWidth,imgHeight),切图原点(originX,originY)还有像素值DPI。同时我们还要通过接口得到此时地图的界定(dXMin,dYMin,dX马克斯,dYMax)。

   流程的盒模型如下所示:

       图片 2            

  

2.三依照以上公式流程

  
大家第一获得用户输入的切图等级数组levelScaleArr,瓦片大小(imgWidth,imgHeight),切图原点(originX,originY)还有像素值DPI。同时大家还要经过接口获得此时地图的限量(dXMin,dYMin,dX马克斯,dY马克斯)。

   流程的盒模型如下所示:

       图片 3            

  

三.壹 为何要换算瓦片行列号

上一节中自身付诸了形象图切成离散型图后文件的团协会方式,个中给大家来得了在那种切图下,文件的团体其实是安份守己瓦片的等第、行、列号来协会的。事实上,紧密型瓦片(Bundle)的集体体制也是这么,只是它在获得了行列号后还要进行一名目繁多换算,比如读取索引文件找到文件中的偏移量等,这么些换算格局本身在随后的章节跟大家来谈谈。并且,标准的WMS请求中也关系到行列号的折算,WMS请求中有一个Bbox的参数,而以此参数也与行列号的折算有涉嫌。而规范的WMTS请求中,TILEMAT汉兰达IX、TILEROW、TILECOL那多少个参数代表的正是瓦片的等级、行、列号。

有鉴于此,不管是对准哪一种离线或在线的地图的瓦片请求中,获得瓦片的level、col、row是伸手能够实现的主题。

2.4实现

兑现上,首要运用了AE做了这么多少个职能:

(a).使用IMapControl类得到mxd的四角坐标。

(b).使用IActiveView、ExportPNGClass和EnvelopeClass完成将地图局地导出成效。

别的均依据上述流程图完成。

2.4实现

贯彻上,首要运用了AE做了这么多少个成效:

(a).使用IMapControl类获得mxd的四角坐标。

(b).使用IActiveView、ExportPNGClass和EnvelopeClass完成将地图局地导出成效。

其它均依据上述流程图实现。

三.2瓦片行列号换算原理

上面,我们先交付瓦片行列号换算的公式。

若是,地图切图的原点是(x0,y0),地图的瓦片大小是tileSize,地图显示器上1像素代表的骨子里距离是resolution。总括坐标点(x,y)所在的瓦片的体系号的公式是:

col  = floor((x0 – x)/( tileSize*resolution))

row = floor((y0 – y)/( tileSize*resolution))

以此公式应该轻巧驾驭,轻易点说就是,首先算出一个瓦片所涵盖的其实尺寸是稍稍LtileSize,然后再算出此时显示屏上的地理坐标点离瓦片切图的伊始点间的实际距离LrealSize,然后用实际距离除以二个瓦片的骨子里尺寸,就可以得此时的瓦片行列号:LrealSize/LtileSize。

三.成效优化

叁.职能优化

叁.3 resolution的折算原理

如自身在上1节《地图比例尺换算原理》中描述的,当系统是经纬度系统时,此resolution能够直接使用切图像和文字书档案中的resolution。要是系统是平面坐标系统时,此resolution的算法是:

resolution=scale*inch2centimeter/dpi。在那之中scale是地图比例尺,inch贰centimeter为英寸转毫米的参数,dpi为一英寸所包含的像素。

3.一导出图片系列的优化

在AE中得以导出多样格式的图片。利用ExportJPEGClass(),ExportBMPClass(),ExportEMFClass(),ExportGIFClass()等就可以兑现。

3.一导出图片体系的优化

在AE中得以导出各样格式的图样。利用ExportJPEGClass(),ExportBMPClass(),ExportEMFClass(),ExportGIFClass()等就可以兑现。

四.实在系统中的运用处境

近期自家把实际的施用中的须要总括如下:

(1)得到画布的万丈和增长幅度以及此时亟待呈现的地图的几何范围

(二)获得画布的冲天和宽度以及此时急需呈现的地形图的几何范围,同时也博得了特殊须求展现的地图的品级

末段,大家须求取得在这两种需要下的瓦片行列号范围。

③.二图纸透明的优化

由此地点的类直接导出的图纸其背景观私下认可为了反动。而AGS切图中,背景观是晶莹的,所以那边还要做多个图纸发光度优化进程。C#中间转播成Bitmap后,利用该类自带的MakeTransparent就可以兑现。

三.2图纸透明的优化

透过上边的类间接导出的图片其背景象暗中同意为了草绿。而AGS切图中,背景象是透明的,所以那里还要做三个图片折射率优化进程。C#中转成Bitmap后,利用该类自带的MakeTransparent就可以达成。

伍.换算流程

4.算法的优化

4.算法的优化

5.1 流程图

本着在第二节中提到的两种要求,大家进行了分化的折算进度,这里笔者先是给出流程图:

 图片 4

四.一 减弱切图范围

在工艺流程中,我们暗中认可的切图是从切图原点起始的,那样会切成很多浩大的无用图。大家得以一向从离地图DXmin和DYmax近来处伊始切图就能够。

startXByLevel = (int)Math.Abs((Math.Floor((DXmin-originX) /
dImageWidth)));

startYByLevel = (int)Math.Abs((Math.Floor((originY-DYMax) /
dImageHeight)));

startXByLevel和startYByLevel即为X轴和Y轴的切图初步点。

4.1 收缩切图范围

在流程中,大家私下认可的切图是从切图原点初始的,那样会切成很多众多的无用图。咱们能够直接从离地图DXmin和DYmax方今处初始切图就可以。

startXByLevel = (int)Math.Abs((Math.Floor((DXmin-originX) /
dImageWidth)));

startYByLevel = (int)Math.Abs((Math.Floor((originY-DYMax) /
dImageHeight)));

startXByLevel和startYByLevel即为X轴和Y轴的切图初叶点。

五.2 详细讲解

以下步骤中涉及到部分集体变量,为了方便描述,笔者那边用英文代表某个参数。

originX,originY:地图切图时的切图原点坐标。

tileSize:瓦片的荧屏像素大小。

Level:地图品级。

resolution:某地图等第下荧屏壹像素代表的实在单位大小。

canvasWidth、canvasHeight:显示器的长度宽度

geo马克斯X、geoMinX:地理范围中的最大即最小X坐标。

4.2不切无效图

作者们平时会切出整张图都是晶莹的空白图。可是在AGS的切图中,是看不到那样的无效图的。大家得以在切图时先判断此限制内是还是不是有要素存在,有的话就切,未有的话,continue掉。那样也能够减小切图的数额。

四.2不切无效图

小编们平常会切出整张图都以晶莹的空域图。不过在AGS的切图中,是看不到那样的无效图的。我们得以在切图时先判断此限制内是不是有要素存在,有的话就切,未有的话,continue掉。那样也足以收缩切图的数量。

五.二.一第3步,获得请求地理范围中的宗旨点(center吉优Point)

其1换算相比较轻松,可是为啥大家要首先换算这几个宗旨点啊。原因是我们最后索要的忠实地理范围,并不一定是显示器范围所对应的充足地理范围,它极有望是高于这些荧屏地理范围的。而实际是,它自然是过量的,在后面大家讲解瓦片图层类的统一筹划时,会涉及多少个地理范围缓冲宽度,那时候我们就更能驾驭为什么是要首先取得地理范围中的大旨点了。

5.算法的愈发优化——帮衬经纬度地图切图

眼下下面的享有进程,均只对做了阴影转变的mxd有效,可是假诺我们的mxd中的坐标系无投影调换只有1个地理坐标系呢,也正是地面图为经纬度坐标时,此时该怎么达成切图?

实在思路也非常粗略,固然大家实在驾驭以上resolution的所代表实际意义,那么解决那么些标题的思绪就应当有了。

本地图为经纬度时,我们切图的比例尺设置相应改为切图的分辨率设置。那样大家就径直拿走了每一个级其余resolution,然后用resolution来切图就能够。不用再做如上的将比例尺转变为resolution的步调。

伍.算法的愈加优化——协理经纬度地图切图

日前地点的有所进程,均只对做了影子转变的mxd有效,不过一旦我们的mxd中的坐标系无投影调换唯有三个地理坐标系呢,也便是本地图为经纬度坐标时,此时该怎么兑现切图?

实际思路也很简短,即使大家实在清楚以上resolution的所代表实际意义,那么化解那个难点的思路就相应有了。

本土图为经纬度时,大家切图的比例尺设置相应改为切图的分辨率设置。那样大家就直接得到了各类品级的resolution,然后用resolution来切图就能够。不用再做上述的将比例尺转变为resolution的步子。

伍.2.二 第1步,判断请求中是否包蕴了需求体现的地图等第,分别处理

6.注意

在levelScaleArr中,里面的比例尺数字是随着index扩展而增添的,不过比例尺数字越大,其对应的Level是越小的。所以大家在遍历Level层时,应该是1个递减的遍历,那样生成的L文件夹的编号才是毋庸置疑的。

6.注意

在levelScaleArr中,里面包车型地铁比例尺数字是随着index扩展而充实的,不过比例尺数字越大,其相应的Level是越小的。所以我们在遍历Level层时,应该是叁个递减的遍历,那样生成的L文件夹的号码才是毋庸置疑的。

5.2.2.1 包含了Level

假诺请求中曾经钦赐了选用的Level,则大家接下去能够一贯动用此Level来张开地图其实请求范围的折算。

7.效果图

以下是效益图:

 图片 5

7.效果图

以下是魔法图:

 图片 6

5.2.二.二 未有包蕴Level

而当呼吁中无Level时,我们的折算将会相比复杂壹些,那几个换算的目标就是求出此时的地图应该以怎么着Level彰显是最合适的,即nearestLevel。它的长河是,首先根据请求中的地理范围和荧屏大小范围,求得此时我们本要求的瓦片实际尺寸,即:(geo马克斯X-geoMinX)/(
canvasWidth/tileSize),也正是用实际地理长度除以此时的瓦片个数,从而赢得了小编们请求中本必要的瓦片实际尺寸。

而是,近日大家无法担保我们所切的图中是早晚有那一个要求里的比例尺的。于是我们还索要做一个遍历,遍历我们的地图中全体的比例尺,寻觅二个与此必要比例尺下的瓦片实际尺寸最接近的诚实瓦片实际尺寸,而这一个瓦片实际大小所对应的此时的地形图比例尺,正是我们求得到的最合适的比例尺,它所表示的地形图等级正是最接近需要的地形图等第,nearestLevel。

8.不足

(a).近日不恐怕切出紧密型(Compact)瓦片。消除思路,用地方的不2法门导出图后,需求把图变成贰进制然后依照bundle的格式重新生成,并且还要生成索引文件bundleX。

(b).所用的AE毕竟是包装的很好的机件库了。用GDAL的话,由于包裹层次低1些,成效应该会越来越好有的。

 

                                                               
 —–欢迎转载,但保留版权,请于分明处标明出处:http://www.cnblogs.com/naaoveGIS/

                                                                          
假诺您觉得本文确实帮忙了你,能够微信扫一扫,实行小额的打赏和鞭策,谢谢^_^

                                    图片 7

8.不足

(a).近日不也许切出紧密型(Compact)瓦片。消除思路,用地点的艺术导出图后,供给把图变成2进制然后依照bundle的格式重新生成,并且还要生成索引文件bundleX。

(b).所用的AE终归是包装的很好的零部件库了。用GDAL的话,由于包裹层次低1些,成效应该会更加好1些。

 

                                                               
 —–欢迎转载,但保留版权,请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/

                                                                          
倘使你认为本文确实支持了您,能够微信扫一扫,举办小额的打赏和鼓励,谢谢^_^

                                    图片 8

5.二.三 第一步,算出显示器范围所对应的地理范围 (minX、minY、maxX、maxY)

在率先步中收获了centerGeoPoint,第二步获得了Level的准绳下,这一步就很不难了。

第叁获得Level下的1像素代表的莫过于尺寸,即resolution。然后用center吉优Point加上或减去半个显示屏尺寸(canvasBounds)乘以resolution后得到的限制就是要求中的显示屏范围在获得的Level下相应相应的实际上地理范围。

以显示器左上角X所对应的其实地理坐标为例:

minX =centerGeoPoint – (resolution* canvasWidth)/2;

此处顺便提一下,算出的那个显示器范围所对应的地理范围,它的效益是老大大的,在事后的显示屏坐标调换到地理坐标,以及地理坐标转换到显示器坐标,还有偏移补偿量的折算上是重中之重的七个参数。

五.二.四 第四步,总括别的参数,比如瓦片行列的起先号以及瓦片个数

这一步为告竣工作,依照以前算出来的1层层参数来开始展览末段的折算。

5.2.四.壹 瓦片开始行列号(fixedTileLeftTopNumX、fixedTileLeftTopNumY)

在了然了请求的地理范围后,此早先行列号的折算便是马到功成了。可是那里依旧要多少做个补充,大家算出来的地理范围并不能够保险真实的瓦片的开首瓦片所对应的地理坐标与地理范围的左上角地理范围重合,为此我们相应允许地理范围的二个恢弘,那些扩充多少是一个很值得推敲的地方。那里大家默许为扩大至请求到的首先张瓦片左上角所对应的地理坐标。

公式为:

fixedTileLeftTopNumX = Math.floor((Math.abs(originX –
minX))/resolution*tileSize);

fixedTileLeftTopNumY = Math.floor((Math.abs(originY –
maxY))/resolution*tileSize);

伍.贰.四.二 实际地理范围(realMinX、real马克斯Y)

作者们事先只是求得了荧屏范围所对应的地理范围,而当我们换算出这么些范围所急需的瓦片后,这几个算得的瓦片其所对应的地理范围并不一定是显示器范围所对应的不行地理范围,此时大家须要再行算出实际地理范围。

realMinX = fixedTileLeftTopNumX * curLevelClipLength + originX;

realMaxY= originY – fixedTileLeftTopNumY * curLevelClipLength;

5.2.肆.3 左上角偏移像素(offSetX、offSetY)

出于地理范围中的第2张瓦片,即左上角的首先张瓦片,并不一定是一点一滴蕴涵在显示器地理范围内的,于是那里又关联到此外1对参数,左上角偏移像素。

缘何须要这些参数呢,原因是,当我们把瓦片都请求回来后还要做四个折算,即换算出每一张瓦片的左上角坐标应该对应在图层(TIleCanvas)上的哪1个荧屏坐标。那么些偏移像素便是为了那些换算而做的预备。

offSetX = ((realMinX- minX )/resolution);

offSetY = ((maxY – realMaxY )/resolution);

再度补充,当中resolution表示的是此Level下的壹像素所表示的实际单位大小。

伍.二.肆.四 X、Y轴上的瓦片个数(mapXClipNum、mapYClipNum)

那里本身先交付一个显示器地理范围与事实上请求出的瓦片地理范围间关系的示意图:

 图片 9

 在前头小编一度诉说了,我们求得的显示器地理范围内的瓦片所代表的瓦片个数基本上是会比屏幕范围本人是要大的。其实那个原因简单精晓,因为瓦片是地图表示的纤维单位了,其不容许再细分,所以在大家恳请瓦片的开始行列号时,用到了Math.floor那几个函数,即求得离显示屏范围的左上角坐标近日的瓦片行列号。不过,在求得X、Y轴上的瓦片个数时,大家得用到Math.ceil这一个函数,那是为着能求得离荧屏范围的右下角坐标近日的瓦片行列号数。

具体公式是:

mapXClipNum = Math.ceil((canvasWidth + Math.abs(offSetX))/tileSize);

mapYClipNum = Math.ceil((canvasHeight + Math.abs(offSetY))/tileSize);

6.总结

依照上面步骤,大家最后能够求出瓦片的系列号,以及要求的在X、Y轴的个数。同时大家还求得了将瓦片画在画布上时所急需的参数,左上角偏移像素。

这1节相信大家都会看的很累,因为那1节流程太多,公式太多,但是也正因为如此,那1节是我们介绍前端彰显地图的三番四回串中最关键的壹节了,希望我们能和作者1块儿将那个规律好好的钻探与钻探。下一节里自身将写的类容相对相比轻巧了,主要介绍的会是我们算出了行列号后,怎么样使用它。笔者将对两种常见在线地图和离线地图的乞请格局做三个介绍和小结。欢迎大家频频关心。

后天是星节,祝节日欢喜。对和本身一样本身过节的人,写句话和豪门共勉:

在贫乏思量的中途

你是小船3头,大桥一座。

 

                                                     
—–欢迎转发,但保留版权,请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/

                                                               
如若您认为本文确实支持了你,能够微信扫一扫,实行小额的打赏和鞭策,谢谢^_^

                              图片 10

相关文章