乐趣区

关于前端:OpenLayers6学习笔记三-瓦片地图基础知识

一. 数据加载

  1. OpenLayers 的地图数据通过图层(Layer)进行组织渲染,通过数据源(Source)设置具体的地图数据起源。Layer 能够看作渲染地图的容器,具体的数据须要通过 Source 设置,Source 和 Layer 是一对一的关系,有一个 Source 必然须要有一个 Layer。
  2. 地图数据依据数据源(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. 分辨率的简略定义是屏幕上 1 像素示意的事实世界的高空理论间隔。
  2. 以 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&times2。
  • 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. 比例尺是指地图上间隔与理论间隔的比例。
  2. 在计算地图比例尺时,须要用到高空分辨率与屏幕分辨率两个参数。屏幕分辨率是指屏幕上每英寸(1 英寸 =0.0254 米)长度内蕴含的像素数量,默认是 96。
  3. 计算公式为:比例尺 =0.0254÷(分辨率 &times96)

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 教程十:多源数据加载之瓦片地图原理二

退出移动版