npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

vue-openlayers-d

v1.6.8

Published

地图辅助包

Downloads

194

Readme

openlayer + vue 地图辅助包

一个开箱即用、功能齐全、可高度配置的 Vue2 + OpenLayers 地图容器组件。
支持 多种底图切换聚合点位绘制测量闪烁动画点位序号坐标转换 等常用能力,全部封装成 一行调用 的 API。

✨ 特性一览

| 类别 | 能力 | 状态 | | ------------ | ------------------------------------------------------------ | ---- | | 地图控制 | 缩放/平移/旋转/范围限制/级别限制/比例尺/滑动缩放/缩略图/全屏 | ✅ | | 图层管理 | 矢量图层增删改查、Z-index、显隐、按 ID 清理 | ✅ | | 覆盖物 | Overlay 添加/删除/按 ID 查询、闪烁动画、CSS 扩散 | ✅ | | 点位渲染 | 批量单点、序号、自定义图标、文字偏移、聚合(高性能) | ✅ | | 绘制测量 | 线/面绘制、实时长度面积、分段提示、一键清除 | ✅ | | 坐标系 | 自动 4326 ↔ 3857 互转、地图投影自适应 | ✅ | | 事件 | 单击/双击/右键/移动/缩放/聚合点击/鼠标悬停 | ✅ | | 性能 | 聚合缓存、节流 60 fps、内存清理、生命周期销毁 | ✅ |

🛠 依赖

{
    "@turf/along": "^6.5.0",
    "@turf/area": "^6.5.0",
    "@turf/bbox-polygon": "^6.0.1",
    "@turf/boolean-contains": "^6.0.1",
    "@turf/buffer": "^5.1.5",
    "@turf/kinks": "^7.3.1",
    "@turf/length": "^6.5.0",
    "@turf/line-intersect": "^6.5.0",
    "core-js": "^2.6.5",
    "ol": "^6.15.1"
}

npm 下载

  📦 安装
  npm install vue-openlayers-d -S

main.js 配置

//main.js 加入引用
import openlayersD from 'vueOpenlayersD'
// import 'vue-openlayers-d/dist/vue-openlayers-d.css'
Vue.use(openlayersD)

🗺️ 地图对象

Props 参数

| 参数 | 类型 | 默认值 | 说明 | | ------------------ | --------- | ----------- | ---------------------- | | center | Array | [] | 地图初始中心点 [x,y] | | layerMapDefault | String | - | 默认底图服务地址 | | zoom | Number | 16 | 初始缩放级别 | | minZoom | Number | 2 | 最小缩放级别 | | maxZoom | Number | 28 | 最大缩放级别 | | projection | String | EPSG:3857 | 投影坐标系 | | extent | Array | [] | 初始范围 | | isOpenScaleLine | Boolean | true | 是否显示比例尺 | | isOpenZoomSlider | Boolean | true | 是否显示缩放条 | | isOpenOverview | Boolean | true | 是否显示鹰眼 | | isOpenFullScreen | Boolean | false | 是否显示全屏按钮 | | isOpenBottomZoom | Boolean | false | 是否显示右下角缩放值 | | mapType | Number | 4 | 底图类型 (业务自定义) | | config | Object | {} | 额外配置 | | noLayer | Boolean | false | 是否禁用默认底图 |

Events 回调事件

| 事件名 | 参数 | 说明 | | -------------- | -------------------------------- | ------------------------------------- | | ready | { map } | 地图初始化完成 | | click | { lon,lat,feature,attributes } | 点击地图要素/空白处 | | clickCluster | Array, center | 点击聚合点时返回聚合内所有 attributes | | dblclick | { lon, lat } | 双击地图 | | rightClick | { lon, lat } | 右键地图 | | pointerMove | Object | 鼠标移动经过要素 | | zoomMoveEnd | { zoom, center, extent } | 缩放或移动结束 | | zoomend | { zoom, center, extent } | 缩放级别变化 |

视角控制

| 方法 | 参数 | 返回值 | 说明 | | ---------------------------- | ----------------------- | ----------------------- | -------------------- | | setCenter(point) | [x, y] | — | 设置中心点 | | getCenter() | — | [x, y] | 获取当前中心 | | setLevel(level) | Number | — | 设置缩放级别 | | getLevel() | — | Number | 获取当前级别 | | centerAt(x, y) | x, y | — | 移动中心到指定坐标 | | centerArray(point) | [x, y] | — | 同 setCenter | | centerAndZoom(x, y, level) | x, y, level | — | 一次性定位并缩放 | | zoomIn() | — | — | 放大一级 | | zoomOut() | — | — | 缩小一级 | | setExtent(extent) | {minX,minY,maxX,maxY} | — | 缩放到指定范围 | | getCurrentExtent() | — | {minX,minY,maxX,maxY} | 当前视口 | | getExtent() | — | [minX,minY,maxX,maxY] | 当前视口(数组形式) |

图层管理

| 方法 | 参数 | 返回值 | 说明 | | ------------------------ | ----------------------------------------------- | ------------------------ | ----------------------- | | addLayer(config) | Object | ol/layer/Vector | 创建并添加矢量/聚合图层 | | removeLayer(id) | String | — | 根据 id 删除图层 | | removeLayerById(id) | String | — | 同上 | | removeBaseMapLayer() | — | — | 移除所有底图 | | switchBaseMap(config) | Object | — | 一键切换底图 | | getLayer(id) | String | ol/layer/Base / null | 按 id 取图层 | | getAllLayers() | — | Array<ol/layer/Base> | 所有图层 | | clearLayerFeatures(id) | String | — | 清空指定矢量图层要素 | | isLayerExist(id) | String | Boolean | 是否存在 | | setVisible(id) | String | — | 显/隐切换 | | addRootLayer(config) | Object | — | 向地图直接追加底图图层 | | addGeoJson | geojson,styles = { color: '#62aad0', width: 2 } | - | 添加 geojson 格式边界 |

覆盖物(Overlay)

| 方法 | 参数 | 返回值 | 说明 | | ------------------------ | ------------ | --------------------- | -------------- | | addOverlay(overlay) | ol/Overlay | — | 添加覆盖物 | | removeOverlay(overlay) | ol/Overlay | — | 删除覆盖物 | | getOverlayById(id) | String | ol/Overlay / null | 按 id 取覆盖物 | | deleteOverlayById(id) | String | — | 删除 | | getOverlays() | — | Array<ol/Overlay> | 全部覆盖物 |

坐标转换

