离线地图实现方案+动态轨迹绘制
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 style="text-align: right;">'; // 右对齐
contentHTML += '<button id="customButton" class="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 name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- <link rel="stylesheet" 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 id="app" class="body">
<div class="header">危化品企业一览
<div class="btn">
<el-button type="primary" plain @click="beginFlow()">开启轨迹监听</el-button>
<el-button type="danger" plain @click="closFlow()">关闭轨迹监听</el-button>
</div>
</div>
<el-container style="height: 90%; border: 1px solid #eee">
<el-aside width="250px" style="height: 100%; background-color: rgb(238, 241, 246)">
<el-menu :default-openeds="['1', '3']">
<el-submenu index="1">
<template slot="title"><i class="el-icon-message"></i>企业信息</template>
<el-menu-item-group>
<el-menu-item class="el-icon-reading" @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 id="container">
</el-main>
</el-container>
</div>
</body>
<!--<script src="../js/vue.js"></script>-->
<!--<script src="../element-ui/lib/index.js"></script>-->
<!--<script src="../js/axios-0.18.0.js"></script>-->
<th:block th:include="include :: footer" />
<script type="text/javascript" src=""></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 style="text-align: right;">'; // 右对齐
contentHTML += '<button id="customButton" class="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>