(十六)WebGIS中偏移补偿量引发的问题之探讨

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/

1.背景

在上一章里讲解地图平移功能的实现时,我在最后提出了两个问题:

A.在地图平移后,矢量图层的canvas的XY都发生了变化,此时根据地理坐标转换为屏幕坐标公式得出的屏幕坐标,在canvas上能将要素正确显示吗?

B.矢量图层canvas的原点坐标XY有需要还原成初始的(0,0)的时候吗?

对这两个问题我给出的答案是:不能和需要。

在这一章里,我们将详细讲解得出这两个答案的原因。

2.何为偏移补偿量?

在地图平移时,我们做了两个操作:一个是对MapCanvas的原点坐标XY进行了变化,第二个是对此时屏幕的实际地理范围做了变化。详细的实现过程以及公式可以参考上一章WebGIS中平移功能的设计和实现。

而这两个操作都需要用到一个共同的参数,即此时操作偏移量(moveX,moveY)。但是,此时操作偏移量并不是偏移补偿量。偏移补偿量,是针对于初始坐标(0,0),此时canvas的左上角坐标XY的整体偏移量,我们用做(sumMoveX,sumMoveY)来表示。

3.偏移补偿量的影响

3.1如果不考虑偏移补偿量,会出现的问题

假设,此时地图的canvas原点已经被平移了(sumMoveX,sumMoveY),当我们再次使用地理或业务服务端的矢量服务,解析返回的矢量数据中的Geometry时,会先把Geometry中的地理坐标转换屏幕坐标,然后再将此时用屏幕坐标绘出的要素添加到该canvas中。但是,问题来了,我们会发现,此时的要素并不在我们想要的位置上(实际坐标处),而是在了其他地方从而发生了偏移。这也是我们第一个问题的完整描述。

3.2出现此问题的原因

3.2.1 回顾屏幕坐标与地理坐标互转换公式

在讨论此问题前,我们有必要回看一下我在第十章中给出的屏幕坐标和地理坐标互转换的公式:

A.屏幕坐标转换为地理坐标

geoXY.x = screenGeoBounds.left + screenX * sliceLevelLength / tileSize;

geoXY.y = screenGeoBounds.top - screenY * sliceLevelLength / tileSize;

B.地理坐标转换为屏幕坐标

screenXY.x = (geoX - screenGeoBounds.left)/(sliceLevelLength/ tileSize);

screenXY.y = (screenGeoBounds.top - geoY)/(sliceLevelLength/ tileSize);

其中geoXY表示地理坐标,screenXY表示屏幕坐标,screenGeoBounds表示屏幕地理范围,slieceLevelLenth表示此事地图级别下的一张瓦片所代表的实际地理长度,tileSize表示一张瓦片的像素大小。

3.2.2 从公式分析产生偏移的问题

 我们仔细观察地理坐标转换为屏幕坐标的公式,其原理是,用此时的地理坐标减去屏幕容器左上角所代表的地理坐标,然后除以一个像素所代表的地理长度,得出此时相对于屏幕容器左上角坐标的屏幕坐标。

 大家看我的描述中,反复提到的是屏幕容器左上角坐标,何为屏幕容器左上角坐标呢?我们再看下上一章我给出的平移原理示意图:

                          

这其中的容器左上角屏幕坐标就是初始时和canvas左上角A点重叠的坐标(0,0)。

所以,当我们把一个相对于(0,0)的要素,加入到一个左上角已经变为(sumMoveX,sumMoveY)的canvas中时,便发生了要素位置偏移的问题。

3.3如何解决此偏移问题

知道了引发偏移的问题,我们便只需要对症下药即可。即当我们把矢量数据中的地理坐标变为屏幕坐标后,再减去一个偏移补偿量即可。

也就是:

ScreenXY=geoXYToSreenXY(geoXY)-sumMoveXY

表现在代码层面上,便是绘制时,将转换得到的屏幕坐标减去偏移补偿量。

4.偏移补偿量何时归零?

要弄清楚这个问题,我们得再次研究坐标转换公式。在这个公式中涉及到一个重要的参数,即sliceLevelLength,当前地图级别下瓦片长度所代表的实际地理长度。

试想,当我们的地图级别变化了,则此参数sliceLevelLength也变化了,如果sumMoveXY还是之前的那个数字,那么sumMoveXY所代表 实际地理长度便不再是正确的地理长度了。

这样会导致一个问题,地图级别变化后,如果继续使用之前的sumMoveXY值,得到的转换后的屏幕坐标会发生偏移。