| 方法 | 参数 | 返回值 | 说明 | | ------------------------ | ----------- | ----------- | ----------- | | wGS84ToMercator(point) | [lon,lat] | [x,y] | 4326 → 3857 | | mercatorToWGS84(point) | [x,y] | [lon,lat] | 3857 → 4326 |

辅助工具

| 方法 | 参数 | 返回值 | 说明 | | -------------------- | ---- | ---------------- | ---------------------- | getViewport() | — | HTMLElement | 地图视口 DOM | | getTargetElement() | — | HTMLElement | 地图容器 DOM | | getSize() | — | [width,height] | 容器像素尺寸 | | | render() | — | — | 手动触发地图重绘 | | updateSize() | — | — | 容器尺寸变化后刷新地图 | | createMapPolygon() | — | — | 容器尺寸变化后刷新地图 |

例子


 <OpenLayers
      class="map"
      ref="olmap"
      :zoom="map.zoom"
      :center="map.center"
      :projection="map.projection"
      :layerMapDefault="map.layerMapDefault"
      @click="pointClick"
      @zoomend="zoomend"
      @ready="ready"
    ></OpenLayers>

     let  map= {
        center: [79.92941, 37.123631], //中心点
        zoom: 11, //地图缩放级别
        projection: "EPSG:4326", //地图的投影坐标系,
        mapType:4,
        maxZoom: 19, ///最大缩放级别
        minZoom: 6, //最小缩放级别
        layerMapDefault:
          "https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer/tile/{z}/{y}/{x}"
          //瓦片服务地址
      }
     pointClick(obj) {
      console.log('地图点击')
    },
    zoomend() {},
    ready(obj) {
      console.log('地图加载完成')
      this.mapObj = obj.map
      let config={

              layerName: 'layer-root',
              id: 'ol-map-root',
              ...this.map
      }
      this.$refs.olmap.addRootLayer(config)
      //点位转跳
	    this.$refs.olmap.centerAndZoom(87.60834, 43.829723, 16)
    }

📍 点标注组件(MapIconMark)

| 参数名 | 必选 | 类型 | 说明 | | :--------- | :--- | :----- | ------------------------------------------------ | | position | 是 | Array | 点位 [array] [lon, lat] | | label | 否 | String | 显示文本信息 | | icon | 否 | Object | 如果只要标签名称就设置成一个像素的透明图标, 必须 | | elmentName | 否 | Object | 默认 'el-mapIconMark' | | className | 否 | String | 默认 'map-icon-mark' | | zIndex | 否 | Number | z 轴高度, 非必须, 默认 800 |

<MapIconMark
  :position="mapIconData.position"
  :label="mapIconData.label"
  :icon='mapIconData.icon'
  :elementName="mapIconData.elementName"
  :className="mapIconData.className">
</MapIconMark>

🎯 JS 画标注点

| 参数名 | 必选 | 类型 | 说明 | | :--------- | :--- | :----- | ----------------------- | | position | 是 | Array | 点位 [array] [lon, lat] | | id | 是 | String | 唯一 id | | icon | 否 | Object | 标注图片 | | attributes | 否 | Object | 附加属性 | | label | 否 | String | 显示文本信息 | | style | 否 | String | 文本信息样式 |

let defaultStle = {
  font: '14px Microsoft YaHei',
  color: '#fff',
  offsetX: 0,
  offsetY: 30,
  padding: [2, 10, 0, 10],
  bgColor: 'rgba(0,0,0,0.5)'
}
let config = {
  position: [87.60081797338869, 43.83722919055176],
  id: 'layerMark',
  icon: require('./mark.png'),
  attributes: { name: '标注点位' },
  label: '测试点位',
  style: { bgColor: 'rgba(255,1,1,0.5)' }
}
this.$refs.olmap.createIconMark(config)

📈 折线组件(MapLineString)

Attributes

| 参数名 | 必选 | 类型 | 说明 | 默认值 | | :---------- | :--- | :--------------------- | ----------------------------------------- | ---------------- | | pointList | 必须 | array [[lon, lat],...] | 组成线的点列表数组 Array, 必须 | | | lineColor | 否 | String | 线条颜色 | '#409eff' | | lineWidth | 否 | number | 线条宽度 | 2 | | lineDash | 否 | Array[number] | 是否使用虚线 | null | | className | 否 | number | 图层的 className | map-line-string | | zIndex | 否 | number | 图层 z 轴高度 | 300 | | elementName | 否 | String | feature.get('name')方法可以获得该叠加图层 | el-mapLineString |

<MapLineString
  :pointList="mapLineStringData.pointlist"
  :lineColor="mapLineStringData.lineColor"
  :lineWidth="mapLineStringData.lineWidth"
  :lineDash="mapLineStringData.lineDash"
  :elementName="mapLineStringData.elementName"
  :className="mapLineStringData.className"
></MapLineString>

🟦 多边形组件(MapPolygon)

Attributes

| 参数名 | 必选 | 类型 | 说明 | 默认值 | | :---------- | :--- | :--------------------- | ---------------------------------- | ----------------- | | pointList | 必须 | array [[lon, lat],...] | 组成多边形的点列表数组 Array, 必须 | | | fillColor | 否 | String | 线条填充颜色 | 'rgba(0,0,0,0.8)' | | lineColor | 否 | String | 多边形线条颜色 | '#409eff' | | lineWidth | 否 | number | 线条宽度 | 2 | | lineDash | 否 | Array[number] | 是否使用虚线 识别名称 识别名称 | null | | className | 否 | number | 图层的 className | map-polygon | | zIndex | 否 | number | 图层 z 轴高度 | 300 | | elementName | 否 | String | 识别名称 | el-mapPolygon |

<MapPolygon
  :pointList="mapPolygonData.pointlist"
  :fillColor="mapPolygonData.fillColor"
  :lineColor="mapPolygonData.lineColor"
  :lineWidth="mapPolygonData.lineWidth"
  :lineDash="mapPolygonData.lineDash"
  :elementName="mapPolygonData.elementName"
  :className="mapPolygonData.className">
</MapPolygon>

🔴 圆形组件(MapCircle)

Attributes

