OpenLayers v3.6.0 升级指南:Draw 绘制交互与 tilegrid 瓦片坐标体系重构详解
2026/9/24 5:18:17 网站建设 项目流程
  • 前端
  • GIS
  • 数据可视化

【免费下载链接】openlayers

OpenLayers

项目地址:https://gitcode.com/gh_mirrors/op/openlayers
点击查看免费下载

本篇文章以 OpenLayers 官方 v3.6.0 变更日志 为主体,系统解读该版本对"实验性(experimental)"特性的一轮整理:ol.interaction.Draw的配置项与事件类型重命名、ol.tilegrid的 XYZ 工厂函数化与瓦片坐标变换规则调整,以及ol.source.TileWMSwrapX行为变更。读完本文,你将清楚掌握 v3.5.0 升级到 v3.6.0 时需要修改的每一处代码,并能结合当前仓库源码理解这些 API 背后的设计意图与延续至今的实现形态。

版本概览:40 个 PR 与一次"实验特性"整理

根据官方变更日志,v3.6.0 自 v3.5.0 以来共合入40 个 pull request,涵盖新特性、缺陷修复与文档改进。该版本的核心动作是对若干"实验性"功能进行代码库简化,因此官方在 Summary 中明确提醒:请务必跟随升级说明(upgrade notes)调整应用代码,以保证与最新版本兼容。

这轮变更主要集中两大区域:

  1. ol.interaction.Draw(绘制交互):配置项minPointsPerRing重命名、事件类型命名空间调整;
  2. ol.tilegrid(瓦片网格体系)XYZ构造器替换为静态工厂函数、瓦片坐标变换公式变更、widths选项移除、TileWMS 的wrapX默认值修正。

这两部分内容在仓库的 changelog/upgrade-notes.md 中有完全对应的历史升级章节,可作为交叉验证的权威依据。下文将逐条展开。

ol.interaction.Draw变更:minPoints 与事件类型命名

minPointsPerRingminPoints:从"仅多边形"到"线、面通用"

v3.6.0 将 Draw 交互的配置项minPointsPerRing重命名为minPoints,并且该选项不再只对多边形(polygon)绘制生效,而是同样适用于线串(linestring)绘制

  • 旧写法(v3.5.0 及之前):绘制多边形时,只有minPointsPerRing可以限制"每一圈(ring)至少要绘制的点数";
  • 新写法(v3.6.0 起):统一使用minPoints,线串与多边形均可配置,语义更直观、覆盖面更广。

从当前仓库源码看,这一配置项延续至今。在 src/ol/interaction/Draw.js 中可以看到其文档定义:

/** * @property {number} [minPoints] The number of points that must be drawn */

其内部实现在构造器中读取:

this.minPoints_ = options.minPoints ? options.minPoints : ...

(见 src/ol/interaction/Draw.js)。而在完成判定逻辑中,线串与多边形的点数校验分别使用了它(见 src/ol/interaction/Draw.js):

/** @type {LineCoordType} */ (sketchCoords).length > this.minPoints_; ... potentiallyDone = sketchCoordsPoly[0].length > this.minPoints_;

也就是说,minPoints决定了"绘制到多少个点时才允许结束(finish)"。升级时只需做如下替换即可:

// 旧写法 new ol.interaction.Draw({ source: vectorSource, type: 'Polygon', minPointsPerRing: 4 }); // 新写法 new ol.interaction.Draw({ source: vectorSource, type: 'Polygon', minPoints: 4 });

事件类型重命名:ol.DrawEventol.interaction.DrawEvent

v3.6.0 同时将ol.DrawEventol.DrawEventType重命名为ol.interaction.DrawEventol.interaction.DrawEventType。官方特别说明:只有当你的代码与 OpenLayers 一起编译(compiled together)时,这项重命名才会对代码产生影响——如果你只是通过全局ol命名空间使用库,则无需改动。

当前仓库中 Draw 交互的事件体系正是这套命名:在 src/ol/interaction/Draw.js 中,DrawEventType定义了三个事件类型,且DrawEvent继承自 OpenLayers 的基类Event

const DrawEventType = { /** @event DrawEvent#drawstart */ DRAWSTART: 'drawstart', /** @event DrawEvent#drawend */ DRAWEND: 'drawend', /** @event DrawEvent#drawabort */ DRAWABORT: 'drawabort' }; export class DrawEvent extends Event { ... }

类声明上通过@fires DrawEvent标注(见 src/ol/interaction/Draw.js),并在绘制流程中依次派发drawstart(如 src/ol/interaction/Draw.js)、drawend(L1478)、drawabort(L1513)事件。升级后的监听代码形如:

draw.on('drawstart', function (evt) { // evt 为 ol.interaction.DrawEvent 实例 // 可通过 evt.feature 获取正在绘制的草图要素 }); draw.on('drawend', function (evt) { // 绘制完成,evt.feature 为最终要素 });

ol.tilegrid变更:XYZ 工厂函数与瓦片坐标体系

ol.tilegrid.XYZ构造器 → 静态函数ol.tilegrid.createXYZ()

v3.6.0 将ol.tilegrid.XYZ构造器替换为静态函数ol.tilegrid.createXYZ()。新函数接受与旧构造器相同的参数,但返回一个普通的ol.tilegrid.TileGrid实例(不再有独立的 XYZ 子类类型)。

当前仓库中该工厂函数位于 src/ol/tilegrid.js,其选项类型XYZOptions(见 src/ol/tilegrid.js)定义了以下参数:

选项类型默认值说明
extentExtentEPSG:3857 全图范围网格范围,XYZ 网格原点取该范围的左上角;未指定maxResolution时,0 级分辨率由"一个瓦片恰好覆盖该范围"推算
maxResolutionnumber由 extent 与 tileSize 推算0 级分辨率
maxZoomnumber42最大缩放级别,决定网格层级数量(如maxZoom为 21 表示 0~21 共 22 级)
minZoomnumber0最小缩放级别
tileSizenumber \| Size[256, 256]瓦片像素尺寸

工厂函数内部用resolutionsFromExtent(src/ol/tilegrid.js)按缩放因子 2(即每级分辨率减半:maxResolution / 2^z)生成分辨率数组,并据此构造TileGrid。升级迁移示例:

// 旧写法:new ol.tilegrid.XYZ(...) var tileGrid = new ol.tilegrid.XYZ({ maxZoom: 22, tileSize: 512 }); // 新写法:ol.tilegrid.createXYZ(...) var tileGrid = ol.tilegrid.createXYZ({ maxZoom: 22, tileSize: 512 });

仓库升级说明中亦保留了类似示例(见 changelog/upgrade-notes.md):ol.tilegrid.createXYZ({tileSize: 512, maxZoom: 22}),可用于渲染瓦片尺寸为 512 的 XYZ 源。

内部瓦片坐标变换:-y-1height-y-1

v3.6.0 调整了 XYZ 源的内部瓦片坐标方案

  • 旧方案y坐标通过-y-1变换为源(source)使用的坐标;
  • 新方案y坐标通过height-y-1变换,其中height是该瓦片坐标所在缩放级别下瓦片网格的行数

两者在绝大多数常见情形下结果一致(因为对全球 XYZ 网格,第z级的行数恰为2^z,此时-y-1 ≡ 2^z-y-1),但新公式在网格范围被extent裁剪、行数不再等于2^z时依然正确。这是一次让坐标变换"适配任意网格形状"的底层修正,普通应用代码无需改动,除非你自行实现了瓦片 URL 函数并依赖旧的-y-1语义。

widths选项移除:WMTS 用sizes,其他网格用extent

v3.6.0 移除了ol.tilegrid.TileGrid及其子类(如 XYZ、WMTS)的widths构造选项,官方说明该选项"不再是 180° 经线处正确换行(wrapping)所必需的"。取而代之的是两条路径:

  1. ol.tilegrid.WMTS:新增sizes选项。其中每一项是一个ol.Size,数组第一项为width(对应 WMTS capabilities 中的TileMatrixWidth),第二项为height(对应TileMatrixHeight);
  2. 其他瓦片网格:改用extent来限定源(source)会请求的瓦片范围。

从当前仓库实现可以印证这套设计的延续:

  • src/ol/tilegrid/WMTS.js 中sizes被定义为"每个缩放级别的瓦片行数与列数",并在解析 WMTS capabilities 时按矩阵宽高推入(src/ol/tilegrid/WMTS.js):sizes.push([elt['MatrixWidth'], elt['MatrixHeight']])
  • src/ol/tilegrid/TileGrid.js 中extent的语义明确为:"TileSource源不会请求该范围之外的任何瓦片";同时当未配置origin/origins时,网格原点自动取 extent 的左上角(src/ol/tilegrid/TileGrid.js),并在构造时基于 extent 预先计算各层级瓦片范围(calculateTileRanges_,L232-L233)。

因此升级时,若你此前依赖widths限制请求范围,应改为:

// 旧写法:widths // var tileGrid = new ol.tilegrid.TileGrid({ ... widths: [2, 4, 8] ... }); // 新写法:extent(以自定义范围限制瓦片请求) var tileGrid = new ol.tilegrid.TileGrid({ extent: [-180, -85, 180, 85], resolutions: resolutions });

而对于 WMTS 网格,直接通过sizes描述每一矩阵的尺寸即可。

ol.source.TileWMSwrapX:默认值从undefined变为true

v3.6.0 之前,ol.source.TileWMSwrapX默认值是undefined,此时源会发送超出范围(out-of-extent)的瓦片 BBOX的 WMS 请求。从 v3.6.0 起:

  • wrapX只能是truefalse
  • 新默认值为true
  • 官方强调:通常不需要应用代码改动,但效果是:超出范围的瓦片请求不再使用越界 BBOX,而是改用平移到真实世界坐标的 BBOX。

当前仓库中该默认值逻辑清晰可见(src/ol/source/TileWMS.js 定义选项、L100 赋值):

wrapX: options.wrapX !== undefined ? options.wrapX : true,

结合上一节提到的ol/tilegrid.js中的wrapX(tileGrid, tileCoord, projection)辅助函数(src/ol/tilegrid.js),可以看出这套"水平环绕世界"的能力在 v3.6.0 后成为瓦片请求流程的默认行为:当瓦片中心落在投影范围之外时,会自动按世界宽度平移回有效范围。

v3.6.0 新特性与修复亮点

除升级说明外,v3.6.0 的 40 个 PR 还包含大量功能增强与修复,按主题归纳如下(PR 编号与描述均来自官方 变更日志):

几何与渲染

  • #3764:为ol.geom.Geometry新增intersectsExtent的实现与测试;
  • #3711:修复并测试ol.color.blend(颜色混合);
  • #3637 / #3659:实现后又回退了ol.renderer.Layer#forEachFeatureAtCoordinate,表明该特性当时仍在反复评估中;
  • #3718:为renderOrder增加断言;#3662:澄清renderBuffer选项文档。

交互(Interaction)

  • #3757:将mapBrowserEvent作为ol.SelectEvent的成员暴露;
  • #3673:增强ol.interaction.Draw的控制能力,例如支持绘制正方形(square drawing);
  • #3725:补充ModifyOptions#pixelTolerance的默认值文档;
  • #3740:为 select 交互补充@fires文档标注。

瓦片与网格

  • #3639:为ol.tilegrid.TileGrid增加extent支持(与上文widths移除直接相关);
  • #3722:在内部使用正确的TileCoord变换函数;#3747 / #3759:将tileCoordTransform恢复为成员并标记@api
  • #3689:修复 WMTSoptionsFromCapabilities在缺少OperationsMetadata段时崩溃的问题。

格式(Format)

  • #3699 / #3739:为 WKT 格式增加科学计数法支持,并简化其检测逻辑。

文档、构建与工程化

  • #3749、#3693、#3694、#3672:修正 API 文档、ol.extent.containsExtent文档、升级说明中的拼写与内部链接;
  • #3738:改进ol.TileUrlFunctionType的文档;#3741:增强回调/过滤函数参数与返回值文档;
  • #3683:改进 Map 关于 layers 与 layergroups 的文档;
  • #3692:支持在 Windows + Cygwin 环境下构建;#3649:收紧serve.js中的正则;
  • #3697:改用合法的 SPDX license 表达式;
  • #3677:为示例(examples)补充 metadata;#3665:将 proj4js 与投影定义文件加入示例资源;
  • #3751:测试不再依赖远程服务;#3710:为ol.extent增加更多测试用例;
  • #3732、#3735、#3736、#3682、#3664、#3663、#3709、#3688 等:涵盖示例标记修正、按钮失焦绑定方法、WebGLContextAttributes extern 补充、下载页链接等细节。

升级自检清单

升级到 v3.6.0(或阅读历史代码、迁移旧应用)时,建议对照以下清单逐项排查:

  1. Draw 交互:搜索minPointsPerRing,全部替换为minPoints;若代码与 OpenLayers 一起编译,将ol.DrawEvent/ol.DrawEventType改为ol.interaction.DrawEvent/ol.interaction.DrawEventType
  2. XYZ 网格:搜索new ol.tilegrid.XYZ(,改为ol.tilegrid.createXYZ(,并确认返回类型按TileGrid使用;
  3. TileGrid 配置:移除widths;WMTS 网格改用sizes(宽、高分别对应TileMatrixWidth/TileMatrixHeight),其他网格改用extent限制瓦片请求范围;
  4. TileWMS:确认没有依赖"发送越界 BBOX"的行为,wrapX现在固定为布尔值且默认true
  5. 自定义瓦片 URL 函数:确认内部 y 坐标变换不再依赖旧的-y-1公式。

以上涉及的历史升级条目,可随时回到 changelog/v3.6.0.md 与 changelog/upgrade-notes.md 核对原文;对应 API 的现行实现可分别查阅 src/ol/interaction/Draw.js、src/ol/tilegrid.js、src/ol/tilegrid/TileGrid.js、src/ol/tilegrid/WMTS.js 与 src/ol/source/TileWMS.js。

总结

v3.6.0 是 OpenLayers 在瓦片体系与绘制交互上一次方向明确的整理:createXYZ()工厂函数统一了 XYZ 网格的创建方式,height-y-1坐标变换让任意范围网格都能正确换算瓦片坐标,extent/sizes取代了widthswrapX默认开启则让 WMS 请求始终落在真实世界坐标内;同时minPoints与事件类型的重命名进一步统一了 Draw 交互的配置与类型模型。这些变更虽集中在"实验性"功能上,却深刻影响了后续版本中瓦片网格与绘制交互的 API 形态,理解这轮升级,对阅读 OpenLayers 历史代码与迁移旧工程都很有价值。

  • 前端
  • GIS
  • 数据可视化

【免费下载链接】openlayers

OpenLayers

项目地址:https://gitcode.com/gh_mirrors/op/openlayers
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询