一. 数据加载
- OpenLayers的地图数据通过图层(Layer)进行组织渲染,通过数据源(Source)设置具体的地图数据起源。Layer能够看作渲染地图的容器,具体的数据须要通过Source设置,Source和Layer是一对一的关系,有一个Source必然须要有一个Layer。
- 地图数据依据数据源(Source)可分为Image、Tile、Vector三大类型的数据源,对应设置到地图图层(Layer)的Image、Tile、Vector三大类型的图层上,其中矢量图层Vector通过款式(Style)来设置矢量因素渲染的形式和外观。
- Tile类是瓦片形象基类,其子类作为各类瓦片数据的数据源。
- Vector类是矢量数据源基类,为矢量图层提供具体的数据起源,包含间接组织或读取的矢量数据(Features)、近程数据源的矢量数据(即通过url设置数据源门路)等。
- Image类是繁多图像基类,其子类为画布(canvas)元素、服务器图片、单个动态图片、WMS繁多图像等。
二. ol.source.Tile
因为一些历史问题,多个服务提供商,多种规范等诸多起因,导致要反对世界上大多数的瓦片数据,须要针对这些差别(次要是瓦片坐标系不同、分辨率不同等)提供不同的Tile数据源反对,ol.source.Tile大抵能够分为几类:
- 在线服务的Source:如ol.source.BingMaps(微软提供的Bing在线地图数据)、ol.source.Stamen(Stamen提供的在线地图数据)等,在没有本人的地图服务器的状况下,能够间接应用它们。
- 反对协定规范的Source:如ol.source.TileArcGISRest、ol.source.WMTS、ol.source.TileJSON等,如果要应用它们,要学习对应的协定,并且找到反对这些协定的服务器来提供数据源(服务器能够是地图服务商提供或本人搭建的地图服务器)。
- ol.source.XYZ:目前很多地图服务都反对XYZ形式的申请,用处宽泛,且简略易学。
三. 瓦片坐标系
瓦片坐标系是瓦片地图的组织参考框架,规定了每一块瓦片的行号、列号以及层级数。OpenLayers提供了一个用于调试瓦片坐标系的ol.source.TileDebug类。借助这个类,能够清晰的看到每一个瓦片的坐标。
import React, { useEffect } from 'react';import { Map, View } from 'ol';import TileLayer from 'ol/layer/Tile';import TileDebug from 'ol/source/TileDebug';import { defaults } from 'ol/control';import { fromLonLat } from 'ol/proj';import OSM from 'ol/source/OSM';import 'ol/ol.css';export default function Index() { useEffect(() => { // 初始化地图 initMap(); }, []) /** * 初始化地图 */ const initMap = () => { let osmSource = new OSM(); new Map({ // 挂载到id为map的div容器上 target: 'map', // 设置地图图层 layers: [ // 创立一个应用OpenStreetMap地图源的瓦片图层 new TileLayer({ source: osmSource }), // 创立一个显示OpenStreetMap地图源的瓦片网格图层 new TileLayer({ source: new TileDebug({ // Web墨卡托投影坐标系 projection: 'EPSG:3857', // 获取OpenStreetMap地图源的瓦片坐标系 tileGrid: osmSource.getTileGrid() }) }) ], // 设置地图视图 view: new View({ // 设置空间参考零碎为'EPSG:3857' projection: 'EPSG:3857', // 地图的显示核心 center: fromLonLat([0, 0]), // 地图的显示层级 zoom: 3 }), controls: defaults({ // 移除归属控件 attribution: false, // 移除缩放控件 zoom: false, // 移除旋转控件 rotate: false }) }) } return (<div> <div id='map' style={{ width: '100vw', height: '100vh' }}></div> </div>)}
- 第一个数字是层级z
- 第二个数字是经度方向上的x(列号)
- 第三个数字是纬度方向上的y(行号)
四. 分辨率
4.1 分辨率简介
- 分辨率的简略定义是屏幕上1像素示意的事实世界的高空理论间隔。
- 以OpenStreetMap在线地图为例,层级0应用了一张瓦片,层级1应用了4张瓦片。通过计算能够晓得层级0的整个地球图像为256×256像素大小,层级1的整个地球图像为512×512像素大小。而层级0和层级1示意的地球范畴都是一样的(经度[-180°, 180°],纬度[-90°, 90°])。在层级0的时候,一个像素在程度方向示意360°÷256 = 1.40625°经度范畴, 在竖直方向示意180°÷256 = 0.703125°的纬度范畴。这两个数字就是分辨率,即一个像素示意的事实世界的范畴,这个范畴可能是度(地理坐标零碎),可能是米(投影坐标零碎)或其余单位。
4.2 Web墨卡托投影坐标系的分辨率
在WebGIS中应用的在线瓦片地图采纳Web墨卡托(Mercator)投影坐标系(OpenLayers默认应用EPSG:3857),通过投影后整个地球是一个正方形,范畴为经度[-180°, 180°],纬度[-85°, 85°],单位为度。对应的Web墨卡托投影坐标系的范畴为x[-20037508.3427892, 20037508.3427892],x、y方向上的各层级瓦片地图分辨率计算公式能够演绎为:resolution = rang÷(256×2^z)。
- rang:示意x方向或y方向上的整个范畴,如20037508.3427892×2。
- 256:示意一个瓦片的边长,单位为像素。
- 2^z:示意在层级z下,x或y方向上的瓦片个数。
4.3 获取OpenLayers默认应用的分辨率
import React, { useRef, useState, useEffect } from 'react';import { Map, View } from 'ol';import TileLayer from 'ol/layer/Tile';import { defaults } from 'ol/control';import { fromLonLat } from 'ol/proj';import OSM from 'ol/source/OSM';import { unByKey } from 'ol/Observable';import 'ol/ol.css';import styles from './index.less';export default function Index() { // 地图 const map = useRef<any>(); // 以后层级 const [zoom, setZoom] = useState(3); // 以后分辨率 const [resolution, setResolution] = useState(19567.8792); useEffect(() => { // 初始化地图 initMap(); // 绑定视图事件 const resolutionChange = map.current.getView().on('change:resolution', resolutionChangeEvent); return () => { // 解绑视图事件 unByKey(resolutionChange); } }, []) /** * 初始化地图 */ const initMap = () => { map.current = new Map({ // 挂载到id为map的div容器上 target: 'map', // 设置地图图层 layers: [ // 创立一个应用OpenStreetMap地图源的瓦片图层 new TileLayer({ source: new OSM() }) ], // 设置地图视图 view: new View({ // 设置空间参考零碎为'EPSG:3857' projection: 'EPSG:3857', // 地图的显示核心 center: fromLonLat([0, 0]), // 地图的显示层级 zoom: zoom, // 设置缩放级别为整数 constrainResolution: true, // 敞开无级别缩放地图 smoothResolutionConstraint: false }), controls: defaults({ // 移除归属控件 attribution: false, // 移除缩放控件 zoom: false, // 移除旋转控件 rotate: false }) }) } /** * 分辨率扭转事件 */ const resolutionChangeEvent = () => { let zoom = parseInt(map.current.getView().getZoom()); let resolution = map.current.getView().getResolution().toFixed(4); setZoom(zoom); setResolution(resolution); } return (<div className={styles.mapCon}> <div id='map' className={styles.map}></div> <div className={styles.toolBar}> <span>层级:{zoom}</span> <span>分辨率:{resolution}</span> </div> </div>)}
4.4 比例尺
- 比例尺是指地图上间隔与理论间隔的比例。
- 在计算地图比例尺时,须要用到高空分辨率与屏幕分辨率两个参数。屏幕分辨率是指屏幕上每英寸(1英寸=0.0254米)长度内蕴含的像素数量,默认是96。
- 计算公式为:比例尺=0.0254÷(分辨率×96)
4.5 OpenLayers默认分辨率、比例尺表
图像等级 | 地图的宽高 (单位:像素) | 高空分辨率 (单位:米 / 像素) | 地图比例尺 (以96dpi为准) |
---|---|---|---|
1 | 512 | 78,271.5170 | 1:295,829,355.45 |
2 | 1024 | 39,135.7585 | 1:147,914,677.73 |
3 | 2048 | 19,567.8792 | 1:73,957,338.86 |
4 | 4096 | 9,783.9396 | 1:36,978,669.43 |
5 | 8192 | 4,891.9698 | 1:18,489,334.72 |
6 | 16,384 | 2,445.9849 | 1:9,244,667.36 |
7 | 32,768 | 1,222.9925 | 1:4,622,333.68 |
8 | 65,536 | 611.4962 | 1:2,311,166.84 |
9 | 131,072 | 305.7481 | 1:1,155,583.42 |
10 | 262,144 | 152.8741 | 1; 577,791.71 |
11 | 524,288 | 76.4370 | 1:288,895.85 |
12 | 1,048,576 | 38.2185 | 1:144,447.93 |
13 | 2,097,152 | 19.1093 | 1:72,223.96 |
14 | 4,194,304 | 9.5546 | 1:36,111.98 |
15 | 8,388,608 | 4.7773 | 1:18,055.99 |
16 | 16,777,216 | 2.3887 | 1:9,028.00 |
17 | 33,554,432 | 1.1943 | 1:4,514.00 |
18 | 67,108,864 | 0.5972 | 1:2,257.00 |
19 | 134,271,728 | 0.2986 | 1:1,128.50 |
20 | 268,435,456 | 0.1493 | 1:564.25 |
21 | 536,870,912 | 0.0746 | 1:282.12 |
22 | 1,073,741,824 | 0.0373 | 1:141.06 |
23 | 2,147,483,648 | 0.0187 | 1:70.53 |
参考文章:
OpenLayers教程八:多源数据加载之数据组织
OpenLayers教程九:多源数据加载之瓦片地图原理一
OpenLayers教程十:多源数据加载之瓦片地图原理二