| 参数名 | 必选 | 类型 | 说明 | 默认值 | | :---------- | :--- | :--------------- | ---------------- | ----------------------- | | position | 必须 | array [lon, lat] | 圆中心点 | | radius | 否 | number | 圆半径 number | 100 | | fillColor | 否 | String | 圆形填充颜色 | 'rgba(255,255,255,0.5)' | | lineColor | 否 | String | 线条颜色 | '#409eff' | | lineWidth | 否 | number | 线条宽度 | 2 | | lineDash | 否 | Array[number] | 是否使用虚线 | null | | className | 否 | number | 图层的 className | map-circle | | zIndex | 否 | number | 图层 z 轴高度 | 300 | | elementName | 否 | String | 圆形识别名称 | el-mapCircle |

 <MapCircle
  :position="mapCircleData.position"
  :radius="mapCircleData.radius"
  :fillColor="mapCircleData.fillColor"
  :lineColor="mapCircleData.lineColor"
  :lineWidth="mapCircleData.lineWidth"
  :lineDash="mapCircleData.lineDash"
  :elementName="mapCircleData.elementName"
  :className="mapCircleData.className">
 </MapCircle>

📌 自定义覆盖物(MapOverlay)

Attributes

| 参数名 | 必选 | 类型 | 说明 | 默认值 | | :-------- | :--- | :------------ | ----------------------------- | ------------- | | position | 必须 | Array[array] | 标注中心点 Array, 必须 | | className | 否 | String | 设置自定义图层的 class String | map-overlay | | offset | 否 | Array[number] | 弹窗偏移 | 默认为 [0, 0] |

<MapOverlay
  :position="mapOverlayData.position"
  :className="mapOverlayData.className">
  <div>
    <img :src="mapOverlayData.img" alt="">
  </div>
 </MapOverlay>

💬 弹出窗体(MapPopup)

Attributes

| 参数名 | 必选 | 类型 | 说明 | 默认值 | | :-------- | :--- | :------------ | ---------------- | ------------------ | | position | 必须 | Array[array] | 弹窗中心点 | | mapShow | 必须 | Boolean | 弹窗显隐 | | title | 否 | String | 弹窗标题 | | offset | 否 | Array[number] | 弹窗偏移 | 默认为 [0, 0] | | className | 否 | String | 图层的 className | 默认为 'map-popup' | | bodyStyle | 否 | String | 内容样式 | | showClose | 否 | Boolean | 是否显示关闭按钮 |

Events

| 事件名称 | 说明 | 回调参数 | | :------- | :------- | -------- | | close | 关闭事件 | - |

<MapPopup
  :position="mapPopupData.position"
  :title="mapPopupData.title"
  :offset="mapPopupData.offset"
  :mapShow="mapPopupData.show"
  @close="mapPopupClose"
  :className="'map-popup'">
  {{ popupText }}
</MapPopup>
mapPopupData: {
  position: [87.621589, 43.827187], // 弹窗中心点 Array[array], 必须
  title: "点位标题详情", // 弹窗标题 String,非必须,默认为 ' '
  show: false, // 弹窗显隐 Boolean,必须,默认为 true
  offset: [0, 0], // 弹窗偏移 Array[number],必须,默认为 [0, 0]
  className: "map-popup", // 图层的class String,非必须,默认为 'map-popup'
  attributes: {}
}

🌟 海量点(MapPointCollection)

Attributes

| 参数名 | 必选 | 类型 | 说明 | 默认值 | | :---------- | :--- | :--------------------- | ---------------- | ------------------------------ | | pointlist | 必须 | array [[lon, lat],...] | 点列表数组 | | distance | 否 | number | 收起点的间距 | 40 | | zIndex | 否 | String | 图层 z 轴高度 | 400 | | offset | 否 | Array[number] | 弹窗偏移 | 默认为 [0, 0] | | fontColor | 否 | String | 文字的颜色 | '#fff' | | fillColor | 否 | String | 线条填充颜色 | '#f00' | | img | 否 | String | 点位图片 | 蓝色点 | | bgImg | 否 | String | 设置背景图 | | | className | 否 | String | 图层的 className | 默认为 'map-point-collection' | | elementName | 否 | String | 图层的 id 标识 | 默认为 'el-mapPointCollection' |

<MapPointCollection
  :pointList="mapPointCollectionData.pointlist"
  :distance="mapPointCollectionData.distance"
  :fillColor="mapPointCollectionData.fillColor"
  :fontColor="mapPointCollectionData.fontColor"
  :zIndex='mapPointCollectionData.zIndex'
  :offset="mapPointCollectionData.offset">
</MapPointCollection>

  mapPointCollectionData: {
    pointlist: [],
    distance: 100, // 收起点的间距  number,必须,默认为 40
    zIndex: 500, // 图层z轴高度, 非必须, 默认 400
    offset: [0, 2], // 文字偏移距离 [x,y], 非必须, 默认 [0,0]
    fontColor: "#000", // 文字的颜色 string (色彩标识,支持rgba),默认'#fff'(如果去掉文字那么直接rgba透明度设置为0)
    fillColor: "#2290e799", // 文字的背景颜色 string(色彩标识,支持rgba),默认'#f00'(如果去不要背景颜色那么直接rgba透明度设置为0)
    scale: 0.6 //图标缩放大小
  }

🔗 聚合点位组件 (MapClusterLayer)

✨ 核心能力

| 能力 | 状态 | | ----------------------------- | ------------------------- | | 万级点位 秒级聚合 | ✅ | | 平滑清空 不卡界面 | ✅(图层替换 + 异步分批) | | 点击聚合 散列动画 | ✅(带关闭按钮) | | 单点 / 聚合 样式自定义 | ✅ | | 自动 4326 ↔ 3857 坐标转换 | ✅ | | 增量更新 无闪烁 | ✅ | | 防抖 10w+ 数据 | ✅ | | 内存泄漏保护 | ✅ |


🎯 Props 参数

