离线地图实现方案+动态轨迹绘制

文章正文
发布时间:2024-12-11 03:06

1.项目简介及技术栈

简介:基于内网离线环境开发
1.考虑到地图问题做了离线地图,使用百度离线API,基于以上底图需要实现点击企业名称后定位到该企业所在位置处。
2.定位过去后通过点击点标记,可展示企业基本信息,通过点击查验按钮,调用腾讯会议API对该企业进行查验呼叫入会
3.企业通过智能眼镜或者单兵设备向web端发送坐标数据,根据数据id跟点坐标去匹配当前企业,在企业周围实现动态轨迹的绘制,实现对查验企业的监管
4.技术栈:SpringBoot+Thymeleaf+Vue+Websocket

2.离线地图下载及部署 2.1 离线地图下载器

网上有很多下载工具,我用到的是一个开源的项目,网盘链接放下面

链接:https://pan.baidu.com/s/1vZwBe2AxoHuVMEqipcN1yA
提取码:47iv

程序账号密码:admin/admin

说明:application.properties文件中的appk需要自己去百度地图申请

2.2 离线地图案例

ps:只需要下载下来瓦片后把瓦片放到tiles文件夹下即可,网盘链接也放上

链接:https://pan.baidu.com/s/1Nli1r8k-1bFZQtpe46peww
提取码:8dxt

文件结构

3.企业点标记及+调用腾讯会议快速入会 3.1 企业点位信息标记

数据目前为写死的假数据前端代码如下

数据

