百度地图右击添加点标记
发表于:2023-06-02 |

前言

这是我之前外包接的一个毕设项目的需求,要求鼠标右击可以创建站点和补给点,然后站点之间是要互相连接的,补给点不需要连接,emm,怎么说呢,总感觉现在这种私人接的外包一点都不赚钱,p事还特多,不过就当增加点代码量了,这里记录一下百度地图右击添加点标记的实现。
参考实现文档
百度地图注册引导

1. 引入百度地图

首先,你得先去百度地图开放平台注册一个账号,然后创建一个应用,然后就可以拿到一个ak了,这个ak是用来调用百度地图api的,这里就不多说了,直接上代码
引入,我在index.html中使用script标签直接引入了

1
2
3
4
5
6
7
8
<script
type="text/javascript"
src="http://api.map.baidu.com/api?v=3.0&ak=你的ak值"
></script>
<script
type="text/javascript"
src="//api.map.baidu.com/api?v=3.0&type=webgl&ak=你的ak值"
></script>

2. 完整组件代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
<template>
<div id="map" style="width: 100%; height: 100vh"></div>
</template>

<script lang="ts" setup>
import { onMounted, ref, watch, defineEmits, defineExpose, defineProps } from 'vue';
const mapList = ref([]);
// 点数组
const markList = ref([]);
const mapRef = ref(null);
const BMap = (window as any).BMapGL;
// 点位连接数组
const pointlygon_array = ref([]);

// 父组件传下来的值
const props = defineProps(['mapList', 'markList', 'pointlygon_array']);

const emit = defineEmits(['emits-data']);
const handleSave = () => {
emit('emits-data', {
mapList: mapList.value,
markList: markList.value,
pointlygon_array: pointlygon_array.value,
});
};

onMounted(() => {
var point =
props.mapList && props.mapList.length > 0
? new BMap.Point(props.mapList[0][0], props.mapList[0][1])
: new BMap.Point(121.18, 28.1);
if (props.mapList && props.mapList.length > 0) {
mapList.value = props.mapList;
}
if (props.markList && props.markList.length > 0) {
markList.value = props.markList;
}
if (props.pointlygon_array && props.pointlygon_array.length > 0) {
pointlygon_array.value = props.pointlygon_array;
}
var cityCtrl = new BMap.CityListControl(); // 添加城市列表控件
mapRef.value = new BMap.Map('map'); // 引入新地图
mapRef.value.addControl(cityCtrl);
mapRef.value.centerAndZoom(point, 15); // 添加中心点
mapRef.value.enableScrollWheelZoom(true); // 滚轮放大缩小打开
// 百度地图右键唤出菜单
var menu = new BMap.ContextMenu();
var txtMenuItem = [
{
text: '放大',
callback: function () {
mapRef.value.zoomIn();
},
},
{
text: '缩小',
callback: function () {
mapRef.value.zoomOut();
},
},
{
text: '添加补给点',
callback: function (p) {
const marker = new BMap.Marker(p);
const { lng, lat } = p; // 经纬度
// 浏览器原生的方法,可以用自定义dialog替换
const note = prompt('请输入备注:', '');
if (note !== '') {
markList.value.push([lng, lat, note]);
mapRef.value.addOverlay(marker);
}

// 添加marker备注
var opts = {
width: 200, // 信息窗口宽度
height: 100, // 信息窗口高度
title: '补给点', // 信息窗口标题
};
// 偏移
var infoWindow = new BMap.InfoWindow(`经纬度:${lng},纬度:${lat}`, opts); // 创建信息窗口对象
marker.addEventListener('click', function () {
mapRef.value.openInfoWindow(infoWindow, p); //开启信息窗口
});
},
},
{
text: '添加站点',
callback: function (p) {
// 修改marker颜色
var marker2 = new BMap.Marker(p); // 创建标注
const note = prompt('请输入备注:', '');
const { lng, lat } = p;
if (note !== '') {
mapRef.value.addOverlay(marker2); // 将标注添加到地图中
mapList.value.push([lng, lat, note]);
}

// 添加marker备注
var opts = {
width: 200, // 信息窗口宽度
height: 100, // 信息窗口高度
title: '站点', // 信息窗口标题
};
var infoWindow = new BMap.InfoWindow(`经纬度:${lng},纬度:${lat}`, opts); // 创建信息窗口对象
marker2.addEventListener('click', function () {
mapRef.value.openInfoWindow(infoWindow, p); //开启信息窗口
});
},
},
];
for (var i = 0; i < txtMenuItem.length; i++) {
menu.addItem(new BMap.MenuItem(txtMenuItem[i].text, txtMenuItem[i].callback, 100));
}
mapRef.value.addContextMenu(menu);
});
// 通过watch观察是否有新的点创建了,每次都重新画点和线(这个思路我从绘制webgl中借鉴的)
watch(
() => [mapList.value, markList.value],
([newVal, newVal1]) => {
// mapList.value(站点),markList.value(补给点),newVal,newVal1可以通过上文看到0是经度,1是纬度,2是备注
// 清空所有覆盖物
mapRef.value.clearOverlays();
// 把连接线清空
pointlygon_array.value = [];
for (var i = 0; i < newVal.length; i++) {
var marker = new BMap.Marker(new BMap.Point(newVal[i][0], newVal[i][1])); //标创建注点
var content = newVal[i][2];
mapRef.value.addOverlay(marker); //添加覆盖物
marker.setLabel(setLabelStyle(content)); // label样式
var content = newVal[i][2];
pointlygon_array.value[i] = new BMap.Point(newVal[i][0], newVal[i][1]);// 处理连线
}
for (var i = 0; i < newVal1.length; i++) {
var content = newVal1[i][2];
const url = 'src/assets/location.png';
const myIcon = new BMap.Icon(url, new BMap.Size(24, 24));
const marker = new BMap.Marker(new BMap.Point(newVal1[i][0], newVal1[i][1]), { icon: myIcon });
mapRef.value.addOverlay(marker); //添加覆盖物
marker.setLabel(setLabelStyle(content)); //备注
}
if (newVal.length > 1) {
var polygon = new BMap.Polyline(pointlygon_array.value, {
strokeColor: 'red',
strokeWeight: 2,
strokeOpacity: 0.5,
}); //创建折线
mapRef.value.addOverlay(polygon); //添加覆盖物
}
},
{
deep: true,
},
);
// 设置label样式
const setLabelStyle = (content: string) => {
//左偏移 右偏移
var offsetSize = new BMap.Size(10, -60);
var labelStyle = {
color: '#fff',
backgroundColor: '#333333',
border: '0',
fontSize: '14px',
width: '150px',
opacity: '0.8',
verticalAlign: 'center',
borderRadius: '2px',
whiteSpace: 'normal',
wordWrap: 'break-word',
padding: '7px',
};
//用于设置样式
var spanA = "<span class='angle'><span>";
//不同数字长度需要设置不同的样式。
var label = new BMap.Label(content + spanA, {
offset: offsetSize,
});
label.setStyle(labelStyle);
return label;
};

// 暴露出去一个方法,方便父组件使用
defineExpose({
handleSave,
});
</script>
<style lang="less" scoped>
.angle {
display: inline-block;
width: 0px;
height: 0px;
position: absolute;
bottom: -60px;
border: 14px solid;
left: 15px;
bottom: -25px;
opacity: 0.8;
border-color: #333333 transparent transparent transparent;
}
</style>

本篇文章就分享到这里,债见!

上一篇:
【可视化学习】13-shader
下一篇:
手撸编辑器