2026-03-31 14:17:30 +08:00
|
|
|
|
<template>
|
2026-04-02 08:56:49 +08:00
|
|
|
|
<div class="map-controller" :style="{ right: drawerOpen ? '480px' : '12px' }">
|
2026-07-16 17:58:11 +08:00
|
|
|
|
<div
|
|
|
|
|
|
class="map-controller-group"
|
|
|
|
|
|
v-for="(item, index) in controllers"
|
|
|
|
|
|
:key="index"
|
|
|
|
|
|
>
|
|
|
|
|
|
<template v-for="child in item.children" :key="child.key">
|
|
|
|
|
|
<!-- 组件项:直接渲染,自身已有交互逻辑 -->
|
|
|
|
|
|
<component
|
|
|
|
|
|
v-if="child.component"
|
|
|
|
|
|
:is="child.component"
|
|
|
|
|
|
:map="map"
|
|
|
|
|
|
:visible="activeKey === child.key"
|
|
|
|
|
|
:active="activeKey === child.key"
|
|
|
|
|
|
:treeData="tiltPhotoTree"
|
|
|
|
|
|
:disabled="is3DTransition && child.key === 'OSBGController'"
|
|
|
|
|
|
:countdown="countdown"
|
|
|
|
|
|
:inTransition="is3DTransition && child.key === 'OSBGController'"
|
|
|
|
|
|
@update:visible="(v: boolean) => handleComponentVisibleToggle(child.key, v)"
|
2026-07-17 18:03:34 +08:00
|
|
|
|
@loadModel="handleLoadModel"
|
|
|
|
|
|
@unloadModel="handleUnloadModel"
|
|
|
|
|
|
@flyToSite="handleFlyToSite"
|
2026-07-16 17:58:11 +08:00
|
|
|
|
/>
|
|
|
|
|
|
<!-- 非组件项:包裹 tooltip 显示名称 -->
|
|
|
|
|
|
<a-tooltip
|
2026-06-01 08:42:06 +08:00
|
|
|
|
v-else
|
2026-07-16 17:58:11 +08:00
|
|
|
|
:title="getTooltipTitle(child)"
|
|
|
|
|
|
placement="left"
|
|
|
|
|
|
:color="getTooltipColor(child)"
|
|
|
|
|
|
:open="getTooltipOpen(child)"
|
2026-06-01 08:42:06 +08:00
|
|
|
|
>
|
2026-07-16 17:58:11 +08:00
|
|
|
|
<div
|
|
|
|
|
|
class="map-controller-item"
|
|
|
|
|
|
:class="{
|
|
|
|
|
|
'is-active':
|
|
|
|
|
|
(child.key === 'TJ' && tjVisible) ||
|
|
|
|
|
|
(activeKey === child.key && child.key !== 'threedRoam'),
|
|
|
|
|
|
'is-disabled': isItemDisabled(child)
|
|
|
|
|
|
}"
|
|
|
|
|
|
@click="handleControllerClick(child)"
|
|
|
|
|
|
>
|
|
|
|
|
|
<i
|
|
|
|
|
|
class="icon iconfont"
|
|
|
|
|
|
:class="
|
|
|
|
|
|
child.key === 'threedRoam' && activeKey === 'threedRoam'
|
|
|
|
|
|
? 'icon-closeCircle'
|
|
|
|
|
|
: 'icon-' + child.icon
|
|
|
|
|
|
"
|
|
|
|
|
|
></i>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</a-tooltip>
|
|
|
|
|
|
</template>
|
2026-03-31 14:17:30 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
2026-07-16 17:58:11 +08:00
|
|
|
|
import { ref, watch, toRef, computed, onUnmounted } from 'vue';
|
2026-06-01 08:42:06 +08:00
|
|
|
|
import { useUiStore } from '@/store/modules/ui';
|
|
|
|
|
|
import Calculate from './Calculate.vue';
|
|
|
|
|
|
import LayerController from './LayerController.vue';
|
2026-07-16 17:58:11 +08:00
|
|
|
|
import OSBGController from './OSBGController.vue';
|
|
|
|
|
|
import { getAllTiltPhotoTree } from '@/api/system/map/TiltPhotoManagement';
|
2026-05-15 17:38:03 +08:00
|
|
|
|
|
2026-04-22 17:53:20 +08:00
|
|
|
|
const props = defineProps<{
|
|
|
|
|
|
map: any;
|
2026-05-15 17:38:03 +08:00
|
|
|
|
onClick: (key: any, mapType: any) => void;
|
2026-04-22 17:53:20 +08:00
|
|
|
|
}>();
|
2026-07-16 17:58:11 +08:00
|
|
|
|
const map = toRef(props, 'map');
|
2026-04-02 08:56:49 +08:00
|
|
|
|
|
|
|
|
|
|
// 使用 Pinia store
|
|
|
|
|
|
const uiStore = useUiStore();
|
|
|
|
|
|
const drawerOpen = ref(uiStore.drawerOpen);
|
2026-06-03 15:03:31 +08:00
|
|
|
|
const tjVisible = ref(false);
|
2026-04-02 08:56:49 +08:00
|
|
|
|
|
|
|
|
|
|
// 监听 store 中的 drawerOpen 变化
|
2026-04-02 09:27:56 +08:00
|
|
|
|
watch(
|
|
|
|
|
|
() => uiStore.drawerOpen,
|
2026-06-01 08:42:06 +08:00
|
|
|
|
newVal => {
|
2026-04-02 09:27:56 +08:00
|
|
|
|
drawerOpen.value = newVal;
|
|
|
|
|
|
}
|
|
|
|
|
|
);
|
2026-04-02 08:56:49 +08:00
|
|
|
|
|
2026-06-03 15:03:31 +08:00
|
|
|
|
watch(
|
|
|
|
|
|
() => uiStore.mapType,
|
|
|
|
|
|
newVal => {
|
|
|
|
|
|
if (newVal !== '2D') {
|
|
|
|
|
|
tjVisible.value = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
);
|
|
|
|
|
|
|
2026-03-31 14:17:30 +08:00
|
|
|
|
const isFullScreen = ref(false);
|
2026-04-02 08:56:49 +08:00
|
|
|
|
|
2026-07-16 17:58:11 +08:00
|
|
|
|
// 倾斜摄影数据
|
|
|
|
|
|
const tiltPhotoTree = ref<any[]>([]);
|
|
|
|
|
|
|
|
|
|
|
|
// 将 API 返回的扁平 list 转换为树结构
|
|
|
|
|
|
const buildTiltPhotoTree = (list: any[]) => {
|
|
|
|
|
|
if (!list || list.length === 0) return [];
|
|
|
|
|
|
const baseMap = new Map<string, { baseName: string; children: any[] }>();
|
|
|
|
|
|
for (const item of list) {
|
|
|
|
|
|
const id = String(item.baseId ?? '');
|
|
|
|
|
|
if (!baseMap.has(id)) {
|
|
|
|
|
|
baseMap.set(id, { baseName: item.baseName || '', children: [] });
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
for (const item of list) {
|
|
|
|
|
|
const id = String(item.baseId ?? '');
|
|
|
|
|
|
const group = baseMap.get(id);
|
|
|
|
|
|
if (group) {
|
2026-07-17 18:03:34 +08:00
|
|
|
|
// 直接 push 原始对象(不用展开),确保与 addQxsyLayer 中的 item 是同一引用
|
|
|
|
|
|
// OSGB 状态(osgbtitles, cartesian3, eventListener 等)都挂在这个对象上
|
|
|
|
|
|
item.checked = true;
|
|
|
|
|
|
group.children.push(item);
|
2026-07-16 17:58:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return Array.from(baseMap.entries())
|
|
|
|
|
|
.map(([baseId, group]) => ({
|
|
|
|
|
|
baseId,
|
|
|
|
|
|
baseName: group.baseName,
|
|
|
|
|
|
children: group.children
|
|
|
|
|
|
}))
|
|
|
|
|
|
.sort((a, b) => String(a.baseId).localeCompare(String(b.baseId)));
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 请求倾斜摄影树数据
|
|
|
|
|
|
const fetchTiltPhotoTree = async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const res = await getAllTiltPhotoTree({
|
|
|
|
|
|
filter: {
|
|
|
|
|
|
logic: 'and',
|
|
|
|
|
|
filters: [
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'url',
|
|
|
|
|
|
operator: 'contains',
|
|
|
|
|
|
dataType: 'string',
|
|
|
|
|
|
value: 'http'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'sttpCode',
|
|
|
|
|
|
operator: 'eq',
|
|
|
|
|
|
dataType: 'string',
|
|
|
|
|
|
value: 'OSGB'
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
sort: [
|
|
|
|
|
|
{ field: 'rstcdStepSort', dir: 'asc' },
|
|
|
|
|
|
{ field: 'ttpwr', dir: 'desc' }
|
|
|
|
|
|
]
|
|
|
|
|
|
});
|
|
|
|
|
|
const list = res.data.data;
|
|
|
|
|
|
tiltPhotoTree.value = buildTiltPhotoTree(list);
|
2026-07-17 18:03:34 +08:00
|
|
|
|
|
|
|
|
|
|
// 全部加载倾斜摄影模型(dynamicSetVisible 按 12km 距离自动控制显隐)
|
|
|
|
|
|
list.forEach((item: any) => {
|
|
|
|
|
|
map.value.addQxsyLayer?.(item);
|
|
|
|
|
|
});
|
2026-07-16 17:58:11 +08:00
|
|
|
|
} catch (err) {
|
|
|
|
|
|
console.error('获取倾斜摄影数据失败:', err);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2026-07-17 18:03:34 +08:00
|
|
|
|
// 倾斜摄影模型相关事件处理
|
|
|
|
|
|
const handleLoadModel = (item: any) => {
|
|
|
|
|
|
// 开关打开:加载/显示模型
|
|
|
|
|
|
map.value.qxsyChangeClick?.(item, true);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handleUnloadModel = (item: any) => {
|
|
|
|
|
|
// 开关关闭:卸载/隐藏模型
|
|
|
|
|
|
map.value.qxsyChangeClick?.(item, false);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handleFlyToSite = (item: any) => {
|
|
|
|
|
|
// 先加载模型(如果还没加载),再飞行定位
|
|
|
|
|
|
map.value.addQxsyLayer?.(item);
|
|
|
|
|
|
map.value.qxsyToPosition?.(item);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2026-07-16 17:58:11 +08:00
|
|
|
|
// 3D过渡动画状态
|
|
|
|
|
|
// layerController / OSBGController / threedRoam 三者互斥,最多一个被选中
|
|
|
|
|
|
const activeKey = ref<string | null>(null);
|
|
|
|
|
|
const is3DTransition = ref(false);
|
|
|
|
|
|
const countdown = ref(0);
|
|
|
|
|
|
let transitionTimer: ReturnType<typeof setTimeout> | null = null;
|
|
|
|
|
|
|
|
|
|
|
|
const start3DTransition = () => {
|
|
|
|
|
|
cleanup3DTransition();
|
|
|
|
|
|
is3DTransition.value = true;
|
|
|
|
|
|
countdown.value = 5;
|
|
|
|
|
|
|
|
|
|
|
|
const tick = () => {
|
|
|
|
|
|
countdown.value--;
|
|
|
|
|
|
if (countdown.value <= 0) {
|
|
|
|
|
|
// 过渡完成
|
|
|
|
|
|
is3DTransition.value = false;
|
|
|
|
|
|
countdown.value = 0;
|
|
|
|
|
|
// 自动选中OSBGController
|
|
|
|
|
|
activeKey.value = 'OSBGController';
|
|
|
|
|
|
transitionTimer = null;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
transitionTimer = setTimeout(tick, 1000);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
transitionTimer = setTimeout(tick, 1000);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const cleanup3DTransition = () => {
|
|
|
|
|
|
if (transitionTimer) {
|
|
|
|
|
|
clearTimeout(transitionTimer);
|
|
|
|
|
|
transitionTimer = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
is3DTransition.value = false;
|
|
|
|
|
|
countdown.value = 0;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Tooltip 辅助函数(仅用于非组件项,如 threedRoam)
|
|
|
|
|
|
const getTooltipTitle = (child: any) => {
|
|
|
|
|
|
if (is3DTransition.value && child.key === 'threedRoam') {
|
|
|
|
|
|
return child.name + ' ' + countdown.value + 's';
|
|
|
|
|
|
}
|
|
|
|
|
|
return child.name;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const getTooltipColor = (child: any) => {
|
|
|
|
|
|
if (is3DTransition.value && child.key === 'threedRoam') {
|
|
|
|
|
|
return '#008BFF';
|
|
|
|
|
|
}
|
|
|
|
|
|
return undefined;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const getTooltipOpen = (child: any) => {
|
|
|
|
|
|
if (is3DTransition.value && child.key === 'threedRoam') {
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
return undefined;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const isItemDisabled = (child: any) => {
|
|
|
|
|
|
return is3DTransition.value && child.key === 'threedRoam';
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 组件切换回调(插槽面板 open/close,互斥)
|
|
|
|
|
|
const handleComponentVisibleToggle = (key: string, visible: boolean) => {
|
|
|
|
|
|
activeKey.value = visible ? key : null;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
onUnmounted(() => {
|
|
|
|
|
|
cleanup3DTransition();
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2026-04-02 08:56:49 +08:00
|
|
|
|
// 响应式的控制器配置
|
2026-04-02 13:51:36 +08:00
|
|
|
|
const controllers: any = computed(() => [
|
2026-03-31 14:17:30 +08:00
|
|
|
|
{
|
2026-04-02 09:27:56 +08:00
|
|
|
|
children: [
|
|
|
|
|
|
{
|
2026-06-01 08:42:06 +08:00
|
|
|
|
name: '全屏',
|
|
|
|
|
|
key: 'fullScreen',
|
|
|
|
|
|
icon: isFullScreen.value ? 'exitFullScreen' : 'fullScreen'
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
2026-03-31 14:17:30 +08:00
|
|
|
|
},
|
2026-04-02 09:27:56 +08:00
|
|
|
|
|
2026-07-16 17:58:11 +08:00
|
|
|
|
!uiStore.isRoaming
|
|
|
|
|
|
? {
|
|
|
|
|
|
children: [
|
|
|
|
|
|
// {
|
|
|
|
|
|
// name: "定位",
|
|
|
|
|
|
// key: "positioning",
|
|
|
|
|
|
// icon: "iconGlobal",
|
|
|
|
|
|
// },
|
|
|
|
|
|
{
|
|
|
|
|
|
name: '放大',
|
|
|
|
|
|
key: 'zoomIn',
|
|
|
|
|
|
icon: 'zoomIn'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
name: '缩小',
|
|
|
|
|
|
key: 'zoomOut',
|
|
|
|
|
|
icon: 'zoomOut'
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
2026-06-01 08:42:06 +08:00
|
|
|
|
}
|
2026-07-16 17:58:11 +08:00
|
|
|
|
: {},
|
2026-03-31 14:17:30 +08:00
|
|
|
|
{
|
2026-04-02 13:51:36 +08:00
|
|
|
|
children: [
|
|
|
|
|
|
{
|
2026-06-01 08:42:06 +08:00
|
|
|
|
name: '3D',
|
|
|
|
|
|
key: 'dim',
|
|
|
|
|
|
icon: uiStore.mapType === '2D' ? 'a-3D' : 'a-2D'
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
2026-03-31 14:17:30 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
2026-04-02 13:51:36 +08:00
|
|
|
|
children: [
|
|
|
|
|
|
{
|
2026-06-01 08:42:06 +08:00
|
|
|
|
name: '图层管理',
|
|
|
|
|
|
key: 'layerController',
|
|
|
|
|
|
component: LayerController
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
2026-03-31 14:17:30 +08:00
|
|
|
|
},
|
2026-06-01 08:42:06 +08:00
|
|
|
|
uiStore.mapType === '2D'
|
2026-05-15 17:38:03 +08:00
|
|
|
|
? {
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{
|
2026-06-01 08:42:06 +08:00
|
|
|
|
name: '测量工具',
|
|
|
|
|
|
key: 'Calculate',
|
|
|
|
|
|
component: Calculate
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
2026-05-15 17:38:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
: {},
|
2026-06-01 08:42:06 +08:00
|
|
|
|
uiStore.mapType === '2D'
|
2026-05-15 17:38:03 +08:00
|
|
|
|
? {
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{
|
2026-06-01 08:42:06 +08:00
|
|
|
|
name: '梯级',
|
|
|
|
|
|
key: 'TJ',
|
|
|
|
|
|
icon: 'tiji'
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
2026-05-15 17:38:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
: {},
|
2026-06-01 08:42:06 +08:00
|
|
|
|
uiStore.mapType === '3D'
|
2026-05-15 17:38:03 +08:00
|
|
|
|
? {
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{
|
2026-06-01 08:42:06 +08:00
|
|
|
|
name: '电站倾斜摄影',
|
|
|
|
|
|
key: 'OSBGController',
|
2026-07-16 17:58:11 +08:00
|
|
|
|
component: OSBGController
|
2026-06-01 08:42:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
]
|
2026-05-15 17:38:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
: {},
|
2026-06-01 08:42:06 +08:00
|
|
|
|
uiStore.mapType === '3D'
|
2026-05-15 17:38:03 +08:00
|
|
|
|
? {
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{
|
2026-06-01 08:42:06 +08:00
|
|
|
|
name: '流域三维漫游',
|
|
|
|
|
|
key: 'threedRoam',
|
|
|
|
|
|
icon: 'roaming'
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
2026-05-15 17:38:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
: {},
|
2026-03-31 14:17:30 +08:00
|
|
|
|
{
|
2026-04-02 13:51:36 +08:00
|
|
|
|
children: [
|
|
|
|
|
|
{
|
2026-06-01 08:42:06 +08:00
|
|
|
|
name: '下载',
|
|
|
|
|
|
key: 'screenShot',
|
|
|
|
|
|
icon: 'downLoad'
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
2026-03-31 14:17:30 +08:00
|
|
|
|
]);
|
2026-04-02 13:51:36 +08:00
|
|
|
|
|
|
|
|
|
|
// 添加全屏切换功能
|
2026-06-01 08:42:06 +08:00
|
|
|
|
const toggleFullScreen = () => {
|
|
|
|
|
|
if (!document.fullscreenElement) {
|
|
|
|
|
|
// 进入全屏
|
|
|
|
|
|
document.documentElement.requestFullscreen().catch(err => {
|
|
|
|
|
|
console.error('进入全屏失败:', err);
|
|
|
|
|
|
isFullScreen.value = false;
|
|
|
|
|
|
});
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 退出全屏
|
|
|
|
|
|
document.exitFullscreen().catch(err => {
|
|
|
|
|
|
console.error('退出全屏失败:', err);
|
|
|
|
|
|
isFullScreen.value = true;
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 监听全屏状态变化
|
|
|
|
|
|
document.addEventListener('fullscreenchange', () => {
|
|
|
|
|
|
isFullScreen.value = !!document.fullscreenElement;
|
|
|
|
|
|
});
|
2026-04-02 13:51:36 +08:00
|
|
|
|
|
|
|
|
|
|
// 控制器点击事件处理
|
|
|
|
|
|
const handleControllerClick = (item: any) => {
|
|
|
|
|
|
switch (item.key) {
|
2026-06-01 08:42:06 +08:00
|
|
|
|
case 'fullScreen':
|
2026-06-03 15:03:31 +08:00
|
|
|
|
isFullScreen.value = !isFullScreen.value;
|
2026-07-16 17:58:11 +08:00
|
|
|
|
toggleFullScreen();
|
2026-04-22 17:53:20 +08:00
|
|
|
|
break;
|
2026-06-01 08:42:06 +08:00
|
|
|
|
case 'zoomIn':
|
2026-07-16 17:58:11 +08:00
|
|
|
|
map.value.zoomToggle('in');
|
2026-04-22 17:53:20 +08:00
|
|
|
|
break;
|
2026-06-01 08:42:06 +08:00
|
|
|
|
case 'zoomOut':
|
2026-07-16 17:58:11 +08:00
|
|
|
|
map.value.zoomToggle('out');
|
2026-04-22 17:53:20 +08:00
|
|
|
|
break;
|
2026-07-16 17:58:11 +08:00
|
|
|
|
case 'dim': // 切换3D/2D
|
|
|
|
|
|
{
|
|
|
|
|
|
const switchingTo3D = uiStore.mapType === '2D';
|
|
|
|
|
|
uiStore.mapType = switchingTo3D ? '3D' : '2D';
|
|
|
|
|
|
if (switchingTo3D) {
|
|
|
|
|
|
// 2D→3D:关闭抽屉,请求倾斜摄影数据,开始过渡
|
|
|
|
|
|
uiStore.drawerOpen = false;
|
|
|
|
|
|
fetchTiltPhotoTree();
|
|
|
|
|
|
start3DTransition();
|
|
|
|
|
|
} else {
|
2026-07-17 18:03:34 +08:00
|
|
|
|
// 3D→2D:打开抽屉,清理过渡,卸载所有倾斜摄影模型
|
2026-07-16 17:58:11 +08:00
|
|
|
|
uiStore.drawerOpen = true;
|
|
|
|
|
|
uiStore.isRoaming = false;
|
|
|
|
|
|
cleanup3DTransition();
|
|
|
|
|
|
activeKey.value = null;
|
2026-07-17 18:03:34 +08:00
|
|
|
|
// 卸载所有倾斜摄影
|
|
|
|
|
|
tiltPhotoTree.value.forEach((group: any) => {
|
|
|
|
|
|
group.children?.forEach((item: any) => {
|
|
|
|
|
|
map.value.removeQxsyLayer?.(item);
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
tiltPhotoTree.value = [];
|
2026-07-16 17:58:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
props.onClick('dim', uiStore.mapType);
|
2026-05-15 17:38:03 +08:00
|
|
|
|
}
|
2026-04-02 13:51:36 +08:00
|
|
|
|
break;
|
2026-07-16 17:58:11 +08:00
|
|
|
|
case 'threedRoam': // 流域三维漫游
|
|
|
|
|
|
if (is3DTransition.value) break;
|
|
|
|
|
|
// 互斥:选中threedRoam时取消其他选中
|
|
|
|
|
|
activeKey.value = activeKey.value === 'threedRoam' ? null : 'threedRoam';
|
|
|
|
|
|
uiStore.isRoaming = !uiStore.isRoaming;
|
2026-04-02 13:51:36 +08:00
|
|
|
|
break;
|
|
|
|
|
|
// 可以在这里添加其他控制器的处理逻辑
|
2026-06-01 08:42:06 +08:00
|
|
|
|
case 'screenShot':
|
2026-07-16 17:58:11 +08:00
|
|
|
|
map.value.mapOutPut();
|
2026-04-22 17:53:20 +08:00
|
|
|
|
break;
|
2026-06-01 08:42:06 +08:00
|
|
|
|
case 'TJ':
|
2026-06-03 15:03:31 +08:00
|
|
|
|
tjVisible.value = !tjVisible.value;
|
2026-05-15 17:38:03 +08:00
|
|
|
|
props.onClick(4, null);
|
2026-04-22 17:53:20 +08:00
|
|
|
|
break;
|
2026-04-02 13:51:36 +08:00
|
|
|
|
default:
|
|
|
|
|
|
console.log(`点击了控制器: ${item.name}`);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2026-03-31 14:17:30 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
|
.map-controller {
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
right: 480px;
|
|
|
|
|
|
bottom: 114px;
|
|
|
|
|
|
z-index: 10;
|
|
|
|
|
|
.map-controller-group {
|
|
|
|
|
|
box-shadow: 0 1px 2px #00000026;
|
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
|
border: none;
|
|
|
|
|
|
.map-controller-item {
|
|
|
|
|
|
height: 40px;
|
|
|
|
|
|
width: 40px;
|
|
|
|
|
|
color: #000;
|
|
|
|
|
|
line-height: 40px;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
.iconfont {
|
|
|
|
|
|
font-size: 20px;
|
|
|
|
|
|
}
|
|
|
|
|
|
&:hover {
|
|
|
|
|
|
background-color: #005292;
|
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
|
}
|
2026-06-03 15:03:31 +08:00
|
|
|
|
&.is-active {
|
|
|
|
|
|
background-color: #005292;
|
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
|
}
|
2026-07-16 17:58:11 +08:00
|
|
|
|
&.is-disabled {
|
|
|
|
|
|
pointer-events: none;
|
|
|
|
|
|
opacity: 0.5;
|
|
|
|
|
|
}
|
2026-03-31 14:17:30 +08:00
|
|
|
|
}
|
2026-04-02 13:51:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
.map-controller-group:not(:first-child) {
|
|
|
|
|
|
margin-top: 10px;
|
2026-03-31 14:17:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-04-02 09:27:56 +08:00
|
|
|
|
</style>
|