|
|
|
@ -377,6 +377,8 @@ class DroneMap:
|
|
|
|
var clickStartPos = null;
|
|
|
|
var clickStartPos = null;
|
|
|
|
var lastManualMapMoveAt = 0;
|
|
|
|
var lastManualMapMoveAt = 0;
|
|
|
|
var autoCenteringMap = false;
|
|
|
|
var autoCenteringMap = false;
|
|
|
|
|
|
|
|
const autoFollowPanThresholdRatio = 0.25;
|
|
|
|
|
|
|
|
var lastAutoFollowPanAt = 0;
|
|
|
|
|
|
|
|
|
|
|
|
function markManualMapMove() {
|
|
|
|
function markManualMapMove() {
|
|
|
|
if (!autoCenteringMap) {
|
|
|
|
if (!autoCenteringMap) {
|
|
|
|
@ -386,6 +388,42 @@ class DroneMap:
|
|
|
|
|
|
|
|
|
|
|
|
map.on('dragstart drag dragend zoomstart zoomend', markManualMapMove);
|
|
|
|
map.on('dragstart drag dragend zoomstart zoomend', markManualMapMove);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function isOutsideAutoFollowWindow(latlng) {
|
|
|
|
|
|
|
|
if (!latlng) {
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var size = map.getSize();
|
|
|
|
|
|
|
|
if (!size || size.x <= 0 || size.y <= 0) {
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var centerPoint = map.latLngToContainerPoint(map.getCenter());
|
|
|
|
|
|
|
|
var targetPoint = map.latLngToContainerPoint(latlng);
|
|
|
|
|
|
|
|
var dx = Math.abs(targetPoint.x - centerPoint.x);
|
|
|
|
|
|
|
|
var dy = Math.abs(targetPoint.y - centerPoint.y);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return dx >= size.x * autoFollowPanThresholdRatio ||
|
|
|
|
|
|
|
|
dy >= size.y * autoFollowPanThresholdRatio;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function autoFollowPanTo(latlng) {
|
|
|
|
|
|
|
|
if (!isOutsideAutoFollowWindow(latlng)) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Date.now() - lastManualMapMoveAt < 1000) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Date.now() - lastAutoFollowPanAt < 250) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lastAutoFollowPanAt = Date.now();
|
|
|
|
|
|
|
|
autoCenteringMap = true;
|
|
|
|
|
|
|
|
map.panTo(latlng, {animate: true});
|
|
|
|
|
|
|
|
setTimeout(() => { autoCenteringMap = false; }, 300);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 路徑標記變量 (跟隨模式用)
|
|
|
|
// 路徑標記變量 (跟隨模式用)
|
|
|
|
var routePoints = [];
|
|
|
|
var routePoints = [];
|
|
|
|
var routeMarkers = [];
|
|
|
|
var routeMarkers = [];
|
|
|
|
@ -738,13 +776,8 @@ class DroneMap:
|
|
|
|
|
|
|
|
|
|
|
|
setInterval(() => {
|
|
|
|
setInterval(() => {
|
|
|
|
if (focusedId && markers[focusedId]) {
|
|
|
|
if (focusedId && markers[focusedId]) {
|
|
|
|
if (Date.now() - lastManualMapMoveAt < 1000) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
var latlng = markers[focusedId].getLatLng();
|
|
|
|
var latlng = markers[focusedId].getLatLng();
|
|
|
|
autoCenteringMap = true;
|
|
|
|
autoFollowPanTo(latlng);
|
|
|
|
map.panTo(latlng);
|
|
|
|
|
|
|
|
setTimeout(() => { autoCenteringMap = false; }, 300);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, 1000);
|
|
|
|
}, 1000);
|
|
|
|
|
|
|
|
|
|
|
|
@ -760,6 +793,9 @@ class DroneMap:
|
|
|
|
.setLatLng([lat, lon])
|
|
|
|
.setLatLng([lat, lon])
|
|
|
|
.setRotationAngle(heading);
|
|
|
|
.setRotationAngle(heading);
|
|
|
|
idLabels[id].setLatLng([lat, lon]);
|
|
|
|
idLabels[id].setLatLng([lat, lon]);
|
|
|
|
|
|
|
|
if (id === focusedId) {
|
|
|
|
|
|
|
|
autoFollowPanTo(markers[id].getLatLng());
|
|
|
|
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
initTrajectory(id);
|
|
|
|
initTrajectory(id);
|
|
|
|
addTrajectoryPoint(id, lat, lon);
|
|
|
|
addTrajectoryPoint(id, lat, lon);
|
|
|
|
|