ol-ext:OpenLayers 扩展从 0 到可运行:弹窗、动画集群、历史地图叠加
ol-extOpenLayers 扩展从 0 到可运行弹窗、动画集群、历史地图叠加【免费下载链接】ol-extCool extensions for Openlayers (ol) - animated clusters, CSS popup, Font Awesome symbol renderer, charts for statistical map (pie/bar), layer switcher, wikipedia layer, animations, canvas filters.项目地址: https://gitcode.com/gh_mirrors/ol/ol-ext地图页面上的 4 个需求你要在一个 OpenLayers 地图页面上加四样东西点会聚合的动画集群、点选后弹出的提示框、叠在现代底图上的历史航片、点上直接渲染的统计图表。用原生 API 做每一项都要自己写 canvas 绘制、坐标换算或定位逻辑用 ol-extOpenLayers 的扩展库每一项都是现成类——ol.layer.AnimatedCluster、ol.Overlay.Popup、ol.layer.GeoImage、ol.style.Chart各写几行参数即可。下面按仓库里的示例代码验证这四个能力的用法。能力地图ol-ext 里能直接用的扩展把散点变成带动画聚合的圆ol-ext 动画集群AnimatedCluster在原生ol.source.Cluster之上做了两件事缩放时聚合圆之间的点位平滑过渡以及点击聚合后点位像弹簧一样散开。聚合圆里可以直接画扇区图用ol.style.Chart按类别拆分点数。const cluster new ol.source.Cluster({ distance: 40, source: vectorSource }); const clusterLayer new ol.layer.AnimatedCluster({ source: cluster, animationDuration: 700, // 缩放时点位过渡的时长毫秒 style: f f.get(features).length 1 ? pointStyle(f) // 单点用普通样式 : [new ol.style.Style({ image: new ol.style.Chart({ type: pie, radius: 20, data: countsByType(f) })})] // 混合点画扇区图 }); map.addLayer(clusterLayer); map.addInteraction(new ol.interaction.SelectCluster({ animate: true }));完整示例见examples/map/map.clustering.html里面还带了选择高亮和样式缓存的写法。屏幕上几百到几千个点、需要看清分布并点击展开时用它点少于一两百个时原生Cluster就够动画反而增加每帧渲染成本。把历史航片地理配准后叠成图层ol-ext 历史地图叠加ol.layer.GeoImage配ol.source.GeoImage把一张扫描地图或航拍照片按中心坐标 每像素米数钉到地球上再叠加在 OSM 或正射影像上面。支持裁切、旋转、透明度仓库示例里用的是 1976 年的 IGN 航拍照片const geoimg new ol.layer.GeoImage({ opacity: 0.7, source: new ol.source.GeoImage({ url: data/IGNF_PVA_1-0__1976-03-24_pt.jpg, imageCenter: [274764.75, 6243935.64], // 图片中心对应的地图坐标 imageScale: [0.589, 0.597], // 水平/垂直每像素代表的米数 imageCrop: [0, 0, 5526, 5000], // 只取图片的这个矩形区域 projection: EPSG:3857 }) }); map.addLayer(geoimg);跑出来长这样——上为示例直接引用的 1976 年航片原图下为同系列其他年份的影像都可用同样参数叠成图层做年代对比手上有航片、扫描图等单张地理配准图片时用它如果数据来自瓦片服务WMTS/WMS直接用原生 source不必绕道 GeoImage。给点挂一个 CSS 气泡ol-ext CSS 弹窗ol.Overlay.Popup继承自Overlay但把定位、边框、关闭按钮都变成了 CSS。popupClass提供 default、tips、warning、black 等现成套皮positioning支持 12 种方位auto会自动避开地图边缘。const popup new ol.Overlay.Popup({ positioning: auto, // 根据点击位置自动选方位 autoPan: { animation: { duration: 250 } }, // 靠近边缘时平移视图让出空间 closeBox: true, // 显示关闭按钮 popupClass: default // 换 tips / warning / black 换皮 }); map.addOverlay(popup); // 在选中要素的坐标处显示内容参数是 HTML 字符串 popup.show(feature.getGeometry().getFirstCoordinate(), h3属性详情/h3);想让弹窗外观随主题切换而不用自己写 CSS 时用它如果你的弹窗内容需要接 React/Vue 组件和状态管理建议保留原生Overlay内容区自己渲染。直接在点位置渲染统计图表和字体符号ol.style.Chart把饼图或柱状图画在单个点上data数组对应各扇区数值ol.style.FontSymbol把 Maki 或 Font Awesome 的字体字形画成地图符号可叠加 marker、circle、square 等底形矢量的改属性即可换颜色、描边、投影。// 饼图一个点表达一组统计数据 const chart new ol.style.Chart({ type: pie, data: [10, 30, 20], radius: 18, rotateWithView: true, stroke: new ol.style.Stroke({ color: #fff, width: 2 }) }); // 字体符号Maki 图标 marker 底形 const sym new ol.style.FontSymbol({ glyph: maki-cafe, form: marker, radius: 20, fill: { color: #fd0 }, stroke: { color: #fff, width: 3 } });需要在一个点上表达多类别统计、或想用同一套图标系统保持视觉一致时用它如果图标是固定的几张 PNG原生ol.style.Icon更省事。最小可运行示例集群聚合 点击弹窗前提npm install ol ol-extol-ext 4.x 声明 ol ≥ 5.3.0 为 peer 依赖页面引入ol/ol.css和ol-ext/dist/ol-ext.css下面代码用 webpack/parcel/Vite 等任意打包器运行。import ol/ol.css; import ol-ext/dist/ol-ext.css; import Map from ol/Map.js; import View from ol/View.js; import TileLayer from ol/layer/Tile.js; import OSM from ol/source/OSM.js; import VectorSource from ol/source/Vector.js; import ClusterSource from ol/source/Cluster.js; import Feature from ol/Feature.js; import Point from ol/geom/Point.js; import Style from ol/style/Style.js; import AnimatedCluster from ol-ext/layer/AnimatedCluster; import Chart from ol-ext/style/Chart; import Popup from ol-ext/overlay/Popup; import SelectCluster from ol-ext/interaction/SelectCluster; const map new Map({ target: map, view: new View({ center: [166326, 5992663], zoom: 5 }), layers: [new TileLayer({ source: new OSM() })] }); // 随机撒 500 个点 const source new VectorSource(); const ext map.getView().calculateExtent(map.getSize()); for (let i 0; i 500; i) { source.addFeature(new Feature(new Point([ ext[0] Math.random() * (ext[2] - ext[0]), ext[1] Math.random() * (ext[3] - ext[1]) ]))); } // 动画集群层混合点画饼图 map.addLayer(new AnimatedCluster({ source: new ClusterSource({ distance: 30, source }), animationDuration: 600, style: f { const feats f.get(features); return new Style({ image: feats.length 1 ? null : new Chart({ type: pie, radius: 16, data: [feats.length] })}); } })); // 点击集群点位散开并弹窗 const popup new Popup({ positioning: auto, closeBox: true }); map.addOverlay(popup); const select new SelectCluster({ animate: true, selectCluster: true }); map.addInteraction(select); select.getFeatures().on(add, e { const c e.element.get(features); popup.show(e.element.getGeometry().getCoordinates(), c.length 1 ? 单点 : 此聚合含 c.length 个点); }); select.getFeatures().on(remove, () popup.hide());跑起来之后500 个点聚合成若干圆滚轮缩放时圆之间的点平滑移动点击一个圆点位弹开并弹出气泡显示聚合数量再点一下收回、气泡消失。性能与调优几千个点时缩放动画掉帧甚至卡死。原因动画期间每帧要重绘所有聚合内的点成本与要素数成正比。修正clusterLayer.set(animationDuration, 0)关掉过渡或调大distance减少聚合数量。首次渲染时 FontSymbol 点位显示空白或方块。原因Maki/Font Awesome 字体尚未加载canvas 回退到系统字体。修正await document.fonts.load(20px Maki)之后再构建样式或仿照示例轮询字体宽度、加载完成后重建 styleCache。加载 5000 像素级别的历史航片时页面卡几秒。原因GeoImage 一次性解码全图并绘入 canvas。修正用imageCrop: [xmin, ymin, xmax, ymax]只取当前关心的区域再加载。选型与边界如果你的需求是在 OpenLayers 项目上叠加弹窗、动画集群、字体符号或历史地图这类交互与视觉扩展ol-ext 适合能力都是独立类用哪个引哪个如果项目不基于 OpenLayers或只是基础的图层显隐控制建议直接用原生 API或换用不依赖 ol 的底层库。延伸路径examples/官方示例页按 control、interaction、layer、style 等分目录浏览器直接打开即可运行src/源码按能力分 control、overlay、style、layer 等子目录要改默认行为时从这里入手doc/doc-pages/JSDoc 生成的 API 文档每个类一页含完整参数说明【免费下载链接】ol-extCool extensions for Openlayers (ol) - animated clusters, CSS popup, Font Awesome symbol renderer, charts for statistical map (pie/bar), layer switcher, wikipedia layer, animations, canvas filters.项目地址: https://gitcode.com/gh_mirrors/ol/ol-ext创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考