新普金娱乐网址


沙漠菜

好导师对男女有多紧要?

按照图片实现酷炫地图显示和交互的方案

  • 一月 17, 2019
  • 地理
  • 没有评论

作品版权由作者李晓晖和果壳网共有,若转载请于显著处标明出处:http://www.cnblogs.com/naaoveGIS/

随笔版权由作者李晓晖和和讯共有,若转载请于显然处标明出处:http://www.cnblogs.com/naaoveGIS/

1.前言

在上一节中我们精通了屏幕上一像素等于实际中稍加单位长度(米或经纬度)的折算方法,而知道那多少个规律后,接下去大家要怎么用它吗?它和我们前端展现地图有哪些关系呢?这一节,我会尽量详细的将那三个问题逐四次答。说一个题外话,这一多样的篇章我都会少给代码,多画流程图或者UML图来跟我们互换,一来便于没有过多GIS和编程基础的人读懂,二来使我们不囿于于某种代码的实现而更关注于原理。

1. 背景

     
 近日大屏幕上显示酷炫地图的急需日趋成风,大家正常的方案是行使arcmap对数据开展配图。不过,arcmap配图的局限性相比较大,并且针对不同要求,常规配图方案可能反而让事情复杂化了。这里跟我们大快朵颐两个经过美工设计的图形来解决地图问题的案例。

2.影象金字塔简介

咱俩事先反复提到了影象金字塔这些概念,但是尚未对其做一个大概的牵线,这里自己将这一个定义补充一下。

2. 案例1——倾斜地图

    图片 1

    图片 2

     此示例中,需求总结有两点:

    a.地图需要倾斜显示。

    b.地图上急需以不同款型显得一些POI点。

   
尽管以传统方案来做,对地图配图后还亟需对二维地图框架的器皿举行倾斜,并且对所急需出示的POI数据坐标点举办倾斜转换,实现相比较艰巨。

   
仔细研究需要,其交互设计上只有针对点数据POI的交互,切交互简单,而且在大屏的总体呈现中,地图不需要有缩放平移需求。于是,大家得以付出另外一种实现思路:

    a.不用地图框架,前端用DIV引入原始未倾斜图片。

    b.用CSS控制该DIV的倾斜角度。

   
c.设定图片左上角的地理坐标,确定图片的1个像素所代表的地理长度,然后针对POI地理坐标算出其在原本图片上的图样坐标。

   
d.拿到POI的原有图片坐标后,再使用倾斜角度算出在倾斜图片上的图样坐标,然后同样使用DIV引入该POI的图标即可。 

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

现在,我假诺大家的服务器上有一个1G的形象,需要将其在前者举行体现。大家传统的做法就是率先将服务器中的1G影象下载到前端,然后浏览器加载渲染出图。可是我们想想,首先客户端下载1G的印象需要的时刻一定是个漫长的进程,其次浏览器加载这么大的文件也大半会招致其崩溃。而最要紧的一个问题是,我们的急需仅仅是浏览全图中的某一个区域下的某多少个级别,现在却将全图下载完毕了,而这无异还致使了数据的不安全性(下载到本地),同时我们的每三重放大和压缩以及拖拽都将会使浏览器花上充足长的时光去渲染。

可见,传统的主意是不符合实际需求的。到新兴,又有了新的解决办法,比如arcgis的IMS版本中指出了动态出图的定义。也就是眼前端发出的请求里含有了亟待出示的限量、突显窗口的轻重缓急等参数后,后台动态的在原有数据中切出一个契合要求的瓦片,然后将以此数目重回给前台,并且在服务器中对这些瓦片做缓存。

只是,这些法子前端出图依旧很慢,并且使地图服务器的压力过大。终于,大家的印象金字塔解决方案出现了。

3. 案例2——复杂交互的三维效果地图

    同样,先付给设计稿:

   图片 3

   图片 4

    需求描述:

    a.带3D效果显示地图。

    b.行政区划可以选中交互。

    c.行政中央点图标可以操纵。

    难点分析:

   
遵照上一个方案中的纯前端方法,在行政区划的入选高亮交互上有一定难度。这里指出了此外一个方案:

   
a.将3D效果地图当做是忠实地图,进行简易纠正,处理成包含地理坐标的忠实地图。 
  

    图片 5

    b.基于纠正后的图样,将行政区划矢量化。

    c.将地理图片切图,并用GIS框架加载。

    d.将处理好的矢量化行政数据以矢量图层叠加,响应交互。

    e.将行行政中央点在GIS框架上叠加显示。

   