| 属性 | 类型 | 默认值 | 说明 | | ----------------- | --------- | -------- | -------------------------------------- | | id | String | 必填 | 图层唯一标识 | | name | String | 必填 | 图层名称 | | features | Array | [] | 点位数据,见下方格式 | | visible | Boolean | true | 是否显示 | | zIndex | Number | 6 | 图层层级 | | clusterDistance | Number | 100 | 聚合距离(像素) | | img | String | 蓝点图标 | 单点默认图标 URL | | scale | Number | 0.9 | 图标缩放 | | fontColor | String | '#fff' | 聚合数字颜色 | | fillColor | String | 渐变蓝 | 聚合圆填充色 | | offset | Array | [0, 2] | 文字偏移 [x, y] | | noClusterZoom | Number | 18 | 该级别以上不聚合 | | clusterStyleFn | Function | - | 自定义聚合样式 `(size)=>{color,radius} |

📡 事件 Event

| 事件 | 回调参数 | 触发时机 | | --------------- | ---------------------------------------- | ------------ | | @featureClick | {feature,type,center,coods,attributes} | 点击单个点位 | | @clusterClick | Array<同上> | 点击聚合群 | | @clearDone | - | 清空完成 |

📋 features 数据格式

;[
  {
    geom: { lon: 116.3974, lat: 39.9092 },
    attributes: { id: 1, name: '车辆-101', icon: '/img/car.png' }
  }
  // ...支持 10w+ 条
]

icon 留空则使用默认 bluePoint


🎨 自定义聚合样式

:clusterStyleFn="size => ({
  color: size > 100 ? '#ff4d4f' : '#91c7ff',
  radius: size > 100 ? 30 : 16
})"

📦 快速使用

      <MapClusterLayer
        id="deviceLayer"
        name="deviceLayer"
        ref="deviceLayer"
        :features="deviceLayerConfig.features"
        :fontColor="deviceLayerConfig.fontColor"
        :fillColor="deviceLayerConfig.fillColor"
        :img="deviceLayerConfig.img"
        :scale="deviceLayerConfig.scale"
          @featureClick="onPointClick"
          @clusterClick="onClusterClick"

      />
     let  deviceLayerConfig= {
        features: [{
          geom: {
            type: 'Point',
            lon: 12.111,
            lat: 6.111
          },
          attributes: {
            type: 'device',
            index: index,
            info: {},
            id: index,
            icon: '/icon/red.png'
          }
        }
        ],
        img: require("./1-06.png"), //点位图标 默认为蓝色小点
        fontColor: "#fff", //字体颜色 默认#FFF
        fillColor: "#2290e799", //背景颜色 默认 #2290e799
        scale: 0.5 //默认为0.9
      },

通过 js 生成聚合点位

| 参数名 | 必选 | 类型 | 说明 | | :-------------- | :--- | :----- | ------------------------------- | | id | 是 | String | 唯一 ID | | features | 是 | Array | 点位集合 array [[lon, lat],...] | | img | 否 | Object | 点位图标 | | scale | 否 | Number | 图标缩放比例 | | fontColor | 否 | Number | 字体颜色 | | fillColor | 否 | Number | 背景颜色 | | clusterDistance | 否 | Number | 聚合间隔 | | offset | 否 | Number | 偏移量 |

    const uqPoints = Array.from({ length: 100 }, (_, i) => ({
        geom: {
          lon: 87.3 + Math.random() * 0.4, // 87.3 ~ 87.7
          lat: 43.7 + Math.random() * 0.2 // 43.7 ~ 43.9
        },
        attributes: { id: i + 1000, name: `点位${i + 1}` }
      }));

      // 使用
      this.$refs.olmap.createClusterTemplate({
        id: 'poi-cluster',
        name: '乌鲁木齐设备聚合',
        features: uqPoints,
        clusterDistance: 60
      })

后台服务聚合只返回数字

<MapServerClusterLayer
id="serverLayer"
name="serverLayer" ref="serverLayer"
:features="serverLayerConfig.features"
:fontColor="serverLayerConfig.fontColor"
:fillColor="serverLayerConfig.fillColor"
:img="serverLayerConfig.img"
:scale="serverLayerConfig.scale" />

      serverLayerConfig: {
        features: [{
          geom: {
            type: 'Point',
            ...points
          },
          attributes: {
            type: 'device',
            index: index,
            pointType: 1, //针对后台聚合功能 0是普通点位  1是聚合点位
            count: 100, //聚合点位数量
            info: {},
            id: index
          }
        }],
        img: require("./1-06.png"), //点位图标 默认为蓝色小点
        fontColor: "#fff", //字体颜色
        fillColor: "#fea81a99", //背景颜色
        scale: 0.5 //默认为0.9
      },

📡 FlashPoint 雷达扩散点覆盖物

一个用于在 OpenLayers 地图上添加可自定义颜色 + 任意属性实心雷达扩散动画点的便捷方法。该点使用 CSS 动画实现扩散效果,支持挂载自定义数据到 DOM 与 Overlay 实例。


📥 参数说明

| 参数名 | 类型 | 必填 | 默认值 | 说明 | |--------------|----------|------|----------------|------| | id | string | 否 | 'point_animation' | 覆盖物唯一标识,用于后续删除或查找。若已存在同 ID 覆盖物,将先删除再创建。 | | point | Array | 是 | — | 点的经纬度坐标,格式为 [lng, lat](注意:OpenLayers 默认使用 [x, y],请确保坐标系匹配)。 | | color | string | 否 | '#e6a23c' | 雷达扩散点的颜色,支持任意 CSS 颜色值(如 red, #ff0000, rgba(...))。通过 CSS 变量 --radar-color 注入样式。 | | attributes | Object | 否 | {} | 任意自定义属性对象。键值对将被挂载:• 到 DOM 元素的 dataset(对象值会被 JSON.stringify• 到 Overlay 实例的 .attributes 属性(原始对象,未序列化) |

🎯 返回值

  • Overlay 实例:OpenLayers 的 Overlay 对象,可用于后续操作(如移除、更新位置等)。

🧪 使用示例

// 添加一个红色雷达点
const overlay = this.$refs.olmap.setFlashPoint(
  'warning_point',
  [120.123456, 30.123456],
  'red',
  {
    type: 'alert',
    level: 'high',
    timestamp: Date.now()
  }
)

// 后续可通过 overlay.attributes 访问原始数据
console.log(overlay.attributes.level) // 'high'
// 或通过 DOM dataset 访问(字符串化)
console.log(overlay.getElement().dataset.level) // "high"

🚗 轨迹动画 并出现小车按照轨迹移动(MapTrailAnimate)

一个基于 OpenLayers 的轨迹动画 Vue 组件,支持小车沿轨迹移动、起点终点标记、播放控制等功能。

📋 功能特性

  • 🚗 轨迹动画 - 小车沿预设轨迹平滑移动
  • 🎯 起点终点标记 - 自定义图标标记起终点
  • ⏯️ 播放控制 - 播放、暂停、重启、速度调节
  • 🔁 循环播放 - 支持动画循环播放
  • 🎯 跟随模式 - 地图自动跟随小车移动
  • 🎨 样式定制 - 自定义图标、线条样式、箭头等
  • 📊 事件系统 - 丰富的状态变化事件回调
  • 🛡️ 健壮性 - 完善的错误处理和边界检查

⚙️ Props 配置

| 属性名 | 类型 | 默认值 | 说明 | | ------------ | ------- | ----------------------- | ------------------------------ | | features | Array | [] | 轨迹点数组 [[lng, lat], ...] | | startPic | String | defaultImage.startPic | 起点图标 URL | | endPic | String | defaultImage.endPic | 终点图标 URL | | carPic | String | defaultImage.carPic | 小车图标 URL | | loop | Boolean | false | 是否循环播放 | | speed | Number | 10 | 动画速度 (1-100,数字越小越快) | | lineStyle | Object | {} | 轨迹线条样式配置 | | attributes | Object | {} | 自定义属性 |

<template>
  <OpenLayers ref="map" :center="[116.4, 39.9]" :zoom="12">
    <MapTrailAnimate
      ref="trail"
      :features="trailPoints"
      :speed="trailSpeed"
      :loop="trailLoop"
      @positionUpdate="onPositionUpdate"
      @animationEnd="onAnimationEnd"

    />
    <button @click="$refs.trail.pause()">暂停</button>
    <button @click="$refs.trail.resume()">继续</button>
    <button @click="$refs.trail.restart()">重播</button>
    <button @click="$refs.trail.toggleFollow()">跟随</button>
  </OpenLayers>
</template>

<script>
export default {
  data() {
    return {
      trailPoints: [
        [87.575309, 43.816728],
        [87.60081797338869, 43.83722919055176]
      ],
      trailSpeed: 50,
      trailLoop: false,
      lineStyle: {
        strokeColor: '#ff6600',
        strokeWeight: 5,
        showDir: false,
        dirStep: 50
      }
    }
  }
}
</script>

线条样式配置

lineStyle:{
  zIndex: 2, // 覆盖物的叠加顺序
  showDir: true, // 是否显示白色方向箭头
  dirStep:100 //白色方向箭头的间距默认100 showDir:true时生效
  strokeOpacity: 0.9, //  线条透明度
  strokeWeight: 5, //  线条宽度
  strokeStyle: "solid", // 轮廓线样式,实线: solid 虚线:dashed
  strokeDasharray: [], // 轮廓线间隙
  lineCap: "butt", // 折线两端线帽的绘制样式,默认值为'butt'无头,其他可选值:'round'圆头、'square'方头
  lineJoin: "round", // 折线拐点的绘制样式,默认值为'round'圆角,其他可选值:'round'圆角、'bevel'斜角
  isOutline: false, // 线条是否带描边,默认false
  borderWeight: 10, // 描边的宽度,默认为1
  outlineColor: "#000000", // 线条描边颜色,此项仅在isOutline为true时有效,默认:#000000
  extData: null, // 自定义信息
  strokeColor: "#28F"// 默认填充颜色
}

🎯 事件回调

| 事件名 | 参数 | 说明 | | ---------------- | ------------------------------- | ------------ | | start | - | 动画开始 | | end | - | 动画结束 | | paused | - | 动画暂停 | | resumed | - | 动画继续 | | restarted | - | 动画重新开始 | | loopStart | - | 循环开始 | | turnPoint | {index} | 到达转弯点 | | positionUpdate | {index, coordinate, progress} | 位置更新 | | positionJump | {index} | 位置跳转 | | followToggled | follow | 跟随模式切换 | | animationStart | - | 动画开始 | | animationEnd | - | 动画结束 | | error | error | 错误发生 |

🎛️ 方法 API

播放控制

// 播放控制
this.$refs.trail.pause() // 暂停
this.$refs.trail.resume() // 继续
this.$refs.trail.restart() // 重新开始
this.$refs.trail.stopAndContinue() // 暂停/继续切换

// 速度控制
this.$refs.trail.setSpeed(50) // 设置速度 (1-100)

// 跟随模式
this.$refs.trail.toggleFollow() // 切换跟随模式

// 状态查询
this.$refs.trail.getStatus() // 获取当前状态
this.$refs.trail.isPlaying() // 是否正在播放
this.$refs.trail.isPaused() // 是否暂停
this.$refs.trail.getProgress() // 获取进度百分比
this.$refs.trail.getCurrentPosition() // 获取当前位置

状态查询

// 获取状态
const status = this.$refs.trail.getStatus()
// {
//   isPlaying: true,
//   isPaused: false,
//   currentIndex: 5,
//   totalPoints: 20,
//   progress: 0.25,
//   isLoop: false,
//   speed: 50,
//   follow: true
// }

// 其他查询方法
this.$refs.trail.getProgress() // 进度百分比
this.$refs.trail.getCurrentPosition() // 当前坐标
this.$refs.trail.getTotalPoints() // 总点数
this.$refs.trail.isPlaying() // 是否播放中
this.$refs.trail.isPaused() // 是否暂停

JS 绘画 Line

| 参数名 | 必选 | 类型 | 说明 | | :--------- | :--- | :----- | ------------------------------- | | features | 是 | Array | 点位集合 array [[lon, lat],...] | | id | 是 | String | 唯一 ID | | attributes | 否 | String | 附加属性 非必填 | | lineStyle | 否 | JSON | 线条样式 |

let points = [
  [87.575309, 43.816728],
  [87.60081797338869, 43.83722919055176],
  [87.61420756079103, 43.82950442858887],
  [87.64012842871095, 43.847872195922854],
  [87.618283, 43.892136]
]
let lineStyle = {
  zIndex: 2, // 覆盖物的叠加顺序
  showDir: true, // 是否显示白色方向箭头
  dirStep:100 //白色方向箭头的间距默认100 showDir:true时生效
  strokeOpacity: 0.9, //  线条透明度
  strokeWeight: 5, //  线条宽度
  strokeStyle: 'solid', // 轮廓线样式,实线: solid 虚线:dashed
  strokeDasharray: [], // 轮廓线间隙
  lineCap: 'butt', // 折线两端线帽的绘制样式,默认值为'butt'无头,其他可选值:'round'圆头、'square'方头
  lineJoin: 'round', // 折线拐点的绘制样式,默认值为'round'圆角,其他可选值:'round'圆角、'bevel'斜角
  isOutline: false, // 线条是否带描边,默认false
  borderWeight: 10, // 描边的宽度,默认为1
  outlineColor: '#000000', // 线条描边颜色,此项仅在isOutline为true时有效,默认:#000000
  extData: null, // 自定义信息
  strokeColor: '#28F' // 默认填充颜色
}
let config = {
  features: points,
  id: 'LineLayer',
  attributes: { name: '测试' },
  lineStyle: lineStyle
}
this.$refs.olmap.createLine(config)

JS 画圆 drawCircle

| 参数名 | 类型 | 必须 | 默认值 | 描述 | | ---------- | ------------- | ---- | ------------------------- | ---------------------------------------------------------------------------------------- | | id | String | 否 | 'el-map-circle' | 圆形图层的唯一标识符,用于后续查找和删除图层。 | | position | Array | 否 | [0, 0] | 圆心的经纬度坐标,格式为 [经度, 纬度]。 | | radius | number | 否 | 100 | 圆的半径,单位为米。 | | lineColor | String | 否 | '#409eff' | 圆边框的颜色,使用标准的 CSS 颜色格式(如十六进制、RGB 等)。 | | lineWidth | number | 否 | 2 | 圆边框的宽度,单位为像素。 | | lineDash | Array | 否 | null | 圆边框的虚线模式,指定线段和间隔的长度,例如 [4, 2] 表示 4 像素的线段和 2 像素的间隔。 | | fillColor | String | 否 | 'rgba(255,255,255,0.5)' | 圆内部的填充颜色,使用标准的 CSS 颜色格式。 | | zIndex | number | 否 | 200 | 圆形图层的 Z 轴索引,用于控制图层的显示顺序。 | | className | String | 否 | 'map-circle' | 圆形图层的 CSS 类名,用于样式定制。 | | attributes | Object | 否 | null | 附加在圆形要素上的自定义属性数据,可以用于存储与圆形相关的额外信息。 |

  this.$refs.olmap.drawCircle({
        position: [87.611935, 43.963691],
        radius: 1000,
        id: 'circle-beijing',
        width: 3,
        lineColor: '#ff0000',
        fillColor: 'rgba(255, 0, 0, 0.3)',
        attributes:{name:123}
      })
      this.$refs.olmap.centerAt(87.611935, 43.963691)

🔥 热力图(MapHeat)

| 参数名 | 必选 | 类型 | 说明 | | :-------- | :--- | :-------------- | --------------------------------------------------- | | name | 否 | string | 图层名字 | | data | 是 | object / array | 热力图的数据[{lon: 87.620,lat: 43.837,weight: 0.2}] | | gradient | 否 | array | 热力图渲染色带颜色 | | longitude | 否 | string | 热力图数据中代表经度的字段(默认为 lon) | | latitude | 否 | string | 热力图数据中代表纬度的字段(默认为 lat) | | radius | 否 | number | 每个像素渲染点半径 | | blur | 否 | number | 模糊度 | | zIndex | 否 | string / number | 图层层级,默认为 1 | | visible | 否 | boolean | 图层是否可见,默认为 false |



<MapHeat :map="mapObj" :data="heatData"></MapHeat>
   this.heatData.push({
        log: 87.62081797338869,  // 经度
        lat: 43.83722919055176, // 纬度
        weight: 0.2 // 该坐标点的权重值(0-1之间的小数)
      })

📏 测量工具(MapMeasureTool) 测距 测面积

Attributes

| 参数名 | 必选 | 类型 | 说明 | | :------ | :--- | :----- | ------------------------------------------- | | name | 否 | string | 图层名字 | | actived | 是 | Bool | 绘画状态 true 开始 | | type | 否 | string | LineString 测距 Polygon 测面积 默认 Polygon |

Events

| 事件名称 | 说明 | 回调参数 | | :-------- | :----------- | -------- | | mesureEnd | 绘画完成事件 | object |

  <MapMeasureTool :name="'MapMeasureTool'" :id="'MapMeasureTool'" :actived="actived"  :type="'LineString'" @mesureEnd="mesureEnd"></MapMeasureTool>

✏️ 绘制工具(MapDraw)绘制圆形矩形多边形

| 参数名 | 必选 | 类型 | 说明 | | :------ | :--- | :----- | --------------------------------------- | | name | 否 | string | 图层名字 | | actived | 是 | Bool | 绘画状态 true 开始 | | type | 是 | string | Circle 圆形 Box 多边形 默认矩形 Polygon |

Events

| 事件名称 | 说明 | 回调参数 | | :-------- | :----------- | -------- | | mesureEnd | 绘画完成事件 | object |

 <MapDraw id="drawLayers" name="绘制图层" :actived="drawActive" @drawend="drawFinish" :type="drawType"></MapDraw>

🏷️ 海量文本标注(addTextLabels)

| 参数名 | 类型 | 默认值 | 说明 | | ---------------- | ------------------ | ------------ | ------------------------------------------ | | cfg | Object | {} | 配置对象 | | ├─ layerId | string | text-layer | 图层唯一标识,重复调用自动复用 | | ├─ id | string | text-layer | 同 layerId,二选一即可 | | ├─ zIndex | number | 100 | 图层层级 | | ├─ data | Array<Object> | [] | 标注数据,每一项必须包含 textcoord | | ├─ style | Object | Function | {} | 文字样式对象,或 (text)=>Style 函数 | | ├─ onClick | Function | — | 点击回调 (feature, attrs, evt)=>{} | | ├─ onHover | Function | — | 悬停回调 (feature, attrs, evt)=>{} | | ├─ onMouseOut | Function | — | 鼠标移出回调 (feature, attrs, evt)=>{} | | ├─ clearBefore | boolean | false | 首次渲染前是否清空旧数据 |

// 1. 一次性渲染
const labels = this.$refs.olmap.addTextLabels({
  layerId: 'city-names', // 图层 id(重复调用会复用同一层)
  data: [
    {
      text: '北京',
      coord: fromLonLat([116.404, 39.915]),
      attributes: { id: 1 }
    },
    { text: '上海', coord: fromLonLat([121.4737, 31.2304]) }
  ],
  style: {
    // 文字样式
    font: 'bold 14px Arial',
    fillColor: '#ff0000',
    strokeColor: '#fff',
    strokeWidth: 2,
    offsetX: 0,
    offsetY: 0
  },
  onClick: (feature, attrs, evt) => console.log('点击 →', attrs.text),
  onHover: (feature, attrs, evt) => console.log('悬停 →', attrs.text),
  onMouseOut: (feature, attrs, evt) => console.log('移出 →', attrs.text),
  clearBefore: false, // 首次渲染是否清空旧数据
  zIndex: 100 // 图层层级
})

// 2. 动态追加 / 替换
labels.update([{ text: '广州', coord: fromLonLat([113.2644, 23.1291]) }], {
  clear: true
}) // clear=true 先清空再添加

// 3. 仅移除图层
labels.remove()

// 4. 完全销毁(清理交互)
labels.dispose()

setMapIconMarks 添加标注物 图片+文字

list 数组字段

| 字段 | 类型 | 必填 | 默认值 | 说明 | | ------------ | ------------------ | ---- | ------------------- | --------------------------------- | | id | string | ✔ | — | 唯一标识,用于增量更新 | | position | [number, number] | ✔ | — | 坐标 [lng, lat] | | icon | string | ✖ | opts.defaultIcon | 图标 URL | | scale | number | ✖ | opts.defaultScale | 图标缩放比例 | | label | string | ✖ | — | 标注文本 | | attributes | Object | ✖ | {} | 任意附加属性,会透传到 feature 上 |

opts 配置字段

| 字段 | 类型 | 必填 | 默认值 | 说明 | | -------------- | -------- | ---- | ----------------------- | -------------- | | layerKey | string | ✖ | _map_icon_marks_layer | 图层唯一标识 | | className | string | ✖ | map-icon-marks | 图层 CSS class | | zIndex | number | ✖ | 30 | 图层层级 | | defaultIcon | string | ✖ | /img/bluePoint.png | 默认图标 URL | | defaultScale | number | ✖ | 1.5 | 默认缩放比例 |

// 模拟生成 5 个点
const points = [
  {
    id: 'p1',
    position: [87.3, 43.7],
    icon: '/img/hot.png',
    label: '点位1',
    attributes: { pop: 100 }
  },
  {
    id: 'p2',
    position: [87.35, 43.75],
    icon: '/img/hot.png',
    label: '点位2',
    attributes: { pop: 200 }
  },
  {
    id: 'p3',
    position: [87.4, 43.78],
    label: '点位3',
    attributes: { pop: 150 }
  }
]
// 添加/更新图标图层
const layer = setMapIconMarks(points, {
  className: 'my-icon-layer',
  zIndex: 50,
  defaultIcon: '/img/default.png'
})

// 后续更新或删除某些点,只需再次调用 setMapIconMarks
const updatedPoints = [
  {
    id: 'p1',
    position: [87.31, 43.71],
    label: '点位1更新',
    attributes: { pop: 120 }
  },
  {
    id: 'p4',
    position: [87.42, 43.79],
    icon: '/img/new.png',
    label: '新增点',
    attributes: { pop: 300 }
  }
]

this.$refs.olmap.setMapIconMarks(updatedPoints)

🟨 多边形绘制(createMapPolygon)

| 参数 | 类型 | 默认值 | 说明 | | ------------ | -------- | ----------------- | ---------------------------------- | | id | String | el-mapPolygon | 图层唯一标识,重复调用会先删除旧层 | | className | String | map-polygon | 图层 CSS 类名 | | attributes | Object | — | 任意业务属性,挂载到 feature | | zIndex | Number | 200 | 层级 | | lineColor | String | rgba(0,0,0,0.6) | 边框颜色 | | lineWidth | Number | 2 | 边框宽度 | | lineDash | Array | null | 虚线样式,如 [5, 5] | | fillColor | String | rgba(0,0,0,0.1) | 填充色,支持透明 | | pointList | Array | — | 必填 坐标数组,见下 | | projection | String | EPSG:4326 | 传入坐标的坐标系 |

// 在组件 methods 中直接调用
this.$refs.olmap.createMapPolygon({
  id: 'fence',
  pointList: [
    [120, 30],
    [121, 30],
    [121, 31],
    [120, 31],
    [120, 30] // 外环闭合
  ],
  fillColor: 'rgba(255,0,0,0.2)',
  lineColor: '#ff0000',
  lineWidth: 3,
  zIndex: 200
})

参数总览

| 参数 | 类型 | 默认值 | 说明 | | ----------- | --------------- | ---------------------- | ---------------------------------- | | polygons | Array<Object> | [] | 必填 多边形配置数组 | | layerKey | String | _batch_polygon_layer | 图层唯一标识,重复调用自动替换 | | className | String | map-batch-polygon | 图层 CSS 类名 | | zIndex | Number | 200 | 图层叠加层级 |

单条多边形配置(polygons[i])

| 字段 | 类型 | 说明 | | ------------ | -------- | ------------------------------------ | | id | String | 多边形唯一标识(可选,用于属性查询) | | pointList | Array | 必填 坐标数组,见下方格式 | | lineColor | String | 边框颜色,默认 #007bff | | lineWidth | Number | 边框宽度,默认 2 | | lineDash | Array | 虚线样式,如 [5, 5] | | fillColor | String | 填充色,默认 rgba(0,0,0,0.1) | | attributes | Object | 任意业务字段,挂载到 feature | | projection | String | 传入坐标系,默认 EPSG:4326 |

返回值

| 字段 | 类型 | 说明 | | -------- | ----------------- | ---------------------- | | layer | ol/layer/Vector | 图层实例,可进一步操作 | | remove | Function | 调用立即删除整张图层 |

// 1) 导入方法
// 已在组件 methods 中提供 createMapPolygons

// 2) 准备数据
const polygons = [
  {
    id: 'area1',
    pointList: [
      [120, 30],
      [121, 30],
      [121, 31],
      [120, 31],
      [120, 30] // 外环
    ],
    fillColor: 'rgba(255,0,0,0.3)',
    lineColor: '#f00',
    lineWidth: 2,
    attributes: { name: 'A区域' } // 任意业务字段
  },
  {
    id: 'area2',
    pointList: [
      [
        [120.5, 30.5],
        [120.8, 30.5],
        [120.8, 30.8],
        [120.5, 30.8],
        [120.5, 30.5]
      ], // 外环
      [
        [120.6, 30.6],
        [120.7, 30.6],
        [120.7, 30.7],
        [120.6, 30.7],
        [120.6, 30.6]
      ] // 内环(孔)
    ],
    fillColor: 'rgba(0,128,255,0.2)',
    lineDash: [5, 5],
    attributes: { name: 'B区域(带孔)' }
  }
]

// 3) 调用
const { layer, remove } = this.createMapPolygons(polygons, {
  layerKey: 'myPolygons',
  zIndex: 300
})

// 4) 一键删除
// remove()
// 更新数据
this.createMapPolygons(newPolygons, { layerKey: 'myPolygons' })

addPointsWithNumbers 使用说明

一键在 OpenLayers 地图上批量绘制 带数字序号 的点位(图标 + 文字),支持 自定义图标、偏移、样式、坐标系自动转换 等。


1. 快速上手

// 最简单的调用
mapComp.addPointsWithNumbers({
  points: [
    { lon: 116.3974, lat: 39.9092 },
    { lon: 121.4737, lat: 31.2304 }
  ]
})

| 效果 | | ------------------------------------------- | | 两个默认蓝色圆点,分别显示数字 12 |


2. 参数总览

| 字段 | 类型 | 默认值 | 说明 | | ------------- | ---------- | --------------------------- | --------------------------------------- | | layerId | string | 'custom-points-layer' | 图层 ID,重复调用会先删除旧图层 | | points | Array | [] | 必填 点位数组,支持三种写法,见下方 | | center | number[] | this.center | 地图中心备用坐标 | | iconUrl | string | '' | 图标完整 URL,留空则显示圆点 | | iconScale | number | 0.5 | 图标缩放 | | showNumber | boolean | true | 是否显示数字 | | startIndex | number | 1 | 序号起始值 | | font | string | '14px Calibri,sans-serif' | 文字字体 | | textColor | string | '#000' | 文字颜色 | | strokeColor | string | '#fff' | 文字描边颜色 | | strokeWidth | number | 2 | 文字描边宽度 | | offsetX | number | 0 | 文字水平偏移(像素) | | offsetY | number | -10 | 文字垂直偏移(像素) | | zIndex | number | 0 | 图层层级 |


3. 点位数据格式

三种写法均可混用:

// ① 对象式(推荐)
{ lon: 116.3, lat: 39.9, text: 'A', attributes: { id: 1001 } }

// ② 数组式
[116.3, 39.9]

// ③ 备用中心(当 lon/lat 缺失时使用)
{ lon: null, lat: null }   // 会退化成 center

4. 自定义单点样式

{
  lon: 116.3,
  lat: 39.9,
  text: '起',               // 显示文字
  style: {
    iconUrl: '/img/start.png',
    iconScale: 0.8,
    offsetX: 10,            // 单独偏移
    offsetY: -20,
    textColor: '#ff0000',
    font: 'bold 16px Arial'
  }
}

单点 style 里的字段会 覆盖全局参数


5. 完整示例

// 删除旧图层并重新绘制
mapComp.addPointsWithNumbers({
  layerId: 'patrol-points',
  points: [
    { lon: 116.3974, lat: 39.9092, text: '起' },
    { lon: 116.41, lat: 39.915 },
    { lon: 116.42, lat: 39.92, text: '终', style: { iconUrl: '/img/end.png' } }
  ],
  iconUrl: '/img/dot.png',
  iconScale: 0.6,
  startIndex: 0,
  offsetY: -15,
  zIndex: 999
})

6. 返回值

| 类型 | 说明 | | ------------- | --------------------------------------------- | | VectorLayer | OpenLayers 矢量图层实例,可后续手动移除或隐藏 | | null | 参数异常或点位为空,已自动输出错误日志 |


7. 错误排查速查表

| 现象 | 快速定位 | | -------------------- | --------------------------------------------------------------------------------------------- | | 一个点都不显示 | ① console.log(points) 看有没有数据② 看控制台是否报 坐标无效 | | 只显示圆点无数字 | ① showNumber 被设成 falsetext 为空且 startIndex 不是数字 | | 图标不显示 | ① 浏览器 网络面板 404 → 地址写错跨域 → 服务器加 Access-Control-Allow-Origin:* | | 文字偏移不对 | 用 offsetX / offsetY 一次调 1-2 像素,实时刷新看效果 |


8. 与地图坐标系无关

函数内部已自动:

// 如果地图不是 EPSG:4326,会自动 fromLonLat
if (mapProjection !== 'EPSG:4326') {
  pointCoords = fromLonLat([lon, lat], mapProjection)
}

无论地图是 3857 还是 4326,直接给经纬度即可。


9. 清理图层

// 按 ID 移除
mapComp.removeLayerById('patrol-points')

✈️MapFlyline飞线组件

让地图飞线像电影一样丝滑:粒子 + 流光尾巴 + 起点终点标记,一行组件即可拥有。


✨ 特性

| 功能 | 状态 | | ---- | ---- | | 粒子动画 | ✅ 连续插值,60 FPS | | 流光拖尾 | ✅ 紧跟粒子,无黑色 | | 起点/终点标记 | ✅ 可独立开关 | | 性能优化 | ✅ 视野裁剪 + 帧率节流 | | 颜色/速度/宽度 | ✅ 全 props 控制 | | WebGL 就绪 | ✅ 分段 ≤ 20,GPU 友好 |


⚙️ Props

| 属性 | 类型 | 默认值 | 说明 | | ---- | ---- | ------ | ---- | | id | String | - | 图层唯一标识 | | name | String | - | 图层名称 | | flights | Array | [] | 飞线数据,见下方格式 | | visible | Boolean | true | 显示/隐藏 | | zIndex | Number | 10 | 图层叠放顺序 | | lineColor | String | '#00ffff' | 底线颜色 | | lineWidth | Number | 2 | 底线宽度 | | lineOpacity | Number | 0.8 | 底线透明度 | | particleColor | String | '#ffffff' | 粒子颜色 | | particleSize | Number | 4 | 粒子半径 | | glow | Boolean | true | 是否开启流光拖尾 | | glowColor | String | '#52e884' | 流光主色 | | glowWidth | Number | 6 | 流光宽度(像素) | | glowTrailLength | Number | 0.3 | 拖尾占全长比例 | | glowSpeed | Number | 0.02 | 流光流动速度(0-1) | | animationDuration | Number | 3000 | 单趟动画时长(ms) | | loop | Boolean | true | 是否循环播放 | | density | Number | 1 | 0-1 线路采样率,<1 时随机丢弃 | | showStartPoint | Boolean | true | 显示起点标记 | | showEndPoint | Boolean | true | 显示终点标记 | | startPointStyle | Object | {color:'#00ff00', size:6} | 起点样式 | | endPointStyle | Object | {color:'#ff0000', size:6} | 终点样式 |


📡 Events

| 事件 | 参数 | 说明 | | ---- | ---- | ---- | | flightClick | {feature, flightData, index, coordinate} | 点击飞线时触发 |


🔧 快速使用

<template>
  <MapFlyline
    id="fly-1"
    name="北京→上海"
    :flights="flights"
    :visible="true"
    :zIndex="10"
    lineColor="#00ffff"
    glowColor="#52e884"
    :glowWidth="6"
    :glowTrailLength="0.3"
    :speed="5"
    :animationDuration="3000"
    :loop="true"
    @flightClick="onFlightClick"
  />
</template>

<script>
import MapFlyline from '@/components/MapFlyline.vue'

export default {
  components: { MapFlyline },
  data() {
    return {
      flights: [
        {
          from: { lon: 116.4074, lat: 39.9042 }, // 北京
          to: { lon: 121.4737, lat: 31.2304 },   // 上海
          curve: 0.3,                            // 弯曲度
          value: 80                              // 热力值
        }
      ]
    }
  },
  methods: {
    onFlightClick(e) {
      console.log('点击飞线', e.flightData, e.index)
    }
  }
}
</script>