此时,我们如果采用这样一种做法,在地图级别变化后,将所有的sumMoveXY都变成0,即重新恢复到未发生偏移的状态下,则能很好的解决如果保留sumMoveXY值所引发的位置偏移问题。

表现在代码层面上,便是每次地图进行级别变化时,会抛出一个zoom事件,图层应该监听此事件,然后将图层(canvas)的做上角坐标XY变为0。

5.进一步探讨偏移补偿量本质以及其引发的问题

5.1 提出问题

这里,我继续给出两个问题:

A.本希望每次点击鼠标后能在鼠标点击的地方画出一个圆点,可是当拖动了地图后,鼠标再点击到地图上时,却没有将圆点画在点击的地方,而是偏移了。

B.同样也是想点击鼠标后能在鼠标点击的地方画出一个圆点,即使不拖动地图,当鼠标点击到已经画出的要素上后,发现现在画出的圆点偏移到其他地方了。

5.2实验及实验结果分析

在解答上面两个问题时,我首先给出一组实验数据。

stageXY:全局舞台的坐标;

localXY: 本地坐标系;

geoPoint:此时的地理坐标;

mapDrawCanvas:此图层(Canvas)的原点坐标;

screenPoint:此时将地理坐标转换为屏幕坐标后的坐标;

fixedSreenPoint:将screenPoint减去偏移量后的修正坐标;

1)未拖动地图时,即没有偏移补偿量时:

2)拖动地图后,即有偏移补偿量时:

5.2.1结论1—用于坐标转换的屏幕坐标最好是stageXY

在不拖动地图和拖动地图的情况下,stageXY和将地理坐标转换成屏幕坐标后的screenPoint是能很好的对应的。其原因,我们在仔细的看了地理坐标转换成屏幕坐标的公式后就不难理解了,因为转换回来的屏幕坐标其相对的是(0,0)坐标,而此mapDrawCanvas所对应的stageXY坐标便是相对于(0,0)的。

这个结论告诉我们,用于坐标转换的屏幕坐标最好是stageXY。

5.2.2 结论2-转换得到的屏幕坐标必须减去偏移量后才能等于此时的localXY

观察实验结论,将screenPoint减去偏移量后得到的fixedScreenPoint去掉最小误差便是等于localXY。而想要在一个容器内画图,必须是使用其localXY坐标。

5.2.3 结论3-偏移量便是容器的原点(mapDrawCanvas .x, mapDrawCanvas .y)

我们发现,当容器(mapDrawCanvas)的原点坐标(mapDrawCanvas .x, mapDrawCanvas .y)变化后,在本地坐标系下所得的localXY也发生了相关的变化。而这个偏移量,便可以直接使用容器的原点。

5.3 问题解答

由结论1我们可以知道,用于坐标转换的坐标最好是stageXY。

问题1的原因在于,使用localXY作为屏幕坐标,然后将localXY转换成地理坐标后进行保存。在地图平移后,此时保存的地理坐标便不再是正确的地理坐标了,于是要素绘制时发生了偏移。

问题2的原因在于,当我们点击到一个要素后,此时获得的localXY不再是相对于容器mapDrawCanvas的本地坐标了,而是相对于该被点击要素的本地坐标。所以坐标转换后会出现很严重的偏移。

6.总结

在这一章里,我们详细对偏移补偿量的本质及其造成的问题和解决方法。在这一章里,我们提到了很多之前已经讲到的内容,主要包括坐标转换以及平移本质。最后我给出了一个简单的实验数据,为大家进一步讲解了偏移补偿量的本质。

在下一章里,我们将跟大家一起讨论工具条中长度量算工具和面积量算工具所涉及的算法、设计和实现。希望大家持续关注。

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

                                                                           如果您觉得本文确实帮助了您,可以微信扫一扫,进行小额的打赏和鼓励,谢谢 ^_^

                                          

 

时间: 2024-09-18 13:02:45

(十六)WebGIS中偏移补偿量引发的问题之探讨的相关文章

(十二) WebGIS中矢量图层的设计

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.前言 在前几章中我们已经了解了什么是矢量查询.屏幕坐标与地理坐标之前的转换以及要素的设计,有了这些知识,这一章里我们终于可以进行矢量图层的设计了. 在Catalog里创建一个FeatureClass时,我们能够选择是创建点图层或者线图层或者面图层等.所谓点图层,即该图层中的要素只能是点,其他几个图层顾名思义,也是如此.那么在WebGIS中,我们同样也可以按照Arc

