OpenLayers中文文档2栅格重投影

栅格重投影

[Raster Reprojection]

OpenLayers has an ability to display raster data from WMS, WMTS, static images and many other sources in a different coordinate system than delivered from the server. Transformation of the map projections of the image happens directly in a web browser. The view in any Proj4js supported coordinate reference system is possible and previously incompatible layers can now be combined and overlaid.

OpenLayers有能力显示来自WMS、WMTS、静态图像和许多其他来源的栅格数据,其坐标系与从服务器交付的不同。图像的地图投影的转换直接发生在网络浏览器中。可以在任何Proj4js支持的坐标参考系统中查看,以前不兼容的图层现在可以合并和叠加。

使用方法 Usage

The API usage is very simple. Just specify proper projection (e.g. using EPSG code) on ol/View:

API的使用非常简单。只要在ol/View上指定适当的投影(例如使用EPSG代码):

import Map from 'ol/Map.js';
import TileLayer from 'ol/layer/Tile.js';
import TileWMS from 'ol/source/TileWMS.js';
import View from 'ol/View.js';
​
const map = new Map({
  target: 'map',
  view: new View({
    projection: 'EPSG:3857', // here is the view projection
    center: [0, 0],
    zoom: 2,
  }),
  layers: [
    new TileLayer({
      source: new TileWMS({
        projection: 'EPSG:4326', // here is the source projection
        url: 'https://ahocevar.com/geoserver/wms',
        params: {
          'LAYERS': 'ne:NE1_HR_LC_SR_W_DR',
        },
      }),
    }),
  ],
});

Copy

If a source (based on ol/source/TileImage or ol/source/Image) has a projection different from the current ol/View’s projection then the reprojection happens automatically under the hood.

如果一个源(基于ol/source/TileImageol/source/Image)的投影与当前ol/View的投影不同,那么重新投影会自动发生。

实例 Examples

自定义 Custom projection

The easiest way to use a custom projection is to add the Proj4js library to your project and then define the projection using a proj4 definition string. It can be installed with

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

npm install proj4

Following example shows definition of a British National Grid:

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

import proj4 from 'proj4';
import {get as getProjection} from 'ol/proj.js';
import {register} from 'ol/proj/proj4.js';
​
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);
const proj27700 = getProjection('EPSG:27700');
proj27700.setExtent([0, 0, 700000, 1300000]);

视图投影的改变

[Change of the view projection​]

To switch the projection used to display the map you have to set a new ol/View with selected projection on the ol/Map:

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

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

Copy

瓦片网格和

[TileGrid and Extents​]

外延

When reprojection is needed, new tiles (in the target projection) are under the hood created from the original source tiles. The TileGrid of the reprojected tiles is by default internally constructed using ol/tilegrid~getForProjection(projection). The projection should have extent defined (see above) for this to work properly.

当需要重新投影时,新的瓷砖(在目标投影中)是由原始的源瓷砖创建的。重新投影的瓷砖的TileGrid默认是使用ol/tilegrid~getForProjection(projection)内部构建的。为了正常工作,投影应该已经定义了范围(见上文)。

Alternatively, a custom target TileGrid can be constructed manually and set on the source instance using ol/source/TileImage~setTileGridForProjection(projection, tilegrid). This TileGrid will then be used when reprojecting to the specified projection instead of creating the default one. In certain cases, this can be used to optimize performance (by tweaking tile sizes) or visual quality (by specifying resolutions).

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

它是如何工作的

The reprojection process is based on triangles – the target raster is divided into a limited number of triangles with vertices transformed using ol/proj capabilities (proj4js is usually utilized to define custom transformations). The reprojection of pixels inside the triangle is approximated with an affine transformation (with rendering hardware-accelerated by the canvas 2d context):

重投过程是基于三角形的–目标光栅被分成有限的三角形,顶点使用ol/proj功能进行转换(proj4js通常被用来定义自定义转换)。三角形内像素的重新投射是通过仿射变换来实现的(通过canvas 2d context进行硬件加速渲染)

how-it-works.jpg
This way we can support a wide range of projections from proj4js (or even custom transformation functions) on almost any hardware (with canvas 2d support) with a relatively small number of actual transformation calculations.

