Skip to content

地图组件

目的与范围

本文档详细介绍 Map 类,它是 OpenLayers 中的中央协调器,负责协调整个地图功能。Map 类管理渲染管线、集成图层和数据源、处理用户交互、控制瓦片加载系统,并维护整体应用程序状态。有关视图状态管理,请参阅 视图系统。有关图层架构详细信息,请参阅 图层架构

概述

Map 类是中央协调器,将所有 OpenLayers 组件协调成一个连贯的地图应用程序。它管理驱动渲染管线的 FrameState 对象、协调用 TileQueue 进行高效数据加载,并集成包含图层、控件、交互和覆盖的 Collection 对象。该类扩展 BaseObject 并提供地图操作和事件处理的主要 API。

Map 协调架构

SVG
100%

Map 类结构

SVG
100%

架构

Map 类图

SVG
100%

构造函数选项

Map 构造函数接受一个具有以下属性的 MapOptions 对象:

选项类型描述
targetHTMLElement|string地图将渲染到的 DOM 元素或其 ID
layersArray|Collection|LayerGroup地图中包含的图层
viewView|Promise地图的视图配置
controlsCollection|Array要添加到地图的控件(默认:defaultControls())
interactionsCollection|Array要添加到地图的交互(默认:defaultInteractions())
overlaysCollection|Array要添加到地图的覆盖
pixelRationumber设备像素比(默认:DEVICE_PIXEL_RATIO)
moveTolerancenumber点击事件的移动容差(默认:1)
keyboardEventTargetHTMLElement|Document|string监听键盘事件的元素
maxTilesLoadingnumber同时加载的最大瓦片数(默认:16)

构造函数通过 createOptionsInternal() 处理这些选项并初始化地图的内部状态,包括 TileQueue、视口 DOM 结构和事件处理器。

初始化

要创建新的地图实例,您需要提供包括目标元素、视图和图层在内的配置选项。以下显示典型的初始化模式:

const map = new Map({
  target: 'map',
  layers: [
    new TileLayer({
      source: new OSM()
    })
  ],
  view: new View({
    center: [0, 0],
    zoom: 2
  })
});

DOM 结构和视口管理

Map 类创建一个管理渲染图层、覆盖和控件的层次 DOM 结构。此结构是动态创建的并插入到目标元素中。

Map DOM 层次结构

SVG
100%

DOM 结构创建过程:

  1. viewport 创建:src/ol/Map.js369-375

    • CSS 类包含触摸检测:'ol-viewport' + ('ontouchstart' in window ? ' ol-touch' : '')
    • 相对定位,隐藏溢出
  2. overlayContainer 设置:src/ol/Map.js381-388

    • 绝对定位,全尺寸
    • pointerEvents: 'none' 允许地图交互
  3. overlayContainerStopEvent 设置:src/ol/Map.js394-401

    • 类似于 overlayContainer_ 但停止事件传播
    • 用于控件和阻止覆盖

访问方法:

来源:src/ol/Map.js369-401 src/ol/Map.js1059-1083

渲染管线和 FrameState 管理

Map 类协调一个围绕 FrameState 对象的复杂渲染管线,该对象包含单次渲染帧所需的所有信息。

渲染流程

SVG
100%

FrameState 对象结构

FrameState typedef 定义了完整的渲染上下文:

属性类型目的
pixelRationumber高 DPI 显示器的设备像素比
timenumber请求渲染时的时间戳
viewStateViewState当前视图中心、缩放、旋转、投影
layerStatesArrayLayerState[]所有图层的计算状态
tileQueueTileQueue瓦片加载优先级队列
coordinateToPixelTransformTransform地图坐标到像素变换
pixelToCoordinateTransformTransform像素到地图坐标变换
extentExtent视图投影中的当前可见范围
sizeSize地图的像素大小
declutterObject重叠要素的去重树

渲染过程:

  1. 帧调度render() 使用 requestAnimationFrame 进行平滑动画 src/ol/Map.js1486-1490
  2. 状态创建renderFrame_() 使用当前地图状态构建 FrameState src/ol/Map.js1549-1655
  3. 渲染器执行renderer_ 处理帧状态并渲染所有图层
  4. 后处理:处理瓦片加载、事件和帧调度

核心组件管理

视图管理

Map 管理一个 View 对象,该对象控制地图的中心、缩放级别、旋转和投影。可以在初始化期间或稍后使用 setView() 设置视图。

// 设置新视图
map.setView(new View({
  center: [0, 0],
  zoom: 2
}));

// 获取当前视图
const view = map.getView();

当视图更改时,地图更新其渲染以反映新的视图状态。

