尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

OpenLayers v3.19.0 版本特性解析:Canvas 填充跟随地图、自由手绘绘制与样式克隆

OpenLayers v3.19.0 版本特性解析:Canvas 填充跟随地图、自由手绘绘制与样式克隆 前端GIS数据可视化【免费下载链接】openlayersOpenLayers项目地址https://gitcode.com/gh_mirrors/op/openlayers点击查看免费下载本篇技术指南以 OpenLayers 仓库中的版本发布文档 changelog/v3.19.0.md 为主体系统讲解该版本引入的四大核心能力CanvasGradient/CanvasPattern矢量填充随地图平移旋转、freehand 自由手绘模式、跨分辨率瓦片无缝对齐以及样式克隆同时结合仓库源码与示例完整梳理该版本要求的 API 命名空间与类型重命名等升级事项帮助开发者理解变更原理并顺利完成从 v3.18.x 到 v3.19.0 的平滑迁移。版本概况v3.19.0 是 OpenLayers 3.x 系列的一个重要功能与维护版本聚合了 120 余个 Pull Request、380 余次提交。除大量缺陷修复与文档增强外该版本持续推进对 Google Closure Library 依赖的移除工作并带来了若干直接影响开发者体验的新特性使用CanvasGradient或CanvasPattern作为矢量填充时填充会随地图一起移动和旋转交互行为更加直观对应 PR #5950freehand自由手绘模式下的绘制行为更加符合直觉对应 PR #5970、#5973、#5975当图层混合使用不同分辨率的瓦片时即最佳分辨率瓦片尚未全部加载完成之前低分辨率瓦片会与高分辨率瓦片对齐地图不再出现缝隙对应 PR #5890样式对象Style现在可以方便地克隆对应 PR #5832。此外openlayers.org 官方网站开始支持https协议访问。下文先深入讲解新特性的实现原理与使用方式再给出完整的升级说明。矢量填充渐变与图案随地图移动旋转行为变更在 v3.19.0 之前ol.style.Fill使用CanvasGradient或CanvasPattern作为填充时渐变与图案是相对于画布canvas对齐的也就是说当地图平移或旋转时填充内容并不会跟着地图动视觉上会出现填充漂移的怪异效果。v3.19.0 将这一行为修正为更符合直觉的方式填充锚定到地图原点通常是地图坐标[0, 0]因此渐变和图案会随着地图一起移动和旋转。这一实现细节在源码中得到了印证——当前仓库的 src/ol/style/Fill.js 中getKey()方法会专门区分CanvasPattern/CanvasGradient与普通颜色getKey() { const fill this.getColor(); if (!fill) { return ; } return fill instanceof CanvasPattern || fill instanceof CanvasGradient ? getUid(/** type {Object} */ (fill)) : typeof fill object src in fill ? fill.src : fill.offset : asArray(fill).toString(); }也就是说渐变/图案这类非颜色对象以对象唯一标识getUid参与渲染缓存查找这与普通颜色、图片图案PatternDescriptor按src与offset缓存走的是不同路径。从源码结构看渲染器正是在此基础上将填充变换与视图的旋转、平移变换叠加从而实现填充跟随地图。使用示例仓库为此新增了专门的示例 examples/canvas-gradient-pattern.js演示如何用CanvasGradient填充矢量要素。示例中特别注意到渐变与图案处于 canvas 像素空间因此需要结合pixelRatio进行调整import Fill from ../src/ol/style/Fill.js; // Gradient and pattern are in canvas pixel space, so we adjust for the // pixel ratio here const context document.createElement(canvas).getContext(2d); const pixelRatio window.devicePixelRatio; const gradient context.createLinearGradient(0, 0, 1024 * pixelRatio, 0); gradient.addColorStop(0, red); gradient.addColorStop(1, blue); const fill new Fill({color: gradient});把创建好的gradient直接作为Fill的color传入即可获得随地图平移旋转的渐变填充。除Fill外本版本还允许将CanvasPattern或CanvasGradient作为描边stroke样式使用对应 PR #5863以及允许按MultiPolygon进行裁剪对应 PR #5914。说明getKey()、setColor()中同时支持PatternDescriptor带src的对象形式的图片图案填充并提供了loading()/ready()方法用于处理图案图片的异步加载状态详见 src/ol/style/Fill.js。自由手绘freehand绘制模式交互优化v3.19.0 对手绘绘制做了三处关键改进PR #5970、#5973、#5975圆形、正方形与矩形都支持 freehand 模式——此前 freehand 仅适用于线与多边形本版本将其扩展到了Circle、Square与Box等几何类型为 Draw 交互新增freehand选项——可以全局开启 freehand 模式而不再只能依赖按住 Shift 键临时激活指针抬起pointerup时结束绘制——freehand 模式下松开鼠标/手指即完成绘制体验更符合手绘直觉。选项与运行时开关从当前仓库 src/ol/interaction/Draw.js 的 JSDoc 可以确认两个核心选项/** * property {boolean} [freehandfalse] Operate in freehand mode for lines, * polygons, and circles. This makes the interaction always operate in freehand * mode and takes precedence over any freehandCondition option. * property {import(../events/condition.js).Condition} [freehandCondition] * Condition that activates freehand drawing for lines and polygons. This * function takes a {link module:ol/MapBrowserEvent~MapBrowserEvent} and * returns a boolean to indicate whether that event should be handled. The * default is {link module:ol/events/condition.shiftKeyOnly}, meaning that the * Shift key activates freehand drawing. */freehand: true时交互始终处于手绘模式并优先于freehandCondition未设置freehand时默认通过freehandCondition激活默认条件是shiftKeyOnly——即按住 Shift 键拖拽即可手绘手绘模式下trace选项会被忽略见 src/ol/interaction/Draw.js。源码实现上freehand开关通过setFreehand(freehand)在运行时切换开启时把freehandCondition_替换为always恒真条件关闭时恢复为配置的条件函数对应 src/ol/interaction/Draw.js而getFreehand()可查询当前状态。手绘模式下顶点不再逐点吸附snapTolerance会被强制设为 1src/ol/interaction/Draw.js以保证轨迹平滑连续。示例draw-freehand仓库示例 examples/draw-freehand.js 演示了完整的交互式用法——通过复选框实时切换 freehand 模式并支持动态更换几何类型let draw; // global so we can remove it later function addInteraction() { if (typeSelect.value ! None) { draw new Draw({ source: source, type: typeSelect.value, freehand: freehandCheckbox.checked, }); map.addInteraction(draw); } } typeSelect.onchange function () { map.removeInteraction(draw); addInteraction(); }; freehandCheckbox.onchange function () { if (draw) { draw.setFreehand(freehandCheckbox.checked); } };对应的页面为 examples/draw-freehand.html。该示例的关键模式是切换几何类型时先removeInteraction(draw)再重建而切换 freehand 时则直接调用draw.setFreehand()原地切换无需重建交互。Draw 相关事件类型说明结合本版本的命名空间整理Draw交互相关事件常量已收敛为ol.interaction.Draw.EventType取值包括const DrawEventType { DRAWSTART: drawstart, DRAWEND: drawend, DRAWABORT: drawabort, };见 src/ol/interaction/Draw.js分别对应绘制开始、绘制结束与绘制中止三个事件。跨分辨率瓦片无缝对齐当图层所需的最高分辨率瓦片尚未全部加载完成时渲染器会先用较低分辨率的瓦片占位。v3.19.0 之前这些不同分辨率的瓦片在画布上的位置可能错位导致地图出现缝隙或重叠PR #5890本版本修正了该问题使低分辨率瓦片与高分辨率瓦片正确对齐地图整体无缝隙。从当前仓库 src/ol/renderer/canvas/TileLayer.js 的实现看瓦片绘制时会根据瓦片网格推导分辨率如tileGrid.getZForResolution(viewState.resolution)第 324 行并在绘制时按目标分辨率计算缩放const scaleX imageWidth / w; const scaleY imageHeight / h; context.drawImage( // ... gutter (rx - x) * scaleX, gutter (ry - y) * scaleY, rw * scaleX, rh * scaleY, // ... );见 src/ol/renderer/canvas/TileLayer.js。其中gutter的计算在 v3.19.0 中还引入了瓦片像素比tile pixel ratio的修正PR #6002保证 HiDPI 环境下 gutter 数值正确。整体看跨分辨率瓦片通过按分辨率缩放绘制并复用frameState的 extentPR #5895与瓦片/范围数组PR #5894实现了平滑的无缝过渡。样式克隆clone背景此前开发者若想基于现有样式派生新样式只能手动逐字段复制既繁琐又容易遗漏。v3.19.0 为样式体系统一增加了clone()方法PR #5832覆盖Fill、Stroke、Circle、RegularShape、Icon、Image、Text、Style等全部样式类KML 格式内部也改为使用clone方法复制样式PR #5876避免共享引用带来的副作用。实现要点以 src/ol/style/Fill.js 为例/** * Clones the style. The color is not cloned if it is a {link module:ol/colorlike~ColorLike}. * return {Fill} The cloned style. * api */ clone() { const color this.getColor(); return new Fill({ color: Array.isArray(color) ? color.slice() : color || undefined, }); }需要特别注意普通ColorArraynumber形式会被slice()深拷贝避免新旧样式共享同一颜色数组若颜色是ColorLike如CanvasGradient、CanvasPattern则不克隆新样式与旧样式共享该渐变/图案对象——这与getKey()中以getUid识别渐变/图案的缓存逻辑一致。典型用法克隆样式最常见的场景是以基础样式为模板做微调例如基于一个填充样式派生不同颜色的版本const baseFill new Fill({color: [200, 30, 30, 0.8]}); const derivedFill baseFill.clone(); // 颜色数组被 slice() 拷贝 derivedFill.setColor([30, 200, 30, 0.8]); // 修改克隆体不影响 baseFill同时本版本还为 src/ol/style/Circle.js 增加了setRadius()方法PR #5776配合克隆可以更方便地在运行时动态调整圆形样式半径。升级说明Upgrade Notes升级到 v3.19.0 时以下变更需要开发者跟进1.goog.DEBUG更名为ol.DEBUG作为移除 Google Closure Library 依赖的最后一步编译器 define 常量goog.DEBUG被重命名为ol.DEBUGPR #5834。如果你使用了自定义构建配置JSON 文件请将其中对应的键名同步修改。2.ol.format.ogc.filter命名空间简化为ol.format.filterol.format.ogc.filter简化为ol.format.filterPR #5903升级时直接移除名称中的ogc字符串即可。例如旧名称新名称ol.format.ogc.filter.andol.format.filter.and当前仓库中 src/ol/format/filter 目录即对应新命名空间包含And、Or、Not、EqualTo、NotEqualTo、GreaterThan、LessThan、IsBetween、IsNull、IsLike、During、DWithin、Bbox、Intersects、Within、Contains、Disjoint等过滤器实现以及ComparisonBinary、Comparison、LogicalNary、Spatial等抽象基类。另有一项相关修复InBetween过滤器的值现在会被包裹进Literal标签PR #5800保证 WFS 请求 XML 合法。3. 类型重命名仅影响与 Closure Compiler 一起编译应用的开发者以下内部类型被重命名。仅使用库 API 的开发者不受影响但如果你把应用与 OpenLayers 一起交给 Closure Compiler 编译、并在代码中使用这些类型名则需要按下表替换旧类型名新类型名ol.CollectionPropertyol.Collection.Propertyol.DeviceOrientationPropertyol.DeviceOrientation.Propertyol.DragBoxEventol.interaction.DragBox.Eventol.DragBoxEventTypeol.interaction.DragBox.EventTypeol.GeolocationPropertyol.Geolocation.Propertyol.OverlayPositioningol.Overlay.Positioningol.OverlayPropertyol.Overlay.Propertyol.control.MousePositionPropertyol.control.MousePosition.Propertyol.format.IGCZol.format.IGC.Zol.interaction.InteractionPropertyol.interaction.Interaction.Propertyol.interaction.DrawModeol.interaction.Draw.Modeol.interaction.DrawEventol.interaction.Draw.Eventol.interaction.DrawEventTypeol.interaction.Draw.EventTypeol.interaction.ExtentEventol.interaction.Extent.Eventol.interaction.ExtentEventTypeol.interaction.Extent.EventTypeol.interaction.DragAndDropEventol.interaction.DragAndDrop.Eventol.interaction.DragAndDropEventTypeol.interaction.DragAndDrop.EventTypeol.interaction.ModifyEventol.interaction.Modify.Eventol.interaction.SelectEventol.interaction.Select.Eventol.interaction.SelectEventTypeol.interaction.Select.EventTypeol.interaction.TranslateEventol.interaction.Translate.Eventol.interaction.TranslateEventTypeol.interaction.Translate.EventTypeol.layer.GroupPropertyol.layer.Group.Propertyol.layer.HeatmapLayerPropertyol.layer.Heatmap.Propertyol.layer.TilePropertyol.layer.Tile.Propertyol.layer.VectorTileRenderTypeol.layer.VectorTile.RenderTypeol.MapEventTypeol.MapEvent.Typeol.MapPropertyol.Map.Propertyol.ModifyEventTypeol.interaction.Modify.EventTypeol.RendererTypeol.renderer.Typeol.render.EventTypeol.render.Event.Typeol.source.ImageEventol.source.Image.Eventol.source.ImageEventTypeol.source.Image.EventTypeol.source.RasterEventol.source.Raster.Eventol.source.RasterEventTypeol.source.Raster.EventTypeol.source.TileEventol.source.Tile.Eventol.source.TileEventTypeol.source.Tile.EventTypeol.source.VectorEventol.source.Vector.Eventol.source.VectorEventTypeol.source.Vector.EventTypeol.source.wms.ServerTypeol.source.WMSServerTypeol.source.WMTSRequestEncodingol.source.WMTS.RequestEncodingol.style.IconAnchorUnitsol.style.Icon.AnchorUnitsol.style.IconOriginol.style.Icon.Origin这些重命名与 v3.19.0 整体推进的每个文件一个 provideone provide per file重构方向一致对应 PR #5937、#5960、#5860、#5855、#5859、#5864、#5861、#5880 等把散落在顶层命名空间下的类型收拢到所属模块之下为彻底摆脱 Closure Library 做准备。其他值得关注的增强除了上述核心变更v3.19.0 还包含一批实用增强GeoJSON 读取更灵活readFeature/readFeatures可直接接收 GeoJSON 几何对象PR #5944且GeoJSON构造器支持直接传入要素投影PR #5917BingMaps 源新增 getter为 api key 与 imagerySet 提供访问方法PR #5955Select 交互增强默认样式函数可处理无几何要素PR #5445并修复了multi选项的问题PR #5857绘制框的便捷函数新增绘制 Box 的便捷方法PR #5977URL 展开支持多位数字ol.TileUrlFunction.expandUrl支持多于一位的数字范围PR #5853Modify 交互停用时移除当前顶点PR #5963ol.getUid的序列行为得到文档化与测试覆盖PR #5835移除 DOM 渲染器ol.renderer.dom相关代码被移除PR #5815地图渲染统一收敛到 Canvas/WebGL 体系同时移除ol.globalPR #5837等 Closure 遗留设施。小结v3.19.0 是 OpenLayers 3.x 中期一次承上启下的版本功能层面随地图移动旋转的渐变/图案填充、支持圆形与矩形的 freehand 手绘、跨分辨率瓦片无缝对齐以及样式克隆都直接提升了日常开发的体验工程层面goog.DEBUG→ol.DEBUG、ol.format.ogc.filter→ol.format.filter及数十个内部类型的命名空间收敛标志着 OpenLayers 与 Google Closure Library 的彻底解耦进入收尾阶段。对升级者而言只需按上文升级说明一节处理自定义构建配置与类型名即可对普通 API 使用者则可直接享受新特性带来的收益。本版本的完整变更列表可参见 changelog/v3.19.0.md 原文相关示例代码位于 examples/draw-freehand.js 与 examples/canvas-gradient-pattern.js核心实现可进一步阅读 src/ol/style/Fill.js、src/ol/interaction/Draw.js 与 src/ol/renderer/canvas/TileLayer.js。赞分享前端GIS数据可视化【免费下载链接】openlayersOpenLayers项目地址https://gitcode.com/gh_mirrors/op/openlayers点击查看免费下载相关推荐Rodauth-Rails邮件模板定制打造专业的企业级邮件通知系统Rodauth Rails邮件模板定制打造专业的企业级邮件通知系统 Rodauth Rails作为Rodauth认证框架的Rails集成方案提供了强大的邮件Manim v0.14.0 版本更新全解析虚线绘制、标签构造器与 3D 填充渐变新特性Manim v0.14.0 版本更新全解析虚线绘制、标签构造器与 3D 填充渐变新特性 本文基于 Manim 社区版Manim Community Edit图形学教育Chart.js 面积图填充绘制时序指南用 filler.drawTime 精确控制填充区域的绘制层次Chart.js 面积图填充绘制时序指南用 filler.drawTime 精确控制填充区域的绘制层次 导读 在 Chart.js 中折线图与雷达图通过 f图表库前端数据可视化创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表