f.鼠标移动到行政点上后取拿到行政点的屏幕坐标,利用DIV将规划好的气泡框结合自定义内容展开互动展现。

2.2原理

形象金字塔就是,我们先是将原有映像依照用户的需要,比如用户需要出示多少种比例尺下的多少,需要呈现的是原始映像中的哪个区域的数据,将原本映像遵照这多少个需要举办划分和提取。如图:

 图片 6

最低层就是大家领到和分叉出的比例尺最小的一流的瓦片,而最上层的则是比例尺最大的一流的瓦片。我们精心考察可以发现这样的一个法则:比例尺越小的级别瓦片数据越少,反之则越大。而以此规律造成的结果就是:比例尺越小的级别切图的速度越快,同时,同样大小的瓦片所涵盖的形象范围越多。

当我们创设好了影象金子塔后,前端再请求地图时,则将只是在切好的瓦片缓存中,找到呼应级别里对应的瓦片即可。然后在前端将这些请求到的瓦片拼接出来,便可以赢得用户需要的级别下的可视范围内的瓦片了。

4. 总结

   
我们做GIS的人看来地图就忍不住的想用地图框架去实现,须知针对不同要求,解决方案得以是丑态百出的。

    a.比如现在的echarts、highcharts在化解简单地图突显上是很好用的。

    b.某些在线环境场面下,利用百度API或者高德API也是实用的。

    c.特定复杂现象,利用图片直接处理也是一个路子。

    d.真不行,配图加上地理框架再上。

 

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

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

                                图片 7

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

3.1 为啥要换算瓦片行列号

上一节中自己付出了形象图切成离散型图后文件的集团模式,其中给我们来得了在这种切图下,文件的社团其实是按照瓦片的级别、行、列号来社团的。事实上,紧凑型瓦片(Bundle)的公司体制也是这么,只是它在拿到了行列号后还要开展一层层换算,比如读取索引文件找到文件中的偏移量等,这一个换算格局本身在随后的章节跟大家来商量。并且,标准的WMS请求中也关乎到行列号的折算,WMS请求中有一个Bbox的参数,而以此参数也与行列号的折算有涉嫌。而标准的WMTS请求中,TILEMATRIX、TILEROW、TILECOL那两个参数代表的就是瓦片的级别、行、列号。

有鉴于此,不管是本着哪类离线或在线的地图的瓦片请求中,拿到瓦片的level、col、row是伸手可以实现的骨干。

3.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.3 resolution的折算原理

如本人在上一节《地图比例尺换算原理》中描述的,当系统是经纬度系统时,此resolution能够一直运用切图文档中的resolution。假如系统是平面坐标系统时,此resolution的算法是:

resolution=scale*inch2centimeter/dpi。其中scale是地图比例尺,inch2centimeter为英寸转分米的参数,dpi为1英寸所富含的像素。

4.实际上系统中的运用意况

现在自己把实际的拔取中的需求总结如下:

(1)拿到画布的冲天和幅度以及此时内需展示的地形图的几何范围

(2)得到画布的莫大和幅度以及此时亟待体现的地图的几何范围,同时也博得了急需出示的地图的级别

末段,我们需要拿到在这二种需求下的瓦片行列号范围。

5.换算流程

5.1 流程图

本着在第3节中涉及的两种需求,大家举行了不同的折算过程,这里我先是给出流程图:

 图片 8

5.2 详细讲解

以下步骤中涉嫌到有的共用变量,为了有利于描述,我这边用英文代表有些参数。

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

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

Level:地图级别。

resolution:某地图级别下屏幕一像素代表的实际上单位大小。

canvasWidth、canvasHeight:屏幕的长宽

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

5.2.1率先步,拿到请求地理范围中的中央点(centerGeoPoint)

这一个换算相比简单,不过为何我们要率先换算那多少个基本点吧。原因是我们最终索要的实在地理范围,并不一定是屏幕范围所对应的特别地理范围,它极有可能是过量这么些屏幕地理范围的。而实质上是,它必将是出乎的,在背后大家上课瓦片图层类的计划性时,会涉及一个地理范围缓冲宽度,这时候我们就更能了解怎么是要首先拿到地理范围中的中心点了。

5.2.2 第二步,判断请求中是不是带有了索要出示的地形图级别,分别处理

5.2.2.1 包含了Level

