栅格重投影(投影变换)

OpenLayers能够在不同的坐标系统中显示来自WMS、WMTS、静态图像和许多其他源的栅格数据。图像的地图重投影直接发生在web浏览器中。在任何Proj4js支持的坐标参考系统中都是可视的,并且以前不兼容的图层现在可以组合和叠加。

使用:

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

import {Map, View} from 'ol';
import TileLayer from 'ol/layer/Tile';
import TileWMS from 'ol/source/TileWMS';

var map = new Map({
  target: 'map',
  view: new View({
    projection: 'EPSG:3857', // 视图投影
    center: [0, 0],
    zoom: 2
  }),
  layers: [
    new TileLayer({
      source: new TileWMS({
        projection: 'EPSG:4326', // 数据源投影
        url: 'http://demo.boundlessgeo.com/geoserver/wms',
        params: {
          'LAYERS': 'ne:NE1_HR_LC_SR_W_DR'
        }
      })
    })
  ]
});

如果一个源(基于ol/source/TileImage或ol/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);
var proj27700 = getProjection('EPSG:27700');
proj27700.setExtent([0, 0, 700000, 1300000]);

改变视图投影:

要切换投影以显示地图,你必须在在ol/Map上设置一个新的ol/View并选择投影:

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

TileGrid和Extents:

当需要重投影时,新瓦片(在目标投影中)将在从原始源瓦片(Source Tiles)的底层创建。重投影瓦片的TileGrid默认使用ol/ TileGrid ~getForProjection(projection)在内部构造。投影应该有定义的范围(见上面),这样才能正常工作。

另外,一个自定义的目标TileGrid可以手动构造,并使用ol/source/TileImage~setTileGridForProjection(projection, tileGrid)在源实例上设置。当重投影到指定的投影而不是创建默认投影时,将使用这个TileGrid。在某些情况下,这可以用来优化性能(通过调整瓦片大小)或视觉质量(通过指定分辨率)。

工作原理:

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

通过这种方式,我们可以在几乎任何硬件上(使用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 vs EPSG:4326的极地区域),不同的投影会有明显不同的分辨率,在整个缩放级别执行单一的分辨率会导致一些贴图被放大/缩小,可能需要加载大量的源瓦片。因此,对每个重投影的贴图(在瓦片范围的中间)分别计算分辨率映射。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值