- 前端
- GIS
- 数据可视化
【免费下载链接】openlayers
OpenLayers
本篇文章以 OpenLayers 官方 v3.6.0 变更日志 为主体,系统解读该版本对"实验性(experimental)"特性的一轮整理:ol.interaction.Draw的配置项与事件类型重命名、ol.tilegrid的 XYZ 工厂函数化与瓦片坐标变换规则调整,以及ol.source.TileWMS的wrapX行为变更。读完本文,你将清楚掌握 v3.5.0 升级到 v3.6.0 时需要修改的每一处代码,并能结合当前仓库源码理解这些 API 背后的设计意图与延续至今的实现形态。
版本概览:40 个 PR 与一次"实验特性"整理
根据官方变更日志,v3.6.0 自 v3.5.0 以来共合入40 个 pull request,涵盖新特性、缺陷修复与文档改进。该版本的核心动作是对若干"实验性"功能进行代码库简化,因此官方在 Summary 中明确提醒:请务必跟随升级说明(upgrade notes)调整应用代码,以保证与最新版本兼容。
这轮变更主要集中两大区域:
ol.interaction.Draw(绘制交互):配置项minPointsPerRing重命名、事件类型命名空间调整;ol.tilegrid(瓦片网格体系):XYZ构造器替换为静态工厂函数、瓦片坐标变换公式变更、widths选项移除、TileWMS 的wrapX默认值修正。
这两部分内容在仓库的 changelog/upgrade-notes.md 中有完全对应的历史升级章节,可作为交叉验证的权威依据。下文将逐条展开。
ol.interaction.Draw变更:minPoints 与事件类型命名
minPointsPerRing→minPoints:从"仅多边形"到"线、面通用"
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.DrawEvent→ol.interaction.DrawEvent
v3.6.0 同时将ol.DrawEvent和ol.DrawEventType重命名为ol.interaction.DrawEvent与ol.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)定义了以下参数:
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
extent | Extent | EPSG:3857 全图范围 | 网格范围,XYZ 网格原点取该范围的左上角;未指定maxResolution时,0 级分辨率由"一个瓦片恰好覆盖该范围"推算 |
maxResolution | number | 由 extent 与 tileSize 推算 | 0 级分辨率 |
maxZoom | number | 42 | 最大缩放级别,决定网格层级数量(如maxZoom为 21 表示 0~21 共 22 级) |
minZoom | number | 0 | 最小缩放级别 |
tileSize | number \| 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-1→height-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)所必需的"。取而代之的是两条路径:
ol.tilegrid.WMTS:新增sizes选项。其中每一项是一个ol.Size,数组第一项为width(对应 WMTS capabilities 中的TileMatrixWidth),第二项为height(对应TileMatrixHeight);- 其他瓦片网格:改用
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.TileWMS的wrapX:默认值从undefined变为true
v3.6.0 之前,ol.source.TileWMS的wrapX默认值是undefined,此时源会发送超出范围(out-of-extent)的瓦片 BBOX的 WMS 请求。从 v3.6.0 起:
wrapX只能是true或false;- 新默认值为
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:修复 WMTS
optionsFromCapabilities在缺少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(或阅读历史代码、迁移旧应用)时,建议对照以下清单逐项排查:
- Draw 交互:搜索
minPointsPerRing,全部替换为minPoints;若代码与 OpenLayers 一起编译,将ol.DrawEvent/ol.DrawEventType改为ol.interaction.DrawEvent/ol.interaction.DrawEventType; - XYZ 网格:搜索
new ol.tilegrid.XYZ(,改为ol.tilegrid.createXYZ(,并确认返回类型按TileGrid使用; - TileGrid 配置:移除
widths;WMTS 网格改用sizes(宽、高分别对应TileMatrixWidth/TileMatrixHeight),其他网格改用extent限制瓦片请求范围; - TileWMS:确认没有依赖"发送越界 BBOX"的行为,
wrapX现在固定为布尔值且默认true; - 自定义瓦片 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取代了widths,wrapX默认开启则让 WMS 请求始终落在真实世界坐标内;同时minPoints与事件类型的重命名进一步统一了 Draw 交互的配置与类型模型。这些变更虽集中在"实验性"功能上,却深刻影响了后续版本中瓦片网格与绘制交互的 API 形态,理解这轮升级,对阅读 OpenLayers 历史代码与迁移旧工程都很有价值。
- 前端
- GIS
- 数据可视化
【免费下载链接】openlayers
OpenLayers
相关推荐
OpenLayers 10.10.0 版本详解:WebGL 文本渲染、智能瓦片绘制与 WMTS 瓦片矩阵限制支持
OpenLayers 10.10.0 版本详解:WebGL 文本渲染、智能瓦片绘制与 WMTS 瓦片矩阵限制支持 OpenLayers 10.10.0 是一次覆
前端GIS数据可视化OpenLayers 4.3.0 升级指南:像素拾取、球面测量与交互/矢量瓦片新特性全解析
OpenLayers 4.3.0 升级指南:像素拾取、球面测量与交互/矢量瓦片新特性全解析 本指南以 OpenLayers v4.3.0 发布说明为核心,系统梳
前端GIS数据可视化Dear PyGui 绘图系统完整指南:Plot 架构、数据序列、坐标轴控制与高级交互
Dear PyGui 绘图系统完整指南:Plot 架构、数据序列、坐标轴控制与高级交互 Dear PyGui 的 plot 是构建在底层 C++ 库 ImPlo
桌面应用UI组件
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考