首页 新闻中心 技术文档 OpenLayers中文教程文档

OpenLayers的投影方式

发布时间:2021-12-12 22:57:52   浏览量:2996   作者:openlayers.org

OpenLayers 能够在不同于服务器提供的坐标系中显示来自 WMS、WMTS、静态图像和许多其他来源的栅格数据。图像的地图投影的转换直接在 Web 浏览器中进行。任何 Proj4js 支持的坐标参考系统中的视图都是可能的,以前不兼容的层现在可以组合和覆盖。

用法

API 的使用非常简单。只需指定正确的投影(例如使用EPSG代码)ol/View

import {Map, View} from'ol';import TileLayer from'ol/layer/Tile';import TileWMS from'ol/source/TileWMS';varmap =newMap({target:'map',view:newView({projection:'EPSG:3857',//HERE IS THE VIEW PROJECTIONcenter: [0,0],zoom:2}),layers: [newTileLayer({source:newTileWMS({projection:'EPSG:4326',//HERE IS THE DATA SOURCE PROJECTIONurl:'https://ahocevar.com/geoserver/wms',params: {'LAYERS':'ne:NE1_HR_LC_SR_W_DR'}})})]});

如果源(基于ol/source/TileImageol/source/Image)的投影与当前 的投影不同,ol/View则重新投影会在幕后自动发生。

自定义投影

使用自定义投影的最简单方法是将Proj4js库添加到您的项目中,然后使用 proj4 定义字符串定义投影。它可以安装

npm install proj4

以下示例显示了英国国家网格的定义:

import proj4 from'proj4';import {get as getProjection, register} from'ol/proj';proj4.defs('EPSG:27700','+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 '+'+x_0=400000 +y_0=-100000 +ellps=airy '+'+towgs84=446.448,-125.157,542.06,0.15,0.247,0.842,-20.489 '+'+units=m +no_defs');register(proj4);varproj27700 = getProjection('EPSG:27700');proj27700.setExtent([0,0,700000,1300000]);

视图投影的变化

要切换用于显示地图的投影,您必须在 上设置一个ol/View具有选定投影的新投影ol/Map

map.setView(newView({projection:'EPSG:27700',center: [400000,650000],zoom:4}));

TileGrid 和范围

当需要重新投影时,新的图块(在目标投影中)位于从原始源图块创建的引擎盖下。默认情况下,重新投影图块的 TileGrid 是使用ol/tilegrid~getForProjection(projection). 投影应该有范围定义(见上文)才能正常工作。

或者,可以手动构建自定义目标 TileGrid 并使用ol/source/TileImage~setTileGridForProjection(projection, tilegrid). 当重新投影到指定的投影而不是创建默认投影时,将使用此 TileGrid。在某些情况下,这可用于优化性能(通过调整图块大小)或视觉质量(通过指定分辨率)。

怎么运行的

重投影过程基于三角形——目标栅格被分成有限数量的三角形,顶点使用ol/proj功能转换(proj4js通常用于定义自定义转换)。三角形内像素的重投影近似于仿射变换(渲染硬件由画布 2d 上下文加速):

通过这种方式,我们可以在几乎任何硬件(支持 canvas 2d)上支持来自 proj4js(甚至自定义转换函数)的各种投影,而实际转换计算数量相对较少。

重投影的精度受三角形数量的限制。

重投影过程会保留源(png 或 gif)提供的栅格数据的透明度,并且重投影生成的间隙和无数据像素会自动透明。

动态三角测量

上图显示了当原始图像(左;EPSG:27700)仅使用有限数量的三角形(右;EPSG:3857)进行转换时,会出现明显的错误(尤其是在边缘)。可以通过增加使用的三角形数量来最小化误差。

由于某些转换需要更详细的三角剖分网络,因此动态三角剖分过程会自动测量重投影误差并迭代细分以满足特定的误差阈值:

对于调试,可以通过 启用重投影边缘的渲染ol.source.TileImage#setRenderReprojectionEdges(true)

先进的

三角剖分精度阈值

以像素为单位的默认三角测量误差阈值由ERROR_THRESHOLD(0.5 像素) 给出。如果需要为不同的源定义不同的阈值,reprojectionErrorThreshold可以在构建瓦片图像源时传递该选项。

按范围限制重新投影地图的可见性

重投影算法使用逆变换(从视图投影到数据投影)。对于某些坐标系,这可能会导致源数据在地图上“重复出现”。例如,当将瑞士地图从 EPSG:21781 重新投影到 EPSG:3857 时,它会显示两次:一次在欧洲的适当位置,但也在地球另一侧的新西兰附近的太平洋中。

尽管这是逆变换在数学上正确的行为,但用户并不期望图层在多个位置的可见性。一个可能的通用解决方案是也计算每个顶点的前向变换 - 但这会显着降低性能(特别是对于计算成本高的变换)。

因此,推荐的解决方法是ol.layer.Tile在视图投影上定义适当的可见性范围。重投影演示示例中演示了如何设置此类限制。

分辨率计算

在确定要加载的源切片时,需要计算理想的源分辨率。该ol/reproj~calculateSourceResolution(sourceProj, targetProj, targetCenter, targetResolution)函数计算理想值,以便在重投影期间实现尽可能接近 1:1 的像素映射,然后用于从源中选择适当的缩放级别。

然而,对整个目标缩放级别使用相同的源缩放级别通常是不切实际的——不同的投影在世界不同地区可能具有显着不同的分辨率(例如 EPSG:3857 和 EPSG:4326 中的极地地区)和对整个缩放级别强制使用单一分辨率会导致某些图块按比例放大/缩小,可能需要加载大量源图块。因此,分辨率映射是针对每个重新投影的瓦片(在瓦片范围的中间)单独计算的。