使用高德定位、区分防区无人机

This commit is contained in:
zengmingjie 2025-06-26 22:31:31 +08:00
parent 27698dbf0b
commit 68aacde426
4 changed files with 221 additions and 209 deletions

View File

@ -171,7 +171,7 @@ body {
width: 100%; width: 100%;
height: calc(100% - 140px); height: calc(100% - 140px);
margin-top: 25px; margin-top: 25px;
pointer-events: none; overflow: hidden;
.title { .title {
width: 100%; width: 100%;
height: 40px; height: 40px;
@ -181,7 +181,9 @@ body {
height: 100%; height: 100%;
padding: 0; padding: 0;
margin: 0; margin: 0;
overflow: auto; overflow-y: auto;
-webkit-overflow-scrolling: touch;
touch-action: pan-y; /* 允许垂直方向的触摸滑动 */
margin-top: 10px; margin-top: 10px;
li { li {
@ -192,6 +194,7 @@ body {
margin-top: 3%; margin-top: 3%;
position: relative; position: relative;
display: flex; display: flex;
pointer-events: auto;
.details-one { .details-one {
width: 60%; width: 60%;
height: 100%; height: 100%;

View File

@ -33,7 +33,9 @@
<div class="left"> <div class="left">
{{ index < 9 ? "0" + (index + 1) : index + 1 }} {{ index < 9 ? "0" + (index + 1) : index + 1 }}
</div> </div>
<div class="text">{{ drone.serial_number }}</div> <div class="text" style="font-size: 14px">
{{ drone.serial_number }}
</div>
<div class="img-vector"> <div class="img-vector">
<img src="@/assets/img/Vector.png" alt="" /> <img src="@/assets/img/Vector.png" alt="" />
</div> </div>
@ -65,7 +67,9 @@
<div class="left"> <div class="left">
{{ index < 9 ? "0" + (index + 1) : index + 1 }} {{ index < 9 ? "0" + (index + 1) : index + 1 }}
</div> </div>
<div class="text">{{ drone.serial_number }}</div> <div class="text" style="font-size: 14px">
{{ drone.serial_number }}
</div>
<div class="img-vector"> <div class="img-vector">
<img src="@/assets/img/Vector.png" alt="" /> <img src="@/assets/img/Vector.png" alt="" />
</div> </div>
@ -280,7 +284,7 @@ export default {
.utc() .utc()
.subtract(1, "month") .subtract(1, "month")
.format("YYYY-MM-DD HH:mm:ss"); .format("YYYY-MM-DD HH:mm:ss");
console.log("Initialized time range:", this.startTime, "to", this.endTime); this.enableTouchScroll();
}, },
watch: { watch: {
homeData: { homeData: {
@ -338,114 +342,118 @@ export default {
// Id: "1936279217155215360" // Id: "1936279217155215360"
// } // }
// ]; // ];
newVal.forEach((newItem) => { let positionID = localStorage.getItem("PositionIds");
// BatchId if (positionID === null || positionID === undefined) {
if (newItem.BatchId) { const match = newVal.some((item) => positionID.includes(item.id));
const existingTimer = this.droneTimers.get(newItem.BatchId); if (match) {
if (existingTimer) { newVal.forEach((newItem) => {
clearInterval(existingTimer); // // BatchId
if (newItem.BatchId) {
const existingTimer = this.droneTimers.get(newItem.BatchId);
if (existingTimer) {
clearInterval(existingTimer); //
}
// 15
newItem.currTime = window.mapConfig.currTime;
//
const timer = this.startTimer(newItem);
this.droneTimers.set(newItem.BatchId, timer);
// detailsShow
if (!(newItem.BatchId in this.droneStates)) {
this.$set(this.droneStates, newItem.BatchId, true);
}
// navigation-content
if (!(newItem.BatchId in this.navigationStates)) {
this.$set(this.navigationStates, newItem.BatchId, false);
}
//
const existingIndex = this.drones.findIndex(
(d) => d.BatchId === newItem.BatchId
);
newItem.times = moment(newItem.CreateTime).format("HH:mm:ss");
newItem.distance = parseInt(newItem.distance.toFixed(0));
if (existingIndex !== -1) {
this.$set(this.drones, existingIndex, { ...newItem });
} else {
this.$set(this.drones, this.drones.length, { ...newItem });
}
}
});
if (newVal.length === 0) {
this.iswarning = false;
this.showAudioPrompt = false; //
} }
// 15 if (this.drones) {
newItem.currTime = window.mapConfig.currTime; mapUavFiex(this.drones, window.olMap);
//
const timer = this.startTimer(newItem);
this.droneTimers.set(newItem.BatchId, timer);
// detailsShow
if (!(newItem.BatchId in this.droneStates)) {
this.$set(this.droneStates, newItem.BatchId, true);
}
// navigation-content
if (!(newItem.BatchId in this.navigationStates)) {
this.$set(this.navigationStates, newItem.BatchId, false);
} }
const media = this.$refs.uavAudio;
let alarm = this.drones.find((d) => d.alarmLevel === 1);
if (alarm) {
this.iswarning = true;
this.$nextTick(() => {
if (media) {
media.muted = true; //
const savedVolume = localStorage.getItem("soundValue");
media.volume = savedVolume !== null ? savedVolume / 100 : 1;
media.muted = this.isZoomedIn ? false : true;
// //
const existingIndex = this.drones.findIndex( if (!this.isAudioPlaying) {
(d) => d.BatchId === newItem.BatchId media
); .play()
newItem.times = moment(newItem.CreateTime).format("HH:mm:ss"); .then(() => {
newItem.distance = parseInt(newItem.distance.toFixed(0)); console.log("播放音频");
// newItem.drone_lon = newItem.drone_lon.toFixed(6); this.isAudioPlaying = true;
// newItem.drone_lat = newItem.drone_lat.toFixed(6); //
media.onended = () => {
if (existingIndex !== -1) { if (this.iswarning) {
this.$set(this.drones, existingIndex, { ...newItem }); media.play().catch((error) => {
} else { console.log("循环播放失败:", error);
this.$set(this.drones, this.drones.length, { ...newItem }); this.showAudioPrompt = true;
} });
} } else {
}); this.isAudioPlaying = false;
if (newVal.length === 0) { }
this.iswarning = false; };
this.showAudioPrompt = false; // })
} .catch((error) => {
console.log("播放失败:", error);
if (this.drones) { this.showAudioPrompt = true;
mapUavFiex(this.drones, window.olMap);
}
const media = this.$refs.uavAudio;
let alarm = this.drones.find((d) => d.alarmLevel === 1);
if (alarm) {
this.iswarning = true;
this.$nextTick(() => {
if (media) {
media.muted = true; //
const savedVolume = localStorage.getItem("soundValue");
media.volume = savedVolume !== null ? savedVolume / 100 : 1;
media.muted = this.isZoomedIn ? false : true;
//
if (!this.isAudioPlaying) {
media
.play()
.then(() => {
console.log("播放音频");
this.isAudioPlaying = true;
//
media.onended = () => {
if (this.iswarning) {
media.play().catch((error) => {
console.log("循环播放失败:", error);
this.showAudioPrompt = true;
});
} else {
this.isAudioPlaying = false; this.isAudioPlaying = false;
} });
}; }
}) }
.catch((error) => { });
console.log("播放失败:", error); } else if (!alarm && this.iswarning) {
this.showAudioPrompt = true; //
this.isAudioPlaying = false; this.iswarning = false;
}); if (media) {
media.pause();
media.currentTime = 0;
this.isAudioPlaying = false;
media.onended = null; //
this.showAudioPrompt = false;
} }
} }
}); //
} else if (!alarm && this.iswarning) { if (newVal.length === 0) {
// this.iswarning = false;
this.iswarning = false; this.showAudioPrompt = false;
if (media) { this.isAudioPlaying = false;
media.pause(); if (media) {
media.currentTime = 0; media.pause();
this.isAudioPlaying = false; media.currentTime = 0;
media.onended = null; // media.onended = null;
this.showAudioPrompt = false; }
vectorSource.clear();
}
} }
} }
//
if (newVal.length === 0) {
this.iswarning = false;
this.showAudioPrompt = false;
this.isAudioPlaying = false;
if (media) {
media.pause();
media.currentTime = 0;
media.onended = null;
}
vectorSource.clear();
}
} }
}, },
deep: true deep: true
@ -465,6 +473,24 @@ export default {
} }
}, },
methods: { methods: {
enableTouchScroll() {
const ulElement = this.$el.querySelector(".drone-list ul");
if (ulElement) {
let startY, startScrollTop;
ulElement.addEventListener("touchstart", (e) => {
startY = e.touches[0].clientY;
startScrollTop = ulElement.scrollTop;
});
ulElement.addEventListener("touchmove", (e) => {
const deltaY = e.touches[0].clientY - startY;
ulElement.scrollTop = startScrollTop - deltaY;
//
// e.preventDefault();
});
}
},
closeNavigation(drone) { closeNavigation(drone) {
console.log(drone.app_lat, drone.app_lon, "导航"); console.log(drone.app_lat, drone.app_lon, "导航");
// drone.app_lon drone.app_lat // drone.app_lon drone.app_lat

View File

@ -24,13 +24,13 @@
<script> <script>
import { mapGetters } from "vuex"; import { mapGetters } from "vuex";
import { HomeSyncLocation } from "@/api/home"; import { HomeSyncLocation } from "@/api/home";
import Geolocation from "ol/Geolocation"; import { fromLonLat } from "ol/proj";
import { fromLonLat, transform } from "ol/proj";
import { Vector as VectorLayer } from "ol/layer"; import { Vector as VectorLayer } from "ol/layer";
import VectorSource from "ol/source/Vector"; import VectorSource from "ol/source/Vector";
import Point from "ol/geom/Point"; import Point from "ol/geom/Point";
import { Style, Icon, Stroke } from "ol/style"; import { Style, Icon } from "ol/style";
import Feature from "ol/Feature"; import Feature from "ol/Feature";
export default { export default {
name: "header-top", name: "header-top",
props: { props: {
@ -51,7 +51,6 @@ export default {
lastUpdated: "", lastUpdated: "",
timer: null, timer: null,
locationTimer: null, locationTimer: null,
geolocation: null,
showPermissionPrompt: false, showPermissionPrompt: false,
retryCount: 0, retryCount: 0,
positionLayer: null positionLayer: null
@ -61,10 +60,8 @@ export default {
...mapGetters(["positionPoint"]) ...mapGetters(["positionPoint"])
}, },
mounted() { mounted() {
console.log("组件挂载,启动定位");
this.isAdmins = JSON.parse(localStorage.getItem("isAdmin")); this.isAdmins = JSON.parse(localStorage.getItem("isAdmin"));
this.updateTime(); this.updateTime();
this.timer = setInterval(() => { this.timer = setInterval(() => {
this.updateTime(); this.updateTime();
}, 1000); }, 1000);
@ -73,24 +70,17 @@ export default {
watch: { watch: {
positionPoint: { positionPoint: {
handler(newVal) { handler(newVal) {
if (newVal) { if (newVal && this.latitude && this.longitude && window.olMap) {
// this.$message.success(this.latitude + ", " + this.longitude); const newLocation = fromLonLat(
console.log("位置更新", newVal, this.latitude, this.longitude); [this.longitude, this.latitude],
if (newVal && this.latitude && this.longitude && window.olMap) { "EPSG:3857"
const newLocation = fromLonLat( );
[this.longitude, this.latitude], this.$message.success("定位成功");
"EPSG:3857" this.updateMapPosition(this.longitude, this.latitude);
); window.olMap.getView().animate({
this.$message.success("定位成功"); center: newLocation,
this.updateMapPosition(this.longitude, this.latitude); zoom: 13
const zoomLevel = 13; });
window.olMap.getView().animate({
center: newLocation,
zoom: zoomLevel
});
} else {
this.$message.error("定位失败,请稍后重试");
}
this.$store.commit("SET_POSITIONPOINT", false); this.$store.commit("SET_POSITIONPOINT", false);
} }
}, },
@ -99,19 +89,19 @@ export default {
}, },
methods: { methods: {
updateMapPosition(lng, lat) { updateMapPosition(lng, lat) {
// positionLayer // Remove existing position layer
if (this.positionLayer) { if (this.positionLayer) {
window.olMap.removeLayer(this.positionLayer); window.olMap.removeLayer(this.positionLayer);
this.positionLayer = null; this.positionLayer = null;
} }
let center = fromLonLat([lng, lat]);
var iconFeature = new Feature({ const center = fromLonLat([lng, lat], "EPSG:3857");
const iconFeature = new Feature({
geometry: new Point(center), geometry: new Point(center),
name: "当前位置", name: "当前位置"
population: 4000,
rainfall: 500
}); });
var iconStyle = new Style({
const iconStyle = new Style({
image: new Icon({ image: new Icon({
anchor: [0.5, 46], anchor: [0.5, 46],
scale: 0.4, scale: 0.4,
@ -120,10 +110,12 @@ export default {
src: require("@/assets/img/icon_dev.png") src: require("@/assets/img/icon_dev.png")
}) })
}); });
iconFeature.setStyle(iconStyle); iconFeature.setStyle(iconStyle);
var vectorSource = new VectorSource({ const vectorSource = new VectorSource({
features: [iconFeature] features: [iconFeature]
}); });
this.positionLayer = new VectorLayer({ this.positionLayer = new VectorLayer({
source: vectorSource source: vectorSource
}); });
@ -136,94 +128,88 @@ export default {
this.currentDate = now.toLocaleDateString(); this.currentDate = now.toLocaleDateString();
}, },
startTracking() { startTracking() {
if (!window.olMap) { if (!window.AMap) {
console.error("OpenLayers 地图未传入,延迟重试"); console.error("高德地图 SDK 未加载,延迟重试");
this.$message.error("高德地图 SDK 加载失败");
setTimeout(() => this.startTracking(), 1000); setTimeout(() => this.startTracking(), 1000);
return; return;
} }
// locationTimer // Clear existing location timer
if (this.locationTimer) { if (this.locationTimer) {
clearInterval(this.locationTimer); clearInterval(this.locationTimer);
} }
// Geolocation // Initialize AMap Geolocation
this.geolocation = new Geolocation({ AMap.plugin("AMap.Geolocation", () => {
trackingOptions: { const geolocation = new AMap.Geolocation({
enableHighAccuracy: true, enableHighAccuracy: true,
timeout: 30000, timeout: 30000,
maximumAge: 10000 maximumAge: 10000,
}, zoomToAccuracy: true
projection: window.olMap.getView().getProjection() });
});
// // Handle geolocation errors
this.geolocation.on("error", (error) => { geolocation.on("error", (error) => {
let message = ""; let message = "";
this.retryCount = this.retryCount || 0; this.retryCount = this.retryCount || 0;
switch (error.code) {
case error.PERMISSION_DENIED: switch (error.info) {
message = "请允许地理位置权限"; case "PERMISSION_DENIED":
this.showPermissionPrompt = true; message = "请允许地理位置权限";
this.$message.error("请在浏览器设置中启用地理位置权限"); this.showPermissionPrompt = true;
break; this.$message.error("请在浏览器设置中启用地理位置权限");
case error.POSITION_UNAVAILABLE: break;
message = "无法获取位置信息"; case "POSITION_UNAVAILABLE":
if (this.retryCount < 3) { message = "无法获取位置信息";
this.retryCount++; if (this.retryCount < 3) {
setTimeout(() => this.startTracking(), 5000); this.retryCount++;
} else { setTimeout(() => this.startTracking(), 5000);
this.$message.error("多次尝试后仍无法定位,请检查设备设置"); } else {
this.$message.error("多次尝试后仍无法定位,请检查设备设置");
}
break;
case "TIMEOUT":
message = "获取位置超时";
if (this.retryCount < 3) {
this.retryCount++;
setTimeout(() => this.startTracking(), 5000);
} else {
this.$message.error("定位超时,请检查网络或 GPS 信号");
}
break;
default:
message = "未知错误";
}
this.leftText = message;
this.rightText = "定位异常";
});
// Start continuous tracking
this.locationTimer = setInterval(() => {
geolocation.getCurrentPosition((status, result) => {
if (status === "complete") {
this.handleSuccess(result.position);
} }
break; });
case error.TIMEOUT: }, 2000);
message = "获取位置超时";
if (this.retryCount < 3) {
this.retryCount++;
setTimeout(() => this.startTracking(), 5000);
} else {
this.$message.error("定位超时,请检查网络或 GPS 信号");
}
break;
default:
message = "未知错误";
}
this.leftText = message;
this.rightText = "定位异常";
}); });
//
this.geolocation.setTracking(true);
// 2
this.locationTimer = setInterval(() => {
const coordinates = this.geolocation.getPosition();
if (coordinates) {
this.handleSuccess(coordinates);
}
}, 2000);
}, },
handleSuccess(coordinates) { handleSuccess(position) {
// WGS84 this.longitude = position.lng;
const wgs84 = transform(coordinates, "EPSG:3857", "EPSG:4326"); this.latitude = position.lat;
this.longitude = wgs84[0]; this.lastUpdated = new Date().toLocaleString();
this.latitude = wgs84[1];
this.lastUpdated = new Date().toLocaleString(); //EPSG:3857 EPSG:4326
this.showPermissionPrompt = false; this.showPermissionPrompt = false;
this.retryCount = 0; this.retryCount = 0;
// API this.updateMapPosition(this.longitude, this.latitude);
let params = {
const params = {
lat: this.latitude, lat: this.latitude,
lon: this.longitude, lon: this.longitude,
userId: localStorage.getItem("userId") userId: localStorage.getItem("userId")
}; };
this.updateMapPosition(this.longitude, this.latitude);
// console.log(":", {
// latitude: this.latitude,
// longitude: this.longitude,
// time: this.lastUpdated
// });
HomeSyncLocation(params) HomeSyncLocation(params)
.then((res) => { .then((res) => {
if (res.code === 0) { if (res.code === 0) {
@ -246,9 +232,6 @@ export default {
} }
}, },
beforeDestroy() { beforeDestroy() {
if (this.geolocation) {
this.geolocation.setTracking(false);
}
if (this.timer) { if (this.timer) {
clearInterval(this.timer); clearInterval(this.timer);
} }

View File

@ -342,9 +342,9 @@ export default {
}); });
}, },
onMapLoad(map) { onMapLoad(map) {
setTimeout(() => { // setTimeout(() => {
this.initPositon(); // this.initPositon();
}, 2000); // }, 2000);
// //
const camera = window.mapConfig || {}; const camera = window.mapConfig || {};
if (camera.isCamera) { if (camera.isCamera) {