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>
|