这样我们就可以在几乎所有的硬件(支持画布2D)上支持来自proj4js的各种投影(甚至是自定义变换功能),而实际的变换计算数量相对较少。

The precision of the reprojection is then limited by the number of triangles.

再投影的精度则受限于三角形的数量。

The reprojection process preserves transparency on the raster data supplied from the source (png or gif) and the gaps and no-data pixels generated by reprojection are automatically transparent.

重投过程保留了从源头(png或gif)提供的光栅数据的透明度,重投产生的空隙和无数据像素也自动透明。

动态三角测量

[Dynamic triangulation​]

The above image above shows a noticeable error (especially on the edges) when the original image (left; EPSG:27700) is transformed with only a limited number of triangles (right; EPSG:3857). The error can be minimized by increasing the number of triangles used.

上面的图片显示,当原始图像(左边;EPSG:27700)只用有限的三角形(右边;EPSG:3857)进行转换时,有明显的误差(特别是在边缘)。通过增加使用的三角形数量,误差可以最小化。

Since some transformations require a more detail triangulation network, the dynamic triangulation process automatically measures reprojection error and iteratively subdivides to meet a specific error threshold:

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

iterative-triangulation.png
For debugging, rendering of the reprojection edges can be enabled by ol.source.TileImage#setRenderReprojectionEdges(true).

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

高级Advanced

三角测量精度阈值 Triangulation precision threshold

The default triangulation error threshold in pixels is given by ERROR_THRESHOLD (0.5 pixel). In case a different threshold needs to be defined for different sources, the reprojectionErrorThreshold option can be passed when constructing the tile image source.

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

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

[Limiting visibility of reprojected map by extent​]

The reprojection algorithm uses inverse transformation (from view projection to data projection). For certain coordinate systems this can result in a “double occurrence” of the source data on a map. For example, when reprojecting a map of Switzerland from EPSG:21781 to EPSG:3857, it is displayed twice: once at the proper place in Europe, but also in the Pacific Ocean near New Zealand, on the opposite side of the globe.

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

double-occurrence.jpg
Although this is mathematically correct behavior of the inverse transformation, visibility of the layer on multiple places is not expected by users. A possible general solution would be to calculate the forward transformation for every vertex as well - but this would significantly decrease performance (especially for computationally expensive transformations).

尽管这在数学上是正确的反变换行为,但用户并不希望在多个地方看到该层。一个可能的通用解决方案是为每个顶点也计算正向变换–但这将大大降低性能(特别是对于计算量大的变换)。

Therefore a recommended workaround is to define a proper visibility extent on the ol.layer.Tile in the view projection. Setting such a limit is demonstrated in the reprojection demo example.

因此,推荐的解决方法是在视图投影中对ol.layer.Tile定义一个适当的可见度范围。设置这样的限制在reprojection demo example中演示。

分辨率计算

[Resolution calculation​]

When determining source tiles to load, the ideal source resolution needs to be calculated. The ol/reproj~calculateSourceResolution(sourceProj, targetProj, targetCenter, targetResolution) function calculates the ideal value in order to achieve pixel mapping as close as possible to 1:1 during reprojection, which is then used to select proper zoom level from the source.

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

It is, however, generally not practical to use the same source zoom level for the whole target zoom level – different projections can have significantly different resolutions in different parts of the world (e.g. polar regions in EPSG:3857 vs EPSG:4326) and enforcing a single resolution for the whole zoom level would result in some tiles being scaled up/down, possibly requiring a huge number of source tiles to be loaded. Therefore, the resolution mapping is calculated separately for each reprojected tile (in the middle of the tile extent).

然而,对整个目标缩放级别使用相同的源缩放级别通常是不实际的–不同的投影在世界的不同地方可能有明显不同的分辨率(例如EPSG:3857与EPSG:4326中的极地地区),对整个缩放级别执行单一的分辨率会导致一些瓦片被放大/缩小,可能需要加载大量的源瓦片。因此,分辨率映射是为每个重新投影的瓦片单独计算的(在瓦片范围的中间)。

Code licensed under the 2-Clause BSD. All documentation CC BY 3.0. Thanks to our sponsors.

代码根据2-Clause BSD授权。所有文件CC BY 3.0。感谢我们的赞助商

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值