(十八)WebGIS中清空功能和地图定位功能的设计以及实现

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.背景 当地图中增加了很多元素后,对不同的元素需要进行一定的控制,最简单的控制就是能对元素有选择的进行清空删除.在本节中,还将介绍WebGIS中另外一个常用功能,即地图定位功能.具体描述便是:当输入一个坐标点后,能够将地图缩放到该点处.下面我便就以上两个功能展开此章节的内容. 2.清空功能 2.1设计思路 根据功能点,我们可以将清空分为如下几个情形: a.清空某个或

(十)WebGIS中地理坐标与屏幕坐标间的转换原理

 文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.前言 地图本身是拥有坐标的,一般可以大致分为平面坐标和经纬度坐标,在这里我们统称为地理坐标,比如北京,(115.9°E ,39.6°N)和(506340,304400)均是其地理坐标,只是表示形式不同而已. 我们在上一章讲解了矢量图层中数据的来源,最后提出了一个还未解决的问题,即当我们获得了矢量数据后,如何在屏幕中将这些数据里的地理(Geometry)坐标转换为

(十五)WebGIS中平移功能的设计和实现

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.前言 这一章我们将详细讲解WebGIS工具栏中另一个基础工具--平移工具(Pan).在介绍命令模式时,我们已经知道了此工具为Tool型的. 这个工具主要有如下两个功能: A.当切换到此工具上时,按下鼠标不放,移动鼠标时可以拖动地图. B.当切换到此工具上时,点击鼠标(鼠标不做平移),可以使地图平移,以点击处为中心. 2.设计 2.1 原理 我们已经知道,WebGI

(十九)WebGIS中I查询的原理及设计(包含AGS、GeoServer、Supermap)

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.背景 我们在使用arcmap时,经常会用到被称为I查询的工具.具体功能便是,当激活I查询功能后,鼠标点击到某个要素上时,界面上会弹出一个对话框用来显示该要素的各属性信息.该功能截图如下:                         2.原理 在WebGIS中设计和实现该功能之前,我们有必要对该功能的原理做一个了解. 在OGC的WMS标准中规定了一个接口:Get

(十四)WebGIS中地图放大缩小的设计和实现

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.背景 在上一章中,我们给出了整个工具栏设计的核心,使用命令模式,并设计了具体工具类所继承的基类--Command类.从这一章开始我们便正式进入了具体工具类的设计和实现. 放大和缩小工具是最基础的工具之一,其操作分为三种: a.点击地图,进行放大缩小 b.拉框,进行放大缩小 c.滚轮调控放大缩小 针对这三种操作方式,我们进行了不同的代码逻辑设计. 2.分析 a.滚轮

x264代码剖析(十六):核心算法之宏块编码中的量化编码

x264代码剖析(十六):核心算法之宏块编码中的量化编码           为了进一步节省图像的传输码率,需要对图像进行压缩,通常采用变换编码及量化来消除图像中的相关性以减少图像编码的动态范围.本文主要介绍量化的相关内容,并给出x264中量化编码的代码分析.   1.量化编码           量化过程就是根据图像的动态范围大小确定量化参数,既保留图像必要的细节,又可以减少码流.在图像编码中,变换编码和量化从原理上讲是两个独立的过程.但在H.264中,将两个过程中的乘法合二为一,并进一步采用

热点推荐:PHP中十六个魔术方法详解

前言 PHP中把以两个下划线__开头的方法称为魔术方法(Magic methods),这些方法在PHP中充当了举足轻重的作用. 魔术方法包括: __construct(),类的构造函数 __destruct(),类的析构函数 __call(),在对象中调用一个不可访问方法时调用 __callStatic(),用静态方式中调用一个不可访问方法时调用 __get(),获得一个类的成员变量时调用 __set(),设置一个类的成员变量时调用 __isset(),当对不可访问属性调用isset()或emp

(六)WebGIS中地图瓦片在Canvas上的拼接显示原理

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.前言 在之前的五个章节中,我们在第一章节里介绍了WebGIS的基本框架和技术,第二章节里介绍了什么是瓦片行列号以及计算它的原因,第三章节里介绍了如何通过地理范围计算出这个范围内瓦片的行列号,第四和第五章节里介绍了在得到瓦片行列号后如何获得离线和在线地图的URL,这个章节里,我们将介绍在通过URL得到瓦片后,如何将其显示在浏览器相对应的地方,拼接出整块地图. 2.左