今天分享一下,使用高德地图api实现上图可自由画线的效果。
查看高德官方文档会发现,并没有可自主画图,文档提供的矢量图功能有:
除了以上功能,还有根据geojson数据生成矢量图。
但这些并不满足上图效果的场景。那该怎么办?
这就是实现自由画线效果的核心思想,线——就是无数个点连接起来的,按照这个思路我们就知道从哪里入手了:
- // 初始化地图
- var map = new AMap.Map("container", {
- center: [116.395577, 39.892257],
- zoom: 14,
- dragEnable: false, // 禁用拖动
- defaultCursor: 'crosshair' // 鼠标hover样式
- });
- // 监听鼠标按下
- map.on('mousedown', function(e){
- mouseStatus = 'mousedown'
- })
- // 监听鼠标移动
- map.on('mousemove', function mousemove(e) {
- // 鼠标按下
- if (mouseStatus === 'mousedown') {
- // 获取鼠标移动生成的点
- drawPath.push(e.lnglat)
- }
- })
-
监听鼠标按下,开始移动,并收集所有的点
- // 生成线段
- var polyline = new AMap.Polyline({
- path: drawPath,
- strokeWeight: 6, // 线条宽度,默认为 1
- strokeColor: '#ff0000', // 线条颜色
- strokeOpacity: 1,
- lineJoin: 'round', // 折线拐点连接处样式
- bubble: true, // 可冒泡到地图上
- });
- map.add(polyline);
-
这里记得需要优化,画线之前需要将之前的线段清除掉,不然每次连线,都是从起始点连接,造成不必要的性能浪费。
一般的场景,目的都是得到闭合的区域范围,来获取区域内的数据,所以我们需要将最后鼠标抬起时的点位,和开始点连接起来。并生成矢量图实例,以便使用api得到想要的数据(如:范围坐标、路径坐标等)。
- if (drawPath.length) {
- // 绘制成矢量区域实例
- var userDrawPolygon = new AMap.Polygon({
- path: drawPath,
- strokeWeight: 6, // 线条宽度,默认为 1
- strokeColor: '#ff0000', // 线条颜色
- fillOpacity: 0.1,
- });
- map.add(userDrawPolygon);
- drawPath = [] // 清空
- console.log('绘制完成的区域实例对象', userDrawPolygon)
- console.log('绘制区域范围', userDrawPolygon.getBounds())
- }
-
- const drawPath = [] // 所有的点
- const mouseStatus = 'mouseup' // 鼠标状态
- const startPoint = null // 最开始的点
- const endPoint = null // 结束点
- const lastPolyLine = null // 最后一段线段
- const map = new AMap.Map("container", {
- center: [116.395577, 39.892257],
- zoom: 14,
- dragEnable: false, // 禁用拖动
- defaultCursor: 'crosshair' // 鼠标hover样式
- });
-
- map.on('mousedown', mousedown)
- map.on('mousemove', mousemove)
- map.on('mouseup', mouseup)
-
- // 鼠标按下事件函数
- function mousedown(e) {
- mouseStatus = 'mousedown'
- }
- // 鼠标移动事件函数
- function mousemove(e) {
- // 鼠标按下
- if (mouseStatus === 'mousedown') {
- // 记录起始点
- startPoint = startPoint ? startPoint : e.lnglat
- // 存储鼠标移动经过的点
- drawPath.push(e.lnglat)
- // 把之前的渲染过的线段删掉,不然每一次移动生成的线段,都会从头开始渲染
- if (lastPolyLine) {
- map.remove(lastPolyLine)
- }
- // 生成线段
- let polyline = new AMap.Polyline({
- path: drawPath,
- strokeWeight: 6, // 线条宽度,默认为 1
- strokeColor: '#ff0000', // 线条颜色
- strokeOpacity: 1,
- lineJoin: 'round', // 折线拐点连接处样式
- bubble: true, // 可冒泡到地图上
- });
- map.add(polyline);
- // 记录下最后的线段
- lastPolyLine = polyline
- }
- }
- // 鼠标抬起事件函数
- function mouseup(e) {
- // 结束点
- endPoint = e.lnglat
- // 如果结束点未闭合,则自动闭合
- if (endPoint && (endPoint.getLng() !== startPoint.getLng() || endPoint.getLat() !== startPoint.getLat())) {
- drawPath.push(endPoint, startPoint)
- }
- // 删除所有拼接起来的线段
- if (lastPolyLine) {
- map.remove(lastPolyLine)
- }
- if (drawPath.length) {
- // 绘制成矢量区域实例,方便调用api获取所需数据
- let userDrawPolygon = new AMap.Polygon({
- path: drawPath,
- strokeWeight: 6, // 线条宽度,默认为 1
- strokeColor: '#ff0000', // 线条颜色
- fillOpacity: 0.1,
- });
- map.add(userDrawPolygon);
- drawPath = [] // 清空
- console.log('绘制完成的区域实例对象', userDrawPolygon)
- console.log('绘制区域范围', userDrawPolygon.getBounds())
- }
- mouseStatus = 'mouseup' // 恢复默认鼠标状态
- startPoint = null // 最开始的点
- endPoint = null // 结束点
- lastPolyLine = null // 最后一段线段
- // 卸载所有事件
- map.off('mousemove', mousemove);
- map.off('mousedown', mousedown);
- map.off('mouseup', mouseup);
- // 恢复鼠标hover样式
- map.setDefaultCursor('default')
- }
-