Vue3 + 高德地图实现围栏绘制与线路渲染(含 GeoJSON 支持)

在项目中,往往需要通过地图进行区域围栏绘制、线路渲染 等功能,用于数据可视化、行为监控、地理标注等业务场景。本文将基于 Vue 3 + 高德地图 JSAPI 实现一个完整的地图功能模块,包括:

  • 地图初始化与 GeoJSON 加载

  • 绘制围栏(可编辑)

  • 渲染多边形遮罩层

  • 动态加载中心线、左/右边界线等结构化线路

📌 适用于城市交通可视化、车辆轨迹管控、地图交互平台等项目。


🧩一、技术栈与依赖

  • Vue 3 Composition API

  • 高德地图 JSAPI v2.0

  • 支持 Element Plus 按钮交互(仅 UI)

  • 加载本地 GeoJSON 线路数据


🗺️二、地图初始化与基础设置

我们首先使用 @amap/amap-jsapi-loader 来加载高德地图 JS:

复制代码
AMapLoader.load({
  key: "你的高德Key",
  version: "2.0",
  plugins: [
    "AMap.MouseTool", "AMap.Polygon", "AMap.PolyEditor", 
    "AMap.OverlayGroup", "AMap.DistrictSearch", ...
  ],
}).then((AMap) => {
  map = new AMap.Map("container", {
    zoom: 15.5,
    center: [113.50099365, 23.04139783],
    mapStyle: "amap://styles/darkblue", // 暗色背景,突出图层
    WebGLParams: { preserveDrawingBuffer: true },
  });

  pointsGroup = new AMap.OverlayGroup();
  map.add(pointsGroup);

  drawGeoJsonLines(); // 加载线路
  drawDist(map);      // 加载遮罩层
});

🧱三、GeoJSON 数据线路渲染

使用一个本地 outlines.json 文件进行数据加载。我们通过 drawGeoJsonFeature 方法解析每一个 feature:

复制代码
const drawGeoJsonFeature = (feature) => {
  const { geometry, properties } = feature;

  // 多边形区域显示为透明遮罩
  const polygon = new AMap.Polygon({
    path: geometry.coordinates?.[0]?.map(([lng, lat]) => [lng, lat]),
    strokeColor: "#fff",
    strokeOpacity: 0.1,
    fillOpacity: 0.01,
  });
  polygon.setMap(map);
  overlays.push(polygon);

  // 渲染每一类线(如中心线、左右边界线)
  Object.entries(lineStyleMap).forEach(([key, color]) => {
    const lineData = properties[key];
    if (!lineData?.geometry?.length) return;

    const path = lineData.geometry.map(p => [p.lng, p.lat]);
    const polyline = new AMap.Polyline({ path, strokeColor: color });
    polyline.setMap(map);
    overlays.push(polyline);
  });
};

centerLineleftBoundaryLinerightBoundaryLine 等结构都封装在 GeoJSON 的 properties 属性中,便于扩展。


🖌️四、围栏绘制与编辑功能

地图点击按钮可开启手绘模式,利用高德的 MouseTool 工具类进行绘制:

复制代码
const drawFence = () => {
  let mouseTool = new AMap.MouseTool(map);
  mouseTool.polygon({
    strokeColor: "#FEB80A",
    strokeWeight: 6,
    fillOpacity: 0.2,
  });

  mouseTool.on("draw", (event) => {
    mouseTool.close(true);
    const path = event.obj.getPath().map((p) => [p.lng, p.lat]);
    blockDrawFence({ path, flag: "2" });
  });
};

用户绘制完成后,可进入编辑模式,并监听结束编辑事件:

复制代码
blockEditor = new AMap.PolyEditor(map, polygonLayer);
blockEditor.on("end", (event) => {
  emit("fence-update", event.target._opts.path); // 实时更新路径
});

🧱五、遮罩层区域绘制

为确保围栏和线路都只在我们指定的区域显示,我们绘制一个包含全国的"外包围"大矩形作为遮罩外框:

复制代码
const drawDist = (map) => {
  let outer = [
    new AMap.LngLat(-360, 90), new AMap.LngLat(-360, -90),
    new AMap.LngLat(360, -90), new AMap.LngLat(360, 90),
  ];
  let pathArray = [outer, JSON.parse(props.fences)];

  let polygon = new AMap.Polygon({
    strokeColor: "#00eeff",
    fillColor: "#71B3ff",
    fillOpacity: 0.5,
  });

  polygon.setPath(pathArray);
  map.add(polygon);
};

📌 注意:遮罩图层要最晚渲染,并使用较高的 fillOpacity,可防止路线图层"盖住"遮罩图层。


🎮六、交互 UI 与地图控制面板

复制代码
<el-button v-if="editPoints[0] == ''" @click="drawFence">标记角点</el-button>
<el-button v-else @click="editBlockDrawFence">编辑围栏</el-button>
<el-button v-else @click="editBlockCloseDrawFence">结束编辑</el-button>

可通过按钮实现"开始绘制 - 编辑围栏 - 结束编辑"三段式操作,符合用户思维流。


🧠七、层级问题及修复建议

问题:线路在遮罩层上方

此问题常见于:

  • 多边形 Polygon 图层未设置 zIndex,默认图层排序不一致;

  • 线路渲染顺序早于遮罩层;

  • 遮罩层 fillOpacity 太小。

✅解决方案:

复制代码
const polygon = new AMap.Polygon({
  path: coords,
  strokeColor: "#fff",
  fillColor: "#fff",
  fillOpacity: 0.9,  // 不透明
  zIndex: 1000,       // 提升层级
});

确保遮罩层 zIndex 高于线路图层(线路建议设为 zIndex: 10 ~ 100)。


✅总结

本组件可作为地图绘制交互模块的通用模板,具备以下优势:

  • ✅ 支持任意 GeoJSON 线路绘制(中心线、边界线)

  • ✅ 支持区域围栏绘制与编辑

  • ✅ 可灵活接入业务平台,适用于智慧城市、交通监控等项目

  • ✅ 支持遮罩层绘制,限制展示区域


📦项目扩展建议

  • 🚀支持多围栏绘制

  • 📊集成围栏属性统计与数据绑定

  • 📍支持围栏内点位聚合或热力图渲染

  • 🌍兼容 Mapbox 或 Cesium 等其他地图平台


如果你对这个项目感兴趣,可以点赞+收藏+关注我,后续我将推出 Vue3 + Mapbox 实现 3D 车辆轨迹回放 的实战教程。

相关推荐
Juchecar1 小时前
Vue3 组件生命周期详解
前端·vue.js
Juchecar1 小时前
Vue3 模板引用 useTemplateRef 详解
前端·vue.js
YuJie2 小时前
vue3 无缝滚动
前端·javascript·vue.js
Juchecar2 小时前
Vue3 表单输入 v-model 指令详解
前端·vue.js
DevUI团队3 小时前
MateChat V1.7.0版本发布,前端智能化项目贡献者已经达到90+,智能化卡片特性持续演进,快来体验吧~
前端·vue.js·人工智能
Juchecar3 小时前
Vue3 事件处理 v-on 指令 (@) 详解
前端·vue.js
GISBox4 小时前
GISBox支持WMS协议的技术突破
vue.js·json·gis
Juchecar4 小时前
Vue3 v-if、v-show、v-for 详解及示例
前端·vue.js
小高0074 小时前
⚡️ Vue 3.5 正式发布:10× 响应式性能、SSR 水合黑科技、告别 .value!
前端·javascript·vue.js
撰卢4 小时前
总结一下vue3的组件之间数据转递,子组件传父组件,父组件传子组件
前端·javascript·vue.js