data() { return { // 线条样式 polylinePoints:[], socket:null, // src:"../static/img/map.jpg", map: null, // 将地图对象定义为数据属性 form: { name: '', region: '', date1: '', date2: '', delivery: false, type: [], resource: '', desc: '' }, formLabelWidth: '120px', dialogFormVisible:false, // 企业基本信息 items:[ {id:"51c89d4f-6623-9d27-43f4-516a0fdc312c",companyName:"危化品公司1",info:"世界500强",address:"山东省济南市历下区",lng: 116.404, lat: 39.915}, {id:"51c89d4f-6623-9d27-43f4-516a0fdc312c",companyName:"危化品公司2",info:"世界500强",address:"山东省济南市历下区",lng: 116.484, lat: 39.955}, {id:"51c89d4f-6623-9d27-43f4-516a0fdc312c",companyName:"危化品公司3",info:"世界500强",address:"山东省济南市历下区",lng: 116.354, lat: 39.815}, {id:"51c89d4f-6623-9d27-43f4-516a0fdc312c",companyName:"危化品公司4",info:"世界500强",address:"山东省济南市历下区",lng: 116.304, lat: 39.995}, {id:"51c89d4f-6623-9d27-43f4-516a0fdc312a",companyName:"危化品公司5",info:"世界500强",address:"山东省济南市历下区",lng: 116.204, lat: 39.985}, {id:"51c89d4f-6623-9d27-43f4-516a0fdc312d",companyName:"济南危化品公司6",info:"世界500强",address:"山东省济南市历下区",lng: 117.010213, lat: 36.608779}, ], } }

渲染

mounted(){ var map = new BMap.Map("container"); // 创建地图实例 this.map=map; var point0 = new BMap.Point(117.010213, 36.608768); // 创建点坐标 map.centerAndZoom(point0, 18); // 初始化地图,设置中心点坐标和地图级别 map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放 // 创建点坐标数组 var points = this.items; // 遍历点坐标数组,创建标记点和文本标注 for (var i = 0; i < points.length; i++) { var point = new BMap.Point(points[i].lng, points[i].lat); // 创建点标记 var marker = new BMap.Marker(point); map.addOverlay(marker); // 创建信息窗口 var opts = { width: 200, height: 100, title: points[i].companyName, enableMessage: true // 启用信息窗口发送消息功能 }; var contentHTML = '简介:' + points[i].info; // 添加按钮元素 contentHTML += '<div>'; // 右对齐 contentHTML += '<button >' + '<span>我要查验</span>' + '</button>'; contentHTML += '</div>'; // 关闭右对齐 var infoWindow = new BMap.InfoWindow(contentHTML, opts); // 点标记添加点击事件 marker.addEventListener('click', (function (infoWin, pt, pointInfo) { return function () { map.openInfoWindow(infoWin, pt); // 开启信息窗口 // 添加按钮点击事件处理程序 var button = document.getElementById('customButton'); button.addEventListener('click', function () { // 在这里执行您的事件处理逻辑,pointInfo 包含点位的信息 var obj = JSON.stringify(pointInfo); axios.get('/hg/createMeeting/'+ pointInfo.id+"?companyName="+pointInfo.companyName) .then(response => { // 成功响应后设置 items 的值为获取的数据 console.log(response.data) var url = response.data.msg; var link = document.createElement('a'); link.href=url link.click(); link.remove(); // alert('按钮被点击了!点位信息:' + response.data.msg); // this.items = response.data; }) .catch(error => { console.error('Axios 请求出错:', error); }); }); }; })(infoWindow, point, points[i])); // 创建文本标注对象 var labelOpts = { position: point, offset: new BMap.Size(-80, -90) }; var label = new BMap.Label(points[i].companyName, labelOpts); // 自定义文本标注样式 label.setStyle({ color: 'black', borderRadius: '5px', borderColor: '#ccc', padding: '10px', fontSize: '16px', height: '50px', lineHeight: '30px', fontFamily: '微软雅黑', maxWidth:"none" }); map.addOverlay(label); } }

效果图

3.2 点击企业后定位

点击后定位到该企业的点位上,重新设置中心点

点击红色标记呼叫腾讯会议

// 点标记添加点击事件 marker.addEventListener('click', (function (infoWin, pt, pointInfo) { return function () { map.openInfoWindow(infoWin, pt); // 开启信息窗口 // 添加按钮点击事件处理程序 var button = document.getElementById('customButton'); button.addEventListener('click', function () { // 在这里执行您的事件处理逻辑,pointInfo 包含点位的信息 var obj = JSON.stringify(pointInfo); axios.get('/hg/createMeeting/'+ pointInfo.id+"?companyName="+pointInfo.companyName) .then(response => { // 成功响应后设置 items 的值为获取的数据 console.log(response.data) var url = response.data.msg; var link = document.createElement('a'); link.href=url link.click(); link.remove(); // alert('按钮被点击了!点位信息:' + response.data.msg); // this.items = response.data; }) .catch(error => { console.error('Axios 请求出错:', error); }); }); }; })(infoWindow, point, points[i])); 3.3 呼叫腾讯会议

腾讯会议用的是企业版,需要自己创建应用,获取相关key,具体方式请自行百度。

后台代码

package com.ruoyi.project.hg.util; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.ruoyi.project.hg.tencent.domain.MeetingData; import com.ruoyi.project.hg.tencent.domain.Settings; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.*; public class TencentUtil { private static final Log log = LogFactory.getLog(TencentUtil.class); static String HMAC_ALGORITHM = "HmacSHA256"; public final static String appId=""; public final static String secretId=""; public final static String sdkId=""; public final static String secretKey=""; public final static String address="https://api.meeting.qq.com"; static char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; public static String bytesToHex(byte[] bytes) { char[] buf = new char[bytes.length * 2]; int index = 0; for (byte b : bytes) { buf[index++] = HEX_CHAR[b >>> 4 & 0xf]; buf[index++] = HEX_CHAR[b & 0xf]; } return new String(buf); } /** * 生成签名,开发版本oracle jdk 1.8.0_221 * * @param secretId 邮件下发的secret_id * @param secretKey 邮件下发的secret_key * @param httpMethod http请求方法 GET/POST/PUT等 * @param headerNonce X-TC-Nonce请求头,随机数 * @param headerTimestamp X-TC-Timestamp请求头,当前时间的秒级时间戳 * @param requestUri 请求uri,eg:/v1/meetings * @param requestBody 请求体,没有的设为空串 * @return 签名,需要设置在请求头X-TC-Signature中 * @throws NoSuchAlgorithmException e * @throws InvalidKeyException e */ static String sign(String secretId, String secretKey, String httpMethod, String headerNonce, String headerTimestamp, String requestUri, String requestBody) throws NoSuchAlgorithmException, InvalidKeyException { String tobeSig = httpMethod + "\nX-TC-Key=" + secretId + "&X-TC-Nonce=" + headerNonce + "&X-TC-Timestamp=" + headerTimestamp + "\n" + requestUri + "\n" + requestBody; Mac mac = Mac.getInstance(HMAC_ALGORITHM); SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), mac.getAlgorithm()); mac.init(secretKeySpec); byte[] hash = mac.doFinal(tobeSig.getBytes(StandardCharsets.UTF_8)); String hexHash = bytesToHex(hash); return new String(Base64.getEncoder().encode(hexHash.getBytes(StandardCharsets.UTF_8))); } /** * 获取公共请求头 * * @param httpMethod 请求方式:POST|GET * @param requestUri 请求uri * @param requestBody 请求体 GET方法请求体需传"" * @return 拼接好的请求头 */ public static Map<String, String> getHeader(String httpMethod, String requestUri, String requestBody) { HashMap<String, String> header = new HashMap<>(8); // 请求随机数 String headerNonce = String.valueOf(new Random().nextInt(999999)); // 当前时间的UNIX时间戳 String headerTimestamp = String.valueOf(System.currentTimeMillis() / 1000); String signature = null; try { signature = sign(secretId, secretKey, httpMethod, headerNonce, headerTimestamp, requestUri, requestBody); } catch (Exception e) { log.error("签名生成异常", e); } header.put("Content-Type", "application/json"); header.put("X-TC-Key", secretId); header.put("X-TC-Timestamp", headerTimestamp); header.put("X-TC-Nonce", headerNonce); header.put("AppId", appId); header.put("X-TC-Version", "1.0"); header.put("X-TC-Signature", signature); header.put("SdkId", sdkId); header.put("X-TC-Registered", "1"); return header; } /** * 腾讯会议发送post请求 携带生产签名和公共请求头参数 * * @param address 请求地址 * @param uri 请求uri生产签名使用 * @param requestBody 请求参数 * @return 请求响应结果 */ public static String sendRequest(String method,String address, String uri, String requestBody) { if (method.equals("GET"))requestBody=""; //生成公共请求头参数和签名 Map<String, String> headerMap = getHeader(method, uri, requestBody); String jsonStr = ""; StringBuilder sub = new StringBuilder(); try { URL url = new URL(address+uri); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 设置连接请求属性post conn.setDoOutput(true); conn.setDoInput(true); conn.setRequestMethod(method); // 设置请求头 for (Map.Entry<String, String> header : headerMap.entrySet()) { conn.setRequestProperty(header.getKey(), header.getValue()); } DataOutputStream out =new DataOutputStream(conn.getOutputStream()); out.write(requestBody.getBytes()); out.flush(); out.close(); // 定义BufferedReader输入流来读取URL的响应 int code = conn.getResponseCode(); System.out.print("====="+conn.getResponseMessage()); if (HttpURLConnection.HTTP_OK == code) { BufferedReader in = new BufferedReader(new InputStreamReader( conn.getInputStream(), "UTF-8")); String line; while ((line = in.readLine()) != null) { sub.append(line); } in.close(); } return sub.toString(); // log.info("腾讯会议httpPost请求相应信息{}", jsonStr); } catch (IOException e) { log.info("腾讯会议http"+method+"发送异常", e); } return jsonStr; } /** * 创建会议 */ public static String creatMeeting(String userId,String companyName) throws JsonProcessingException { String[] invitees = userId.split(","); // String string = Arrays.toString(invitees); // 开始时间 long startTime = System.currentTimeMillis(); // 获取当前时间 Calendar calendar = Calendar.getInstance(); Calendar calendar2 = Calendar.getInstance(); // 增加30分钟 calendar.add(Calendar.MINUTE, 30); calendar2.add(Calendar.MINUTE, 3); // 获取增加后的时间戳 long endTime = calendar.getTimeInMillis(); startTime = calendar2.getTimeInMillis(); long endTimeInSeconds = endTime / 1000; long startTimeInSeconds = startTime / 1000; String st = String.valueOf(startTimeInSeconds); String et = String.valueOf(endTimeInSeconds); String data="{\n" + "\t\"userid\": \"9d2fbf1c-4376-838a-4d06-ada53d20915b\",\n" + "\t\"instanceid\": 1,\n" + "\t\"subject\": \"测试demo\",\n" + "\t\"type\": 0,\n" + "\t\"invitees\": [\"51c89d4f-6623-9d27-43f4-516a0fdc312c\"],\n" + "\t\"start_time\": \"1696823400\",\n" + "\t\"end_time\": \"1696824000\",\n" + "\t\"settings\": {\n" + "\t\t\"mute_enable_join\": true,\n" + "\t\t\"allow_unmute_self\": true,\n" + "\t\t\"play_ivr_on_leave\": false,\n" + "\t\t\"play_ivr_on_join\": false,\n" + "\t\t\"allow_in_before_host\": true,\n" + "\t\t\"auto_in_waiting_room\": false,\n" + "\t\t\"allow_screen_shared_watermark\": false,\n" + "\t\t\"only_enterprise_user_allowed\": false\n" + "\t\t\n" + "\t},\n" + "\t\"meeting_type\": 0,\n" + "\t\"enable_live\": false\n" + "}"; Settings settings=new Settings(); settings.setMute_enable_join(true); settings.setAllow_in_before_host(true); settings.setAllow_screen_shared_watermark(false); settings.setAllow_unmute_self(true); settings.setPlay_ivr_on_join(false); settings.setPlay_ivr_on_leave(false); settings.setAuto_in_waiting_room(false); settings.setOnly_enterprise_user_allowed(false); settings.setAuto_record_type("local"); MeetingData meetingData=new MeetingData(); // 发起人的id meetingData.setUserid("9d2fbf1c-4376-838a-4d06-ada53d20915b"); meetingData.setInstanceid(1); meetingData.setSubject("已发起对"+companyName+"的会议~"); meetingData.setType(0); meetingData.setInvitees(invitees); meetingData.setStart_time(st); meetingData.setEnd_time(et); meetingData.setSettings(settings); meetingData.setMeeting_type(0); meetingData.setEnable_live(false); // 创建ObjectMapper对象 ObjectMapper objectMapper = new ObjectMapper(); // 使用ObjectMapper将Java对象转换为JSON字符串 String json = objectMapper.writeValueAsString(meetingData); // 创建会议室 String s = sendRequest("POST",address, "/v1/meetings", json); // String s2 = sendRequest("POST",address, "/v1/meetings/4583169091896823219/invitees", data2); JSONObject jsonObject = JSONObject.parseObject(s); JSONArray meetingInfoList = jsonObject.getJSONArray("meeting_info_list"); Map<String, Object> objectMap = (Map<String, Object>) meetingInfoList.get(0); String string1 = (String) objectMap.get("join_url"); // System.out.println(jsonObject); return string1; } }

返回结果

ps 通过join_url可调起腾讯会议并入会

{ "meeting_number": 1, "meeting_info_list":[ { "subject": "tester's meeting", "meeting_id": "433471464134410364", "meeting_code": "637228110", "password": "1111", "host_key":"168168", "start_time" : "1572172200", "end_time" : "1572175800", "hosts":["test1"], "participants":[], "join_url": "https://wemeet.qq.com/w/5oxCqAc", "settings":{ "mute_enable_type_join": 2 }, "enable_live":true, "live_config":{ "live_addr":"https://meeting.tencent.com/l/ehewFSfengBPae" } } ] } 4.实时轨迹绘制

ps:主要是用到了websocket实现实时监听绘制,关于websocket可参考我的另一篇文章 https://www.cnblogs.com/sy2022/p/17611638.html

4.1 注册websocket const socketUrl = "ws://localhost:2000/websocket/admin"; console.log(socketUrl); if(this.socket!=null){ this.socket.close(); this.socket=null; } this.socket = new WebSocket(socketUrl); //打开事件 this.socket.onopen = () => { console.log("websocket已打开"); this.open2(); }; 4.1 接收后台传过来的点位数据,并完成轨迹绘制。 this.socket.onmessage = (event) => { const receivedData = JSON.parse(event.data); // 获取数据中的id字段 const id = receivedData.id; // 检查是否已经存在具有相同id的轨迹数组 if (!idToPolylinesMap[id]) { idToPolylinesMap[id] = []; } console.log("收到WebSocket消息:", receivedData); idToPolylinesMap[id].push(new BMap.Point(receivedData.longitude, receivedData.latitude)); // 创建线条对象 var polyline = new BMap.Polyline(idToPolylinesMap[id], polylineOptions); // 将线条添加到地图 this.map.addOverlay(polyline); // 此时,receivedData 是您从后端发送的 map 对象的 JavaScript 表示 // 您可以在这里处理它,访问其中的属性和值 }; 4.2 开启关闭轨迹监听

开启

// 开启绘制点位信息 beginFlow(){ var self = this; const socketUrl = "ws://localhost:2000/websocket/admin"; console.log(socketUrl); if(this.socket!=null){ this.socket.close(); this.socket=null; } this.socket = new WebSocket(socketUrl); //打开事件 this.socket.onopen = () => { console.log("websocket已打开"); this.open2(); }; this.socket.onmessage = (event) => { const receivedData = JSON.parse(event.data); // 获取数据中的id字段 const id = receivedData.id; // 检查是否已经存在具有相同id的轨迹数组 if (!idToPolylinesMap[id]) { idToPolylinesMap[id] = []; } console.log("收到WebSocket消息:", receivedData); idToPolylinesMap[id].push(new BMap.Point(receivedData.longitude, receivedData.latitude)); // 创建线条对象 var polyline = new BMap.Polyline(idToPolylinesMap[id], polylineOptions); // 将线条添加到地图 this.map.addOverlay(polyline); // 此时,receivedData 是您从后端发送的 map 对象的 JavaScript 表示 // 您可以在这里处理它,访问其中的属性和值 }; //关闭事件 this.socket.onclose = function() { console.log("websocket已关闭"); }; //发生了错误事件 this.socket.onerror = function() { console.log("websocket发生了错误"); } },

关闭

closFlow(){ if(this.socket!=null){ this.socket.close(); this.socket=null; } this.open1(); },

效果如下

5.代码

前端

<!DOCTYPE html> <html> <head> <meta content="initial-scale=1.0, user-scalable=no" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <!-- <link href="../element-ui/lib/theme-chalk/index.css">--> <th:block th:include="include :: header('危化品')" /> <title>Baidu Map </title> <style type="text/css"> html{height:100%} body{height:100%;margin:0px;padding:0px} .header{ text-align: left; /* 水平居中 */ height: 60px; /* 垂直居中,根据高度调整 */ line-height: 60px; /* 垂直居中,根据高度调整 */ background-color: #76a1dc; font-weight: bold; /* 加粗字体 */ color: white; /* 字体颜色白色 */ font-size: 50px; font-family: 楷体, KaiTi, STKaiti, "楷体_GB2312", "楷体_GB18030"; /* 使用楷体字体 */ } .body{ height: 100%; } .el-menu{ height: 100%; } .el-menu-item{ width: 100%; } .button{ -webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent; font-family: inherit; display: inline-block; line-height: 1; white-space: nowrap; cursor: pointer; background: #fff; border: 1px solid #dcdfe6; -webkit-appearance: none; text-align: center; box-sizing: border-box; outline: none; margin: 0; transition: .1s; font-weight: 500; -webkit-user-select: none; font-size: 14px; color: #fff; background-color: #409eff; border-color: #409eff; border-radius: 20px; padding: 12px 23px; margin-left: 10px; } /*#container{height:90%}*/ .btn{ width: 30%; height: 50px; float: right; margin-top: 5px; } </style> </head> <body> <div> <div>危化品企业一览 <div> <el-button type="primary" plain @click="beginFlow()">开启轨迹监听</el-button> <el-button type="danger" plain @click="closFlow()">关闭轨迹监听</el-button> </div> </div> <el-container> <el-aside> <el-menu :default-openeds="['1', '3']"> <el-submenu index="1"> <template slot="title"><i></i>企业信息</template> <el-menu-item-group> <el-menu-item @click="clickmenu(item)" v-for="(item,index) in items" :key="index" :index="index.toString()">{{ item.companyName }}</el-menu-item> </el-menu-item-group> </el-submenu> </el-menu> </el-aside> <el-main> </el-main> </el-container> </div> </body> <!--<script ></script>--> <!--<script ></script>--> <!--<script ></script>--> <th:block th:include="include :: footer" /> <script type="text/javascript" src="/uploads/6/87/14/88065ea8e0a03ce0" ></script> <script> // 创建点数组,用于构建线条 var idToPolylinesMap = {}; var polylinePoints = []; var polylineOptions={ strokeColor: "#ef4343", // 线条颜色 strokeWeight: 3, // 线条宽度 strokeOpacity: 0.8 // 线条透明度 }; new Vue({ el: "#app", methods:{ open1() { this.$message({ message: '轨迹监听已关闭', type: 'warning' }); }, open2() { this.$message({ message: '轨迹监听已打开', type: 'success' }); }, closFlow(){ if(this.socket!=null){ this.socket.close(); this.socket=null; } this.open1(); }, // 开启绘制点位信息 beginFlow(){ var self = this; const socketUrl = "ws://localhost:2000/websocket/admin"; console.log(socketUrl); if(this.socket!=null){ this.socket.close(); this.socket=null; } this.socket = new WebSocket(socketUrl); //打开事件 this.socket.onopen = () => { console.log("websocket已打开"); this.open2(); }; this.socket.onmessage = (event) => { const receivedData = JSON.parse(event.data); // 获取数据中的id字段 const id = receivedData.id; // 检查是否已经存在具有相同id的轨迹数组 if (!idToPolylinesMap[id]) { idToPolylinesMap[id] = []; } console.log("收到WebSocket消息:", receivedData); idToPolylinesMap[id].push(new BMap.Point(receivedData.longitude, receivedData.latitude)); // 创建线条对象 var polyline = new BMap.Polyline(idToPolylinesMap[id], polylineOptions); // 将线条添加到地图 this.map.addOverlay(polyline); // 此时,receivedData 是您从后端发送的 map 对象的 JavaScript 表示 // 您可以在这里处理它,访问其中的属性和值 }; //关闭事件 this.socket.onclose = function() { console.log("websocket已关闭"); }; //发生了错误事件 this.socket.onerror = function() { console.log("websocket发生了错误"); } }, clickmenu(item){ var point0 = new BMap.Point(item.lng, item.lat); // 创建点坐标 debugger this.map.centerAndZoom(point0, 18); } }, data() { return { // 线条样式 polylinePoints:[], socket:null, // src:"../static/img/map.jpg", map: null, // 将地图对象定义为数据属性 form: { name: '', region: '', date1: '', date2: '', delivery: false, type: [], resource: '', desc: '' }, formLabelWidth: '120px', dialogFormVisible:false, // 企业基本信息 items:[ {id:"51c89d4f-6623-9d27-43f4-516a0fdc312c",companyName:"危化品公司1",info:"世界500强",address:"山东省济南市历下区",lng: 116.404, lat: 39.915}, {id:"51c89d4f-6623-9d27-43f4-516a0fdc312c",companyName:"危化品公司2",info:"世界500强",address:"山东省济南市历下区",lng: 116.484, lat: 39.955}, {id:"51c89d4f-6623-9d27-43f4-516a0fdc312c",companyName:"危化品公司3",info:"世界500强",address:"山东省济南市历下区",lng: 116.354, lat: 39.815}, {id:"51c89d4f-6623-9d27-43f4-516a0fdc312c",companyName:"危化品公司4",info:"世界500强",address:"山东省济南市历下区",lng: 116.304, lat: 39.995}, {id:"51c89d4f-6623-9d27-43f4-516a0fdc312a",companyName:"危化品公司5",info:"世界500强",address:"山东省济南市历下区",lng: 116.204, lat: 39.985}, {id:"51c89d4f-6623-9d27-43f4-516a0fdc312d",companyName:"济南危化品公司6",info:"世界500强",address:"山东省济南市历下区",lng: 117.010213, lat: 36.608779}, ], } }, beforeMount(){ // 在狗子函数出发之前执行,可以获取items中的数据 // 在组件挂载之前执行 Axios 请求获取数据 // axios.get('your_backend_api_url') // .then(response => { // // 成功响应后设置 items 的值为获取的数据 // this.items = response.data; // }) // .catch(error => { // console.error('Axios 请求出错:', error); // }); }, created(){ }, mounted(){ var map = new BMap.Map("container"); // 创建地图实例 this.map=map; var point0 = new BMap.Point(117.010213, 36.608768); // 创建点坐标 map.centerAndZoom(point0, 18); // 初始化地图,设置中心点坐标和地图级别 map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放 // 创建点坐标数组 var points = this.items; // 遍历点坐标数组,创建标记点和文本标注 for (var i = 0; i < points.length; i++) { var point = new BMap.Point(points[i].lng, points[i].lat); // 创建点标记 var marker = new BMap.Marker(point); map.addOverlay(marker); // 创建信息窗口 var opts = { width: 200, height: 100, title: points[i].companyName, enableMessage: true // 启用信息窗口发送消息功能 }; var contentHTML = '简介:' + points[i].info; // 添加按钮元素 contentHTML += '<div>'; // 右对齐 contentHTML += '<button >' + '<span>我要查验</span>' + '</button>'; contentHTML += '</div>'; // 关闭右对齐 var infoWindow = new BMap.InfoWindow(contentHTML, opts); // 点标记添加点击事件 marker.addEventListener('click', (function (infoWin, pt, pointInfo) { return function () { map.openInfoWindow(infoWin, pt); // 开启信息窗口 // 添加按钮点击事件处理程序 var button = document.getElementById('customButton'); button.addEventListener('click', function () { // 在这里执行您的事件处理逻辑,pointInfo 包含点位的信息 var obj = JSON.stringify(pointInfo); axios.get('/hg/createMeeting/'+ pointInfo.id+"?companyName="+pointInfo.companyName) .then(response => { // 成功响应后设置 items 的值为获取的数据 console.log(response.data) var url = response.data.msg; var link = document.createElement('a'); link.href=url link.click(); link.remove(); // alert('按钮被点击了!点位信息:' + response.data.msg); // this.items = response.data; }) .catch(error => { console.error('Axios 请求出错:', error); }); }); }; })(infoWindow, point, points[i])); // 创建文本标注对象 var labelOpts = { position: point, offset: new BMap.Size(-80, -90) }; var label = new BMap.Label(points[i].companyName, labelOpts); // 自定义文本标注样式 label.setStyle({ color: 'black', borderRadius: '5px', borderColor: '#ccc', padding: '10px', fontSize: '16px', height: '50px', lineHeight: '30px', fontFamily: '微软雅黑', maxWidth:"none" }); map.addOverlay(label); } } }) </script> </html>

首页
评论
分享
Top