本文主要介绍如何通过百度地图的JavaScript API v3.0版本绘制不规则多边形的相关内容
样例代码如下
html代码
<div ref={filingGridMap} id={'filingGridMap'} className={'map-box'} /> //地图载体
<div id={'myPanel'} /> // 地图搜索载体
ts部分代码
import React, { useEffect, useRef } from 'react';
import _ from 'lodash';
const scriptInterval = useRef(null);//js加载计时器
const filingGridMap = useRef(null);//地图div
const mapCanvas = useRef(null); // 地图主体渲染画布
const drawingManger = useRef(null); // 地图绘制标点功能
const drawOverlay = useRef(null); // 当前绘制的图形
const searchLocal = useRef(null); // 搜索
const allDrawPoint = useRef([]); // 所有点字符串
useEffect(() => {
initMapScript().then(() => {
setTimeout(() => {
initMapCanvas();
}, 1000);
});
}, []);
//初始化地图脚本
const initMapScript = () => {
return new Promise((resolve, reject) => {
if (window.BMap !== undefined && window.MapCore !== undefined && window.BMapLib !== undefined) {
resolve('success');
}
let headElement = document.getElementsByTagName('head').item(0);
let scriptElement = document.createElement('script');
scriptElement.type = 'text/javascript';
scriptElement.src = config.mapUrl; //百度地图引用地址
scriptElement.onload = () => {
scriptInterval.current = setInterval(() => {
if (window.BMap !== undefined && window.MapCore !== undefined && window.BMapLib !== undefined) {
clearInterval(scriptInterval.current);
scriptInterval.current = null;
resolve('success');
}
}, 100);
};
scriptElement.onerror = () => {
if (scriptInterval.current) {
clearInterval(scriptInterval.current);
scriptInterval.current = null;
}
reject('error');
};
headElement.appendChild(scriptElement);
});
};
//初始化地图
const initMapCanvas = () => {
mapCanvas.current = new window.BMap.Map(filingGridMap.current, { enableMapClick: false });
const defaultPoint = new window.BMap.Point(98, 35); //默认设置一个中心点
mapCanvas.current.centerAndZoom(defaultPoint, 6); //设置到中心点位置
mapCanvas.current.enableScrollWheelZoom();//开启滚动缩放
//这两个控件会被其他老版本地图页面干扰导致显示异常和位置异常
mapCanvas.current.addControl(new window.BMap.ScaleControl({}));//比例尺
mapCanvas.current.addControl(new window.BMap.NavigationControl({ anchor: window.BMAP_ANCHOR_TOP_RIGHT, offset: new window.BMap.Size(0, 20) } as any)); //缩放移动控件
initMapDrawing(); //初始化地图绘制部分内容
getGirdList(); //若需要默认绘制部分覆盖则可以在此处进行(这个方法在下面)
};
//调用接口进行默认绘制
const getGirdList =() =>{
allDrawPoint.current = [];
mapCanvas.current.clearOverlays();//删除所有覆盖物
//接口查询默认绘制内容
//drawGrid(item)//循环调用
const viewBounds = new window.BMap.Bounds();
allDrawPoint.current.forEach((item) => { //循环绘制会塞这个值
viewBounds.extend(item);
});
mapCanvas.current.setViewport(viewBounds);
}
//获取绘制覆盖物的点坐标字符串
const getLocation = (path) => {
let location = ""; // 坐标点用空格隔开
if(path.length>0){
path.forEach(function(item) {
location = location + item.lng + " " + item.lat + ",";
});
location = location + path[0].lng + " " + path[0].lat;
}
return location
}
//通过坐标字符串获取bmap格式坐标列表以及中心点
const getPointAndCenter = (location) => {
const list = location.split(',');
const drawPointList = [];
list.forEach((item) => {
const pointList = item.split(' ');
drawPointList.push(new window.BMap.Point(Number(pointList[0]), Number(pointList[1])));
});
//获取中心点
const polygon = new window.BMap.Polygon(drawPointList);
const bounds = polygon.getBounds();
const centerPoint = bounds.getCenter(); //获取中心点
return { drawPointList, centerPoint };
};
//设置网格区域点击监听
const listenerPolygon = (polygon) => {
polygon.addEventListener('click', (event) => {
//网格点击地图出现弹框
if (drawOverlay.current) {//如果存在正在编辑的图形则关闭对应的编辑
if (event.currentTarget.da === drawOverlay.current?.da) { //判断是否为同个绘制区域
return;
}
drawOverlay.current.disableEditing();
}
const location = getLocation(polygon.getPath());
const { drawPointList } = getPointAndCenter(location);
const viewBounds = new window.BMap.Bounds();
drawPointList.forEach((item) => {
viewBounds.extend(item);
});
mapCanvas.current.setViewport(viewBounds);
drawOverlay.current = polygon;
console.log('图形编辑----', event);
polygon.enableEditing(); //开启编辑
});
};
//添加label
const addLabel = (centerPoint, name) => {
const label = new window.BMap.Label(name, {
position: centerPoint,
});
label.setStyle({
color: '#fff', // 字体颜色
fontSize: '12px', // 字体大小
backgroundColor: '#ff8355', // 背景色
padding: '5px',
border: '1px solid #ff8355', // 边框大小
});
mapCanvas.current.addOverlay(label);
};
//初始化地图绘制
const initMapDrawing = () => {
drawingManger.current = new window.BMapLib.DrawingManager(mapCanvas.current, {
isOpen: false,
enableDrawingTool: true, // 是否显示工具栏
drawingMode: 'hander',
drawingToolOptions: {
anchor: window.BMAP_ANCHOR_TOP_RIGHT, // 工具栏停靠位置
offset: new window.BMap.Size(80, 20),
scale: 0.7, // 工具栏缩放比例
drawingModes: ['polygon'], // 允许绘制的图形类型
},
polygonOptions: {
path: [], // 设置多边形的路径
strokeColor: '#4882f3', // 设置边框颜色
strokeWeight: 2, // 设置边框宽度
strokeOpacity: 0.8, // 设置边框透明度
fillColor: '#4882f3', // 设置填充颜色
fillOpacity: 0.2, // 设置填充透明度
enableEditing: false, // 是否可编辑
}
});
drawingManger.current.addEventListener('overlaycomplete', ({ overlay }) => {
console.log('绘制完成----', overlay);
if (drawOverlay.current) {//如果存在正在编辑的图形则关闭对应的编辑
drawOverlay.current.disableEditing();
}
const location = getLocation(overlay.getPath());
const { drawPointList } = getPointAndCenter(location);
const viewBounds = new window.BMap.Bounds();
drawPointList.forEach((item) => {
viewBounds.extend(item);
});
mapCanvas.current.setViewport(viewBounds); //将绘制的多边形完全显示在屏幕正中间
drawOverlay.current = overlay; //设置当前绘制的多边形
overlay.enableEditing(); //开启编辑
listenerPolygon(overlay);
});
}
//非手动绘制多边形网格
const drawGrid = (data) => {
if (!data.location || data.location === '0') {
return;
}
const { drawPointList, centerPoint } = getPointAndCenter(data.location);
allDrawPoint.current = allDrawPoint.current.concat(drawPointList); //存储所有的点字符串,绘制全部后统一进行居中操作
const polygon = new window.BMap.Polygon(drawPointList, {
strokeColor: data?.border_color || '#4882f3', // 设置边框颜色
strokeWeight: 2, // 设置边框宽度
strokeOpacity: 0.8, // 设置边框透明度
fillColor: data?.color_in_box || '#4882f3', // 设置填充颜色
fillOpacity: 0.2, // 设置填充透明度
});
polygon.defaultData = { ...data }; //接口内容 直接获取里面获取
addLabel(centerPoint, data.grid_name);
mapCanvas.current.addOverlay(polygon);
listenerPolygon(polygon);
};
//网格删除
const onGirdDelete = async () => {
drawOverlay.current.disableEditing();
mapCanvas.current.removeOverlay(drawOverlay.current);
drawOverlay.current = null;
};
// 地图根据名称搜索
const onPointSearch = _.debounce((v) => {
onClearSearch();
if (v) {
//根据输入项通过百度地图进行搜索具体坐标地址
searchLocal.current = new window.BMap.LocalSearch(searchCity[searchCity.length - 1], {
renderOptions: { map: mapCanvas.current, autoViewport: true, selectFirstResult: false, panel: 'myPanel' },
pageCapacity: 5,
});
searchLocal.current.search(v);
}
}, 500);
//清除搜索
const onClearSearch = () => {
if (searchLocal.current) {
searchLocal.current.clearResults();
searchLocal.current = null;
}
};