00基本概念教程
官方文档:
教程:https://openlayers.org/doc/tutorials/
一、基本概念
1.map 地图(图层)
OpenLayers的核心组件是map(来自 ol/Map
模块)。它被渲染到 target
容器(例如,包含地图的网页上的 div
元素)。所有的map属性都可以在构造时配置,或者使用setter方法,例如 setTarget()
。
下面的标签可用于创建包含地图的 <div>
。
<div id="map" style="width: 100%; height: 400px"></div>
下面的脚本使用元素的 id=map作为选择器,构造了一个在上面的 <div> 中呈现的地图。
import Map from 'ol/Map.js';
const map = new Map({target: 'map'});
2.View 视图
地图不负责中心、缩放级别和投影等。这些是 ol/View
实例的属性。
import View from 'ol/View.js';
map.setView(new View({
center: [0, 0],
zoom: 2,
}));
View
也有一个 projection
(投影) 。投影确定 center
的坐标系以及地图分辨率计算的单位。如果未指定(如上面的代码片段所示),则默认投影为球面墨卡托投影 (EPSG:3857),以米为地图单位。
zoom
选项是指定地图分辨率的便捷方法。-
maxZoom
(默认值:28) -
zoomFactor
(默认值:2) -
maxResolution
(默认值的计算方式是投影的有效范围适合256 x256像素图块)
3.Source 源
为了获取图层的远程数据,OpenLayers 使用 ol/source/Source
子类。包含免费和商业地图图块服务(例如 OpenStreetMap 或 Bing)、OGC 源(例如 WMS 或 WMTS)以及格式为 GeoJSON 或 KML 的矢量数据。
import OSM from 'ol/source/OSM.js';
const source = OSM();
4.Layer 层
图层是来自源的数据的可视化表示。 OpenLayers 有四种基本类型的层:
-
ol/layer/Tile
- 渲染在网格中提供平瓦片像的源,这些网格按特定分辨率的缩放级别进行组织。 -
ol/layer/Image
- 渲染提供任意范围和分辨率的地图图像的源。 -
ol/layer/Vector
- 在客户端呈现矢量数据。 -
ol/layer/VectorTile
- 渲染以矢量切片形式提供的数据。
import TileLayer from 'ol/layer/Tile.js';
// ...
const layer = new TileLayer({source: source});
map.addLayer(layer);
把代码整合到一起
上面的代码片段可以组合成一个脚本,用单个图块层渲染地图:
import Map from 'ol/Map.js';
import View from 'ol/View.js';
import OSM from 'ol/source/OSM.js';
import TileLayer from 'ol/layer/Tile.js';
new Map({
layers: [
new TileLayer({source: new OSM()}),
],
view: new View({
center: [0, 0],
zoom: 2,
}),
target: 'map',
});
二、背景
1.概述
OpenLayers 是一个模块化、高性能、功能丰富的库,用于显示地图和地理空间数据并与之交互。
该库内置了对各种商业和免费图像和矢量切片源以及最流行的开放和专有矢量数据格式的支持。借助 OpenLayers 的地图投影支持,数据可以处于任何投影中。
2.公共API
OpenLayers 以 ol
npm 包的形式提供,它提供了官方支持的 API 的所有模块。
3.浏览器支持
OpenLayers 可在所有现代浏览器上运行(全球使用率超过 1%)。这包括 Chrome、Firefox、Safari 和 Edge。对于较旧的浏览器,可能需要添加polyfills。
该库适用于台式机/笔记本电脑和移动设备,并支持指针和触摸交互。
4.模块和命名约定
具有 CamelCase (驼峰命名法)名称的 OpenLayers 模块提供类作为默认导出,并且可能包含其他常量或函数作为命名导出:
import Map from 'ol/Map.js';
import View from 'ol/View.js';
类的层次结构由它们的父级分组,在包的子文件夹中提供,例如 layer/
。
为了方便起见,这些也可以作为命名导出,例如。
import {Map, View} from 'ol';
import {Tile, Vector} from 'ol/layer.js';
除了这些重新导出的类之外,具有小写名称(是小驼峰命名吗?)的模块还提供常量或函数作为命名导出:
import {getUid} from 'ol';
import {fromLonLat} from 'ol/proj.js';
三、栅格重投影
OpenLayers 能够以与服务器传送不相同的坐标系显示来自 WMS、WMTS、静态图像和许多其他来源的栅格数据。图像的地图投影的转换直接在 Web 浏览器中进行。任何 Proj4js 支持的坐标参考系中的视图都可以使用,并且现在可以合并和叠加以前不兼容的图层。
1.用法
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',
},
}),
}),
],
});
如果源(基于 ol/source/TileImage
或 ol/source/Image
)的投影与当前 ol/View
的投影不同,则重新投影会在后台自动发生。
自定义投影
使用自定义投影的最简单方法是将Proj4js库添加到项目中,然后使用proj4定义字符串定义投影。
视图投影的更改
要切换用于显示标测图的投影,您必须在 ol/Map
上设置一个新的 ol/View
,并选择投影:
map.setView(new View({
projection: 'EPSG:27700',
center: [400000, 650000],
zoom: 4,
}));
瓦片网格和范围
当需要重投影时,新的图块(在目标投影中)是从原始源图块创建的。默认情况下,重新投影图块的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)
启用重投影边缘的渲染。
Advanced 高级
三角测量精度阈值
默认三角测量误差阈值(以像素为单位)由 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 中的极地区域)并且对整个缩放级别强制使用单一分辨率将导致某些图块被放大/缩小,可能需要加载大量源瓦片。因此,为每个重新投影的瓦片(位于瓦片范围的中间)单独计算分辨率映射。