在项目中,往往需要通过地图进行区域围栏绘制、线路渲染 等功能,用于数据可视化、行为监控、地理标注等业务场景。本文将基于 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);
});
};
✅
centerLine
、leftBoundaryLine
、rightBoundaryLine
等结构都封装在 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 车辆轨迹回放 的实战教程。