|
|
@ -35,7 +35,7 @@ |
|
|
@delete="deleteEntityFromContextMenu" |
|
|
@delete="deleteEntityFromContextMenu" |
|
|
@update-property="updateEntityProperty" |
|
|
@update-property="updateEntityProperty" |
|
|
/> |
|
|
/> |
|
|
|
|
|
|
|
|
<!-- 定位弹窗 --> |
|
|
<!-- 定位弹窗 --> |
|
|
<locate-dialog |
|
|
<locate-dialog |
|
|
:visible="locateDialogVisible" |
|
|
:visible="locateDialogVisible" |
|
|
@ -43,7 +43,7 @@ |
|
|
@confirm="handleLocateConfirm" |
|
|
@confirm="handleLocateConfirm" |
|
|
@cancel="handleLocateCancel" |
|
|
@cancel="handleLocateCancel" |
|
|
/> |
|
|
/> |
|
|
|
|
|
|
|
|
<!-- 地图右下角:比例尺 + 经纬度 --> |
|
|
<!-- 地图右下角:比例尺 + 经纬度 --> |
|
|
<div class="map-info-panel"> |
|
|
<div class="map-info-panel"> |
|
|
<div class="scale-bar"> |
|
|
<div class="scale-bar"> |
|
|
@ -358,7 +358,7 @@ export default { |
|
|
const backendUrl = process.env.VUE_APP_BACKEND_URL || ''; |
|
|
const backendUrl = process.env.VUE_APP_BACKEND_URL || ''; |
|
|
return backendUrl + cleanPath; |
|
|
return backendUrl + cleanPath; |
|
|
}, |
|
|
}, |
|
|
//正式航线渲染函数(style 可选:waypoint { pixelSize, color, outlineColor, outlineWidth },line { style, width, color, gapColor, dashLength }) |
|
|
//正式航线渲染函数 |
|
|
renderRouteWaypoints(waypoints, routeId = 'default', platformId, platform, style) { |
|
|
renderRouteWaypoints(waypoints, routeId = 'default', platformId, platform, style) { |
|
|
if (!waypoints || waypoints.length < 1) return; |
|
|
if (!waypoints || waypoints.length < 1) return; |
|
|
// 清理旧线 |
|
|
// 清理旧线 |
|
|
@ -367,6 +367,12 @@ export default { |
|
|
if (existingLine) { |
|
|
if (existingLine) { |
|
|
this.viewer.entities.remove(existingLine); |
|
|
this.viewer.entities.remove(existingLine); |
|
|
} |
|
|
} |
|
|
|
|
|
// 清理属于该航线的旧平台图标 |
|
|
|
|
|
const platformBillboardId = `route-platform-${routeId}`; |
|
|
|
|
|
const existingPlatform = this.viewer.entities.getById(platformBillboardId); |
|
|
|
|
|
if (existingPlatform) { |
|
|
|
|
|
this.viewer.entities.remove(existingPlatform); |
|
|
|
|
|
} |
|
|
// 清理所有属于该航线的旧点 |
|
|
// 清理所有属于该航线的旧点 |
|
|
waypoints.forEach((wp,index) => { |
|
|
waypoints.forEach((wp,index) => { |
|
|
const waypointEntityId = `wp_${routeId}_${wp.id}`; |
|
|
const waypointEntityId = `wp_${routeId}_${wp.id}`; |
|
|
@ -2785,7 +2791,7 @@ export default { |
|
|
handleLocate() { |
|
|
handleLocate() { |
|
|
this.locateDialogVisible = true |
|
|
this.locateDialogVisible = true |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
handleLocateConfirm(location) { |
|
|
handleLocateConfirm(location) { |
|
|
const { lng, lat } = location |
|
|
const { lng, lat } = location |
|
|
if (this.viewer) { |
|
|
if (this.viewer) { |
|
|
@ -2801,29 +2807,29 @@ export default { |
|
|
this.$message.success(`已定位到经度 ${lng.toFixed(4)},纬度 ${lat.toFixed(4)}`) |
|
|
this.$message.success(`已定位到经度 ${lng.toFixed(4)},纬度 ${lat.toFixed(4)}`) |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
handleLocateCancel() { |
|
|
handleLocateCancel() { |
|
|
this.$message.info('已取消定位') |
|
|
this.$message.info('已取消定位') |
|
|
}, |
|
|
}, |
|
|
updateSelectOptions(refName, dataList, labelField) { |
|
|
updateSelectOptions(refName, dataList, labelField) { |
|
|
const select = document.querySelector(`select[ref="${refName}"]`) |
|
|
const select = document.querySelector(`select[ref="${refName}"]`) |
|
|
if (!select) return |
|
|
if (!select) return |
|
|
|
|
|
|
|
|
const currentValue = select.value |
|
|
const currentValue = select.value |
|
|
select.innerHTML = '' |
|
|
select.innerHTML = '' |
|
|
|
|
|
|
|
|
const defaultOption = document.createElement('option') |
|
|
const defaultOption = document.createElement('option') |
|
|
defaultOption.value = '' |
|
|
defaultOption.value = '' |
|
|
defaultOption.textContent = refName === 'routeSelect' ? '请选择航线' : '请选择航点' |
|
|
defaultOption.textContent = refName === 'routeSelect' ? '请选择航线' : '请选择航点' |
|
|
select.appendChild(defaultOption) |
|
|
select.appendChild(defaultOption) |
|
|
|
|
|
|
|
|
dataList.forEach(item => { |
|
|
dataList.forEach(item => { |
|
|
const option = document.createElement('option') |
|
|
const option = document.createElement('option') |
|
|
option.value = item.id |
|
|
option.value = item.id |
|
|
option.textContent = typeof labelField === 'function' ? labelField(item) : item[labelField] |
|
|
option.textContent = typeof labelField === 'function' ? labelField(item) : item[labelField] |
|
|
select.appendChild(option) |
|
|
select.appendChild(option) |
|
|
}) |
|
|
}) |
|
|
|
|
|
|
|
|
select.value = currentValue |
|
|
select.value = currentValue |
|
|
}, |
|
|
}, |
|
|
initScaleBar() { |
|
|
initScaleBar() { |
|
|
@ -3071,25 +3077,25 @@ export default { |
|
|
if (!positions || positions.length < 2) { |
|
|
if (!positions || positions.length < 2) { |
|
|
return -1; |
|
|
return -1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
let closestDistance = Number.MAX_VALUE; |
|
|
let closestDistance = Number.MAX_VALUE; |
|
|
let closestSegmentIndex = -1; |
|
|
let closestSegmentIndex = -1; |
|
|
|
|
|
|
|
|
// 遍历每一段线段 |
|
|
// 遍历每一段线段 |
|
|
for (let i = 0; i < positions.length - 1; i++) { |
|
|
for (let i = 0; i < positions.length - 1; i++) { |
|
|
const startPoint = positions[i]; |
|
|
const startPoint = positions[i]; |
|
|
const endPoint = positions[i + 1]; |
|
|
const endPoint = positions[i + 1]; |
|
|
|
|
|
|
|
|
// 计算鼠标在屏幕上的点到线段的距离 |
|
|
// 计算鼠标在屏幕上的点到线段的距离 |
|
|
const distance = this.distanceToSegment(mousePosition, startPoint, endPoint); |
|
|
const distance = this.distanceToSegment(mousePosition, startPoint, endPoint); |
|
|
|
|
|
|
|
|
// 如果距离小于当前最小距离,更新最小距离和对应的段索引 |
|
|
// 如果距离小于当前最小距离,更新最小距离和对应的段索引 |
|
|
if (distance < closestDistance) { |
|
|
if (distance < closestDistance) { |
|
|
closestDistance = distance; |
|
|
closestDistance = distance; |
|
|
closestSegmentIndex = i; |
|
|
closestSegmentIndex = i; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 如果最小距离小于一个阈值,返回对应的段索引 |
|
|
// 如果最小距离小于一个阈值,返回对应的段索引 |
|
|
const threshold = 10; // 像素阈值 |
|
|
const threshold = 10; // 像素阈值 |
|
|
return closestDistance < threshold ? closestSegmentIndex : -1; |
|
|
return closestDistance < threshold ? closestSegmentIndex : -1; |
|
|
@ -3099,30 +3105,30 @@ export default { |
|
|
// 将3D点转换为屏幕坐标 |
|
|
// 将3D点转换为屏幕坐标 |
|
|
const startScreen = this.viewer.scene.cartesianToCanvasCoordinates(startPoint); |
|
|
const startScreen = this.viewer.scene.cartesianToCanvasCoordinates(startPoint); |
|
|
const endScreen = this.viewer.scene.cartesianToCanvasCoordinates(endPoint); |
|
|
const endScreen = this.viewer.scene.cartesianToCanvasCoordinates(endPoint); |
|
|
|
|
|
|
|
|
if (!startScreen || !endScreen) { |
|
|
if (!startScreen || !endScreen) { |
|
|
return Number.MAX_VALUE; |
|
|
return Number.MAX_VALUE; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 计算线段的向量 |
|
|
// 计算线段的向量 |
|
|
const lineVec = [endScreen.x - startScreen.x, endScreen.y - startScreen.y]; |
|
|
const lineVec = [endScreen.x - startScreen.x, endScreen.y - startScreen.y]; |
|
|
// 计算从线段起点到鼠标点的向量 |
|
|
// 计算从线段起点到鼠标点的向量 |
|
|
const mouseVec = [mousePosition.x - startScreen.x, mousePosition.y - startScreen.y]; |
|
|
const mouseVec = [mousePosition.x - startScreen.x, mousePosition.y - startScreen.y]; |
|
|
|
|
|
|
|
|
// 计算线段的长度平方 |
|
|
// 计算线段的长度平方 |
|
|
const lineLengthSquared = lineVec[0] * lineVec[0] + lineVec[1] * lineVec[1]; |
|
|
const lineLengthSquared = lineVec[0] * lineVec[0] + lineVec[1] * lineVec[1]; |
|
|
|
|
|
|
|
|
if (lineLengthSquared === 0) { |
|
|
if (lineLengthSquared === 0) { |
|
|
// 线段长度为0,返回鼠标点到线段起点的距离 |
|
|
// 线段长度为0,返回鼠标点到线段起点的距离 |
|
|
return Math.sqrt(mouseVec[0] * mouseVec[0] + mouseVec[1] * mouseVec[1]); |
|
|
return Math.sqrt(mouseVec[0] * mouseVec[0] + mouseVec[1] * mouseVec[1]); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 计算鼠标点在直线上的投影参数t |
|
|
// 计算鼠标点在直线上的投影参数t |
|
|
const t = Math.max(0, Math.min(1, (mouseVec[0] * lineVec[0] + mouseVec[1] * lineVec[1]) / lineLengthSquared)); |
|
|
const t = Math.max(0, Math.min(1, (mouseVec[0] * lineVec[0] + mouseVec[1] * lineVec[1]) / lineLengthSquared)); |
|
|
|
|
|
|
|
|
// 计算投影点 |
|
|
// 计算投影点 |
|
|
const projection = [startScreen.x + t * lineVec[0], startScreen.y + t * lineVec[1]]; |
|
|
const projection = [startScreen.x + t * lineVec[0], startScreen.y + t * lineVec[1]]; |
|
|
|
|
|
|
|
|
// 计算鼠标点到投影点的距离 |
|
|
// 计算鼠标点到投影点的距离 |
|
|
const distanceVec = [mousePosition.x - projection[0], mousePosition.y - projection[1]]; |
|
|
const distanceVec = [mousePosition.x - projection[0], mousePosition.y - projection[1]]; |
|
|
return Math.sqrt(distanceVec[0] * distanceVec[0] + distanceVec[1] * distanceVec[1]); |
|
|
return Math.sqrt(distanceVec[0] * distanceVec[0] + distanceVec[1] * distanceVec[1]); |
|
|
|