设若请求中一度指定了接纳的Level,则我们接下去可以直接使用此Level来进展地图实际上请求范围的折算。

5.2.2.2 没有包含Level

而当呼吁中无Level时,我们的折算将会相比较复杂一些,那个换算的目标就是求出此时的地形图应该以什么Level展现是最合适的,即nearestLevel。它的过程是,首先依据请求中的地理范围和屏幕尺寸范围,求得此时我们本需要的瓦片实际尺寸,即:(geo马克斯(Max)X-geoMinX)/(
canvasWidth/tileSize),也就是用实际地理长度除以此时的瓦片个数,从而拿到了俺们请求中本需求的瓦片实际尺寸。

不过,目前大家无法确保我们所切的图中是迟早有其一需要里的比例尺的。于是我们还索要做一个遍历,遍历大家的地形图中有所的比例尺,找出一个与此需求比例尺下的瓦片实际尺寸最接近的忠实瓦片实际尺寸,而这一个瓦片实际大小所对应的此时的地形图比例尺,即是我们求得到的最合适的比例尺,它所表示的地形图级别就是最靠近需求的地形图级别,nearestLevel。

5.2.3 第三步,算出屏幕范围所对应的地理范围 (minX、minY、maxX、maxY)

在第一步中赢得了centerGeoPoint,第二步获得了Level的尺度下,这一步就很简短了。

率先得到Level下的一像素代表的其实尺寸,即resolution。然后用centerGeoPoint加上或减去半个屏幕尺寸(canvasBounds)乘以resolution后拿到的限定便是需求中的屏幕范围在赢得的Level下应当相应的骨子里地理范围。

以屏幕左上角X所对应的实际地理坐标为例:

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

这边顺便提一下,算出的那么些屏幕范围所对应的地理范围,它的功力是万分大的,在其后的屏幕坐标转换成地理坐标,以及地理坐标转换成屏幕坐标,还有偏移补偿量的折算上是生死攸关的一个参数。

5.2.4 第四步,总括其他参数,比如瓦片行列的开头号以及瓦片个数

这一步为截至工作,依照从前算出来的一序列参数来拓展最后的折算。

5.2.4.1 瓦片起首行列号(fixedTileLeftTopNumX、fixedTileLeftTopNumY)

在领略了请求的地理范围后,此起初行列号的折算便是水到渠成了。然而这里依旧要稍稍做个补充,大家算出来的地理范围并不可以确保真实的瓦片的开头瓦片所对应的地理坐标与地理范围的左上角地理范围重合,为此我们应当允许地理范围的一个增添,这一个扩展多少是一个很值得推敲的地点。那里大家默认为扩展至请求到的第一张瓦片左上角所对应的地理坐标。

公式为:

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

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

5.2.4.2 实际地理范围(realMinX、real马克斯Y)

咱俩前边只是求得了屏幕范围所对应的地理范围,而当大家换算出这一个界定所需要的瓦片后,这多少个算得的瓦片其所对应的地理范围并不一定是屏幕范围所对应的不胜地理范围,此时我们需要再度算出实际地理范围。

realMinX = fixedTileLeftTopNumX * curLevelClipLength + originX;

realMaxY= originY – fixedTileLeftTopNumY * curLevelClipLength;

5.2.4.3 左上角偏移像素(offSetX、offSetY)

由于地理范围中的第一张瓦片,即左上角的率先张瓦片,并不一定是一点一滴包含在屏幕地理范围内的,于是这里又提到到此外一对参数,左上角偏移像素。

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

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

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

再也补充,其中resolution表示的是此Level下的一像素所代表的实在单位大小。

5.2.4.4 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轴的个数。同时我们还求得了将瓦片画在画布上时所需要的参数,左上角偏移像素。

这一节相信我们都会看的很累,因为这一节流程太多,公式太多,但是也正因为如此,这一节是我们介绍前端突显地图的不胜枚举中最重大的一节了,希望我们能和自家一起将这些规律好好的酝酿与研讨。下一节里本身将写的类容相对相比轻松了,首要介绍的会是我们算出了行列号后,如何拔取它。我将对三种常见在线地图和离线地图的哀告情势做一个介绍和总括。欢迎我们频频关注。

今天是七夕节,祝节日快乐。对和我同一自己过节的人,写句话和豪门共勉:

在紧缺牵挂的路上

你是小船一只,大桥一座。

 

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

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

                              图片 10

相关文章

No Comments, Be The First!
近期评论
    分类目录
    功能
    网站地图xml地图