图层管理

Map 通过 LayerGroup 管理图层。可以使用以下方法添加、删除或修改图层:

// 添加新图层
map.addLayer(newLayer);

// 删除图层
map.removeLayer(existingLayer);

// 清除并设置新图层
map.setLayers([layer1, layer2]);

// 获取所有图层
const layers = map.getLayers();

控件和交互

Map 管理控件和交互的集合:

// 添加控件
map.addControl(new ZoomControl());

// 添加交互
map.addInteraction(new DragRotate());

// 删除控件
map.removeControl(control);

// 删除交互
map.removeInteraction(interaction);

地图为这些组件正确设置事件监听器,并确保它们与地图正确连接。

渲染过程

渲染流程

SVG
100%

渲染过程从 render() 方法开始,该方法调度一个新帧在下一个动画帧渲染。实际渲染发生在 renderFrame_() 中,该方法:

  1. 使用当前地图状态创建 FrameState 对象
  2. 将帧状态传递给渲染器
  3. 处理渲染后函数
  4. 分发地图事件,如 movestartmoveend

FrameState 对象包含渲染所需的所有信息,包括视图状态、图层状态和变换。

事件处理

Map 浏览器事件

Map 类通过 MapBrowserEventHandler 类处理浏览器事件。事件被处理并作为 MapBrowserEvent 实例分发。

SVG
100%

地图首先将事件分发给自己的监听器,然后按添加顺序的反向分发给所有活动交互。

要素检测

Map 提供方法来检测给定像素处的要素:

// 检查像素处是否有要素
const hasFeature = map.hasFeatureAtPixel(pixel, options);

// 获取像素处的所有要素
const features = map.getFeaturesAtPixel(pixel, options);

// 对像素处的每个要素执行回调
map.forEachFeatureAtPixel(pixel, function(feature, layer) {
  // 对要素执行操作
}, options);

这些方法对于实现要素选择和交互很有用。

常用操作

坐标转换和事件处理

Map 类提供坐标转换功能和用于用户交互的全面事件处理。

坐标转换方法

// 从像素转换为坐标(用户投影)
const coordinate = map.getCoordinateFromPixel(pixel);

// 从坐标转换为像素
const pixel = map.getPixelFromCoordinate(coordinate);

// 从鼠标/触摸事件获取坐标
const eventCoord = map.getEventCoordinate(event);

// 内部方法(视图投影)
const viewCoord = map.getCoordinateFromPixelInternal(pixel);
const viewPixel = map.getPixelFromCoordinateInternal(coordinate);

坐标转换系统使用 FrameState 变换:

  • coordinateToPixelTransform:将地图坐标转换为屏幕像素
  • pixelToCoordinateTransform:将屏幕像素转换为地图坐标

这些变换每帧更新并考虑当前视图状态(中心、缩放、旋转)。

事件处理管线

SVG
100%

事件系统处理包含以下内容的 MapBrowserEvent 对象:

  • 相对于地图视口的像素坐标
  • 用户和视图投影中的地图坐标
  • 原始 DOM 事件引用
  • 事件类型和修饰键

尺寸管理

Map 自动处理其容器的尺寸更改,但您也可以强制更新尺寸:

// 强制更新地图尺寸
map.updateSize();

组件集成和生命周期管理

Map 类作为所有 OpenLayers 组件的集成点,管理它们的生命周期并协调它们的交互。

组件集成架构

SVG
100%

组件生命周期管理

Map 类通过事件驱动模式管理组件生命周期:

  1. 集合事件处理src/ol/Map.js508-590

    • Collection.ADD 事件自动在新组件上调用 setMap(this)
    • Collection.REMOVE 事件调用 setMap(null) 以清理引用
  2. 图层集成src/ol/Map.js177-188

    • setLayerMapProperty() 递归地在图层和图层组上设置地图引用
    • removeLayerMapProperty() 在删除图层时清理地图引用
  3. 视图状态同步src/ol/Map.js493-494

    • handleViewChanged_() 响应视图属性更改
    • 视图状态更改时自动触发渲染
  4. 清理和销毁src/ol/Map.js662-669

    • disposeInternal() 正确清理所有集合和 DOM 元素
    • 断开 ResizeObserver 连接并删除事件监听器

集成确保所有组件对其父地图保持正确的引用,并接收必要的生命周期事件以进行初始化和清理。

总结

Map 类是 OpenLayers 的核心组件,它将所有其他组件聚集在一起创建交互式地图。它管理渲染过程,处理用户交互,并提供用于操作地图状态的 API。理解 Map 类对于有效使用 OpenLayers 至关重要。