Compare commits

...

3 Commits

46 changed files with 3852 additions and 897 deletions

View File

@ -25,6 +25,7 @@
"@electron-toolkit/utils": "^4.0.0", "@electron-toolkit/utils": "^4.0.0",
"@ztree/ztree_v3": "^3.5.48", "@ztree/ztree_v3": "^3.5.48",
"axios": "^1.11.0", "axios": "^1.11.0",
"echarts": "^6.0.0",
"electron-updater": "^6.3.9", "electron-updater": "^6.3.9",
"element-plus": "^2.10.4", "element-plus": "^2.10.4",
"mitt": "^3.0.1", "mitt": "^3.0.1",

View File

@ -19,11 +19,13 @@ declare module 'vue' {
ElOption: typeof import('element-plus/es')['ElOption'] ElOption: typeof import('element-plus/es')['ElOption']
ElPagination: typeof import('element-plus/es')['ElPagination'] ElPagination: typeof import('element-plus/es')['ElPagination']
ElSelect: typeof import('element-plus/es')['ElSelect'] ElSelect: typeof import('element-plus/es')['ElSelect']
ElSlider: typeof import('element-plus/es')['ElSlider']
ElSwitch: typeof import('element-plus/es')['ElSwitch'] ElSwitch: typeof import('element-plus/es')['ElSwitch']
ElTable: typeof import('element-plus/es')['ElTable'] ElTable: typeof import('element-plus/es')['ElTable']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
ElTabPane: typeof import('element-plus/es')['ElTabPane'] ElTabPane: typeof import('element-plus/es')['ElTabPane']
ElTabs: typeof import('element-plus/es')['ElTabs'] ElTabs: typeof import('element-plus/es')['ElTabs']
ElTag: typeof import('element-plus/es')['ElTag']
ElUpload: typeof import('element-plus/es')['ElUpload'] ElUpload: typeof import('element-plus/es')['ElUpload']
Index_b: typeof import('./src/components/SvgIcon/index_b.vue')['default'] Index_b: typeof import('./src/components/SvgIcon/index_b.vue')['default']
Pagination: typeof import('./src/components/Pagination/index.vue')['default'] Pagination: typeof import('./src/components/Pagination/index.vue')['default']

File diff suppressed because one or more lines are too long

View File

@ -65,7 +65,7 @@ export default {
junbiao3d: '三维军标' junbiao3d: '三维军标'
}, },
effect: { effect: {
trajectoryMotion:"轨迹运动", trajectoryMotion: "轨迹运动",
electronicFence: "电子围墙", electronicFence: "电子围墙",
// nightVision: '实体墙', // nightVision: '实体墙',
radarLightWave: "扩散光波", radarLightWave: "扩散光波",
@ -81,7 +81,7 @@ export default {
nightVision: '夜视', nightVision: '夜视',
// nightVision: '飞线', // nightVision: '飞线',
}, },
analysis:{ analysis: {
inundationAnalysis: "淹没分析", inundationAnalysis: "淹没分析",
profileAnalysis: "剖面分析", profileAnalysis: "剖面分析",
sightAnalysis: "视线分析", sightAnalysis: "视线分析",
@ -93,7 +93,7 @@ export default {
contour: "等高线", contour: "等高线",
clear: "清除", clear: "清除",
}, },
measure:{ measure: {
projectionArea: "投影面积", projectionArea: "投影面积",
projectionDistanceMeasure: '投影距离', projectionDistanceMeasure: '投影距离',
areaMeasure: "贴地面积", areaMeasure: "贴地面积",
@ -107,9 +107,9 @@ export default {
clear: "清除测量", clear: "清除测量",
}, },
tool:{ tool: {
routePlan: "路径规划", routePlan: "路径规划",
//清除轨迹 clearRoute: '清除轨迹',
graffiti: "涂鸦", graffiti: "涂鸦",
// stopGraffiti: "结束涂鸦", // stopGraffiti: "结束涂鸦",
clearGraffiti: "清除涂鸦", clearGraffiti: "清除涂鸦",
@ -117,17 +117,20 @@ export default {
coorLocation: "坐标定位", coorLocation: "坐标定位",
mouseLocation: "鼠标定位", mouseLocation: "鼠标定位",
annotationAggregation: "标注点聚合", annotationAggregation: "标注点聚合",
// 卷帘对比 annotation: '卷帘对比',
// 屏幕截图 screenShot: '屏幕截图',
// 高清出图 highQuality: '高清出图',
// 视频录制 videoRecord: '视频录制',
pressModel: "模型压平", pressModel: "模型压平",
terrainDig: "地形开挖", terrainDig: "地形开挖",
tilesetClipping: "剖切", tilesetClipping: "剖切",
clearTilesetClipping: "清除剖切", clearTilesetClipping: "清除剖切",
projConvert: '度分秒', projConvert: '度分秒',
projectionConvert: '投影转换', projectionConvert: '投影转换',
gdbImport: "gdb导入" gdbImport: "gdb导入",
circleStatistics: "圆形统计",
polygonStatistics: "多边形统计",
}, },
bottomMenu: { bottomMenu: {
groundText: '贴地文字', groundText: '贴地文字',

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 948 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 818 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 B

View File

@ -1,14 +1,22 @@
<template> <template>
<div class="YJ-custom-base-dialog" :class="className" ref="baseDialog" :id="id" :style="{ <div
class="YJ-custom-base-dialog"
:class="className"
ref="baseDialog"
:id="id"
:style="{
width: width, width: width,
height: height, height: height,
top: top,
left: left,
position: fix ? 'fixed' : 'absolute' position: fix ? 'fixed' : 'absolute'
}" v-if="dialogVisible" v-show="dialogVisible"> }"
<div class="title-box" ref="titleBox"><span class="title">{{ title }}</span><span class="close-box" v-if="dialogVisible"
@click="close"><span class="close"></span><i></i></span></div> v-show="dialogVisible"
<div class="content" style="padding: 0 24px 0 24px;"> >
<div class="title-box" ref="titleBox">
<span class="title">{{ title }}</span
><span class="close-box" @click="close"><span class="close"></span><i></i></span>
</div>
<div class="content" style="padding: 0 24px 0 24px">
<div> <div>
<slot name="content"></slot> <slot name="content"></slot>
</div> </div>
@ -20,237 +28,233 @@
</template> </template>
<script setup> <script setup>
import { ref, watch, onMounted, nextTick } from 'vue'; import { ref, watch, onMounted, nextTick } from 'vue'
const props = defineProps({ const props = defineProps({
title: { title: {
type: String, type: String,
default: "", default: ''
}, },
width: { width: {
type: String, type: String,
default: "", default: ''
}, },
height: { height: {
type: String, type: String,
default: "", default: ''
}, },
top: { top: {
type: String, type: String,
default: "", default: ''
}, },
left: { left: {
type: String, type: String,
default: "", default: ''
}, },
id: { id: {
type: String, type: String,
default: "", default: ''
}, },
bodyId: { bodyId: {
type: String, type: String,
default: "", default: ''
}, },
clearAnimation: { clearAnimation: {
type: Boolean, type: Boolean,
default: false, default: false
}, },
fix: { fix: {
type: Boolean, type: Boolean,
default: false, default: false
}, },
className: { className: {
type: String, type: String
}, },
nofold: { nofold: {
type: Boolean, type: Boolean,
default: false, default: false
}, },
isfold: { isfold: {
type: Boolean, type: Boolean,
default: false, default: false
}, },
noClose: { noClose: {
type: Boolean, type: Boolean,
default: false, default: false
}, },
show: { show: {
type: Boolean, type: Boolean,
default: false, default: false
}, },
closeCallback: { closeCallback: {
type: Function, type: Function,
default: () => { }, default: () => {}
} }
}); })
// 内部状态 // 内部状态
const first = ref(false); const first = ref(false)
const dialogVisible = ref(false); const dialogVisible = ref(false)
const FontChart = ref(undefined); const FontChart = ref(undefined)
const callback = ref(undefined); const callback = ref(undefined)
const baseDialog = ref(null); const baseDialog = ref(null)
const titleBox = ref(null); const titleBox = ref(null)
const dialogContent = ref(null); const dialogContent = ref(null)
const tableData = ref([]); const tableData = ref([])
// 监听show属性变化 // 监听show属性变化
watch( watch(
() => props.show, () => props.show,
(val) => { (val) => {
dialogVisible.value = val; dialogVisible.value = val
}, },
{ immediate: true } { immediate: true }
); )
// 组件挂载后执行 // 组件挂载后执行
onMounted(() => { onMounted(() => {
// 可以在这里添加初始化逻辑 // 可以在这里添加初始化逻辑
}); })
// 方法定义 // 方法定义
const open = (data) => { const open = (data) => {
if (!first.value) { if (!first.value) {
first.value = true; first.value = true
dialogVisible.value = true; dialogVisible.value = true
nextTick(() => { nextTick(() => {
moveDiv(); moveDiv()
}); })
} }
dialogVisible.value = true; dialogVisible.value = true
nextTick(() => { nextTick(() => {
setTimeout(() => { setTimeout(() => {
openPosition(); openPosition()
}, 0); }, 0)
}); })
}; }
const close = () => { const close = () => {
dialogVisible.value = false; dialogVisible.value = false
if (props.clearAnimation) { if (props.clearAnimation) {
// 假设mapService是全局可用的 // 假设mapService是全局可用的
window.mapService?.removeAnimation(); window.mapService?.removeAnimation()
} }
callback.value && callback.value(); callback.value && callback.value()
props.closeCallback && props.closeCallback() props.closeCallback && props.closeCallback()
}; }
const moveDiv = () => { const moveDiv = () => {
let x = 0; let x = 0
let y = 0; let y = 0
let l = 0; let l = 0
let t = 0; let t = 0
const oClickDiv = baseDialog.value; const oClickDiv = baseDialog.value
const oMoveDiv = titleBox.value; const oMoveDiv = titleBox.value
if (oClickDiv) { if (oClickDiv) {
console.log(oMoveDiv) console.log(oMoveDiv)
oMoveDiv.onmousedown = (e) => { oMoveDiv.onmousedown = (e) => {
// 获取对话框尺寸 // 获取对话框尺寸
const oMoveDivHeight = baseDialog.value.offsetHeight; const oMoveDivHeight = baseDialog.value.offsetHeight
const oMoveDivWidth = baseDialog.value.offsetWidth; const oMoveDivWidth = baseDialog.value.offsetWidth
x = e.clientX; x = e.clientX
y = e.clientY; y = e.clientY
const leftPx = window.getComputedStyle(baseDialog.value).left; const leftPx = window.getComputedStyle(baseDialog.value).left
const topPx = window.getComputedStyle(baseDialog.value).top; const topPx = window.getComputedStyle(baseDialog.value).top
l = parseFloat(leftPx); l = parseFloat(leftPx)
t = parseFloat(topPx); t = parseFloat(topPx)
// 获取视口大小 // 获取视口大小
const container = props.bodyId const container = props.bodyId ? document.getElementById(props.bodyId) : document.body
? document.getElementById(props.bodyId) const windowHeight = container.clientHeight
: document.body; const windowWidth = container.clientWidth
const windowHeight = container.clientHeight;
const windowWidth = container.clientWidth;
// 鼠标移动事件处理 // 鼠标移动事件处理
const handleMouseMove = (e) => { const handleMouseMove = (e) => {
e.preventDefault(); e.preventDefault()
const nx = e.clientX; const nx = e.clientX
const ny = e.clientY; const ny = e.clientY
// 计算新位置 // 计算新位置
let newLeft = nx - (x - l); let newLeft = nx - (x - l)
let newTop = ny - (y - t); let newTop = ny - (y - t)
// 边界检查 // 边界检查
if (newLeft < 0) { if (newLeft < 0) {
newLeft = 0; newLeft = 0
} else if (newLeft + oMoveDivWidth > windowWidth) { } else if (newLeft + oMoveDivWidth > windowWidth) {
newLeft = windowWidth - oMoveDivWidth; newLeft = windowWidth - oMoveDivWidth
} }
if (newTop <= 0) { if (newTop <= 0) {
newTop = 0; newTop = 0
} else if (newTop + oMoveDivHeight > windowHeight) { } else if (newTop + oMoveDivHeight > windowHeight) {
newTop = windowHeight - oMoveDivHeight; newTop = windowHeight - oMoveDivHeight
} }
// 更新位置 // 更新位置
if (baseDialog.value) { if (baseDialog.value) {
baseDialog.value.style.left = newLeft + "px"; baseDialog.value.style.left = newLeft + 'px'
baseDialog.value.style.top = newTop + "px"; baseDialog.value.style.top = newTop + 'px'
baseDialog.value.style.bottom = "unset"; baseDialog.value.style.bottom = 'unset'
baseDialog.value.style.right = "unset"; baseDialog.value.style.right = 'unset'
} }
}; }
// 鼠标抬起事件处理 // 鼠标抬起事件处理
const handleMouseUp = () => { const handleMouseUp = () => {
window.removeEventListener('mousemove', handleMouseMove); window.removeEventListener('mousemove', handleMouseMove)
window.removeEventListener('mouseup', handleMouseUp); window.removeEventListener('mouseup', handleMouseUp)
}; }
// 添加事件监听 // 添加事件监听
window.addEventListener('mousemove', handleMouseMove); window.addEventListener('mousemove', handleMouseMove)
window.addEventListener('mouseup', handleMouseUp); window.addEventListener('mouseup', handleMouseUp)
}; }
} }
}; }
const openPosition = () => { const openPosition = () => {
const oMoveDiv = baseDialog.value; const oMoveDiv = baseDialog.value
if (!oMoveDiv) return; if (!oMoveDiv) return
// 获取对话框尺寸 // 获取对话框尺寸
const oMoveDivHeight = oMoveDiv.offsetHeight; const oMoveDivHeight = oMoveDiv.offsetHeight
const oMoveDivWidth = oMoveDiv.offsetWidth; const oMoveDivWidth = oMoveDiv.offsetWidth
// 获取当前位置 // 获取当前位置
const leftPx = parseFloat(window.getComputedStyle(oMoveDiv).left); const leftPx = parseFloat(window.getComputedStyle(oMoveDiv).left)
const topPx = parseFloat(window.getComputedStyle(oMoveDiv).top); const topPx = parseFloat(window.getComputedStyle(oMoveDiv).top)
// 获取视口大小 // 获取视口大小
const container = props.bodyId const container = props.bodyId ? document.getElementById(props.bodyId) : document.body
? document.getElementById(props.bodyId) const windowHeight = container.clientHeight
: document.body; const windowWidth = container.clientWidth
const windowHeight = container.clientHeight;
const windowWidth = container.clientWidth;
// 边界检查 // 边界检查
let newLeft = leftPx; let newLeft = leftPx
let newTop = topPx; let newTop = topPx
if (newLeft < 0) { if (newLeft < 0) {
newLeft = 0; newLeft = 0
} else if (newLeft + oMoveDivWidth > windowWidth) { } else if (newLeft + oMoveDivWidth > windowWidth) {
newLeft = windowWidth - oMoveDivWidth; newLeft = windowWidth - oMoveDivWidth
} }
if (newTop - 10 <= 0) { if (newTop - 10 <= 0) {
newTop = -10; newTop = -10
} else if (newTop + oMoveDivHeight > windowHeight) { } else if (newTop + oMoveDivHeight > windowHeight) {
newTop = windowHeight - oMoveDivHeight; newTop = windowHeight - oMoveDivHeight
} }
// 更新位置 // 更新位置
oMoveDiv.style.left = newLeft + "px"; oMoveDiv.style.left = newLeft + 'px'
oMoveDiv.style.top = newTop + "px"; oMoveDiv.style.top = newTop + 'px'
}; }
// 暴露公共方法 // 暴露公共方法
defineExpose({ defineExpose({
@ -258,7 +262,7 @@ defineExpose({
close, close,
moveDiv, moveDiv,
openPosition openPosition
}); })
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -272,14 +276,15 @@ defineExpose({
.el-tabs__item:nth-child(2) { .el-tabs__item:nth-child(2) {
padding-left: 0; padding-left: 0;
} }
.el-tabs__item.is-active, .el-tabs__item:hover { .el-tabs__item.is-active,
.el-tabs__item:hover {
color: #fff; color: #fff;
} }
.el-tabs__active-bar { .el-tabs__active-bar {
background-color: rgb(0, 255, 255); background-color: rgb(0, 255, 255);
} }
.el-tabs__nav-wrap:after { .el-tabs__nav-wrap:after {
background-color: rgba(204, 204, 204, 0.2) background-color: rgba(204, 204, 204, 0.2);
} }
} }
} }

View File

@ -67,7 +67,7 @@ const submitForm = async (formEl: FormInstance | undefined) => {
const add = throttle(async () => { const add = throttle(async () => {
let parentId = getKeyOfSelectedNode(window.treeObj, 'id') let parentId = getKeyOfSelectedNode(window.treeObj, 'id')
let fnone = getSelectedNode(window.treeObj) let fnone = getSelectedNode(window.treeObj)
const res:any = await TreeApi.addDirectory({ const res: any = await TreeApi.addDirectory({
id: new YJ.Tools().randomString(), id: new YJ.Tools().randomString(),
sourceName: form.sourceName, sourceName: form.sourceName,
parentId parentId

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="9.85693359375" height="12" viewBox="0 0 9.85693359375 12" fill="none">
<path d="M4.92857 12C1.6194 9.59999 0 7.27058 0 4.94117C0 2.18823 2.18266 0 4.92857 0C7.67449 0 9.85714 2.18823 9.85714 4.94117C9.85714 7.27058 8.23775 9.59999 4.92857 12ZM4.92857 10.0235C7.25204 8.25883 8.44897 6.56471 8.44897 4.94117C8.44897 2.96471 6.9 1.41176 4.92857 1.41176C2.95714 1.41176 1.40817 2.96471 1.40817 4.94117C1.40817 6.56471 2.6051 8.25883 4.92857 10.0235ZM4.92857 7.05882C3.73164 7.05882 2.81633 6.14118 2.81633 4.94117C2.81633 3.74117 3.73164 2.82352 4.92857 2.82352C6.1255 2.82352 7.04081 3.74117 7.04081 4.94117C7.04081 6.14118 6.1255 7.05882 4.92857 7.05882ZM4.92857 5.64706C5.35102 5.64706 5.63266 5.3647 5.63266 4.94117C5.63266 4.51764 5.35102 4.2353 4.92857 4.2353C4.50612 4.2353 4.22449 4.51764 4.22449 4.94117C4.22449 5.3647 4.50612 5.64706 4.92857 5.64706Z" fill="#FFFFFF" >
</path>
</svg>

After

Width:  |  Height:  |  Size: 983 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="19.36865234375" height="20.00006103515625" viewBox="0 0 19.36865234375 20.00006103515625" fill="none">
<path d="M11.576 11.2284L11.576 20.0001L14.6489 16.2511L19.3684 15.6138L11.576 11.2284ZM12.1851 1.9763C9.39733 -0.658764 4.87883 -0.658764 2.09052 1.9763C-0.696842 4.61179 -0.696842 8.88484 2.09052 11.5203L7.13785 18.0964L10.4587 13.769L10.4587 9.33545L12.923 10.6664C14.9237 8.03041 14.6917 4.3466 12.1851 1.9763ZM7.15898 8.58755C5.46872 8.58755 4.09827 7.30834 4.09827 5.72963C4.09827 4.15137 5.46872 2.87173 7.15898 2.87173C8.84876 2.87173 10.2183 4.15137 10.2183 5.72963C10.2183 7.30834 8.84876 8.58755 7.15898 8.58755Z" fill="#00FFFF" >
</path>
</svg>

After

Width:  |  Height:  |  Size: 752 B

View File

@ -0,0 +1,63 @@
import { ipcRenderer, remote } from "electron";
import Vue from "vue";
import { Loading } from "element-ui";
let bus = new Vue();
// let bus = window.$root_home;
let $sendChanel = (chanel, arg = {}) => {
// let bus = new Vue();
bus.$emit(chanel, arg);
};
let $recvChanel = (chanel, cb) => {
bus.$on(chanel, cb);
};
let $offChanel = (chanel, cb) => {
bus.$off(chanel);
};
let $removeChanel = (chanel) => {
bus.$off(chanel);
};
let $sendElectronChanel = (chanel, arg = null) => {
ipcRenderer.send(chanel, arg);
};
let $removeElectronChanel = (chanel, cb) => {
ipcRenderer.removeListener(chanel, cb);
};
let $recvElectronChanel = (chanel, cb) => {
ipcRenderer.once(chanel, cb);
};
let $changeComponentShow = (selector, state, styleStr = false) => {
$(selector).css({ display: state ? "block" : "none" });
if (styleStr) {
console.log(123);
let str = styleStr.split(":");
if (str[0] === "top") $(selector).css({ top: str[1] });
if (str[0] === "z-index") $(selector).css({ zIndex: str[1] });
}
};
let openLoading = (
text = "拼命加载中...",
option = {
fullscreen: true,
background: "rgba(0,0,0,0.63)",
lock: true,
// spinner: 'el-icon-loading'
}
) => {
option.text = text;
let loadingInstance = Loading.service(option);
return loadingInstance;
};
let $remote = remote;
export {
openLoading,
$sendElectronChanel,
$removeElectronChanel,
$recvElectronChanel,
$sendChanel,
$recvChanel,
$offChanel,
$removeChanel,
$changeComponentShow,
$remote,
};

View File

@ -1,8 +1,13 @@
<template> <template>
<div class="bottomMenuBox zIndex9"> <div class="bottomMenuBox zIndex9">
<div class="animate__animated bottomMenu"> <div class="animate__animated bottomMenu">
<div class="bottom_box" v-for="(item, i) of bottomMenuList" :key="i" :title="t('bottomMenu.' + item.sourceType)" <div
@click="addMarker(item)"> class="bottom_box"
v-for="(item, i) of bottomMenuList"
:key="i"
:title="t('bottomMenu.' + item.sourceType)"
@click="addMarker(item)"
>
<svg-icon :name="item.sourceType" :size="20" color="rgba(0, 255, 255, 1)"></svg-icon> <svg-icon :name="item.sourceType" :size="20" color="rgba(0, 255, 255, 1)"></svg-icon>
<div class="span"> <div class="span">
{{ t('bottomMenu.' + item.sourceType) }} {{ t('bottomMenu.' + item.sourceType) }}
@ -15,11 +20,11 @@
<script setup lang="ts"> <script setup lang="ts">
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { inject } from "vue"; import { inject } from 'vue'
import { TreeApi } from '@/api/tree' import { TreeApi } from '@/api/tree'
import { initMapData } from '../tree/initMapData' import { initMapData } from '../tree/initMapData'
const { t } = useI18n() const { t } = useI18n()
const eventBus: any = inject("bus"); const eventBus: any = inject('bus')
const i8n = ref({ const i8n = ref({
DrawRect: 'rect', DrawRect: 'rect',
@ -42,7 +47,7 @@ const bottomMenuList = ref([
sourceType: 'groundText', sourceType: 'groundText',
className: 'public', className: 'public',
fun: () => { fun: () => {
eventBus.emit("openDialog", 'addGroundText'); eventBus.emit('openDialog', 'addGroundText')
} }
}, },
{ {
@ -51,7 +56,7 @@ const bottomMenuList = ref([
sourceType: 'standText', sourceType: 'standText',
className: 'public', className: 'public',
fun: () => { fun: () => {
eventBus.emit("openDialog", 'addStandText'); eventBus.emit('openDialog', 'addStandText')
// eventBus.emit("openDialog", 'standText'); // eventBus.emit("openDialog", 'standText');
} }
}, },
@ -71,17 +76,20 @@ const bottomMenuList = ref([
let options: any = await initMapData('point', { let options: any = await initMapData('point', {
id: id, id: id,
name: name, name: name,
position: position, position: position
}) })
let selectedNodes = window.treeObj.getSelectedNodes() let selectedNodes = window.treeObj.getSelectedNodes()
delete options.host delete options.host
let params = { let params = {
"id": id, id: id,
"sourceName": name, sourceName: name,
"sourceType": "point", sourceType: 'point',
"parentId": (selectedNodes && selectedNodes[selectedNodes.length - 1]) ? selectedNodes[selectedNodes.length - 1].id : undefined, parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id
: undefined,
// "treeIndex": 0, // "treeIndex": 0,
"params": options params: options
} }
TreeApi.addOtherSource(params) TreeApi.addOtherSource(params)
}) })
@ -105,16 +113,19 @@ const bottomMenuList = ref([
let options: any = await initMapData('line', { let options: any = await initMapData('line', {
id: id, id: id,
name: name, name: name,
positions: positions, positions: positions
}) })
let selectedNodes = window.treeObj.getSelectedNodes() let selectedNodes = window.treeObj.getSelectedNodes()
let params = { let params = {
"id": id, id: id,
"sourceName": name, sourceName: name,
"sourceType": "line", sourceType: 'line',
"parentId": (selectedNodes && selectedNodes[selectedNodes.length - 1]) ? selectedNodes[selectedNodes.length - 1].id : undefined, parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id
: undefined,
// "treeIndex": 0, // "treeIndex": 0,
"params": options params: options
} }
TreeApi.addOtherSource(params) TreeApi.addOtherSource(params)
}) })
@ -136,17 +147,19 @@ const bottomMenuList = ref([
let options: any = await initMapData('curve', { let options: any = await initMapData('curve', {
id: id, id: id,
name: name, name: name,
positions: positions, positions: positions
}) })
let selectedNodes = window.treeObj.getSelectedNodes() let selectedNodes = window.treeObj.getSelectedNodes()
let params = { let params = {
"id": id, id: id,
"sourceName": name, sourceName: name,
"sourceType": "curve", sourceType: 'curve',
"parentId": (selectedNodes && selectedNodes[selectedNodes.length - 1]) ? selectedNodes[selectedNodes.length - 1].id : undefined, parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id
: undefined,
// "treeIndex": 0, // "treeIndex": 0,
"params": options params: options
} }
TreeApi.addOtherSource(params) TreeApi.addOtherSource(params)
}) })
@ -173,17 +186,20 @@ const bottomMenuList = ref([
let options: any = await initMapData('panel', { let options: any = await initMapData('panel', {
id: id, id: id,
name: name, name: name,
positions: positions, positions: positions
}) })
let selectedNodes = window.treeObj.getSelectedNodes() let selectedNodes = window.treeObj.getSelectedNodes()
let params = { let params = {
"id": id, id: id,
"sourceName": name, sourceName: name,
"sourceType": "panel", sourceType: 'panel',
"parentId": (selectedNodes && selectedNodes[selectedNodes.length - 1]) ? selectedNodes[selectedNodes.length - 1].id : undefined, parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id
: undefined,
// "treeIndex": 0, // "treeIndex": 0,
"params": options params: options
} }
console.log(params) console.log(params)
// eventBus.emit("openDialog", 'panel'); // eventBus.emit("openDialog", 'panel');
@ -195,7 +211,7 @@ const bottomMenuList = ref([
sourceName: '圆标注', sourceName: '圆标注',
key: 'DrawCircle', key: 'DrawCircle',
sourceType: 'circle', sourceType: 'circle',
className: 'public', className: 'public'
}, },
{ {
sourceName: '矩形', sourceName: '矩形',
@ -218,17 +234,20 @@ const bottomMenuList = ref([
let options: any = await initMapData('panel', { let options: any = await initMapData('panel', {
id: id, id: id,
name: name, name: name,
positions: positions, positions: positions
}) })
let selectedNodes = window.treeObj.getSelectedNodes() let selectedNodes = window.treeObj.getSelectedNodes()
let params = { let params = {
"id": id, id: id,
"sourceName": name, sourceName: name,
"sourceType": "rectangle", sourceType: 'rectangle',
"parentId": (selectedNodes && selectedNodes[selectedNodes.length - 1]) ? selectedNodes[selectedNodes.length - 1].id : undefined, parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id
: undefined,
// "treeIndex": 0, // "treeIndex": 0,
"params": options params: options
} }
console.log(params) console.log(params)
// eventBus.emit("openDialog", 'panel'); // eventBus.emit("openDialog", 'panel');
@ -257,19 +276,22 @@ const bottomMenuList = ref([
let options: any = await initMapData('rendezvous', { let options: any = await initMapData('rendezvous', {
id: id, id: id,
name: name, name: name,
positions: positions, positions: positions
}) })
delete options.label.ground delete options.label.ground
delete options.label.position delete options.label.position
let selectedNodes = window.treeObj.getSelectedNodes() let selectedNodes = window.treeObj.getSelectedNodes()
let params = { let params = {
"id": id, id: id,
"sourceName": name, sourceName: name,
"sourceType": "rendezvous", sourceType: 'rendezvous',
"parentId": (selectedNodes && selectedNodes[selectedNodes.length - 1]) ? selectedNodes[selectedNodes.length - 1].id : undefined, parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id
: undefined,
// "treeIndex": 0, // "treeIndex": 0,
"params": options params: options
} }
console.log(params) console.log(params)
// eventBus.emit("openDialog", 'panel'); // eventBus.emit("openDialog", 'panel');
@ -298,19 +320,22 @@ const bottomMenuList = ref([
let options: any = await initMapData('attackArrow', { let options: any = await initMapData('attackArrow', {
id: id, id: id,
name: name, name: name,
positions: positions, positions: positions
}) })
delete options.label.ground delete options.label.ground
delete options.label.position delete options.label.position
let selectedNodes = window.treeObj.getSelectedNodes() let selectedNodes = window.treeObj.getSelectedNodes()
let params = { let params = {
"id": id, id: id,
"sourceName": name, sourceName: name,
"sourceType": "attackArrow", sourceType: 'attackArrow',
"parentId": (selectedNodes && selectedNodes[selectedNodes.length - 1]) ? selectedNodes[selectedNodes.length - 1].id : undefined, parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id
: undefined,
// "treeIndex": 0, // "treeIndex": 0,
"params": options params: options
} }
console.log(params) console.log(params)
// eventBus.emit("openDialog", 'panel'); // eventBus.emit("openDialog", 'panel');
@ -340,19 +365,22 @@ const bottomMenuList = ref([
let options: any = await initMapData('pincerArrow', { let options: any = await initMapData('pincerArrow', {
id: id, id: id,
name: name, name: name,
positions: positions, positions: positions
}) })
delete options.label.ground delete options.label.ground
delete options.label.position delete options.label.position
let selectedNodes = window.treeObj.getSelectedNodes() let selectedNodes = window.treeObj.getSelectedNodes()
let params = { let params = {
"id": id, id: id,
"sourceName": name, sourceName: name,
"sourceType": "pincerArrow", sourceType: 'pincerArrow',
"parentId": (selectedNodes && selectedNodes[selectedNodes.length - 1]) ? selectedNodes[selectedNodes.length - 1].id : undefined, parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id
: undefined,
// "treeIndex": 0, // "treeIndex": 0,
"params": options params: options
} }
// eventBus.emit("openDialog", 'panel'); // eventBus.emit("openDialog", 'panel');
TreeApi.addOtherSource(params) TreeApi.addOtherSource(params)
@ -457,7 +485,7 @@ const addMarker = (item: any) => {
transform: scale(0.8); transform: scale(0.8);
} }
>.span { > .span {
color: #fff; color: #fff;
font-family: 黑体; font-family: 黑体;
font-size: 1rem; font-size: 1rem;

View File

@ -2,19 +2,30 @@
<div class="leftBox"> <div class="leftBox">
<div class="left animate__animated"> <div class="left animate__animated">
<div class="menus"> <div class="menus">
<div class="menus_itemBox" v-for="(item, index) in menuList" :title="t(`firstMenu.${item.name}`)"> <div
<div class="item_icon" @click="(e) => { handleClick(item, e) }"> class="menus_itemBox"
v-for="(item, index) in menuList"
:title="t(`firstMenu.${item.name}`)"
>
<div
class="item_icon"
@click="
(e) => {
handleClick(item, e)
}
"
>
<!-- <svg-icon :class-name="['absolute', 'zIndex-1', 'left_item_bg']" icon-class="bg2"></svg-icon> --> <!-- <svg-icon :class-name="['absolute', 'zIndex-1', 'left_item_bg']" icon-class="bg2"></svg-icon> -->
<svg-icon :name="item.svg" :size="16" color="rgba(0, 255, 255, 1)"></svg-icon> <svg-icon :name="item.svg" :size="16" color="rgba(0, 255, 255, 1)"></svg-icon>
<div class="item_text"> <div class="item_text">
{{ t(`firstMenu.${item.name}`) }} {{ t(`firstMenu.${item.name}`) }}
</div> </div>
</div> </div>
</div> </div>
<leftSideSecond class="absolute zIndex99 leftSideSecond" ref="leftSideSecondRef"></leftSideSecond> <leftSideSecond
class="absolute zIndex99 leftSideSecond"
ref="leftSideSecondRef"
></leftSideSecond>
</div> </div>
</div> </div>
<div class="left_bottom" @click="fold"></div> <div class="left_bottom" @click="fold"></div>
@ -28,6 +39,7 @@ import { bus } from '@/utils/bus'
import leftSideSecond from '@/views/components/leftSide/leftSideSecond.vue' import leftSideSecond from '@/views/components/leftSide/leftSideSecond.vue'
const { t } = useI18n() const { t } = useI18n()
const eventBus = inject('bus')
const menuList = ref([ const menuList = ref([
// 方案推演 // 方案推演
{ {
@ -52,20 +64,20 @@ const menuList = ref([
// fun: this.showSecondMenu, // fun: this.showSecondMenu,
key: 'effect', key: 'effect',
children: [ children: [
"trajectoryMotion", 'trajectoryMotion',
"electronicFence", 'electronicFence',
// "nightVision", // "nightVision",
"radarLightWave", 'radarLightWave',
"diffusedLightWave", 'diffusedLightWave',
"scanStereoscopic", 'scanStereoscopic',
"multilateralBody", 'multilateralBody',
"waterSurface", 'waterSurface',
"fountain", 'fountain',
"waterL", 'waterL',
"fire", 'fire',
"explosion", 'explosion',
"smoke", 'smoke',
"nightVision", 'nightVision'
// "nightVision", // "nightVision",
] ]
}, },
@ -76,16 +88,16 @@ const menuList = ref([
// fun: this.showSecondMenu, // fun: this.showSecondMenu,
key: 'analysis', key: 'analysis',
children: [ children: [
"inundationAnalysis", 'inundationAnalysis',
"profileAnalysis", 'profileAnalysis',
"sightAnalysis", 'sightAnalysis',
"kenAnalysis", 'kenAnalysis',
"circleKen", 'circleKen',
"slopeDirection", 'slopeDirection',
"cutFill", 'cutFill',
"contour", 'contour',
"globalContour", 'globalContour',
"clear", 'clear'
] ]
}, },
// 测量 // 测量
@ -95,17 +107,17 @@ const menuList = ref([
// fun: this.showSecondMenu, // fun: this.showSecondMenu,
key: 'measure', key: 'measure',
children: [ children: [
"projectionArea", 'projectionArea',
"projectionDistanceMeasure", 'projectionDistanceMeasure',
"areaMeasure", 'areaMeasure',
"distanceMeasure", 'distanceMeasure',
"heightMeasure", 'heightMeasure',
"triangleMeasure", 'triangleMeasure',
"MeasureAzimuth", 'MeasureAzimuth',
"MeasureAngle", 'MeasureAngle',
"lopeDistanceMeasures", 'lopeDistanceMeasures',
"coorMeasure", 'coorMeasure',
"clear", 'clear'
] ]
}, },
@ -116,26 +128,28 @@ const menuList = ref([
// fun: this.showSecondMenu, // fun: this.showSecondMenu,
key: 'tool', key: 'tool',
children: [ children: [
"routePlan", // 'routePlan',
//清除轨迹 // 'clearRoute',
"graffiti", // 'graffiti',
// stopGraffiti: "结束涂鸦", // // stopGraffiti: "结束涂鸦",
"clearGraffiti", // 'clearGraffiti',
"path", // 'path',
"coorLocation", // 'coorLocation',
"mouseLocation", // 'mouseLocation',
"annotationAggregation", // 'annotationAggregation',
// 卷帘对比 // 'annotation',
// 屏幕截图 // 'screenShot',
// 高清出图 // 'highQuality',
// 视频录制 // 'videoRecord',
"pressModel", // 'pressModel',
"terrainDig", // 'terrainDig',
"tilesetClipping", // 'tilesetClipping',
"clearTilesetClipping", // 'clearTilesetClipping',
"projConvert", // 'projConvert',
"projectionConvert", // 'projectionConvert',
"gdbImport", // 'gdbImport',
// 'circleStatistics',
// 'polygonStatistics'
] ]
}, },
{ {
@ -170,12 +184,12 @@ onMounted(() => {
}) })
const leftSideSecondRef = ref() const leftSideSecondRef = ref()
const handleClick = (item: any, e) => { const handleClick = (item: any, e) => {
console.log("点击了", item, e); console.log('点击了', item, e)
$(".leftSideSecond")[0].style.left = "100%"; $('.leftSideSecond')[0].style.left = '100%'
$(".leftSideSecond")[0].style.top = e.layerY - 120 + "px" $('.leftSideSecond')[0].style.top = e.layerY - 120 + 'px'
$(".leftSideSecond")[0].style.display = "none" $('.leftSideSecond')[0].style.display = 'none'
if (item.children.length) { if (item.children.length) {
$(".leftSideSecond")[0].style.display = "block" $('.leftSideSecond')[0].style.display = 'block'
leftSideSecondRef.value.initList(item) leftSideSecondRef.value.initList(item)
} }
} }
@ -228,6 +242,24 @@ const fold = () => {
(itemCount - 1) * itemDelay + itemDuration (itemCount - 1) * itemDelay + itemDuration
) )
} }
const clickMenu = (item: any) => {
console.log(item, 'item')
switch (item.key) {
case 'analysis':
console.log('analysis')
// eventBus.emit('analysisDialog')
eventBus.emit('circleViewShedDialog') //添加高程后测试
// eventBus.emit('submergeDialog')
// eventBus.emit('profileDialog')
// eventBus.emit('viewShedDialog')
// eventBus.emit('cutFillDialog')
// eventBus.emit('contourDialog')
break
default:
break
}
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@ -321,10 +353,6 @@ const fold = () => {
padding-left: 0.5rem; padding-left: 0.5rem;
} }
} }
} }
} }

View File

@ -1,19 +1,24 @@
<template> <template>
<div class="leftSideSecond"> <div class="leftSideSecond">
<div class="leftSideSecondBox"> <div class="leftSideSecondBox">
<template v-if="obj">
<template v-if="obj"> <div class="menuItem" v-for="value in obj.children" @click="handleClick(value)">
<div class="menuItem" v-for="value in obj.children" @click="handleClick(value)"> <img
<img :src="'src/assets/images/second/' + `${value}` + '.png'" alt=""> :src="'src/assets/images/second/' + `${value}` + '.png'"
<span>{{ t(`${obj.key}.${value}`) }}</span> style="color: rgb(255, 0, 0)"
</div> alt=""
</template> />
<span :style="{ color: !clickChange[value] ? 'var(--color-text)' : 'rgb(255,0,0)' }">{{
t(`${obj.key}.${value}`)
}}</span>
</div> </div>
</template>
</div> </div>
</div>
</template> </template>
<script setup> <script setup>
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { ref, reactive, getCurrentInstance } from "vue" import { ref, reactive, getCurrentInstance } from 'vue'
import { useTreeNode } from '../tree/hooks/treeNode' import { useTreeNode } from '../tree/hooks/treeNode'
import { TreeApi } from '@/api/tree' import { TreeApi } from '@/api/tree'
import { renderMethods } from '../tree/hooks/renderTreeNode' import { renderMethods } from '../tree/hooks/renderTreeNode'
@ -21,142 +26,273 @@ const { proxy } = getCurrentInstance()
const { t } = useI18n() const { t } = useI18n()
const { findParentId, findTreeIndex } = useTreeNode() const { findParentId, findTreeIndex } = useTreeNode()
const obj = ref(null) const obj = ref(null)
const isclick = ref(false)
const eventBus = inject('bus')
const initList = (value) => { const initList = (value) => {
obj.value = value obj.value = value
} }
var clickChange = reactive({
mouseLocation: false,
annotation: false,
annotationAggregation: false,
videoRecord: false
})
var graffitiObjArr = reactive([])
eventBus.on('graffitiObj', (data) => {
graffitiObjArr.push(data)
})
const methodMap = { const methodMap = {
// 电子围墙 // 电子围墙
electronicFence: () => { electronicFence: () => {
let draw = new YJ.Draw.DrawPolyline(window.earth); let draw = new YJ.Draw.DrawPolyline(window.earth)
draw.start((err, positions) => { draw.start((err, positions) => {
if (positions.length > 1) { if (positions.length > 1) {
let alt = positions[0].alt; let alt = positions[0].alt
positions.forEach((item) => { positions.forEach((item) => {
if (item.alt < alt) alt = item.alt; if (item.alt < alt) alt = item.alt
});
let id = proxy.$md5(new Date().getTime() + "围墙");
let params = {
sourceName: "电子围墙",
id,
sourceType: "wallStereoscopic",
parentId: findParentId(window.treeObj),
params: {
id,
positions,
color: "#fff",
cornerType: undefined,
extrudedHeight: 2.4,
width: 0.24,
},
treeIndex: findTreeIndex(window.treeObj)
}
// console.log(params);
// 渲染电子围墙
renderMethods.renderWallStereoscopic(params)
// 存入数据库
let res = TreeApi.addOtherSource(params)
console.log("addOtherSource", res);
// 上树
cusAddNodes(window.treeObj, params.parentId, [params])
}
}) })
let id = proxy.$md5(new Date().getTime() + '围墙')
let params = {
sourceName: '电子围墙',
id,
sourceType: 'wallStereoscopic',
parentId: findParentId(window.treeObj),
params: {
id,
positions,
color: '#fff',
cornerType: undefined,
extrudedHeight: 2.4,
width: 0.24
},
treeIndex: findTreeIndex(window.treeObj)
}
// console.log(params);
// 渲染电子围墙
renderMethods.renderWallStereoscopic(params)
// 存入数据库
let res = TreeApi.addOtherSource(params)
console.log('addOtherSource', res)
// 上树
cusAddNodes(window.treeObj, params.parentId, [params])
}
})
},
// 扩散光波
radarLightWave: () => {
let draw = new YJ.Draw.DrawCircle(window.earth)
draw.start((err, params) => {
console.log(params)
if (params) {
}
})
},
//投影面积
projectionArea: () => {
new YJ.Measure.MeasureTyArea(window.earth).start()
},
//投影距离测量
projectionDistanceMeasure: () => {
new YJ.Measure.MeasureProjectionDistance(window.earth).start()
},
areaMeasure: () => {
new YJ.Measure.MeasureTdArea(window.earth).start()
},
//距离测量
distanceMeasure: () => {
new YJ.Measure.MeasureDistance(window.earth).start()
},
//高度测量
heightMeasure: () => {
new YJ.Measure.MeasureHeight(window.earth).start()
},
//三角测量
triangleMeasure: () => {
new YJ.Measure.MeasureTriangle(window.earth).start()
},
// 方位角
MeasureAzimuth() {
new YJ.Measure.MeasureAzimuth(window.earth).start()
},
//夹角测量
MeasureAngle() {
new YJ.Measure.MeasureAngle(window.earth).start()
},
// 坡度测量
lopeDistanceMeasures() {
new YJ.Measure.MeasureSlopeDistance(window.earth).start()
},
//坐标测量
coorMeasure() {
new YJ.Measure.MeasureLocation(window.earth).start()
},
//清除测量
clear() {
YJ.Measure.Clear()
},
//淹没分析
inundationAnalysis() {
eventBus.emit('submergeDialog')
},
//剖面分析
profileAnalysis() {
eventBus.emit('profileDialog')
},
// 视线分析
sightAnalysis() {
eventBus.emit('analysisDialog')
},
//视域分析
kenAnalysis() {
eventBus.emit('viewShedDialog')
},
//圆形视域分析
circleKen() {
eventBus.emit('circleViewShedDialog')
},
//坡向分析
slopeDirection() {
new YJ.Analysis.SlopeAspect(window.earth)
},
// 填挖方分析
cutFill() {
eventBus.emit('cutFillDialog')
},
//全局等高线分析
globalContour() {
eventBus.emit('contourDialog')
},
//等高线分析
contour() {
let Draw = new YJ.Draw.DrawRect(window.earth)
Draw.start((a, positions) => {
// 等高线
new YJ.Analysis.Contour(window.earth, { positions: positions })
// YJ.Analysis.Clear();
})
},
//分析清除
clear() {
YJ.Analysis.Clear()
},
//----------------工具------------------
//路径规划
routePlan() {
eventBus.emit('routePlanningDialog')
},
//路径清除
clearRoute() {},
//涂鸦
graffiti() {
eventBus.emit('graffitiDialog')
},
//涂鸦清除
clearGraffiti() {
graffitiObjArr.forEach((item) => {
item.remove()
})
},
//路径
path() {
eventBus.emit('flyRoamDialog')
},
//坐标定位
coorLocation() {
eventBus.emit('coorLocationDialog')
},
//鼠标定位
mouseLocation() {
clickChange.mouseLocation = !clickChange.mouseLocation
new YJ.Global.MouseCoordinate(window.earth, clickChange.mouseLocation)
},
//聚合标注
annotationAggregation() {
clickChange.annotationAggregation = !clickChange.annotationAggregation
}, YJ.Global.switchCluster(window.earth, clickChange.annotationAggregation)
// 扩散光波 },
radarLightWave: () => { //卷帘对比
let draw = new YJ.Draw.DrawCircle(window.earth); annotation() {
draw.start((err, params) => { clickChange.annotation = !clickChange.annotation
console.log(params); // if (clickChange.annotation) {
if (params) { // YJ.Global.splitScreen.on(window.earth)
// } else {
} // YJ.Global.splitScreen.off()
}) // }
}, },
//投影面积 //屏幕截图
projectionArea: () => { screenShot() {},
new YJ.Measure.MeasureTyArea(window.earth).start(); //高清出图
}, highQuality() {
//投影距离测量 // eventBus.emit('screenShotDialog')
projectionDistanceMeasure: () => { YJ.Global.ScreenShotHD(window.earth)
new YJ.Measure.MeasureProjectionDistance(window.earth).start(); },
}, //视频录制
areaMeasure: () => { videoRecord() {
new YJ.Measure.MeasureTdArea(window.earth).start(); clickChange.videoRecord = !clickChange.videoRecord
}, },
//距离测量 //压模
distanceMeasure: () => { pressModel() {},
new YJ.Measure.MeasureDistance(window.earth).start(); //地形开挖
}, terrainDig() {
//高度测量 eventBus.emit('terrainExcavationDialog')
heightMeasure: () => { },
new YJ.Measure.MeasureHeight(window.earth).start(); //剖切
}, tilesetClipping() {},
//三角测量 //删除剖切
triangleMeasure: () => { clearTilesetClipping() {},
new YJ.Measure.MeasureTriangle(window.earth).start(); //度分秒
}, projConvert() {},
// 方位角 //投影转换
MeasureAzimuth() { projectionConvert() {},
new YJ.Measure.MeasureAzimuth(window.earth).start(); //GDB导入
}, gdbImport() {},
//夹角测量 //圆形统计
MeasureAngle() { circleStatistics() {},
new YJ.Measure.MeasureAngle(window.earth).start(); //多边形统计
}, polygonStatistics() {}
// 坡度测量
lopeDistanceMeasures() {
new YJ.Measure.MeasureSlopeDistance(window.earth).start();
},
//坐标测量
coorMeasure() {
new YJ.Measure.MeasureLocation(window.earth).start();
},
//清除测量
clear() {
YJ.Measure.Clear();
},
} }
const handleClick = (value = 'projectionDistanceMeasure') => { const handleClick = (value = 'projectionDistanceMeasure') => {
methodMap[value]() console.log('点击了', value)
methodMap[value]()
} }
defineExpose({ defineExpose({
initList initList
}) })
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.leftSideSecond { .leftSideSecond {
display: none; display: none;
height: 365px; height: 365px;
width: 275px; width: 275px;
background: url("@/assets/images/secondBj.png") no-repeat; background: url('@/assets/images/secondBj.png') no-repeat;
background-size: 100% 100%; background-size: 100% 100%;
padding: 13px 4px 13px 11px; padding: 13px 4px 13px 11px;
.leftSideSecondBox { .leftSideSecondBox {
border: 1px solid red; border: 1px solid red;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
max-height: 100%; max-height: 100%;
overflow-y: auto; overflow-y: auto;
.menuItem { .menuItem {
width: 25%; width: 25%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
margin: 5px 0; margin: 5px 0;
img { img {
width: 20px; width: 20px;
height: 20px height: 20px;
} }
span { span {
font-size: 12px; font-size: 12px;
} }
}
} }
}
} }
</style> </style>

View File

@ -0,0 +1,123 @@
<template>
<Dialog
ref="baseDialog"
class="circle-view-shed"
title="圆形视域分析"
left="180px"
top="100px"
:closeCallback="closeCallBack"
>
<template #content>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">视点高度</span>
<div class="input-number input-number-unit-1">
<input
id="viewPointHeight"
type="number"
title=""
min="0"
max="999999"
step="0.1"
v-model="viewPointHeight"
@input="viewPointHeightInput"
@change="viewPointHeightChange"
/>
<span class="unit">m</span>
<span class="arrow"></span>
</div>
</div>
</div>
<div class="row">
<div class="col">
<span class="label">采样精度</span>
<!-- <input
id="precision"
type="number"
title=""
min="1"
max="100"
step="1"
v-model="precision"
@input="precisionInput"
@change="precisionChange"
/>
<span class="arrow"></span> -->
<el-slider
v-model="precision"
:min="0"
:max="360"
placement="bottom"
@change="precisionInput"
/>
<span class="firstTip">0</span>
<span class="endTip">360</span>
</div>
</div>
</div>
</template>
<template #footer>
<button @click="draw">绘制</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null)
const eventBus = inject('bus')
const viewPointHeight: any = ref(1.8)
const precision: any = ref(20)
var visibility: any = reactive([])
eventBus.on('circleViewShedDialog', () => {
baseDialog.value?.open()
visibility = new YJ.Analysis.CircleViewShed(window.earth, {
viewPointHeight: viewPointHeight.value,
precision: precision.value
})
})
const closeCallBack = (e) => {
viewPointHeight.value = 1.8
precision.value = 20
YJ.Measure.SetMeasureStatus(false)
}
const viewPointHeightChange = () => {
visibility.viewPointHeights = viewPointHeight.value
}
const viewPointHeightInput = () => {
let dom = document.getElementById('viewPointHeight')
if (viewPointHeight.value < dom.min * 1) {
viewPointHeight.value = dom.min * 1
} else if (viewPointHeight.value > dom.max * 1) {
viewPointHeight.value = dom.max * 1
}
}
const precisionInput = () => {
// let dom = document.getElementById('precision')
// if (precision.value < dom.min * 1) {
// precision.value = dom.min * 1
// } else if (precision.value > dom.max * 1) {
// precision.value = dom.max * 1
// }
console.log(precision, 'eeeeee')
visibility.precisions = precision.value
}
const precisionChange = () => {
console.log(precision, 'yyyy')
}
const draw = (e) => {
visibility.draw()
// visibility.create(this)
// !window.analysisArr && (window.analysisArr = [])
// window.analysisArr.push(visibility)
}
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,173 @@
<template>
<Dialog
ref="baseDialog"
class="contour"
title="全局等高线"
left="180px"
top="100px"
:closeCallback="closeCallBack"
>
<template #content>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row" style="align-items: flex-start">
<div class="col" style="flex: 0 0 120px">
<span class="label">等高线</span>
<input class="btn-switch show" type="checkbox" />
</div>
</div>
</div>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col input-select-unit-box">
<span class="label">等高距</span>
<div class="input-number input-number-unit-1">
<input
class="input equal-height-distance"
id="equalHeightDistance"
type="number"
title=""
min="1"
max="1000"
/>
<span class="unit">m</span>
<span class="arrow"></span>
</div>
</div>
<div class="col input-select-unit-box" style="flex: 0 0 60px"></div>
<div class="col input-select-unit-box" style="flex: 0 0 157px">
<span class="label">选中线颜色</span>
<div class="active-color"></div>
</div>
</div>
</div>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row" style="align-items: flex-start">
<div class="col" style="flex: 0 0 120px">
<span class="label">计曲线</span>
<input class="btn-switch index-contour-switch" type="checkbox" />
</div>
<div class="col input-select-unit-box" style="flex: 0 0 120px">
<span class="label">计曲线颜色</span>
<div class="index-contour-color"></div>
</div>
<div class="col input-select-unit-box">
<span class="label">计曲线宽度</span>
<div class="input-number input-number-unit-1">
<input
class="input index-contour-width"
type="number"
title=""
step="0.1"
min="1"
max="10"
/>
<span class="unit">px</span>
<span class="arrow"></span>
</div>
</div>
</div>
<div class="row" style="align-items: flex-start">
<div class="col" style="flex: 0 0 120px">
<span class="label">首曲线</span>
<input class="btn-switch intermediate-contour-switch" type="checkbox" />
</div>
<div class="col input-select-unit-box" style="flex: 0 0 120px">
<span class="label">首曲线颜色</span>
<div class="intermediate-contour-color"></div>
</div>
<div class="col input-select-unit-box">
<span class="label">首曲线宽度</span>
<div class="input-number input-number-unit-1">
<input
class="input intermediate-contour-width"
type="number"
step="0.1"
title=""
min="1"
max="10"
/>
<span class="unit">px</span>
<span class="arrow"></span>
</div>
</div>
</div>
<div class="row" style="align-items: flex-start">
<div class="col" style="flex: 0 0 120px">
<span class="label">间曲线</span>
<input class="btn-switch halfInterval-contour-switch" type="checkbox" />
</div>
<div class="col input-select-unit-box" style="flex: 0 0 120px">
<span class="label">间曲线颜色</span>
<div class="halfInterval-contour-color"></div>
</div>
<div class="col input-select-unit-box">
<span class="label">间曲线宽度</span>
<div class="input-number input-number-unit-1">
<input
class="input halfInterval-contour-width"
type="number"
title=""
min="1"
max="10"
/>
<span class="unit">px</span>
<span class="arrow"></span>
</div>
</div>
</div>
<div class="row" style="align-items: flex-start">
<div class="col" style="flex: 0 0 120px">
<span class="label">助曲线</span>
<input class="btn-switch supplementary-contour-switch" type="checkbox" />
</div>
<div class="col input-select-unit-box" style="flex: 0 0 120px">
<span class="label">助曲线颜色</span>
<div class="supplementary-contour-color"></div>
</div>
<div class="col input-select-unit-box">
<span class="label">助曲线宽度</span>
<div class="input-number input-number-unit-1">
<input
class="input supplementary-contour-width"
type="number"
title=""
min="1"
max="10"
/>
<span class="unit">px</span>
<span class="arrow"></span>
</div>
</div>
</div>
</div>
</template>
<template #footer>
<button @click="close">取消</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null)
const eventBus = inject('bus')
eventBus.on('contourDialog', () => {
baseDialog.value?.open()
setTimeout(() => {
YJ.Global.Contour(window.earth)
})
})
const closeCallBack = (e) => {}
const close = (e) => {
baseDialog.value?.close()
}
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,218 @@
<template>
<Dialog
ref="baseDialog"
class="coorLocation"
title="坐标定位"
left="180px"
top="100px"
:closeCallback="closeCallBack"
>
<template #content>
<el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
<el-tab-pane label="小数格式" name="first">
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col" style="flex: 0 0 58%">
<span class="label">经度</span>
<input class="input" type="number" v-model="longitude" />
</div>
<div class="col"></div>
</div>
<div class="row">
<div class="col" style="flex: 0 0 58%">
<span class="label">纬度</span>
<input class="input" type="number" v-model="latitude" />
</div>
<div class="col"></div>
</div>
<div class="row">
<div class="col">
<span class="label">定位</span>
<button @click="flyto"><svg-icon name="location" :size="12" />跳转</button>
</div>
<div class="col"></div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="度分秒格式" name="second">
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col" style="flex: 0 0 78%">
<span class="label">经度</span>
<input class="input" type="number" v-model="longitude" />
<span class="label2"></span>
<input class="input" type="number" v-model="lngMin" />
<span class="label2"></span>
</div>
<div class="col"></div>
</div>
<div class="row">
<div class="col" style="flex: 0 0 78%">
<span class="label">纬度</span>
<input class="input" type="number" v-model="latitude" />
<span class="label2"></span>
<input class="input" type="number" v-model="latMin" />
<span class="label2"></span>
</div>
<div class="col"></div>
</div>
<div class="row">
<div class="col">
<span class="label">定位</span>
<button @click="flyto"><svg-icon name="location" :size="12" />跳转</button>
</div>
<div class="col"></div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="度分格式" name="third">
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col" style="flex: 0 0 90%">
<span class="label">经度</span>
<input class="input" type="number" v-model="longitude" />
<span class="label2"></span>
<input class="input" type="number" v-model="lngMin" />
<span class="label2"></span>
<input class="input" type="number" v-model="lngSec" />
<span class="label2"></span>
</div>
<div class="col"></div>
</div>
<div class="row">
<div class="col" style="flex: 0 0 90%">
<span class="label">纬度</span>
<input class="input" type="number" v-model="latitude" />
<span class="label2"></span>
<input class="input" type="number" v-model="latMin" />
<span class="label2"></span>
<input class="input" type="number" v-model="latSec" />
<span class="label2"></span>
</div>
<div class="col"></div>
</div>
<div class="row">
<div class="col">
<span class="label">定位</span>
<button @click="flyto"><svg-icon name="location" :size="12" />跳转</button>
</div>
<div class="col"></div>
</div>
</div>
</el-tab-pane>
</el-tabs>
</template>
<template #footer>
<button @click="draw">确定</button>
<button @click="close">取消</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null)
const eventBus = inject('bus')
const activeName = ref('first')
var longitude = ref(null)
var latitude = ref(null)
var lngMin = ref(null)
var latMin = ref(null)
var lngSec = ref(null)
var latSec = ref(null)
eventBus.on('coorLocationDialog', () => {
baseDialog.value?.open()
})
const handleClick = (tab: TabsPaneContext, event: Event) => {
console.log(tab, event)
longitude.value = null
latitude.value = null
lngMin.value = null
latMin.value = null
lngSec.value = null
latSec.value = null
}
const closeCallBack = (e) => {
longitude.value = null
latitude.value = null
lngMin.value = null
latMin.value = null
lngSec.value = null
latSec.value = null
}
const flyto = (e) => {
switch (activeName.value) {
case 'first':
new YJ.Global.flyTo(window.earth, {
position: { lng: longitude.value, lat: latitude.value, alt: 100 }
})
break
case 'second':
var lng = Math.abs(longitude.value) + Math.abs(lngMin.value) / 60
var lat = Math.abs(latitude.value) + Math.abs(latMin.value) / 60
lng = longitude.value < 0 ? -lng : lng
lat = latitude.value < 0 ? -lat : lat
var position = { lng, lat, alt: 100 }
new YJ.Global.flyTo(window.earth, {
position: position
})
break
case 'third':
var lng =
Math.abs(longitude.value) + Math.abs(lngMin.value) / 60 + Math.abs(lngSec.value) / 3600
var lat =
Math.abs(latitude.value) + Math.abs(latMin.value) / 60 + Math.abs(latSec.value) / 3600
lng = longitude.value < 0 ? -lng : lng
lat = latitude.value < 0 ? -lat : lat
var position = { lng, lat, alt: 100 }
new YJ.Global.flyTo(window.earth, {
position: position
})
break
}
}
const draw = (e) => {
baseDialog.value?.close()
}
const close = (e) => {
baseDialog.value?.close()
}
</script>
<style scoped lang="scss">
::v-deep .label2 {
margin: 0 10px;
}
::v-deep .el-tabs__item {
padding: 0px 30px 0px 0px !important;
font-size: 14px;
font-weight: 500;
letter-spacing: 0px;
line-height: 24px;
color: rgba(255, 255, 255, 1);
text-align: left;
vertical-align: top;
}
::v-deep .el-tabs__item.is-active,
.el-tabs__item:hover {
font-size: 16px;
font-weight: 400;
line-height: 0px;
text-shadow: 0px 0px 9px rgb(20, 118, 255);
}
</style>

View File

@ -0,0 +1,187 @@
<template>
<Dialog
ref="baseDialog"
class="cut-fill"
title="土方分析"
left="180px"
top="100px"
:closeCallback="closeCallBack"
>
<template #content>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label" style="flex: 0 0 70px">绘制分析区域</span>
<button class="draw-btn" @click="draw">
<svg class="icon-edit"><use xlink:href="#yj-icon-edit"></use></svg>开始绘制
</button>
</div>
</div>
</div>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">基准高度</span>
<div class="input-number input-number-unit-1">
<input
class="input"
id="height"
type="number"
title=""
min="-999999"
max="999999"
v-model="height"
@input="heightInput"
/>
<span class="unit">m</span>
<span class="arrow"></span>
</div>
</div>
<div class="col">
<span class="label">精度</span>
<!-- <div class="input-number input-number-unit">
<input
class="input"
id="precision"
type="number"
title=""
min="1"
max="1250"
v-model="precision"
@input="precisionInput"
/>
<span class="arrow"></span>
</div> -->
<el-slider v-model="precision" :min="0" :max="360" @change="precisionInput" />
<span class="firstTip">0</span>
<span class="endTip">360</span>
</div>
</div>
</div>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label" style="flex: 0 0 74px">总分析面积:</span>
<span class="text-number" name="allArea">{{ allArea }}</span>
<span class="unit text-number"></span>
</div>
<div class="col">
<span class="label" style="flex: 0 0 90px">无须填挖面积:</span>
<span class="text-number" name="noArea">{{ noArea }}</span>
<span class="unit text-number"></span>
</div>
</div>
<div class="row">
<div class="col">
<span class="label" style="flex: 0 0 74px">填方面积:</span>
<span class="text-number" name="fillArea">{{ fillArea }}</span>
<span class="unit text-number"></span>
</div>
<div class="col">
<span class="label" style="flex: 0 0 90px">挖方面积:</span>
<span class="text-number" name="cutArea">{{ cutArea }}</span>
<span class="unit text-number"></span>
</div>
</div>
<div class="row">
<div class="col">
<span class="label" style="flex: 0 0 74px">填方体积:</span>
<span class="text-number" name="fillVolume">{{ fillVolume }}</span>
<span class="unit text-number"></span>
</div>
<div class="col">
<span class="label" style="flex: 0 0 90px">挖方体积:</span>
<span class="text-number" name="cutVolume">{{ cutVolume }}</span>
<span class="unit text-number"></span>
</div>
</div>
</div>
<span class="custom-divider"></span>
</template>
<template #footer>
<button @click="close">取消</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null)
const eventBus = inject('bus')
var height: any = ref(70)
var precision: any = ref(125)
var allArea: any = ref(0)
var noArea: any = ref(0)
var fillArea: any = ref(0)
var cutArea: any = ref(0)
var fillVolume: any = ref(0)
var cutVolume: any = ref(0)
var cutFill: any = reactive([])
eventBus.on('cutFillDialog', () => {
baseDialog.value?.open()
cutFill = new YJ.Analysis.CutFillAnalysis(window.earth, {
height: height.value,
precision: precision.value
})
})
const heightInput = () => {
let dom = document.getElementById('height')
if (height.value < dom.min * 1) {
height.value = dom.min * 1
} else if (height.value > dom.max * 1) {
height.value = dom.max * 1
}
cutFill.heights = height.value
}
const precisionInput = () => {
// let dom = document.getElementById('precision')
// if (precision.value < dom.min * 1) {
// precision.value = dom.min * 1
// } else if (precision.value > dom.max * 1) {
// precision.value = dom.max * 1
// }
cutFill.precisions = precision.value
}
const closeCallBack = (e) => {
height.value = 70
precision.value = 125
allArea.value = 0
noArea.value = 0
fillArea.value = 0
cutArea.value = 0
fillVolume.value = 0
cutVolume.value = 0
cutFill && cutFill.clean()
YJ.Measure.SetMeasureStatus(false)
// visibility && visibility.end()
}
function close() {
baseDialog.value?.close()
}
const draw = (e) => {
cutFill.create()
cutFill.onEnd = () => {
height.value = cutFill.heights
precision.value = cutFill.precisions
allArea.value = cutFill.allArea
noArea.value = cutFill.noArea
fillArea.value = cutFill.fillArea
cutArea.value = cutFill.cutArea
fillVolume.value = cutFill.fillVolume
cutVolume.value = cutFill.cutVolume
}
}
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,157 @@
<template>
<Dialog
ref="baseDialog"
class="fly-roam"
title="飞行漫游"
left="180px"
top="100px"
:closeCallback="closeCallBack"
>
<template #content v-if="show">
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">名称</span>
<input class="input" type="text" name="name" />
</div>
<div class="col"></div>
</div>
</div>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<input
type="checkbox"
name="isTotalTime"
style="
width: 16px;
line-height: 15px;
height: 15px;
cursor: pointer;
width: auto;
margin-right: 5px;
"
/>
<span class="label">设置总时长</span>
<div class="input-number input-number-unit-3">
<input
class="input total-time"
type="number"
title=""
min="0"
max="999999.99"
step="0.01"
name="totalTime"
value="0"
/>
<span class="unit" style="top: 6px">(s)</span>
<span class="arrow"></span>
</div>
</div>
<div class="col">
<input
type="checkbox"
name="repeat"
style="
width: 16px;
line-height: 15px;
height: 15px;
cursor: pointer;
width: auto;
margin-right: 5px;
"
/>
<span class="label">是否循环播放</span>
</div>
</div>
</div>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<button class="add-point">
<svg class="icon-add"><use xlink:href="#yj-icon-add"></use></svg>增加视点
</button>
</div>
<div class="col">
<button class="modify-point">
<svg class="icon-edit"><use xlink:href="#yj-icon-edit"></use></svg>调整视点
</button>
</div>
<div class="col">
<button class="afreshPlay">
<svg class="icon-play"><use xlink:href="#yj-icon-play"></use></svg>播放
</button>
</div>
<div class="col">
<button class="cease">
<svg class="icon-pause"><use xlink:href="#yj-icon-pause"></use></svg>结束
</button>
</div>
</div>
<div class="table">
<div class="table-head">
<div class="tr">
<div class="th">序号</div>
<div class="th">时长(s)</div>
<div class="th">操作</div>
</div>
</div>
<div class="table-body">
<div class="table-empty">
<div class="empty-img"></div>
<p>暂无数据</p>
</div>
</div>
</div>
</div>
<span class="custom-divider"></span>
</template>
<template #footer>
<button @click="draw">确定</button>
<button @click="close">关闭</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null)
const eventBus = inject('bus')
var show: any = ref(false)
var flyRoam: any = reactive([])
eventBus.on('flyRoamDialog', () => {
show.value = true
baseDialog.value?.open()
setTimeout(() => {
flyRoam = YJ.Global.FlyRoam.open(window.earth, { repeat: Infinity })
}, 0)
})
const clangeViewPointHeight = () => {}
const viewPointHeightInput = () => {
let dom = document.getElementById('viewPointHeight')
if (viewPointHeight.value < dom.min * 1) {
viewPointHeight.value = dom.min * 1
} else if (viewPointHeight.value > dom.max * 1) {
viewPointHeight.value = dom.max * 1
}
}
const closeCallBack = (e) => {
YJ.Global.FlyRoam.cease(window.earth)
YJ.Global.FlyRoam.close()
}
const draw = (e) => {}
const close = (e) => {
show.value = false
baseDialog.value?.close()
}
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,85 @@
<template>
<Dialog
ref="baseDialog"
class="graffiti"
title="涂鸦参数"
left="180px"
top="100px"
:closeCallback="closeCallBack"
>
<template #content>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">涂鸦颜色</span>
<div class="color"></div>
</div>
<div class="col">
<span class="label">线条宽度</span>
<div class="input-number input-number-unit-2" style="width: 80px">
<input
class="input"
id="width"
type="number"
title=""
min="1"
max="99"
step="1"
v-model="width"
@input="widthInput"
/>
<span class="unit">px</span>
<span class="arrow"></span>
</div>
</div>
</div>
</div>
</template>
<template #footer>
<button @click="draw">确定</button>
<button @click="close">取消</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null)
const eventBus = inject('bus')
var width: any = ref(1)
var graffiti: any = reactive([])
eventBus.on('graffitiDialog', () => {
baseDialog.value?.open()
setTimeout(() => {
graffiti = new YJ.Obj.Graffiti(window.earth, {
width: width.value
})
}, 0)
})
const closeCallBack = (e) => {}
const widthInput = () => {
let dom = document.getElementById('width')
if (width.value < dom.min * 1) {
width.value = dom.min * 1
} else if (width.value > dom.max * 1) {
width.value = dom.max * 1
}
graffiti.width = width.value
}
const close = (e) => {
baseDialog.value?.close()
}
const draw = (e) => {
eventBus.emit('graffitiObj', graffiti)
graffiti.start()
baseDialog.value?.close()
}
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,360 @@
<template>
<Dialog
ref="baseDialog"
class="profile"
title="剖面分析"
left="180px"
top="100px"
:closeCallback="closeCallBack"
>
<template #content>
<span class="custom-divider"></span>
<div class="profile-echarts"></div>
</template>
<template #footer>
<button @click="draw">
<svg class="icon-edit"><use xlink:href="#yj-icon-edit"></use></svg>重新绘制
</button>
<button @click="close">关闭</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null)
const eventBus = inject('bus')
//属性
var profile: any = reactive([])
var echartsObject: any = reactive({})
eventBus.on('profileDialog', () => {
profile = new YJ.Analysis.Profile(window.earth)
profile.onEnd = (point) => {
baseDialog.value?.open()
setTimeout(() => {
initEcharts(point)
})
}
})
const closeCallBack = (e) => {
echartsObject && echartsObject.clear()
profile && profile.clean()
profile = []
echartsObject = []
}
function close() {
baseDialog.value?.close()
}
const draw = (e) => {
initEcharts()
profile.reDraw()
}
function initEcharts(points) {
let datas = [],
coords = []
const pointsData = points
let option
if (pointsData) {
const maxDistance = pointsData[pointsData.length - 1].distance
let xAixMax = Math.ceil(maxDistance)
for (let index = 0; index < pointsData.length; index++) {
const element = pointsData[index]
if (element.position.height === void 0) {
continue
}
const curData = [element.distance.toFixed(2), element.position.height.toFixed(2)]
datas.push(curData)
const curCoords = [element.position.lng, element.position.lat]
coords.push(curCoords)
}
const ele = document.getElementsByClassName('profile-echarts')[0]
echartsObject = echarts.init(ele)
option = {
tooltip: {
trigger: 'axis',
textStyle: {
align: 'left'
},
formatter(params) {
const xy = coords[params[0].dataIndex]
const tipData = params[0]['data']
profile.formatter(xy, tipData)
return (
'距离:' +
tipData[0] +
'm<br>' +
'高度:' +
tipData[1] +
'm<br>' +
'坐标:' +
xy[0].toFixed(5) +
'' +
xy[1].toFixed(5)
)
}
},
grid: {
top: 40,
bottom: 20,
left: 55,
right: 30
},
calculable: true,
xAxis: [
{
type: 'value',
max: xAixMax,
scale: true,
axisLabel: {
color: '#ffffff'
},
axisLine: {
lineStyle: {
color: '#ffffff'
}
}
}
],
yAxis: [
{
type: 'value',
scale: true,
axisLabel: {
color: '#ffffff'
},
axisLine: {
lineStyle: {
color: '#ffffff'
}
}
}
],
series: [
{
name: 'ProfileLine',
type: 'line',
data: datas,
smooth: true,
itemStyle: {
normal: {
color: '#39FDA1'
}
},
lineStyle: {
normal: {
width: 3,
color: {
type: 'linear',
x: 0,
y: 0,
x2: 1,
y2: 0,
colorStops: [
{
offset: 0,
color: 'rgba(85,254,139,1)' // 0% 处的颜色
},
{
offset: 0.5,
color: 'rgba(7,252,202,1)' // 100% 处的颜色
},
{
offset: 1,
color: 'rgba(14,245,210,1)' // 100% 处的颜色
}
],
globalCoord: false // 缺省为 false
}
}
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: 'rgba(102,153,255,1)'
},
{
offset: 0.8,
color: 'rgba(102,153,255,0.08)'
},
{
offset: 1,
color: 'rgba(9,173,208,0.15)'
}
],
false
),
shadowColor: 'rgba(14,245,210,1)', //阴影颜色
shadowBlur: 20
}
},
markPoint: {
data: [
{
type: 'max',
name: '最高点',
label: {
color: '#ffffff'
}
},
{
type: 'min',
name: '最低点',
label: {
color: '#ffffff'
}
}
]
}
}
]
}
} else {
const ele = document.getElementsByClassName('profile-echarts')[0]
echartsObject = echarts.init(ele)
option = {
tooltip: {
trigger: 'axis',
textStyle: {
align: 'left'
}
},
grid: {
top: 40,
bottom: 20,
left: 55,
right: 30
},
calculable: true,
xAxis: [
{
type: 'value',
scale: true,
axisLabel: {
color: '#ffffff'
},
axisLine: {
lineStyle: {
color: '#ffffff'
}
}
}
],
yAxis: [
{
type: 'value',
scale: true,
axisLabel: {
color: '#ffffff'
},
axisLine: {
lineStyle: {
color: '#ffffff'
}
}
}
],
series: [
{
name: 'ProfileLine',
type: 'line',
data: [],
smooth: true,
itemStyle: {
normal: {
color: '#39FDA1'
}
},
lineStyle: {
normal: {
width: 3,
color: {
type: 'linear',
x: 0,
y: 0,
x2: 1,
y2: 0,
colorStops: [
{
offset: 0,
color: 'rgba(85,254,139,1)' // 0% 处的颜色
},
{
offset: 0.5,
color: 'rgba(7,252,202,1)' // 100% 处的颜色
},
{
offset: 1,
color: 'rgba(14,245,210,1)' // 100% 处的颜色
}
],
globalCoord: false // 缺省为 false
}
}
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: 'rgba(102,153,255,1)'
},
{
offset: 0.8,
color: 'rgba(102,153,255,0.08)'
},
{
offset: 1,
color: 'rgba(9,173,208,0.15)'
}
],
false
),
shadowColor: 'rgba(14,245,210,1)', //阴影颜色
shadowBlur: 20
}
},
markPoint: {
data: [
{
type: 'max',
name: '最高点',
label: {
color: '#ffffff'
}
},
{
type: 'min',
name: '最低点',
label: {
color: '#ffffff'
}
}
]
}
}
]
}
}
echartsObject.setOption(option)
}
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,64 @@
<template>
<Dialog ref="baseDialog" title="路径规划" left="180px" top="100px" :closeCallback="closeCallBack">
<template #content>
<div class="row" style="align-items: flex-start">
<div class="col start-col">
<span class="label">起点</span>
<input class="input" type="number" title="" min="-180" max="180" @model="startLng" />
<input class="input" type="number" title="" min="-90" max="90" @model="startLat" />
<button @click="pickStartPos" style="margin-left: 10px">拾取</button>
</div>
</div>
<div class="row" style="align-items: flex-start">
<div class="col">
<span class="label">终点</span>
<input class="input" type="number" title="" min="-180" max="180" @model="endLng" />
<input class="input" type="number" title="" min="-90" max="90" @model="endLat" />
<button class="end-pick-btn" @click="pickEndPos" style="margin-left: 10px">拾取</button>
</div>
</div>
</template>
<template #footer>
<button @click="draw">绘制</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null)
const eventBus = inject('bus')
//属性
var startLng: any = ref(null)
var startLat: any = ref(null)
var endLng: any = ref(null)
var endLat: any = ref(null)
var routePlanning: any = reactive([])
eventBus.on('routePlanningDialog', () => {
baseDialog.value?.open()
routePlanning = new YJ.Obj.RoutePlanning(window.earth, { gps: true })
})
const closeCallBack = (e) => {}
function pickStartPos() {}
function pickEndPos() {}
const draw = (e) => {}
</script>
<style scoped lang="scss">
.YJ-custom-base-dialog > .content {
width: 460px;
}
.YJ-custom-base-dialog > .content > div > .row .col {
margin: 0 10px;
}
.YJ-custom-base-dialog > .content .row .label {
flex: auto;
}
</style>

View File

@ -0,0 +1,252 @@
<template>
<Dialog
ref="baseDialog"
class="screenShotHD"
title="高清出图"
left="180px"
top="100px"
:closeCallback="closeCallBack"
>
<template #content>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">出图方式</span>
<div class="btn-group">
<button
class="btn"
:class="{ active: selectType == 'first' }"
@click="clickChange('first')"
>
比例尺
</button>
<button
class="btn"
:class="{ active: selectType == 'second' }"
@click="clickChange('second')"
>
地图层级
</button>
<button
class="btn"
:class="{ active: selectType == 'third' }"
@click="clickChange('third')"
>
倍数输出
</button>
</div>
</div>
</div>
</div>
<div class="div-item">
<!-- 比例尺 -->
<div class="row" v-if="selectType == 'first'" style="margin-bottom: 20px">
<div class="col">
<span class="label radioWords">比例尺</span>
<el-select v-model="radio" class="radio">
<el-option v-for="item in 20" :key="item" :label="item" :value="item" />
</el-select>
<button class="curLevel" @click="draw">获取当前比例尺</button>
</div>
</div>
<!-- 地图层级 -->
<div class="row" v-else-if="selectType == 'second'" style="margin-bottom: 20px">
<div class="col">
<span class="label">地图层级</span>
<el-select v-model="level" class="level">
<el-option v-for="item in 20" :key="item" :label="item" :value="item" />
</el-select>
</div>
</div>
<!-- 倍数输出 -->
<div v-else-if="selectType == 'third'">
<div class="row text" style="align-items: flex-start">
<div class="col">
<span
>当前窗口长宽<span class="input-width">{{ canvasWidth }}</span
>*<span class="input-height">{{ canvasHeight }}</span
>像素</span
>
</div>
</div>
<div class="row scale-box" style="align-items: flex-start">
<div class="col">
<span class="label">图片大小</span>
<el-select v-model="scale" class="photo">
<el-option v-for="item in 10" :key="item" :label="item" :value="item" />
</el-select>
<span>倍窗口</span>
</div>
</div>
<div class="row text" style="align-items: flex-start">
<div class="col">
<span
>输出图片长宽<span class="output-width">{{ canvasWidth * scale }}</span
>*<span class="output-height">{{ canvasHeight * scale }}</span
>像素</span
>
</div>
</div>
</div>
<div class="row" style="align-items: flex-start; margin-top: 10px">
<div class="col">
<span class="label">输出进度</span>
<div class="range-box">
<div class="range-bg">
<div class="range-process-box">
<div class="range-process"></div>
</div>
</div>
<div class="range-node-box">
<span class="range-node-text">0%</span>
<span class="range-node-text">100%</span>
<div class="range-node-active"><span class="range-node-active-text">0%</span></div>
</div>
<input class="progress-input" type="range" max="100" min="0" step="0.01" />
</div>
</div>
<div class="row" style="align-items: flex-start">
<div class="col">
<el-checkbox v-model="modify" label="出图修饰" size="large" />
</div>
</div>
</div>
</div>
<span class="custom-divider"></span>
</template>
<template #footer>
<button @click="draw">确定</button>
<button @click="close">取消</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null)
const eventBus = inject('bus')
var selectType: any = ref('first')
var scale: any = ref(1)
var radio: any = ref('1:500')
var level: any = ref(1)
var modify: any = ref(false)
var canvasWidth: any = ref(0)
var canvasHeight: any = ref(0)
// onMounted(() => {
// canvasWidth.value = window.earth.viewer.canvas.width
// canvasHeight.value = window.earth.viewer.canvas.height
// })
var visibility: any = reactive([])
eventBus.on('screenShotDialog', () => {
baseDialog.value?.open()
canvasWidth.value = window.earth.viewer.canvas.width
canvasHeight.value = window.earth.viewer.canvas.height
})
const closeCallBack = (e) => {}
const close = (e) => {
baseDialog.value?.close()
}
const draw = (e) => {}
const clickChange = (type) => {
switch (type) {
case 'first': //比例尺
selectType.value = 'first'
break
case 'second': //地图层级
selectType.value = 'second'
break
case 'third': //倍数输出
selectType.value = 'third'
break
default:
break
}
}
</script>
<style scoped lang="scss">
.btn-group {
display: flex;
background: rgba(var(--color-sdk-base-rgb), 0.2);
}
.btn {
background: transparent !important;
border: 1px solid transparent !important;
}
.btn:hover {
border: 1px solid rgba(var(--color-sdk-base-rgb), 1) !important;
color: rgba(var(--color-sdk-base-rgb), 1) !important;
}
.active {
border: 1px solid rgba(var(--color-sdk-base-rgb), 1) !important;
color: rgba(var(--color-sdk-base-rgb), 1) !important;
}
.curLevel {
margin-left: 10px;
}
.radioWords {
width: 56px;
}
.photo {
width: 175px;
height: 32px;
font-size: 12px;
font-weight: 400;
letter-spacing: 0px;
line-height: 24px;
color: rgba(204, 204, 204, 1);
text-align: left;
vertical-align: top;
// background-color: rgba(0, 0, 0, 0.5) !important;
// border: 1px solid rgba(var(--color-sdk-base-rgb), 0.5) !important;
border-radius: 5px;
margin-right: 10px;
}
.radio {
width: 108px;
}
::v-deep .el-select__wrapper {
background-color: rgba(0, 0, 0, 0.5) !important;
border: 1px solid rgba(var(--color-sdk-base-rgb), 0.5) !important;
box-shadow: unset !important;
}
::v-deep .el-select__selected-item {
margin-left: 10px;
color: #ffffff;
}
::v-deep .el-popper .is-pure {
z-index: 1000000 !important;
}
::v-deep .el-popper.is-light,
.el-popper.is-light > .el-popper__arrow:before {
z-index: 1000000 !important;
}
.level {
width: 150px;
}
.el-checkbox {
margin-top: 10px;
}
::v-deep .el-checkbox.el-checkbox--large .el-checkbox__label {
font-size: 14px;
font-weight: 500;
letter-spacing: 0px;
line-height: 24px;
color: rgba(255, 255, 255, 1);
text-align: left;
vertical-align: middle;
margin-left: 5px;
}
::v-deep .range-node-box .range-node-text {
font-size: 14px !important;
}
</style>

View File

@ -0,0 +1,368 @@
<template>
<Dialog
ref="baseDialog"
title="淹没分析"
class="submerge"
left="180px"
top="100px"
:closeCallback="closeCallBack"
>
<template #content>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">最低水位</span>
<div class="input-number input-number-unit-3">
<input
class="input"
id="minWaterLevel"
type="number"
title=""
min="0"
max="9999999"
v-model="minWaterLevel"
@input="minWaterLevelInput"
/>
<span class="unit">m</span>
<span class="arrow"></span>
</div>
</div>
<div class="col">
<span class="label">最高水位</span>
<div class="input-number input-number-unit-3">
<input
class="input"
id="maxWaterLevel"
type="number"
title=""
min="0"
max="9999999"
v-model="maxWaterLevel"
@input="maxWaterLevelInput"
/>
<span class="unit">m</span>
<span class="arrow"></span>
</div>
</div>
</div>
<div class="row">
<div class="col">
<span class="label">水面面积</span>
<div class="input-number input-number-unit-3">
<input
class="input area"
id="area"
placeholder="请绘制分析范围"
type="number"
v-model="area"
min="0"
max="9999999"
:readonly="readOnly"
@input="areaInput"
/>
<span class="unit"></span>
<span class="arrow"></span>
</div>
</div>
<div class="col">
<span class="label">水量</span>
<div class="input-number input-number-unit-3">
<input
class="input"
id="waterVolume"
type="number"
placeholder="请输入水体水量"
title=""
min="0"
max="9999999"
v-model="waterVolume"
@input="waterVolumeInput"
/>
<span class="unit"></span>
<span class="arrow"></span>
</div>
</div>
</div>
</div>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row subtitle-box">
<span class="subtitle">上升速度</span>
</div>
<div class="row">
<div class="col">
<input
type="range"
max="50"
min="0"
step="0.01"
v-model="risingSpeed"
@change="risingSpeedInput"
/>
<span class="rangeWords">水量</span>
<div
class="input-number input-number-unit-3"
style="flex: 0 0 110px; margin-left: 10px"
>
<input
class="input"
id="risingSpeed"
type="number"
title=""
v-model="risingSpeed"
max="50"
min="0"
@input="risingSpeedInput"
/>
<span class="unit">m/s</span>
<span class="arrow"></span>
</div>
</div>
</div>
</div>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col operate-btn-box">
<button class="draw" @click="draw">
<svg class="icon-draw"><use xlink:href="#yj-icon-draw"></use></svg>绘制范围
</button>
<button class="flyto" @click="flyTo">
<svg class="icon-positions">
<use xlink:href="#yj-icon-positions"></use></svg
>定位
</button>
<button class="reset" @click="reset">
<svg class="icon-reset"><use xlink:href="#yj-icon-reset"></use></svg>重置
</button>
<button class="analog" @click="analog">
<svg class="icon-play"><use xlink:href="#yj-icon-play"></use></svg>开始模拟
</button>
<button class="pause" v-if="!isPausng" @click="pause" style="margin-right: 0px">
<svg class="icon-pause"><use xlink:href="#yj-icon-pause"></use></svg>暂停
</button>
<button class="start" v-else-if="isPausng" @click="pause" style="margin-right: 0px">
<svg class="icon-play"><use xlink:href="#yj-icon-play"></use></svg>播放
</button>
</div>
</div>
</div>
<div class="table">
<div class="table-head">
<div class="tr">
<div class="th">序号</div>
<div class="th">经度</div>
<div class="th">纬度</div>
<div class="th">高程</div>
</div>
</div>
<div class="table-body">
<div class="tr" v-for="(value, i) in positions" :key="i">
<div class="td">{{ i + 1 }}</div>
<div class="td">{{ Number(value.lng.toFixed(10)) }}</div>
<div class="td">{{ Number(value.lat.toFixed(10)) }}</div>
<div class="td">{{ Number(value.alt.toFixed(4)) }}</div>
</div>
</div>
<div class="table-empty" v-if="!positions.length">
<div class="empty-img"></div>
<p>暂无数据</p>
</div>
</div>
<span class="custom-divider" style="margin-top: 20px"></span>
</template>
<template #footer>
<button @click="close">取消</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null)
const eventBus = inject('bus')
// 属性
var minWaterLevel: any = ref(0)
var maxWaterLevel: any = ref(0)
var area: any = ref(0)
var waterVolume: any = ref(0)
var risingSpeed: any = ref(1)
var waterLevel: any = ref(0)
var positions: any = reactive([])
var submerge: any = reactive([])
var isPausng = ref(false)
var readOnly = ref(true)
eventBus.on('submergeDialog', () => {
baseDialog.value?.open()
submerge = new YJ.Analysis.Submerge(window.earth)
submerge.onEnd = (areaV, posi) => {
isPausng.value = false
minWaterLevel.value = submerge.minWaterLevel
maxWaterLevel.value = submerge.maxWaterLevel
waterVolume.value = submerge.waterVolume
risingSpeed.value = submerge.risingSpeed
waterLevel.value = submerge.waterLevels
area.value = areaV * 1
positions = posi
}
})
const closeCallBack = (e) => {
minWaterLevel.value = 0
maxWaterLevel.value = 0
area.value = 0
waterVolume.value = 0
risingSpeed.value = 1
waterLevel.value = 0
positions = []
isPausng.value = false
readOnly.value = true
submerge.destroy()
}
function close() {
baseDialog.value?.close()
}
//方法
function draw() {
submerge.draw()
}
function flyTo() {
submerge.flyTo()
}
function reset() {
isPausng.value = false
submerge.restart()
}
function pause() {
if (isPausng.value) {
//暂停中
submerge.start()
} else {
//播放中
submerge.pause()
}
isPausng.value = !isPausng.value
}
function analog() {
isPausng.value = false
submerge.move()
}
function minWaterLevelInput() {
let dom = document.getElementById('minWaterLevel')
if (minWaterLevel.value != '.') {
if (minWaterLevel.value < dom.min * 1) {
minWaterLevel.value = dom.min * 1
} else if (minWaterLevel.value > dom.max * 1) {
minWaterLevel.value = dom.max * 1
}
minWaterLevel.value = Math.floor(minWaterLevel.value * 10000) / 10000
maxWaterLevel.value = minWaterLevel.value + waterLevel.value
submerge.minWaterLevel = minWaterLevel.value
submerge.maxWaterLevel = maxWaterLevel.value
submerge.waterLevels = waterLevel.value
}
}
function maxWaterLevelInput() {
let dom = document.getElementById('maxWaterLevel')
if (minWaterLevel.value != '.') {
if (maxWaterLevel.value < dom.min * 1) {
maxWaterLevel.value = dom.min * 1
} else if (maxWaterLevel.value > dom.max * 1) {
maxWaterLevel.value = dom.max * 1
}
if (maxWaterLevel.value < minWaterLevel.value) {
maxWaterLevel.value = minWaterLevel.value
} else {
maxWaterLevel.value = Math.floor(maxWaterLevel.value * 10000) / 10000
}
waterLevel.value = maxWaterLevel.value - minWaterLevel.value
waterVolume.value = Number((waterLevel.value * area.value).toFixed(4))
submerge.waterVolume = waterVolume.value
submerge.waterLevels = waterLevel.value
submerge.maxWaterLevel = maxWaterLevel.value
}
}
function areaInput() {
let dom = document.getElementById('area')
if (minWaterLevel.value != '.') {
if (area.value < dom.min * 1) {
area.value = dom.min * 1
} else if (area.value > dom.max * 1) {
area.value = dom.max * 1
}
submerge.areas = area.value
waterLevel.value = Number((waterVolume.value / area.value).toFixed(4))
maxWaterLevel.value = minWaterLevel.value + waterLevel.value
submerge.waterLevels = waterLevel.value
submerge.maxWaterLevel = maxWaterLevel.value
}
}
function waterVolumeInput() {
let dom = document.getElementById('waterVolume')
if (waterVolume.value < dom.min * 1) {
waterVolume.value = dom.min * 1
} else if (waterVolume.value > dom.max * 1) {
waterVolume.value = dom.max * 1
}
waterVolume.value = Math.floor(waterVolume.value * 10000) / 10000
if (area.value) {
waterLevel.value = Number((waterVolume.value / area.value).toFixed(4))
maxWaterLevel.value = maxWaterLevel.value + waterLevel.value
submerge.waterLevels = waterLevel.value
submerge.maxWaterLevel = maxWaterLevel.value
}
}
function risingSpeedInput() {
let dom = document.getElementById('risingSpeed')
if (risingSpeed.value != '.') {
if (risingSpeed.value < dom.min * 1) {
risingSpeed.value = dom.min * 1
} else if (risingSpeed.value > dom.max * 1) {
risingSpeed.value = dom.max * 1
}
submerge.risingSpeed = risingSpeed.value
}
}
</script>
<style scoped lang="scss">
.label {
width: 75px;
}
input:read-only {
background-color: rgba(204, 204, 204, 0.2) !important;
}
// .mask {
// position: absolute;
// top: 0;
// left: 0;
// right: 0;
// bottom: 0;
// background-color: rgba(204, 204, 204, 0.2); /* 半透明白色背景 */
// z-index: 2; /* 确保蒙层位于输入框之上 */
// display: flex;
// justify-content: center;
// align-items: center;
// pointer-events: none; /* 允许蒙层下的内容被点击 */
// border: 1px solid rgba(0, 255, 255, 0.5);
// }
</style>

View File

@ -0,0 +1,91 @@
<template>
<Dialog ref="baseDialog" title="地形开挖" left="180px" top="100px" :closeCallback="closeCallBack">
<template #content>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label" style="flex: 0 0 70px">挖掘高度</span>
<div class="input-number input-number-unit-1">
<input
class="input"
type="number"
id="height"
title=""
min="0"
max="5000000"
v-model="height"
@input="heightInput"
@change="changeHeight"
/>
<span class="unit">m</span>
<span class="arrow"></span>
</div>
</div>
</div>
</div>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">绘制开挖区域</span>
<button class="start-excavation" @click="draw">
<svg class="icon-edit"><use xlink:href="#yj-icon-edit"></use></svg>绘制
</button>
</div>
<div class="col">
<span class="label">清除开挖区域</span>
<button class="clean-excavation" @click="clear">
<svg class="icon-close"><use xlink:href="#yj-icon-close"></use></svg>清除
</button>
</div>
</div>
</div>
</template>
<template #footer>
<button @click="close">取消</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null)
const eventBus = inject('bus')
var height: any = ref(10)
var excavation: any = reactive([])
eventBus.on('terrainExcavationDialog', () => {
baseDialog.value?.open()
excavation = new YJ.Analysis.TerrainExcavation(this.sdk, { height: 10 })
})
const changeHeight = () => {
excavation.height = height.value
}
const heightInput = () => {
let dom = document.getElementById('height')
if (height.value < dom.min * 1) {
height.value = dom.min * 1
} else if (height.value > dom.max * 1) {
height.value = dom.max * 1
}
}
const closeCallBack = (e) => {}
const close = (e) => {
baseDialog.value?.close()
}
const draw = (e) => {
excavation.startCreate()
}
const clear = (e) => {
excavation.clear()
}
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,162 @@
<template>
<Dialog
ref="baseDialog"
class="view-shed"
title="可视域分析"
left="180px"
top="100px"
:closeCallback="closeCallBack"
>
<template #content>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">位置拾取(起点终点)</span>
<button class="edit" @click="edit">
<svg class="icon-edit"><use xlink:href="#yj-icon-edit"></use></svg>拾取
</button>
</div>
</div>
</div>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row" style="margin-bottom: 25px">
<div class="col">
<span class="label">视点高度</span>
<div class="input-number input-number-unit-1">
<input
class="input"
id="viewPointHeight"
type="number"
title=""
min="0"
max="999999"
step="0.1"
v-model="viewPointHeight"
@change="viewPointHeightInput"
/>
<span class="unit">m</span>
<span class="arrow"></span>
</div>
</div>
<div class="col"></div>
</div>
<div class="row subtitle-box">
<span class="subtitle">视域夹角</span>
</div>
<div class="row">
<div class="col">
<div class="range-box">
<div class="range-bg">
<div class="range-process-box">
<div class="range-process"></div>
</div>
</div>
<div class="range-node-box">
<span class="range-node-text">0°</span>
<span class="range-node-text">45°</span>
<span class="range-node-text">90°</span>
<span class="range-node-text">135°</span>
<span class="range-node-text">180°</span>
<div class="range-node-active"><span class="range-node-active-text">0°</span></div>
</div>
<input
type="range"
max="180"
min="0"
step="1"
name="horizontalViewAngle"
v-model="horizontalViewAngle"
/>
</div>
</div>
</div>
</div>
<span class="custom-divider"></span>
</template>
<template #footer>
<button @click="draw">绘制</button>
<button @click="close">关闭</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null)
const eventBus = inject('bus')
const viewPointHeight: any = ref(1.8)
var horizontalViewAngle: any = ref(90)
var viewShed: any = reactive([])
var timeout: any = reactive([])
eventBus.on('viewShedDialog', () => {
baseDialog.value?.open()
viewShed && viewShed.destroy && viewShed.destroy()
viewShed = new YJ.Analysis.ViewShed(window.earth)
setTimeout(() => {
let contentElm = document.getElementsByClassName('view-shed')[0]
let e_horizontalViewAngle = contentElm.querySelector("input[name='horizontalViewAngle']")
let rangeNodeActive = contentElm.getElementsByClassName('range-node-active')[0]
let rangeNodeActiveText = rangeNodeActive.getElementsByClassName('range-node-active-text')[0]
let rangeProcess = contentElm.getElementsByClassName('range-process')[0]
let percentage = (horizontalViewAngle.value / 180) * 100
rangeNodeActive.style.left = percentage + '%'
rangeProcess.style.width = percentage + '%'
rangeNodeActiveText.innerHTML = horizontalViewAngle.value + '°'
e_horizontalViewAngle.removeEventListener('input', inputFun)
e_horizontalViewAngle.removeEventListener('change', changeFun)
e_horizontalViewAngle.addEventListener('input', inputFun)
e_horizontalViewAngle.addEventListener('change', changeFun)
})
})
function inputFun() {
let contentElm = document.getElementsByClassName('view-shed')[0]
let rangeNodeActive = contentElm.getElementsByClassName('range-node-active')[0]
let rangeNodeActiveText = rangeNodeActive.getElementsByClassName('range-node-active-text')[0]
let rangeProcess = contentElm.getElementsByClassName('range-process')[0]
let percentage = (horizontalViewAngle.value / 180) * 100
rangeNodeActive.style.left = percentage + '%'
rangeProcess.style.width = percentage + '%'
rangeNodeActiveText.innerHTML = horizontalViewAngle.value + '°'
}
function changeFun() {
clearTimeout(timeout)
timeout = setTimeout(() => {
viewShed.horizontalViewAngles = horizontalViewAngle.value
}, 300)
}
const closeCallBack = (e) => {
viewShed.close()
viewPointHeight.value = 1.8
horizontalViewAngle.value = 90
}
function viewPointHeightInput(e) {
let dom = document.getElementById('viewPointHeight')
if (viewPointHeight.value != '.') {
if (viewPointHeight.value < dom.min * 1) {
viewPointHeight.value = dom.min * 1
} else if (viewPointHeight.value > dom.max * 1) {
viewPointHeight.value = dom.max * 1
}
viewShed.viewPointHeight = viewPointHeight.value
}
}
function draw() {
viewShed.draw()
}
function close() {
baseDialog.value?.close()
}
function edit() {
viewShed.nodeEdit()
}
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,78 @@
<template>
<Dialog
ref="baseDialog"
title="多点视线分析"
left="180px"
top="100px"
:closeCallback="closeCallBack"
>
<template #content>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">视点高度</span>
<div class="input-number input-number-unit-1">
<input
id="viewPointHeight"
type="number"
title=""
min="0"
max="999999"
step="0.1"
placeholder="请输入数值"
v-model="viewPointHeight"
@input="viewPointHeightInput"
@change="clangeViewPointHeight"
/>
<span class="unit">m</span>
<span class="arrow"></span>
</div>
</div>
</div>
</div>
</template>
<template #footer>
<button @click="draw">绘制</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null)
const eventBus = inject('bus')
const viewPointHeight: any = ref(1.8)
var visibility: any = reactive([])
eventBus.on('analysisDialog', () => {
baseDialog.value?.open()
})
const clangeViewPointHeight = () => {}
const viewPointHeightInput = () => {
let dom = document.getElementById('viewPointHeight')
if (viewPointHeight.value < dom.min * 1) {
viewPointHeight.value = dom.min * 1
} else if (viewPointHeight.value > dom.max * 1) {
viewPointHeight.value = dom.max * 1
}
}
const closeCallBack = (e) => {
viewPointHeight.value = 1.8
YJ.Measure.SetMeasureStatus(false)
// visibility && visibility.end()
}
const draw = (e) => {
visibility && visibility.end && visibility.end()
visibility = new YJ.Analysis.Visibility(window.earth, { viewPointHeight: viewPointHeight.value })
// visibility.create(this)
!window.analysisArr && (window.analysisArr = [])
window.analysisArr.push(visibility)
baseDialog.value?.close()
}
</script>
<style scoped lang="scss"></style>

View File

@ -1,7 +1,7 @@
<template> <template>
<Dialog ref="baseDialog" title="贴地文字" left="calc(50% - 160px)" top="calc(50% - 120px)"> <Dialog ref="baseDialog" title="贴地文字" left="calc(50% - 160px)" top="calc(50% - 120px)">
<template #content> <template #content>
<textarea style="height: 76px; width: 270px;" v-model="text"></textarea> <textarea style="height: 76px; width: 270px" v-model="text"></textarea>
</template> </template>
<template #footer> <template #footer>
<button @click="confirm">确定</button> <button @click="confirm">确定</button>
@ -10,18 +10,18 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { ref } from 'vue'
import { inject } from "vue"; import { inject } from 'vue'
import { TreeApi } from '@/api/tree' import { TreeApi } from '@/api/tree'
import Dialog from '@/components/dialog/baseDialog.vue' import Dialog from '@/components/dialog/baseDialog.vue'
import { initMapData } from '../tree/initMapData' import { initMapData } from '../tree/initMapData'
const baseDialog:any = ref(null); const baseDialog: any = ref(null)
const eventBus:any = inject("bus"); const eventBus: any = inject('bus')
const text = ref("") const text = ref('')
eventBus.on("openStandTextAdd", () => { eventBus.on('openStandTextAdd', () => {
baseDialog.value?.open() baseDialog.value?.open()
}); })
const open = () => { const open = () => {
baseDialog.value?.open() baseDialog.value?.open()
} }
@ -31,24 +31,27 @@ const confirm = () => {
text.value = '' text.value = ''
let Draw = new YJ.Draw.DrawPolyline(window.earth, { number: 2 }) let Draw = new YJ.Draw.DrawPolyline(window.earth, { number: 2 })
Draw.start(async (a, positions) => { Draw.start(async (a, positions) => {
if(!positions || positions.length < 2) { if (!positions || positions.length < 2) {
return return
} }
let id = new YJ.Tools().randomString() let id = new YJ.Tools().randomString()
let options: any = await initMapData('groundText', { let options: any = await initMapData('groundText', {
id: id, id: id,
name: name, name: name,
positions: positions, positions: positions
}) })
delete options.host delete options.host
let selectedNodes = window.treeObj.getSelectedNodes() let selectedNodes = window.treeObj.getSelectedNodes()
let params = { let params = {
"id": id, id: id,
"sourceName": name, sourceName: name,
"sourceType": "groundText", sourceType: 'groundText',
"parentId": (selectedNodes && selectedNodes[selectedNodes.length - 1]) ? selectedNodes[selectedNodes.length - 1].id : undefined, parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id
: undefined,
// "treeIndex": 0, // "treeIndex": 0,
"params": options params: options
} }
TreeApi.addOtherSource(params) TreeApi.addOtherSource(params)
}) })

View File

@ -1,7 +1,7 @@
<template> <template>
<Dialog ref="baseDialog" title="立体文字" left="calc(50% - 160px)" top="calc(50% - 120px)"> <Dialog ref="baseDialog" title="立体文字" left="calc(50% - 160px)" top="calc(50% - 120px)">
<template #content> <template #content>
<textarea style="height: 76px; width: 270px;" v-model="text"></textarea> <textarea style="height: 76px; width: 270px" v-model="text"></textarea>
</template> </template>
<template #footer> <template #footer>
<button @click="confirm">确定</button> <button @click="confirm">确定</button>
@ -10,18 +10,18 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { ref } from 'vue'
import { inject } from "vue"; import { inject } from 'vue'
import { TreeApi } from '@/api/tree' import { TreeApi } from '@/api/tree'
import Dialog from '@/components/dialog/baseDialog.vue' import Dialog from '@/components/dialog/baseDialog.vue'
import { initMapData } from '../tree/initMapData' import { initMapData } from '../tree/initMapData'
const baseDialog:any = ref(null); const baseDialog: any = ref(null)
const eventBus:any = inject("bus"); const eventBus: any = inject('bus')
const text = ref("") const text = ref('')
eventBus.on("openStandTextAdd", () => { eventBus.on('openStandTextAdd', () => {
baseDialog.value?.open() baseDialog.value?.open()
}); })
const open = () => { const open = () => {
baseDialog.value?.open() baseDialog.value?.open()
} }
@ -38,17 +38,20 @@ const confirm = () => {
let options: any = await initMapData('standText', { let options: any = await initMapData('standText', {
id: id, id: id,
name: name, name: name,
positions: positions, positions: positions
}) })
delete options.host delete options.host
let selectedNodes = window.treeObj.getSelectedNodes() let selectedNodes = window.treeObj.getSelectedNodes()
let params = { let params = {
"id": id, id: id,
"sourceName": name, sourceName: name,
"sourceType": "standText", sourceType: 'standText',
"parentId": (selectedNodes && selectedNodes[selectedNodes.length - 1]) ? selectedNodes[selectedNodes.length - 1].id : undefined, parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id
: undefined,
// "treeIndex": 0, // "treeIndex": 0,
"params": options params: options
} }
TreeApi.addOtherSource(params) TreeApi.addOtherSource(params)
}) })

View File

@ -2,9 +2,19 @@
<div class="attribute"> <div class="attribute">
<div class="row"> <div class="row">
<div class="col attribute-select-box"> <div class="col attribute-select-box">
<span class="label" style="line-height: 32px;">内容类型</span> <span class="label" style="line-height: 32px">内容类型</span>
<el-select style="width: 175px" v-model="attributeType" @change="attributeChange" placeholder="请选择"> <el-select
<el-option v-for="item in attributeSelect" :key="item.key" :label="item.name" :value="item.key"> style="width: 175px"
v-model="attributeType"
@change="attributeChange"
placeholder="请选择"
>
<el-option
v-for="item in attributeSelect"
:key="item.key"
:label="item.name"
:value="item.key"
>
</el-option> </el-option>
</el-select> </el-select>
</div> </div>
@ -20,8 +30,8 @@
<div class="row attribute-content attribute-content-link" v-show="attributeType === 'link'"> <div class="row attribute-content attribute-content-link" v-show="attributeType === 'link'">
<div class="col"> <div class="col">
<span class="label">添加链接</span> <span class="label">添加链接</span>
<div style="flex: 1;position: relative;"> <div style="flex: 1; position: relative">
<input class="input link_add" type="text" v-model="addlinkInput"> <input class="input link_add" type="text" v-model="addlinkInput" />
<i class="link_add_btn" @click="_addLink"></i> <i class="link_add_btn" @click="_addLink"></i>
</div> </div>
</div> </div>
@ -38,7 +48,7 @@
<div class="table-body" v-if="attribute.link.content && attribute.link.content.length > 0"> <div class="table-body" v-if="attribute.link.content && attribute.link.content.length > 0">
<div class="tr" v-for="(item, index) in attribute.link.content"> <div class="tr" v-for="(item, index) in attribute.link.content">
<div class="td" v-if="linkEditActive.index === index"> <div class="td" v-if="linkEditActive.index === index">
<input class="input" type="text" v-model="linkEditActive.name"> <input class="input" type="text" v-model="linkEditActive.name" />
</div> </div>
<div class="td" v-else>{{ item.name }}</div> <div class="td" v-else>{{ item.name }}</div>
<div class="td" v-if="linkEditActive.index === index"> <div class="td" v-if="linkEditActive.index === index">
@ -53,7 +63,6 @@
<button @click="linkEdit(index, item)">编辑</button> <button @click="linkEdit(index, item)">编辑</button>
<button @click="linkDelete(index)">删除</button> <button @click="linkDelete(index)">删除</button>
</div> </div>
</div> </div>
</div> </div>
<div class="table-empty" v-else> <div class="table-empty" v-else>
@ -66,7 +75,7 @@
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span class="label">编辑内容</span> <span class="label">编辑内容</span>
<input class="input" type="text" @model="cameraName" style="width: 100px;"> <input class="input" type="text" @model="cameraName" style="width: 100px" />
<button class="select btn" @click="cameraSelect">搜索</button> <button class="select btn" @click="cameraSelect">搜索</button>
</div> </div>
</div> </div>
@ -76,17 +85,17 @@
<div class="tr"> <div class="tr">
<div class="th">操作</div> <div class="th">操作</div>
<div class="th">设备名称</div> <div class="th">设备名称</div>
<div class="th" style="width: 80px; flex: 0 80px;min-width: 80px;">设备类型</div> <div class="th" style="width: 80px; flex: 0 80px; min-width: 80px">设备类型</div>
<div class="th" style="width: 126px; flex: 0 126px;min-width: 126px;">设备IP</div> <div class="th" style="width: 126px; flex: 0 126px; min-width: 126px">设备IP</div>
<div class="th" style="width: 80px; flex: 0 80px;min-width: 80px;">设备端口</div> <div class="th" style="width: 80px; flex: 0 80px; min-width: 80px">设备端口</div>
<div class="th" style="width: 80px; flex: 0 80px;min-width: 80px;">用户名</div> <div class="th" style="width: 80px; flex: 0 80px; min-width: 80px">用户名</div>
<div class="th">密码</div> <div class="th">密码</div>
</div> </div>
</div> </div>
<div class="table-body" style="display:none;"> <div class="table-body" style="display: none">
<div class="tr"> <div class="tr">
<div class="td"> <div class="td">
<input type="checkbox" value="2"> <input type="checkbox" value="2" />
<span>绑定</span> <span>绑定</span>
</div> </div>
<div class="td">设备名称</div> <div class="td">设备名称</div>
@ -119,19 +128,19 @@
<div class="table isc-table"> <div class="table isc-table">
<div class="table-head"> <div class="table-head">
<div class="tr"> <div class="tr">
<div class="th" style="width: 74px; flex: 0 74px;min-width: 74px;">操作</div> <div class="th" style="width: 74px; flex: 0 74px; min-width: 74px">操作</div>
<div class="th">设备名称</div> <div class="th">设备名称</div>
<div class="th" style="width: 180px; flex: 0 180px; min-width: 180px;">设备状态</div> <div class="th" style="width: 180px; flex: 0 180px; min-width: 180px">设备状态</div>
</div> </div>
</div> </div>
<div class="table-body" style="display:none;"> <div class="table-body" style="display: none">
<div class="tr"> <div class="tr">
<div class="td"> <div class="td">
<input type="checkbox" value="2"> <input type="checkbox" value="2" />
<span>绑定</span> <span>绑定</span>
</div> </div>
<div class="td">设备名称</div> <div class="td">设备名称</div>
<div class="td" style="width: 180px; flex: 0 180px; min-width: 180px;">设备状态</div> <div class="td" style="width: 180px; flex: 0 180px; min-width: 180px">设备状态</div>
</div> </div>
</div> </div>
<div class="table-empty"> <div class="table-empty">
@ -147,8 +156,8 @@
<div class="row attribute-content attribute-content-vr" v-show="attributeType === 'vr'"> <div class="row attribute-content attribute-content-vr" v-show="attributeType === 'vr'">
<div class="col"> <div class="col">
<span class="label">添加链接</span> <span class="label">添加链接</span>
<div style="flex: 1;position: relative;"> <div style="flex: 1; position: relative">
<input class="input vr_add" type="text"> <input class="input vr_add" type="text" />
<i class="vr_add_btn" @click="_addRr"></i> <i class="vr_add_btn" @click="_addRr"></i>
</div> </div>
</div> </div>
@ -162,8 +171,7 @@
<div class="th">操作</div> <div class="th">操作</div>
</div> </div>
</div> </div>
<div class="table-body"> <div class="table-body"></div>
</div>
<div class="table-empty"> <div class="table-empty">
<div class="empty-img"></div> <div class="empty-img"></div>
<p>暂无数据</p> <p>暂无数据</p>
@ -175,22 +183,26 @@
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span class="label">编辑内容</span> <span class="label">编辑内容</span>
<input class="input goods-select-input" type="text" style="width: 180px;margin-right: 10px;"> <input
class="input goods-select-input"
type="text"
style="width: 180px; margin-right: 10px"
/>
<button class="select btn" @click="goodsFilter">搜索</button> <button class="select btn" @click="goodsFilter">搜索</button>
</div> </div>
</div> </div>
<div class="table goods-table"> <div class="table goods-table">
<div class="table-head"> <div class="table-head">
<div class="tr"> <div class="tr">
<div class="th" style="width: 60px; flex: 0 60px;min-width: 60px;">序号</div> <div class="th" style="width: 60px; flex: 0 60px; min-width: 60px">序号</div>
<div class="th" style="flex: 0 0 280px;">名称</div> <div class="th" style="flex: 0 0 280px">名称</div>
<div class="th">数量</div> <div class="th">数量</div>
</div> </div>
</div> </div>
<div class="table-body" style="display:none;"> <div class="table-body" style="display: none">
<div class="tr"> <div class="tr">
<div class="td" style="width: 60px; flex: 0 60px;min-width: 60px;">序号</div> <div class="td" style="width: 60px; flex: 0 60px; min-width: 60px">序号</div>
<div class="td" style="flex: 0 0 280px;">名称</div> <div class="td" style="flex: 0 0 280px">名称</div>
<div class="td">数量</div> <div class="td">数量</div>
</div> </div>
</div> </div>
@ -205,11 +217,11 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { ref } from 'vue'
import { inject } from "vue"; import { inject } from 'vue'
const baseDialog:any = ref(null); const baseDialog: any = ref(null)
const eventBus:any = inject("bus"); const eventBus: any = inject('bus')
const attributeType = ref('richText') const attributeType = ref('richText')
const props = defineProps({ const props = defineProps({
@ -232,7 +244,7 @@ const attributeSelect = ref([
name: '链接', name: '链接',
value: '链接', value: '链接',
key: 'link' key: 'link'
}, }
// { // {
// name: 'IP摄像头', // name: 'IP摄像头',
// value: 'IP摄像头', // value: 'IP摄像头',
@ -260,10 +272,9 @@ const attributeSelect = ref([
// }, // },
]) ])
const cameraName = ref('') const cameraName = ref('')
const addlinkInput = ref('') const addlinkInput = ref('')
const linkEditActive:any = ref({}) const linkEditActive: any = ref({})
const openRichTextEditor = () => { const openRichTextEditor = () => {
eventBus.emit('openRichText', props.entityOptions.name, richTextContent.value, (val) => { eventBus.emit('openRichText', props.entityOptions.name, richTextContent.value, (val) => {
@ -278,16 +289,15 @@ const _addLink = () => {
} }
attribute.value.link.content.push(link) attribute.value.link.content.push(link)
addlinkInput.value = '' addlinkInput.value = ''
} } else {
else { document.getElementById('fileInputlink')?.click()
document.getElementById('fileInputlink')?.click();
eventBus.emit('defineClickAddLinkCb', (list) => { eventBus.emit('defineClickAddLinkCb', (list) => {
list.forEach((item) => { list.forEach((item) => {
attribute.value.link.content.push({ attribute.value.link.content.push({
name: "链接", name: '链接',
url: item.previewUrl, url: item.previewUrl
}); })
}); })
}) })
} }
} }
@ -309,12 +319,10 @@ const linkConfirmEdit = (index) => {
const linkCancelEdit = () => { const linkCancelEdit = () => {
linkEditActive.value = {} linkEditActive.value = {}
} }
const cameraSelect = () => { } const cameraSelect = () => {}
const _addRr = () => { } const _addRr = () => {}
const goodsFilter = () => { } const goodsFilter = () => {}
const attributeChange = () => { } const attributeChange = () => {}
</script> </script>
<style scoped lang="scss"></style> <style scoped lang="scss"></style>

View File

@ -1,78 +1,132 @@
<template> <template>
<Dialog ref="baseDialog" title="点标注" left="180px" top="100px" :className="'billboard-object'" <Dialog
:closeCallback="closeCallback"> ref="baseDialog"
title="点标注"
left="180px"
top="100px"
:className="'billboard-object'"
:closeCallback="closeCallback"
>
<template #content> <template #content>
<span class="custom-divider"></span> <span class="custom-divider"></span>
<div class="div-item"> <div class="div-item">
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span class="label" style="flex: unset;">名称</span> <span class="label" style="flex: unset">名称</span>
<input class="input" type="text" v-model="entityOptions.name" @change="changeName"> <input class="input" type="text" v-model="entityOptions.name" @change="changeName" />
</div>
<div class="col">
</div> </div>
<div class="col"></div>
</div> </div>
</div> </div>
<span class="custom-divider"></span> <span class="custom-divider"></span>
<div class="div-item"> <div class="div-item">
<div class="row"> <div class="row">
<div style="width: 46%;"> <div style="width: 46%">
<div class="row"> <div class="row">
<p class="lable-left-line">WGS84坐标</p> <p class="lable-left-line">WGS84坐标</p>
</div> </div>
<div class="row" style="margin-bottom: 5px;"> <div class="row" style="margin-bottom: 5px">
<div class="col"> <div class="col">
<span class="label">经度</span> <span class="label">经度</span>
<input class="input" type="number" title="" min="-180" max="180" v-model="entityOptions.lng" <input
@change="changLng"> class="input"
type="number"
title=""
min="-180"
max="180"
v-model="entityOptions.lng"
@change="changLng"
/>
</div> </div>
</div> </div>
<div class="row" style="margin-bottom: 5px;"> <div class="row" style="margin-bottom: 5px">
<div class="col"> <div class="col">
<span class="label">纬度</span> <span class="label">纬度</span>
<input class="input" type="number" title="" min="-90" max="90" v-model="entityOptions.lat" <input
@change="changLat"> class="input"
type="number"
title=""
min="-90"
max="90"
v-model="entityOptions.lat"
@change="changLat"
/>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span class="label">海拔高度</span> <span class="label">海拔高度</span>
<div class="input-number input-number-unit-1 alt-box" <div
:class="{ 'disabled': heightMode == 2 || heightMode === 3 }"> class="input-number input-number-unit-1 alt-box"
<input class="input" type="number" title="" min="-9999999" max="999999999" v-model="entityOptions.alt" :class="{ disabled: heightMode == 2 || heightMode === 3 }"
@change="changAlt"> >
<input
class="input"
type="number"
title=""
min="-9999999"
max="999999999"
v-model="entityOptions.alt"
@change="changAlt"
/>
<span class="unit">m</span> <span class="unit">m</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div style="width: 50%;"> <div style="width: 50%">
<div class="row coordinate-select-box"> <div class="row coordinate-select-box">
<div class="lable-left-line">转换坐标选择 <div class="lable-left-line">
<el-select class="input input-select coordinate-select" style="width: 155px;margin-left: 20px" 转换坐标选择
v-model="coordinate" @change="coordinateChange" placeholder="请选择"> <el-select
<el-option v-for="item in epsg_map" :key="item.epsg" :label="item.name" :value="item.epsg"> class="input input-select coordinate-select"
style="width: 155px; margin-left: 20px"
v-model="coordinate"
@change="coordinateChange"
placeholder="请选择"
>
<el-option
v-for="item in epsg_map"
:key="item.epsg"
:label="item.name"
:value="item.epsg"
>
</el-option> </el-option>
</el-select> </el-select>
</div> </div>
</div> </div>
<div class="row" style="margin-bottom: 5px;"> <div class="row" style="margin-bottom: 5px">
<div class="col"> <div class="col">
<span class="label">X轴:</span> <span class="label">X轴:</span>
<input style="border: none;background: none;" class="input convert-x" readonly v-model="x"> <input
style="border: none; background: none"
class="input convert-x"
readonly
v-model="x"
/>
</div> </div>
</div> </div>
<div class="row" style="margin-bottom: 5px;"> <div class="row" style="margin-bottom: 5px">
<div class="col"> <div class="col">
<span class="label">Y轴:</span> <span class="label">Y轴:</span>
<input style="border: none;background: none;" class="input convert-y" readonly v-model="y"> <input
style="border: none; background: none"
class="input convert-y"
readonly
v-model="y"
/>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span class="label">Z轴:</span> <span class="label">Z轴:</span>
<input style="border: none;background: none;" class="input convert-z" readonly v-model="z"> <input
style="border: none; background: none"
class="input convert-z"
readonly
v-model="z"
/>
</div> </div>
</div> </div>
</div> </div>
@ -81,14 +135,21 @@
<span class="custom-divider"></span> <span class="custom-divider"></span>
<div class="div-item"> <div class="div-item">
<div class="row"> <div class="row">
<div class="col" style="flex: 0 0 120px;"> <div class="col" style="flex: 0 0 120px">
<span class="label">视野缩放</span> <span class="label">视野缩放</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.scaleByDistance"> <input class="btn-switch" type="checkbox" v-model="entityOptions.scaleByDistance" />
</div> </div>
<div class="col"> <div class="col">
<span class="label">最近距离</span> <span class="label">最近距离</span>
<div class="input-number input-number-unit-1"> <div class="input-number input-number-unit-1">
<input class="input" type="number" title="" min="1" max="99999999" v-model="entityOptions.near"> <input
class="input"
type="number"
title=""
min="1"
max="99999999"
v-model="entityOptions.near"
/>
<span class="unit">m</span> <span class="unit">m</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
@ -96,7 +157,14 @@
<div class="col"> <div class="col">
<span class="label">最远距离</span> <span class="label">最远距离</span>
<div class="input-number input-number-unit-1"> <div class="input-number input-number-unit-1">
<input class="input" type="number" title="" min="1" max="99999999" v-model="entityOptions.far"> <input
class="input"
type="number"
title=""
min="1"
max="99999999"
v-model="entityOptions.far"
/>
<span class="unit">m</span> <span class="unit">m</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
@ -110,18 +178,35 @@
<el-tab-pane label="空间信息" name="2"> <el-tab-pane label="空间信息" name="2">
<div class="row"> <div class="row">
<div class="col height-mode-box"> <div class="col height-mode-box">
<span class="label" style="flex: 0 0 56px;">高度模式</span> <span class="label" style="flex: 0 0 56px">高度模式</span>
<el-select class="input input-select height-mode-scelect" style="width: 155px;margin-left: 20px" <el-select
v-model="heightMode" @change="heightModeChange" placeholder="请选择"> class="input input-select height-mode-scelect"
<el-option v-for="item in heightModeData" :key="item.key" :label="item.name" :value="item.key"> style="width: 155px; margin-left: 20px"
v-model="heightMode"
@change="heightModeChange"
placeholder="请选择"
>
<el-option
v-for="item in heightModeData"
:key="item.key"
:label="item.name"
:value="item.key"
>
</el-option> </el-option>
</el-select> </el-select>
</div> </div>
<div class="col height-box" v-show="heightMode == 0 || heightMode == 1"> <div class="col height-box" v-show="heightMode == 0 || heightMode == 1">
<span class="label" style="flex: 0 0 56px;">高度</span> <span class="label" style="flex: 0 0 56px">高度</span>
<div class="input-number input-number-unit-1"> <div class="input-number input-number-unit-1">
<input class="input height" type="number" title="" min="-9999999" max="999999999" v-model="height" <input
@change="changHeight"> class="input height"
type="number"
title=""
min="-9999999"
max="999999999"
v-model="height"
@change="changHeight"
/>
<span class="unit">m</span> <span class="unit">m</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
@ -129,92 +214,134 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<div class="YJ-custom-checkbox-box" style="display: flex;align-items: center;cursor: pointer;" <div
@click="formatChange(1)"> class="YJ-custom-checkbox-box"
<input type="checkbox" class="YJ-custom-checkbox" v-model="format1"> style="display: flex; align-items: center; cursor: pointer"
<span style="margin-left: 10px; margin-bottom: 1px;user-select: none;">小数格式</span> @click="formatChange(1)"
>
<input type="checkbox" class="YJ-custom-checkbox" v-model="format1" />
<span style="margin-left: 10px; margin-bottom: 1px; user-select: none"
>小数格式</span
>
</div> </div>
</div> </div>
<div class="col"> <div class="col">
<div class="YJ-custom-checkbox-box" style="display: flex;align-items: center;cursor: pointer;" <div
@click="formatChange(2)"> class="YJ-custom-checkbox-box"
<input type="checkbox" class="YJ-custom-checkbox" v-model="format2"> style="display: flex; align-items: center; cursor: pointer"
<span style="margin-left: 10px; margin-bottom: 1px;user-select: none;">度分格式</span> @click="formatChange(2)"
>
<input type="checkbox" class="YJ-custom-checkbox" v-model="format2" />
<span style="margin-left: 10px; margin-bottom: 1px; user-select: none"
>度分格式</span
>
</div> </div>
</div> </div>
<div class="col"> <div class="col">
<div class="YJ-custom-checkbox-box" style="display: flex;align-items: center;cursor: pointer;" <div
@click="formatChange(3)"> class="YJ-custom-checkbox-box"
<input type="checkbox" class="YJ-custom-checkbox" v-model="format3"> style="display: flex; align-items: center; cursor: pointer"
<span style="margin-left: 10px; margin-bottom: 1px;user-select: none;">度分秒格式</span> @click="formatChange(3)"
>
<input type="checkbox" class="YJ-custom-checkbox" v-model="format3" />
<span style="margin-left: 10px; margin-bottom: 1px; user-select: none"
>度分秒格式</span
>
</div> </div>
</div> </div>
<div class="col"> <div class="col"></div>
</div>
</div> </div>
<div class="row"> <div class="row">
<div style="flex: 1;"> <div style="flex: 1">
<div class="proj-input-box" v-show="format1"> <div class="proj-input-box" v-show="format1">
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span style="flex: 0 0 40px;">经度</span> <span style="flex: 0 0 40px">经度</span>
<input class="input lng" readonly :value="entityOptions.lng"> <input class="input lng" readonly :value="entityOptions.lng" />
</div>
<div class="col">
</div> </div>
<div class="col"></div>
</div> </div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span style="flex: 0 0 40px;">纬度</span> <span style="flex: 0 0 40px">纬度</span>
<input class="input lat" readonly :value="entityOptions.lat"> <input class="input lat" readonly :value="entityOptions.lat" />
</div>
<div class="col">
</div> </div>
<div class="col"></div>
</div> </div>
</div> </div>
<div class="proj-input-box" style="width: 56%;" v-show="format2"> <div class="proj-input-box" style="width: 56%" v-show="format2">
<div class="row"> <div class="row">
<div class="col" style="flex-direction: column;"> <div class="col" style="flex-direction: column">
<div class="row" style="margin-bottom: 15px;"> <div class="row" style="margin-bottom: 15px">
<span style="flex: 0 0 40px;">经度</span> <span style="flex: 0 0 40px">经度</span>
<input class="input lng-dm-d" style="flex: 1;" readonly :value="lngDmD"> <input class="input lng-dm-d" style="flex: 1" readonly :value="lngDmD" />
<span class="label" style="flex: 0 0 14px;margin: 0 10px;"></span> <span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<input class="input lng-dm-m" style="flex: 1;" readonly :value="lngDmM"> <input class="input lng-dm-m" style="flex: 1" readonly :value="lngDmM" />
<span class="label" style="flex: 0 0 14px;margin: 0 10px;"></span> <span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<span class="top-line"></span> <span class="top-line"></span>
</div> </div>
<div class="row"> <div class="row">
<span style="flex: 0 0 40px;">纬度</span> <span style="flex: 0 0 40px">纬度</span>
<input class="input lat-dm-d" style="flex: 1;" readonly :value="latDmD"> <input class="input lat-dm-d" style="flex: 1" readonly :value="latDmD" />
<span class="label" style="flex: 0 0 14px;margin: 0 10px;"></span> <span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<input class="input lat-dm-m" style="flex: 1;" readonly :value="latDmM"> <input class="input lat-dm-m" style="flex: 1" readonly :value="latDmM" />
<span class="label" style="flex: 0 0 14px;margin: 0 10px;"></span> <span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<span class="bottom-line"></span> <span class="bottom-line"></span>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="proj-input-box" style="width: 70%;" v-show="format3"> <div class="proj-input-box" style="width: 70%" v-show="format3">
<div class="row"> <div class="row">
<div class="col" style="flex-direction: column;"> <div class="col" style="flex-direction: column">
<div class="row" style="margin-bottom: 15px;"> <div class="row" style="margin-bottom: 15px">
<span style="flex: 0 0 40px;">经度</span> <span style="flex: 0 0 40px">经度</span>
<input class="input lng-dms-d" style="flex: 1;" readonly :value="lngDmsD"> <input
<span class="label" style="flex: 0 0 14px;margin: 0 10px;"></span> class="input lng-dms-d"
<input class="input lng-dms-m" style="flex: 1;" readonly :value="lngDmsM"> style="flex: 1"
<span class="label" style="flex: 0 0 14px;margin: 0 10px;"></span> readonly
<input class="input lng-dms-s" style="flex: 1;" readonly :value="lngDmsS"> :value="lngDmsD"
<span class="label" style="flex: 0 0 14px;margin: 0 10px;"></span> />
<span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<input
class="input lng-dms-m"
style="flex: 1"
readonly
:value="lngDmsM"
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<input
class="input lng-dms-s"
style="flex: 1"
readonly
:value="lngDmsS"
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<span class="top-line"></span> <span class="top-line"></span>
</div> </div>
<div class="row"> <div class="row">
<span style="flex: 0 0 40px;">纬度</span> <span style="flex: 0 0 40px">纬度</span>
<input class="input lat-dms-d" style="flex: 1;" readonly :value="latDmsD"> <input
<span class="label" style="flex: 0 0 14px;margin: 0 10px;"></span> class="input lat-dms-d"
<input class="input lat-dms-m" style="flex: 1;" readonly :value="latDmsM"> style="flex: 1"
<span class="label" style="flex: 0 0 14px;margin: 0 10px;"></span> readonly
<input class="input lat-dms-s" style="flex: 1;" readonly :value="latDmsS"> :value="latDmsD"
<span class="label" style="flex: 0 0 14px;margin: 0 10px;"></span> />
<span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<input
class="input lat-dms-m"
style="flex: 1"
readonly
:value="latDmsM"
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<input
class="input lat-dms-s"
style="flex: 1"
readonly
:value="latDmsS"
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<span class="bottom-line"></span> <span class="bottom-line"></span>
</div> </div>
</div> </div>
@ -226,28 +353,38 @@
<el-tab-pane label="标注风格" name="3"> <el-tab-pane label="标注风格" name="3">
<div> <div>
<h4>图标设置</h4> <h4>图标设置</h4>
<div class="row" style="margin-bottom: 10px;"> <div class="row" style="margin-bottom: 10px">
<div class="col" style="flex: 0 0 80px;"> <div class="col" style="flex: 0 0 80px">
<span class="label" style="flex: none;">显隐</span> <span class="label" style="flex: none">显隐</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.billboardShow"> <input
class="btn-switch"
type="checkbox"
v-model="entityOptions.billboardShow"
/>
</div> </div>
<div class="col" style="flex: 0 0 90px;"> <div class="col" style="flex: 0 0 90px">
<span class="label" style="flex: none;">图标</span> <span class="label" style="flex: none">图标</span>
<div class="image-box" @click="clickChangeImage"> <div class="image-box" @click="clickChangeImage">
<img class="image" :src="entityOptions.billboardImage" alt=""> <img class="image" :src="entityOptions.billboardImage" alt="" />
</div> </div>
</div> </div>
<div class="col" style="flex: 0 0 90px;"> <div class="col" style="flex: 0 0 90px">
<span class="label" style="flex: none;">默认图标</span> <span class="label" style="flex: none">默认图标</span>
<div class="image-box" @click="clickChangeDefaultImage"> <div class="image-box" @click="clickChangeDefaultImage">
<img class="image" :src="entityOptions.billboardDefaultImage" alt=""> <img class="image" :src="entityOptions.billboardDefaultImage" alt="" />
</div> </div>
</div> </div>
<div class="col"> <div class="col">
<span class="label">图标倍数</span> <span class="label">图标倍数</span>
<div class="input-number input-number-unit-2"> <div class="input-number input-number-unit-2">
<input class="input" type="number" title="" min="0.1" max="99" <input
v-model="entityOptions.billboardScale"> class="input"
type="number"
title=""
min="0.1"
max="99"
v-model="entityOptions.billboardScale"
/>
<span class="unit"></span> <span class="unit"></span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
@ -257,22 +394,38 @@
<div> <div>
<h4>文字设置</h4> <h4>文字设置</h4>
<div class="row"> <div class="row">
<div class="col" style="flex: 0 0 80px;"> <div class="col" style="flex: 0 0 80px">
<span class="label" style="flex: none;">显隐</span> <span class="label" style="flex: none">显隐</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.labelShow"> <input class="btn-switch" type="checkbox" v-model="entityOptions.labelShow" />
</div> </div>
<div class="col font-select-box"> <div class="col font-select-box">
<span class="label" style="flex: none;">字体选择</span> <span class="label" style="flex: none">字体选择</span>
<el-select class="input input-select font-select" style="width: 100px;" v-model="entityOptions.labelFontFamily"> <el-select
<el-option v-for="item in fontList" :key="item.key" :label="item.name" :value="item.key"> class="input input-select font-select"
style="width: 100px"
v-model="entityOptions.labelFontFamily"
>
<el-option
v-for="item in fontList"
:key="item.key"
:label="item.name"
:value="item.key"
>
</el-option> </el-option>
</el-select> </el-select>
</div> </div>
<div class="col"> <div class="col">
<span class="label">文字大小</span> <span class="label">文字大小</span>
<div class="input-number input-number-unit-2"> <div class="input-number input-number-unit-2">
<input class="input" type="number" title="" min="1" max="99" v-model="entityOptions.labelFontSize" <input
style="width: 70px;"> class="input"
type="number"
title=""
min="1"
max="99"
v-model="entityOptions.labelFontSize"
style="width: 70px"
/>
<span class="unit">px</span> <span class="unit">px</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
@ -289,11 +442,13 @@
</div> </div>
</template> </template>
<template #footer> <template #footer>
<div style="position: absolute; left: 24px; display: flex;"> <div style="position: absolute; left: 24px; display: flex">
<button @click="updateHeight"><svg class="icon-updateheigh"> <button @click="updateHeight">
<use xlink:href="#yj-icon-updateheight"></use> <svg class="icon-updateheigh">
</svg>更新高程</button> <use xlink:href="#yj-icon-updateheight"></use></svg
<button style="margin-left: 10px;" @click="translate">平移</button> >更新高程
</button>
<button style="margin-left: 10px" @click="translate">平移</button>
</div> </div>
<button @click="confirm">确定</button> <button @click="confirm">确定</button>
<button @click="close">关闭</button> <button @click="close">关闭</button>
@ -302,8 +457,8 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { ref } from 'vue'
import { inject } from "vue"; import { inject } from 'vue'
import { TreeApi } from '@/api/tree' import { TreeApi } from '@/api/tree'
import Dialog from '@/components/dialog/baseDialog.vue' import Dialog from '@/components/dialog/baseDialog.vue'
import attribute from './attribute.vue' import attribute from './attribute.vue'
@ -312,15 +467,17 @@ import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
const { cusUpdateNode } = useTreeNode() const { cusUpdateNode } = useTreeNode()
const baseDialog:any = ref(null); const baseDialog: any = ref(null)
const eventBus:any = inject("bus"); const eventBus: any = inject('bus')
const epsg_map = ref([{ const epsg_map = ref([
"name": "WGS 84 / UTM zone 3N", {
"epsg": "EPSG:32603", name: 'WGS 84 / UTM zone 3N',
"def": "+proj=utm +zone=3 +datum=WGS84 +units=m +no_defs" epsg: 'EPSG:32603',
}]) def: '+proj=utm +zone=3 +datum=WGS84 +units=m +no_defs'
let array:any[] = [] }
])
let array: any[] = []
for (const [key, value] of window.earth.proj.epsg_map) { for (const [key, value] of window.earth.proj.epsg_map) {
let item = structuredClone(value) let item = structuredClone(value)
item.name = item.name + `(${item.epsg}})` item.name = item.name + `(${item.epsg}})`
@ -367,10 +524,10 @@ const heightModeData = ref([
} }
]) ])
const activeName = ref('1') const activeName = ref('1')
const entityOptions:any = ref({}); const entityOptions: any = ref({})
const x = ref(); const x = ref()
const y = ref(); const y = ref()
const z = ref(); const z = ref()
const coordinate = ref('EPSG:4326') const coordinate = ref('EPSG:4326')
const heightMode = ref(0) const heightMode = ref(0)
const labelColorRef = ref(null) const labelColorRef = ref(null)
@ -397,7 +554,7 @@ const open = async (id) => {
defaultColor: entityOptions.value.labelColor, defaultColor: entityOptions.value.labelColor,
disabled: false, //是否禁止打开颜色选择器 disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画 openPickerAni: 'opacity', //打开颜色选择器动画
sure: color => { sure: (color) => {
entityOptions.value.labelColor = color entityOptions.value.labelColor = color
}, //点击确认按钮事件回调 }, //点击确认按钮事件回调
clear: () => { clear: () => {
@ -410,10 +567,9 @@ const closeCallback = () => {
entityOptions.value.originalOptions = structuredClone(originalOptions) entityOptions.value.originalOptions = structuredClone(originalOptions)
that.positionEditing = false that.positionEditing = false
that.reset() that.reset()
eventBus?.emit("destroyComponent") eventBus?.emit('destroyComponent')
} }
const changeName = (e) => { const changeName = (e) => {
entityOptions.value.labelText = e.target.value entityOptions.value.labelText = e.target.value
} }
@ -435,7 +591,6 @@ const coordinateChange = () => {
z.value = position[0].z z.value = position[0].z
} }
const heightModeChange = (val) => { const heightModeChange = (val) => {
switch (val) { switch (val) {
case 0: case 0:
@ -445,15 +600,9 @@ const heightModeChange = (val) => {
case 1: case 1:
case '1': case '1':
if (window.earth.viewer.scene.terrainProvider.availability) { if (window.earth.viewer.scene.terrainProvider.availability) {
window.Cesium.sampleTerrainMostDetailed( window.Cesium.sampleTerrainMostDetailed(window.earth.viewer.scene.terrainProvider, [
window.earth.viewer.scene.terrainProvider, window.Cesium.Cartographic.fromDegrees(entityOptions.value.lng, entityOptions.value.lat)
[ ]).then((position) => {
window.Cesium.Cartographic.fromDegrees(
entityOptions.value.lng,
entityOptions.value.lat
)
]
).then(position => {
height.value = entityOptions.value.alt - Number(position[0].height.toFixed(2)) height.value = entityOptions.value.alt - Number(position[0].height.toFixed(2))
}) })
} else { } else {
@ -471,10 +620,12 @@ const heightModeChange = (val) => {
objectsToExclude.push((value as any).entity) objectsToExclude.push((value as any).entity)
} }
} }
entityOptions.value.getClampToHeight(entityOptions.value.options.position, objectsToExclude).then(h => { entityOptions.value
height.value = Number(h.toFixed(2)) .getClampToHeight(entityOptions.value.options.position, objectsToExclude)
entityOptions.value.alt = Number(h.toFixed(2)) .then((h) => {
}) height.value = Number(h.toFixed(2))
entityOptions.value.alt = Number(h.toFixed(2))
})
break break
} }
that.heightMode = val that.heightMode = val
@ -496,24 +647,14 @@ const changAlt = () => {
const changHeight = () => { const changHeight = () => {
switch (heightMode.value) { switch (heightMode.value) {
case 0: case 0:
entityOptions.value.alt = Number( entityOptions.value.alt = Number(Number(height.value).toFixed(2))
Number(height.value).toFixed(2)
)
break break
case 1: case 1:
if (window.earth.viewer.scene.terrainProvider.availability) { if (window.earth.viewer.scene.terrainProvider.availability) {
window.Cesium.sampleTerrainMostDetailed( window.Cesium.sampleTerrainMostDetailed(window.earth.viewer.scene.terrainProvider, [
window.earth.viewer.scene.terrainProvider, window.Cesium.Cartographic.fromDegrees(entityOptions.value.lng, entityOptions.value.lat)
[ ]).then((position) => {
window.Cesium.Cartographic.fromDegrees( entityOptions.value.alt = Number(height.value) + Number(position[0].height.toFixed(2))
entityOptions.value.lng,
entityOptions.value.lat
)
]
).then(position => {
entityOptions.value.alt =
Number(height.value) +
Number(position[0].height.toFixed(2))
}) })
} else { } else {
entityOptions.value.alt = Number(height.value) entityOptions.value.alt = Number(height.value)
@ -524,7 +665,7 @@ const changHeight = () => {
coordinateChange() coordinateChange()
} }
const handleClick = () => { } const handleClick = () => {}
const formatChange = (val) => { const formatChange = (val) => {
switch (val) { switch (val) {
@ -600,7 +741,6 @@ const translate = () => {
that.openPositionEditing(() => { that.openPositionEditing(() => {
changAlt() changAlt()
}) })
} }
const confirm = () => { const confirm = () => {
originalOptions = structuredClone(that.options) originalOptions = structuredClone(that.options)
@ -608,33 +748,28 @@ const confirm = () => {
let params = structuredClone(that.options) let params = structuredClone(that.options)
delete params.host delete params.host
let params2 = { let params2 = {
"id": params.id, id: params.id,
"sourceName": params.name, sourceName: params.name,
"params": params, params: params,
"isShow": params.show ? 1 : 0, isShow: params.show ? 1 : 0
} }
TreeApi.updateDirectoryInfo(params2) TreeApi.updateDirectoryInfo(params2)
cusUpdateNode({"id": params.id, "sourceName": params.name, "params": JSON.stringify(params)}) cusUpdateNode({ id: params.id, sourceName: params.name, params: JSON.stringify(params) })
} }
const close = () => { const close = () => {
baseDialog.value?.close() baseDialog.value?.close()
} }
const clickChangeImage = () => { const clickChangeImage = () => {
eventBus?.emit("openImageSelect") eventBus?.emit('openImageSelect')
} }
const clickChangeDefaultImage = () => { const clickChangeDefaultImage = () => {
eventBus?.emit("openImageSelect") eventBus?.emit('openImageSelect')
} }
const fontChange = (val) => { const fontChange = (val) => {
entityOptions.value.labelFontFamily = val entityOptions.value.labelFontFamily = val
} }
defineExpose({ defineExpose({
open open
}) })

View File

@ -1,14 +1,21 @@
<template> <template>
<Dialog ref="baseDialog" title="曲线标注" left="180px" top="100px" className="polyline" :closeCallback="closeCallback"> <Dialog
ref="baseDialog"
title="曲线标注"
left="180px"
top="100px"
className="polyline"
:closeCallback="closeCallback"
>
<template #content> <template #content>
<span class="custom-divider"></span> <span class="custom-divider"></span>
<div class="div-item"> <div class="div-item">
<div class="row" style="align-items: flex-start;"> <div class="row" style="align-items: flex-start">
<div class="col"> <div class="col">
<span class="label">名称</span> <span class="label">名称</span>
<input class="input" maxlength="40" type="text" v-model="entityOptions.name"> <input class="input" maxlength="40" type="text" v-model="entityOptions.name" />
</div> </div>
<div class="col" style="flex: 0 0 56%;"> <div class="col" style="flex: 0 0 56%">
<div> <div>
<div class="row"> <div class="row">
<div class="col input-select-unit-box"> <div class="col input-select-unit-box">
@ -17,7 +24,7 @@
<el-option label="投影长度" value="1"></el-option> <el-option label="投影长度" value="1"></el-option>
<el-option label="地表长度" value="2"></el-option> <el-option label="地表长度" value="2"></el-option>
</el-select> </el-select>
<input v-model="length" class="input-text" readonly> <input v-model="length" class="input-text" readonly />
<el-select v-model="lengthUnit"> <el-select v-model="lengthUnit">
<el-option label="米" value="m"></el-option> <el-option label="米" value="m"></el-option>
<el-option label="千米" value="km"></el-option> <el-option label="千米" value="km"></el-option>
@ -37,22 +44,48 @@
<el-tab-pane label="空间信息" name="2"> <el-tab-pane label="空间信息" name="2">
<div class="row"> <div class="row">
<div class="col height-mode-box"> <div class="col height-mode-box">
<span class="label" style="flex: 0 0 56px;">高度模式</span> <span class="label" style="flex: 0 0 56px">高度模式</span>
<el-select class="input input-select height-mode-scelect" style="width: 155px;margin-left: 20px" <el-select
v-model="heightMode" @change="heightModeChange" placeholder="请选择"> class="input input-select height-mode-scelect"
<el-option v-for="item in heightModeData" :key="item.key" :label="item.name" :value="item.key"> style="width: 155px; margin-left: 20px"
v-model="heightMode"
@change="heightModeChange"
placeholder="请选择"
>
<el-option
v-for="item in heightModeData"
:key="item.key"
:label="item.name"
:value="item.key"
>
</el-option> </el-option>
</el-select> </el-select>
</div> </div>
<div class="col"> <div class="col">
<span class="label">Z值统一增加</span> <span class="label">Z值统一增加</span>
<div class="input-number input-number-unit-1 height-box" :class="{ 'disabled': heightMode == 2 }"> <div
<input class="input height" type="number" title="" min="-9999999" max="999999999" v-model="height"> class="input-number input-number-unit-1 height-box"
:class="{ disabled: heightMode == 2 }"
>
<input
class="input height"
type="number"
title=""
min="-9999999"
max="999999999"
v-model="height"
/>
<span class="unit">m</span> <span class="unit">m</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
<button class="confirm height-confirm" style="margin-left: 5px;" @click="heightConfirm" <button
:disabled="heightMode == 2">应用</button> class="confirm height-confirm"
style="margin-left: 5px"
@click="heightConfirm"
:disabled="heightMode == 2"
>
应用
</button>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
@ -69,20 +102,40 @@
<div class="tr" v-for="(item, i) in entityOptions.options.positions" :key="i"> <div class="tr" v-for="(item, i) in entityOptions.options.positions" :key="i">
<div class="td">{{ i + 1 }}</div> <div class="td">{{ i + 1 }}</div>
<div class="td lng align-center" @dblclick="inputDblclick($event, i, 'lng')"> <div class="td lng align-center" @dblclick="inputDblclick($event, i, 'lng')">
<input class="input" @blur="inputBlurCallBack($event, i, 'lng', 8)" type="number" <input
v-model="item.lng" min="-180" max="180" v-if="activeTd.index == i && activeTd.name == 'lng'"> class="input"
<span style="pointer-events: none;" v-else>{{ (item.lng).toFixed(8) }}</span> @blur="inputBlurCallBack($event, i, 'lng', 8)"
type="number"
v-model="item.lng"
min="-180"
max="180"
v-if="activeTd.index == i && activeTd.name == 'lng'"
/>
<span style="pointer-events: none" v-else>{{ item.lng.toFixed(8) }}</span>
</div> </div>
<div class="td lat align-center" @dblclick="inputDblclick($event, i, 'lat')"> <div class="td lat align-center" @dblclick="inputDblclick($event, i, 'lat')">
<input class="input" @blur="inputBlurCallBack($event, i, 'lat', 8)" type="number" <input
v-model="item.lat" min="-180" max="180" v-if="activeTd.index == i && activeTd.name == 'lat'"> class="input"
<span style="pointer-events: none;" v-else>{{ (item.lat).toFixed(8) }}</span> @blur="inputBlurCallBack($event, i, 'lat', 8)"
type="number"
v-model="item.lat"
min="-180"
max="180"
v-if="activeTd.index == i && activeTd.name == 'lat'"
/>
<span style="pointer-events: none" v-else>{{ item.lat.toFixed(8) }}</span>
</div> </div>
<div class="td alt align-center" @dblclick="inputDblclick($event, i, 'alt')"> <div class="td alt align-center" @dblclick="inputDblclick($event, i, 'alt')">
<input class="input" @blur="inputBlurCallBack($event, i, 'alt', 2)" type="number" <input
v-model="item.alt" min="-9999999" max="999999999" class="input"
v-if="activeTd.index == i && activeTd.name == 'alt'"> @blur="inputBlurCallBack($event, i, 'alt', 2)"
<span style="pointer-events: none;" v-else>{{ (item.alt).toFixed(2) }}</span> type="number"
v-model="item.alt"
min="-9999999"
max="999999999"
v-if="activeTd.index == i && activeTd.name == 'alt'"
/>
<span style="pointer-events: none" v-else>{{ item.alt.toFixed(2) }}</span>
</div> </div>
</div> </div>
</div> </div>
@ -95,19 +148,35 @@
<span class="label">线条颜色</span> <span class="label">线条颜色</span>
<div class="color" ref="colorRef"></div> <div class="color" ref="colorRef"></div>
</div> </div>
<div class="col" style="flex: 0 0 33%;"> <div class="col" style="flex: 0 0 33%">
<span class="label">线条宽度</span> <span class="label">线条宽度</span>
<div class="input-number input-number-unit-1" style="width: 80px;"> <div class="input-number input-number-unit-1" style="width: 80px">
<input class="input" type="number" title="" min="1" max="999" v-model="entityOptions.lineWidth"> <input
class="input"
type="number"
title=""
min="1"
max="999"
v-model="entityOptions.lineWidth"
/>
<span class="unit">px</span> <span class="unit">px</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
</div> </div>
<div class="col input-select-line-type-box" style="flex: 0 0 37%;"> <div class="col input-select-line-type-box" style="flex: 0 0 37%">
<span class="label">线条形式</span> <span class="label">线条形式</span>
<el-select class="input input-select input-select-line-type" style="margin-left: 20px" <el-select
v-model="entityOptions.lineType" @change="lineTypechange"> class="input input-select input-select-line-type"
<el-option v-for="item in lineTypeData" :key="item.key" :label="item.name" :value="item.key"> style="margin-left: 20px"
v-model="entityOptions.lineType"
@change="lineTypechange"
>
<el-option
v-for="item in lineTypeData"
:key="item.key"
:label="item.name"
:value="item.key"
>
<i class="yj-custom-icon" :class="item.icon"></i> <i class="yj-custom-icon" :class="item.icon"></i>
{{ item.name }} {{ item.name }}
</el-option> </el-option>
@ -117,18 +186,25 @@
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span class="label">线段缓冲</span> <span class="label">线段缓冲</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.extend"> <input class="btn-switch" type="checkbox" v-model="entityOptions.extend" />
</div> </div>
<div class="col" style="flex: 0 0 33%;"> <div class="col" style="flex: 0 0 33%">
<span class="label">缓冲宽度</span> <span class="label">缓冲宽度</span>
<div class="input-number input-number-unit-1" style="width: 80px;"> <div class="input-number input-number-unit-1" style="width: 80px">
<input class="input" type="number" title="" min="0" data-min="0.01" max="999999" <input
v-model="entityOptions.extendWidth"> class="input"
type="number"
title=""
min="0"
data-min="0.01"
max="999999"
v-model="entityOptions.extendWidth"
/>
<span class="unit">m</span> <span class="unit">m</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
</div> </div>
<div class="col" style="flex: 0 0 37%;"> <div class="col" style="flex: 0 0 37%">
<span class="label">缓冲颜色</span> <span class="label">缓冲颜色</span>
<div class="extendColor" ref="extendColorRef"></div> <div class="extendColor" ref="extendColorRef"></div>
</div> </div>
@ -136,23 +212,43 @@
<div class="row" v-show="entityOptions.lineType > 2 && entityOptions.lineType < 13"> <div class="row" v-show="entityOptions.lineType > 2 && entityOptions.lineType < 13">
<div class="col"> <div class="col">
<span class="label">首尾反向</span> <span class="label">首尾反向</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.rotate"> <input class="btn-switch" type="checkbox" v-model="entityOptions.rotate" />
</div> </div>
<div class="col" style="flex: 0 0 33%;"> <div class="col" style="flex: 0 0 33%">
<span class="label">流动速率</span> <span class="label">流动速率</span>
<div class="input-number input-number-unit-1" style="width: 80px;"> <div class="input-number input-number-unit-1" style="width: 80px">
<input class="input" type="number" title="" min="0" max="999999" step="1" <input
v-model="entityOptions.speed"> class="input"
type="number"
title=""
min="0"
max="999999"
step="1"
v-model="entityOptions.speed"
/>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
</div> </div>
<div class="col" style="flex: 0 0 37%;"> <div class="col" style="flex: 0 0 37%">
<span class="label lineSpace" <span
v-show="entityOptions.lineType > 2 && entityOptions.lineType >= 5">线条间距</span> class="label lineSpace"
<div class="input-number input-number-unit-1 lineSpace" style="width: 80px;" v-show="entityOptions.lineType > 2 && entityOptions.lineType >= 5"
v-show="entityOptions.lineType > 2 && entityOptions.lineType >= 5"> >线条间距</span
<input class="input" type="number" title="" min="0" max="4.5" step="0.1" >
v-model="entityOptions.space"> <div
class="input-number input-number-unit-1 lineSpace"
style="width: 80px"
v-show="entityOptions.lineType > 2 && entityOptions.lineType >= 5"
>
<input
class="input"
type="number"
title=""
min="0"
max="4.5"
step="0.1"
v-model="entityOptions.space"
/>
<span class="unit"></span> <span class="unit"></span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
@ -161,7 +257,7 @@
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span class="label">首尾相连</span> <span class="label">首尾相连</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.noseToTail"> <input class="btn-switch" type="checkbox" v-model="entityOptions.noseToTail" />
</div> </div>
</div> </div>
</el-tab-pane> </el-tab-pane>
@ -173,11 +269,13 @@
</div> </div>
</template> </template>
<template #footer> <template #footer>
<div style="position: absolute; left: 24px; display: flex;"> <div style="position: absolute; left: 24px; display: flex">
<button @click="nodeEdit"><svg class="icon-edit"> <button @click="nodeEdit">
<use xlink:href="#yj-icon-edit"></use> <svg class="icon-edit">
</svg>二次编辑</button> <use xlink:href="#yj-icon-edit"></use></svg
<button style="margin-left: 10px;" @click="translate">平移</button> >二次编辑
</button>
<button style="margin-left: 10px" @click="translate">平移</button>
</div> </div>
<button @click="confirm">确定</button> <button @click="confirm">确定</button>
<button @click="close">关闭</button> <button @click="close">关闭</button>
@ -186,8 +284,8 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, getCurrentInstance } from 'vue'; import { ref, getCurrentInstance } from 'vue'
import { inject } from "vue"; import { inject } from 'vue'
import { TreeApi } from '@/api/tree' import { TreeApi } from '@/api/tree'
import Dialog from '@/components/dialog/baseDialog.vue' import Dialog from '@/components/dialog/baseDialog.vue'
import { initMapData } from '../tree/initMapData' import { initMapData } from '../tree/initMapData'
@ -198,8 +296,8 @@ import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
const { cusUpdateNode } = useTreeNode() const { cusUpdateNode } = useTreeNode()
const baseDialog:any = ref(null); const baseDialog: any = ref(null)
const eventBus:any = inject("bus"); const eventBus: any = inject('bus')
const length = ref(0) const length = ref(0)
const lengthUnit = ref('m') const lengthUnit = ref('m')
@ -307,7 +405,7 @@ const activeTd = ref({
index: -1, index: -1,
name: '' name: ''
}) })
const entityOptions:any = ref({}); const entityOptions: any = ref({})
const linePositions = ref([]) const linePositions = ref([])
const colorRef = ref(null) const colorRef = ref(null)
const extendColorRef = ref(null) const extendColorRef = ref(null)
@ -316,7 +414,6 @@ const heightMode = ref(0)
let originalOptions let originalOptions
let that let that
const open = async (id) => { const open = async (id) => {
that = window.earth.entityMap.get(id) that = window.earth.entityMap.get(id)
originalOptions = structuredClone(that.options) originalOptions = structuredClone(that.options)
@ -324,13 +421,12 @@ const open = async (id) => {
heightMode.value = entityOptions.value.heightMode heightMode.value = entityOptions.value.heightMode
length.value = entityOptions.value.lengthByMeter length.value = entityOptions.value.lengthByMeter
linePositions.value = structuredClone(that.options.positions) linePositions.value = structuredClone(that.options.positions)
that.lengthChangeCallBack = ()=>{ that.lengthChangeCallBack = () => {
if (lengthUnit.value == 'km') { if (lengthUnit.value == 'km') {
length.value = entityOptions.value.lengthByMeter / 1000 length.value = entityOptions.value.lengthByMeter / 1000
} } else {
else { length.value = entityOptions.value.lengthByMeter
length.value = entityOptions.value.lengthByMeter }
}
} }
heightModeChange(heightMode.value) heightModeChange(heightMode.value)
baseDialog.value?.open() baseDialog.value?.open()
@ -343,7 +439,7 @@ const open = async (id) => {
defaultColor: entityOptions.value.color, defaultColor: entityOptions.value.color,
disabled: false, //是否禁止打开颜色选择器 disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画 openPickerAni: 'opacity', //打开颜色选择器动画
sure: color => { sure: (color) => {
entityOptions.value.color = color entityOptions.value.color = color
}, //点击确认按钮事件回调 }, //点击确认按钮事件回调
clear: () => { clear: () => {
@ -357,7 +453,7 @@ const open = async (id) => {
defaultColor: entityOptions.value.extendColor, defaultColor: entityOptions.value.extendColor,
disabled: false, //是否禁止打开颜色选择器 disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画 openPickerAni: 'opacity', //打开颜色选择器动画
sure: color => { sure: (color) => {
entityOptions.value.extendColor = color entityOptions.value.extendColor = color
}, //点击确认按钮事件回调 }, //点击确认按钮事件回调
clear: () => { clear: () => {
@ -371,11 +467,13 @@ const heightModeChange = (val) => {
const heightConfirm = () => { const heightConfirm = () => {
that.positionEditing = false that.positionEditing = false
for (let i = 0; i < entityOptions.value.options.positions.length; i++) { for (let i = 0; i < entityOptions.value.options.positions.length; i++) {
entityOptions.value.options.positions[i].alt = Number((entityOptions.value.options.positions[i].alt + Number(height.value)).toFixed(2)) entityOptions.value.options.positions[i].alt = Number(
(entityOptions.value.options.positions[i].alt + Number(height.value)).toFixed(2)
)
} }
} }
const inputDblclick = async (event, i, anme) => { const inputDblclick = async (event, i, anme) => {
if(heightMode.value == 2) { if (heightMode.value == 2) {
return return
} }
activeTd.value = { activeTd.value = {
@ -397,8 +495,7 @@ const inputBlurCallBack = (event, i, name, digit = 2) => {
} }
} }
const lineTypechange = () => { const lineTypechange = () => {}
}
const nodeEdit = () => { const nodeEdit = () => {
entityOptions.value.positionEditing = false entityOptions.value.positionEditing = false
entityOptions.value.noseToTail = false entityOptions.value.noseToTail = false
@ -408,8 +505,7 @@ const nodeEdit = () => {
entityOptions.value.options.positions = structuredClone(positions) entityOptions.value.options.positions = structuredClone(positions)
if (lengthUnit.value == 'km') { if (lengthUnit.value == 'km') {
length.value = lenByMeter / 1000 length.value = lenByMeter / 1000
} } else {
else {
length.value = lenByMeter length.value = lenByMeter
} }
}) })
@ -419,8 +515,7 @@ const translate = () => {
entityOptions.value.options.positions = structuredClone(that.options.positions) entityOptions.value.options.positions = structuredClone(that.options.positions)
if (lengthUnit.value == 'km') { if (lengthUnit.value == 'km') {
length.value = entityOptions.value.lengthByMeter / 1000 length.value = entityOptions.value.lengthByMeter / 1000
} } else {
else {
length.value = entityOptions.value.lengthByMeter length.value = entityOptions.value.lengthByMeter
} }
}) })
@ -431,7 +526,7 @@ const closeCallback = () => {
that.positionEditing = false that.positionEditing = false
entityOptions.value.closeNodeEdit() entityOptions.value.closeNodeEdit()
entityOptions.value.reset() entityOptions.value.reset()
eventBus.emit("destroyComponent") eventBus.emit('destroyComponent')
} }
const confirm = () => { const confirm = () => {
originalOptions = structuredClone(that.options) originalOptions = structuredClone(that.options)
@ -439,13 +534,13 @@ const confirm = () => {
let params = structuredClone(that.options) let params = structuredClone(that.options)
delete params.host delete params.host
let params2 = { let params2 = {
"id": params.id, id: params.id,
"sourceName": params.name, sourceName: params.name,
"params": params, params: params,
"isShow": params.show ? 1 : 0, isShow: params.show ? 1 : 0
} }
TreeApi.updateDirectoryInfo(params2) TreeApi.updateDirectoryInfo(params2)
cusUpdateNode({"id": params.id, "sourceName": params.name, "params": JSON.stringify(params)}) cusUpdateNode({ id: params.id, sourceName: params.name, params: JSON.stringify(params) })
} }
const close = () => { const close = () => {
baseDialog.value?.close() baseDialog.value?.close()
@ -457,14 +552,13 @@ watch(
if (entityOptions.value.lengthByMeter || entityOptions.value.lengthByMeter == 0) { if (entityOptions.value.lengthByMeter || entityOptions.value.lengthByMeter == 0) {
if (lengthUnit.value == 'km') { if (lengthUnit.value == 'km') {
length.value = entityOptions.value.lengthByMeter / 1000 length.value = entityOptions.value.lengthByMeter / 1000
} } else {
else {
length.value = entityOptions.value.lengthByMeter length.value = entityOptions.value.lengthByMeter
} }
} }
}, },
{ immediate: true } { immediate: true }
); )
defineExpose({ defineExpose({
open open
}) })

View File

@ -30,7 +30,7 @@ function getFontList() {
} }
// @ts-ignore // @ts-ignore
function getFontFamily(key:any) { function getFontFamily(key: any) {
for (let i = 0; i < fontData.length; i++) { for (let i = 0; i < fontData.length; i++) {
if (fontData[i].key == key) { if (fontData[i].key == key) {
return fontData[i].font; return fontData[i].font;
@ -40,7 +40,7 @@ function getFontFamily(key:any) {
} }
// @ts-ignore // @ts-ignore
function getFontFamilyName(key:any) { function getFontFamilyName(key: any) {
for (let i = 0; i < fontData.length; i++) { for (let i = 0; i < fontData.length; i++) {
if (fontData[i].key == key) { if (fontData[i].key == key) {
return fontData[i].name; return fontData[i].name;

View File

@ -3,7 +3,7 @@
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span class="label">新增{{ type }}标签风格设置</span> <span class="label">新增{{ type }}标签风格设置</span>
<button style="margin-right: 56px;">初始风格</button> <button style="margin-right: 56px">初始风格</button>
<button>当前风格</button> <button>当前风格</button>
</div> </div>
</div> </div>
@ -11,20 +11,27 @@
<div class="row"></div> <div class="row"></div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span class="label" style="margin-right: 42px;">标签设置</span> <span class="label" style="margin-right: 42px">标签设置</span>
<span class="label">标签显示</span> <span class="label">标签显示</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.labelShow"> <input class="btn-switch" type="checkbox" v-model="entityOptions.labelShow" />
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col" style="flex: 0 0 114px;"> <div class="col" style="flex: 0 0 114px">
<span class="label">视野缩放</span> <span class="label">视野缩放</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.labelScaleByDistance"> <input class="btn-switch" type="checkbox" v-model="entityOptions.labelScaleByDistance" />
</div> </div>
<div class="col"> <div class="col">
<span class="label">最近距离</span> <span class="label">最近距离</span>
<div class="input-number input-number-unit-1"> <div class="input-number input-number-unit-1">
<input class="input" type="number" title="" min="1" max="99999999" v-model="entityOptions.labelNear"> <input
class="input"
type="number"
title=""
min="1"
max="99999999"
v-model="entityOptions.labelNear"
/>
<span class="unit">m</span> <span class="unit">m</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
@ -32,7 +39,14 @@
<div class="col"> <div class="col">
<span class="label">最远距离</span> <span class="label">最远距离</span>
<div class="input-number input-number-unit-1"> <div class="input-number input-number-unit-1">
<input class="input" type="number" title="" min="1" max="99999999" v-model="entityOptions.labelFar"> <input
class="input"
type="number"
title=""
min="1"
max="99999999"
v-model="entityOptions.labelFar"
/>
<span class="unit">m</span> <span class="unit">m</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
@ -46,20 +60,27 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col" style="flex: 0 0 114px;"> <div class="col" style="flex: 0 0 114px">
<span class="label">字体颜色</span> <span class="label">字体颜色</span>
<div class="labelColor" ref="labelColorRef"></div> <div class="labelColor" ref="labelColorRef"></div>
</div> </div>
<div class="col"> <div class="col">
<span class="label">字体大小</span> <span class="label">字体大小</span>
<div class="input-number input-number-unit-2"> <div class="input-number input-number-unit-2">
<input class="input" type="number" title="" min="1" max="99" v-model="entityOptions.labelFontSize"> <input
class="input"
type="number"
title=""
min="1"
max="99"
v-model="entityOptions.labelFontSize"
/>
<span class="unit">px</span> <span class="unit">px</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
</div> </div>
<div class="col font-select-box"> <div class="col font-select-box">
<span class="label" style="flex: none;">字体选择</span> <span class="label" style="flex: none">字体选择</span>
<el-select class="input input-select font-select" v-model="entityOptions.labelFontFamily"> <el-select class="input input-select font-select" v-model="entityOptions.labelFontFamily">
<el-option v-for="item in fontList" :key="item.key" :label="item.name" :value="item.key"> <el-option v-for="item in fontList" :key="item.key" :label="item.name" :value="item.key">
</el-option> </el-option>
@ -76,8 +97,8 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { ref } from 'vue'
import { inject } from "vue"; import { inject } from 'vue'
import { getFontList } from './fontSelect' import { getFontList } from './fontSelect'
const props = defineProps({ const props = defineProps({
@ -106,7 +127,7 @@ onMounted(() => {
defaultColor: entityOptions.value.labelColor, defaultColor: entityOptions.value.labelColor,
disabled: false, //是否禁止打开颜色选择器 disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画 openPickerAni: 'opacity', //打开颜色选择器动画
sure: color => { sure: (color) => {
entityOptions.value.labelColor = color entityOptions.value.labelColor = color
}, //点击确认按钮事件回调 }, //点击确认按钮事件回调
clear: () => { clear: () => {

View File

@ -1,14 +1,21 @@
<template> <template>
<Dialog ref="baseDialog" title="线标注" left="180px" top="100px" className="polyline" :closeCallback="closeCallback"> <Dialog
ref="baseDialog"
title="线标注"
left="180px"
top="100px"
className="polyline"
:closeCallback="closeCallback"
>
<template #content> <template #content>
<span class="custom-divider"></span> <span class="custom-divider"></span>
<div class="div-item"> <div class="div-item">
<div class="row" style="align-items: flex-start;"> <div class="row" style="align-items: flex-start">
<div class="col"> <div class="col">
<span class="label">名称</span> <span class="label">名称</span>
<input class="input" maxlength="40" type="text" v-model="entityOptions.name"> <input class="input" maxlength="40" type="text" v-model="entityOptions.name" />
</div> </div>
<div class="col" style="flex: 0 0 56%;"> <div class="col" style="flex: 0 0 56%">
<div> <div>
<div class="row"> <div class="row">
<div class="col input-select-unit-box"> <div class="col input-select-unit-box">
@ -17,7 +24,7 @@
<el-option label="投影长度" :value="1"></el-option> <el-option label="投影长度" :value="1"></el-option>
<el-option label="地表长度" :value="2"></el-option> <el-option label="地表长度" :value="2"></el-option>
</el-select> </el-select>
<input v-model="length" class="input-text" readonly> <input v-model="length" class="input-text" readonly />
<el-select v-model="lengthUnit"> <el-select v-model="lengthUnit">
<el-option label="米" value="m"></el-option> <el-option label="米" value="m"></el-option>
<el-option label="千米" value="km"></el-option> <el-option label="千米" value="km"></el-option>
@ -37,22 +44,48 @@
<el-tab-pane label="空间信息" name="2"> <el-tab-pane label="空间信息" name="2">
<div class="row"> <div class="row">
<div class="col height-mode-box"> <div class="col height-mode-box">
<span class="label" style="flex: 0 0 56px;">高度模式</span> <span class="label" style="flex: 0 0 56px">高度模式</span>
<el-select class="input input-select height-mode-scelect" style="width: 155px;margin-left: 20px" <el-select
v-model="heightMode" @change="heightModeChange" placeholder="请选择"> class="input input-select height-mode-scelect"
<el-option v-for="item in heightModeData" :key="item.key" :label="item.name" :value="item.key"> style="width: 155px; margin-left: 20px"
v-model="heightMode"
@change="heightModeChange"
placeholder="请选择"
>
<el-option
v-for="item in heightModeData"
:key="item.key"
:label="item.name"
:value="item.key"
>
</el-option> </el-option>
</el-select> </el-select>
</div> </div>
<div class="col"> <div class="col">
<span class="label">Z值统一增加</span> <span class="label">Z值统一增加</span>
<div class="input-number input-number-unit-1 height-box" :class="{ 'disabled': heightMode == 2 }"> <div
<input class="input height" type="number" title="" min="-9999999" max="999999999" v-model="height"> class="input-number input-number-unit-1 height-box"
:class="{ disabled: heightMode == 2 }"
>
<input
class="input height"
type="number"
title=""
min="-9999999"
max="999999999"
v-model="height"
/>
<span class="unit">m</span> <span class="unit">m</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
<button class="confirm height-confirm" style="margin-left: 5px;" @click="heightConfirm" <button
:disabled="heightMode == 2">应用</button> class="confirm height-confirm"
style="margin-left: 5px"
@click="heightConfirm"
:disabled="heightMode == 2"
>
应用
</button>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
@ -69,20 +102,40 @@
<div class="tr" v-for="(item, i) in entityOptions.options.positions" :key="i"> <div class="tr" v-for="(item, i) in entityOptions.options.positions" :key="i">
<div class="td">{{ i + 1 }}</div> <div class="td">{{ i + 1 }}</div>
<div class="td lng align-center" @dblclick="inputDblclick($event, i, 'lng')"> <div class="td lng align-center" @dblclick="inputDblclick($event, i, 'lng')">
<input class="input" @blur="inputBlurCallBack($event, i, 'lng', 8)" type="number" <input
v-model="item.lng" min="-180" max="180" v-if="activeTd.index == i && activeTd.name == 'lng'"> class="input"
<span style="pointer-events: none;" v-else>{{ (item.lng).toFixed(8) }}</span> @blur="inputBlurCallBack($event, i, 'lng', 8)"
type="number"
v-model="item.lng"
min="-180"
max="180"
v-if="activeTd.index == i && activeTd.name == 'lng'"
/>
<span style="pointer-events: none" v-else>{{ item.lng.toFixed(8) }}</span>
</div> </div>
<div class="td lat align-center" @dblclick="inputDblclick($event, i, 'lat')"> <div class="td lat align-center" @dblclick="inputDblclick($event, i, 'lat')">
<input class="input" @blur="inputBlurCallBack($event, i, 'lat', 8)" type="number" <input
v-model="item.lat" min="-180" max="180" v-if="activeTd.index == i && activeTd.name == 'lat'"> class="input"
<span style="pointer-events: none;" v-else>{{ (item.lat).toFixed(8) }}</span> @blur="inputBlurCallBack($event, i, 'lat', 8)"
type="number"
v-model="item.lat"
min="-180"
max="180"
v-if="activeTd.index == i && activeTd.name == 'lat'"
/>
<span style="pointer-events: none" v-else>{{ item.lat.toFixed(8) }}</span>
</div> </div>
<div class="td alt align-center" @dblclick="inputDblclick($event, i, 'alt')"> <div class="td alt align-center" @dblclick="inputDblclick($event, i, 'alt')">
<input class="input" @blur="inputBlurCallBack($event, i, 'alt', 2)" type="number" <input
v-model="item.alt" min="-9999999" max="999999999" class="input"
v-if="activeTd.index == i && activeTd.name == 'alt'"> @blur="inputBlurCallBack($event, i, 'alt', 2)"
<span style="pointer-events: none;" v-else>{{ (item.alt).toFixed(2) }}</span> type="number"
v-model="item.alt"
min="-9999999"
max="999999999"
v-if="activeTd.index == i && activeTd.name == 'alt'"
/>
<span style="pointer-events: none" v-else>{{ item.alt.toFixed(2) }}</span>
</div> </div>
</div> </div>
</div> </div>
@ -95,19 +148,35 @@
<span class="label">线条颜色</span> <span class="label">线条颜色</span>
<div class="color" ref="colorRef"></div> <div class="color" ref="colorRef"></div>
</div> </div>
<div class="col" style="flex: 0 0 33%;"> <div class="col" style="flex: 0 0 33%">
<span class="label">线条宽度</span> <span class="label">线条宽度</span>
<div class="input-number input-number-unit-1" style="width: 80px;"> <div class="input-number input-number-unit-1" style="width: 80px">
<input class="input" type="number" title="" min="1" max="999" v-model="entityOptions.lineWidth"> <input
class="input"
type="number"
title=""
min="1"
max="999"
v-model="entityOptions.lineWidth"
/>
<span class="unit">px</span> <span class="unit">px</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
</div> </div>
<div class="col input-select-line-type-box" style="flex: 0 0 37%;"> <div class="col input-select-line-type-box" style="flex: 0 0 37%">
<span class="label">线条形式</span> <span class="label">线条形式</span>
<el-select class="input input-select input-select-line-type" style="margin-left: 20px" <el-select
v-model="entityOptions.lineType" @change="lineTypechange"> class="input input-select input-select-line-type"
<el-option v-for="item in lineTypeData" :key="item.key" :label="item.name" :value="item.key"> style="margin-left: 20px"
v-model="entityOptions.lineType"
@change="lineTypechange"
>
<el-option
v-for="item in lineTypeData"
:key="item.key"
:label="item.name"
:value="item.key"
>
<i class="yj-custom-icon" :class="item.icon"></i> <i class="yj-custom-icon" :class="item.icon"></i>
{{ item.name }} {{ item.name }}
</el-option> </el-option>
@ -117,30 +186,36 @@
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span class="label">首尾相连</span> <span class="label">首尾相连</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.noseToTail"> <input class="btn-switch" type="checkbox" v-model="entityOptions.noseToTail" />
</div> </div>
<div class="col" style="flex: 0 0 33%;"> <div class="col" style="flex: 0 0 33%">
<span class="label">线段圆滑</span> <span class="label">线段圆滑</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.smooth"> <input class="btn-switch" type="checkbox" v-model="entityOptions.smooth" />
</div>
<div class="col" style="flex: 0 0 37%;">
</div> </div>
<div class="col" style="flex: 0 0 37%"></div>
</div> </div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span class="label">线段缓冲</span> <span class="label">线段缓冲</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.extend"> <input class="btn-switch" type="checkbox" v-model="entityOptions.extend" />
</div> </div>
<div class="col" style="flex: 0 0 33%;"> <div class="col" style="flex: 0 0 33%">
<span class="label">缓冲宽度</span> <span class="label">缓冲宽度</span>
<div class="input-number input-number-unit-1" style="width: 80px;"> <div class="input-number input-number-unit-1" style="width: 80px">
<input class="input" type="number" title="" min="0" data-min="0.01" max="999999" <input
v-model="entityOptions.extendWidth"> class="input"
type="number"
title=""
min="0"
data-min="0.01"
max="999999"
v-model="entityOptions.extendWidth"
/>
<span class="unit">m</span> <span class="unit">m</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
</div> </div>
<div class="col" style="flex: 0 0 37%;"> <div class="col" style="flex: 0 0 37%">
<span class="label">缓冲颜色</span> <span class="label">缓冲颜色</span>
<div class="extendColor" ref="extendColorRef"></div> <div class="extendColor" ref="extendColorRef"></div>
</div> </div>
@ -148,23 +223,43 @@
<div class="row" v-show="entityOptions.lineType > 2 && entityOptions.lineType < 13"> <div class="row" v-show="entityOptions.lineType > 2 && entityOptions.lineType < 13">
<div class="col"> <div class="col">
<span class="label">首尾反向</span> <span class="label">首尾反向</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.rotate"> <input class="btn-switch" type="checkbox" v-model="entityOptions.rotate" />
</div> </div>
<div class="col" style="flex: 0 0 33%;"> <div class="col" style="flex: 0 0 33%">
<span class="label">流动速率</span> <span class="label">流动速率</span>
<div class="input-number input-number-unit-1" style="width: 80px;"> <div class="input-number input-number-unit-1" style="width: 80px">
<input class="input" type="number" title="" min="0" max="999999" step="1" <input
v-model="entityOptions.speed"> class="input"
type="number"
title=""
min="0"
max="999999"
step="1"
v-model="entityOptions.speed"
/>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
</div> </div>
<div class="col" style="flex: 0 0 37%;"> <div class="col" style="flex: 0 0 37%">
<span class="label lineSpace" <span
v-show="entityOptions.lineType > 2 && entityOptions.lineType >= 5">线条间距</span> class="label lineSpace"
<div class="input-number input-number-unit-1 lineSpace" style="width: 80px;" v-show="entityOptions.lineType > 2 && entityOptions.lineType >= 5"
v-show="entityOptions.lineType > 2 && entityOptions.lineType >= 5"> >线条间距</span
<input class="input" type="number" title="" min="0" max="4.5" step="0.1" >
v-model="entityOptions.space"> <div
class="input-number input-number-unit-1 lineSpace"
style="width: 80px"
v-show="entityOptions.lineType > 2 && entityOptions.lineType >= 5"
>
<input
class="input"
type="number"
title=""
min="0"
max="4.5"
step="0.1"
v-model="entityOptions.space"
/>
<span class="unit"></span> <span class="unit"></span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
@ -179,13 +274,17 @@
</div> </div>
</template> </template>
<template #footer> <template #footer>
<div style="position: absolute; left: 24px; display: flex;"> <div style="position: absolute; left: 24px; display: flex">
<button @click="nodeEdit"><svg class="icon-edit"> <button @click="nodeEdit">
<use xlink:href="#yj-icon-edit"></use> <svg class="icon-edit">
</svg>二次编辑</button> <use xlink:href="#yj-icon-edit"></use></svg
<button style="margin-left: 10px;" @click="translate"><svg class="icon-py"> >二次编辑
<use xlink:href="#yj-icon-py"></use> </button>
</svg>平移</button> <button style="margin-left: 10px" @click="translate">
<svg class="icon-py">
<use xlink:href="#yj-icon-py"></use></svg
>平移
</button>
</div> </div>
<button @click="confirm">确定</button> <button @click="confirm">确定</button>
<button @click="close">关闭</button> <button @click="close">关闭</button>
@ -194,8 +293,8 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, getCurrentInstance } from 'vue'; import { ref, getCurrentInstance } from 'vue'
import { inject } from "vue"; import { inject } from 'vue'
import { TreeApi } from '@/api/tree' import { TreeApi } from '@/api/tree'
import Dialog from '@/components/dialog/baseDialog.vue' import Dialog from '@/components/dialog/baseDialog.vue'
import attribute from './attribute.vue' import attribute from './attribute.vue'
@ -204,8 +303,8 @@ import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
const { cusUpdateNode } = useTreeNode() const { cusUpdateNode } = useTreeNode()
const baseDialog: any = ref(null); const baseDialog: any = ref(null)
const eventBus: any = inject("bus"); const eventBus: any = inject('bus')
const length = ref(0) const length = ref(0)
const lengthUnit = ref('m') const lengthUnit = ref('m')
@ -312,7 +411,7 @@ const activeTd = ref({
index: -1, index: -1,
name: '' name: ''
}) })
const entityOptions: any = ref({}); const entityOptions: any = ref({})
const linePositions = ref([]) const linePositions = ref([])
const colorRef = ref(null) const colorRef = ref(null)
const extendColorRef = ref(null) const extendColorRef = ref(null)
@ -321,7 +420,6 @@ const heightMode = ref(0)
let originalOptions: any let originalOptions: any
let that: any let that: any
const open = async (id: any) => { const open = async (id: any) => {
that = window.earth.entityMap.get(id) that = window.earth.entityMap.get(id)
originalOptions = structuredClone(that.options) originalOptions = structuredClone(that.options)
@ -332,8 +430,7 @@ const open = async (id: any) => {
that.lengthChangeCallBack = () => { that.lengthChangeCallBack = () => {
if (lengthUnit.value == 'km') { if (lengthUnit.value == 'km') {
length.value = entityOptions.value.lengthByMeter / 1000 length.value = entityOptions.value.lengthByMeter / 1000
} } else {
else {
length.value = entityOptions.value.lengthByMeter length.value = entityOptions.value.lengthByMeter
} }
} }
@ -348,7 +445,7 @@ const open = async (id: any) => {
defaultColor: entityOptions.value.color, defaultColor: entityOptions.value.color,
disabled: false, //是否禁止打开颜色选择器 disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画 openPickerAni: 'opacity', //打开颜色选择器动画
sure: color => { sure: (color) => {
entityOptions.value.color = color entityOptions.value.color = color
}, //点击确认按钮事件回调 }, //点击确认按钮事件回调
clear: () => { clear: () => {
@ -362,7 +459,7 @@ const open = async (id: any) => {
defaultColor: entityOptions.value.extendColor, defaultColor: entityOptions.value.extendColor,
disabled: false, //是否禁止打开颜色选择器 disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画 openPickerAni: 'opacity', //打开颜色选择器动画
sure: color => { sure: (color) => {
entityOptions.value.extendColor = color entityOptions.value.extendColor = color
}, //点击确认按钮事件回调 }, //点击确认按钮事件回调
clear: () => { clear: () => {
@ -376,12 +473,14 @@ const heightModeChange = (val) => {
const heightConfirm = () => { const heightConfirm = () => {
that.positionEditing = false that.positionEditing = false
for (let i = 0; i < entityOptions.value.options.positions.length; i++) { for (let i = 0; i < entityOptions.value.options.positions.length; i++) {
entityOptions.value.options.positions[i].alt = Number((entityOptions.value.options.positions[i].alt + Number(height.value)).toFixed(2)) entityOptions.value.options.positions[i].alt = Number(
(entityOptions.value.options.positions[i].alt + Number(height.value)).toFixed(2)
)
} }
that.smooth = that.smooth that.smooth = that.smooth
} }
const inputDblclick = async (event, i, anme) => { const inputDblclick = async (event, i, anme) => {
if(heightMode.value == 2) { if (heightMode.value == 2) {
return return
} }
activeTd.value = { activeTd.value = {
@ -403,8 +502,7 @@ const inputBlurCallBack = (event, i, name, digit = 2) => {
} }
} }
const lineTypechange = () => { const lineTypechange = () => {}
}
const nodeEdit = () => { const nodeEdit = () => {
entityOptions.value.positionEditing = false entityOptions.value.positionEditing = false
entityOptions.value.noseToTail = false entityOptions.value.noseToTail = false
@ -414,8 +512,7 @@ const nodeEdit = () => {
entityOptions.value.options.positions = structuredClone(positions) entityOptions.value.options.positions = structuredClone(positions)
if (lengthUnit.value == 'km') { if (lengthUnit.value == 'km') {
length.value = lenByMeter / 1000 length.value = lenByMeter / 1000
} } else {
else {
length.value = lenByMeter length.value = lenByMeter
} }
}) })
@ -425,8 +522,7 @@ const translate = () => {
entityOptions.value.options.positions = structuredClone(that.options.positions) entityOptions.value.options.positions = structuredClone(that.options.positions)
if (lengthUnit.value == 'km') { if (lengthUnit.value == 'km') {
length.value = entityOptions.value.lengthByMeter / 1000 length.value = entityOptions.value.lengthByMeter / 1000
} } else {
else {
length.value = entityOptions.value.lengthByMeter length.value = entityOptions.value.lengthByMeter
} }
}) })
@ -437,7 +533,7 @@ const closeCallback = () => {
that.positionEditing = false that.positionEditing = false
entityOptions.value.closeNodeEdit() entityOptions.value.closeNodeEdit()
entityOptions.value.reset() entityOptions.value.reset()
eventBus.emit("destroyComponent") eventBus.emit('destroyComponent')
} }
const confirm = () => { const confirm = () => {
originalOptions = structuredClone(that.options) originalOptions = structuredClone(that.options)
@ -445,13 +541,13 @@ const confirm = () => {
let params = structuredClone(that.options) let params = structuredClone(that.options)
delete params.host delete params.host
let params2 = { let params2 = {
"id": params.id, id: params.id,
"sourceName": params.name, sourceName: params.name,
"params": params, params: params,
"isShow": params.show ? 1 : 0, isShow: params.show ? 1 : 0
} }
TreeApi.updateDirectoryInfo(params2) TreeApi.updateDirectoryInfo(params2)
cusUpdateNode({ "id": params.id, "sourceName": params.name, "params": JSON.stringify(params) }) cusUpdateNode({ id: params.id, sourceName: params.name, params: JSON.stringify(params) })
} }
const close = () => { const close = () => {
baseDialog.value?.close() baseDialog.value?.close()
@ -463,14 +559,13 @@ watch(
if (entityOptions.value.lengthByMeter || entityOptions.value.lengthByMeter == 0) { if (entityOptions.value.lengthByMeter || entityOptions.value.lengthByMeter == 0) {
if (lengthUnit.value == 'km') { if (lengthUnit.value == 'km') {
length.value = entityOptions.value.lengthByMeter / 1000 length.value = entityOptions.value.lengthByMeter / 1000
} } else {
else {
length.value = entityOptions.value.lengthByMeter length.value = entityOptions.value.lengthByMeter
} }
} }
}, },
{ immediate: true } { immediate: true }
); )
defineExpose({ defineExpose({
open open
}) })

View File

@ -11,25 +11,25 @@ export const useRightOperate = () => {
$changeComponentPop('.adddirectoryBox', true) $changeComponentPop('.adddirectoryBox', true)
} }
//添加资源 //添加资源
const addResource = () => {} const addResource = () => { }
//导入全景 //导入全景
const importPanorama = () => {} const importPanorama = () => { }
//图片定位 //图片定位
const pictureLocation = () => {} const pictureLocation = () => { }
//属性 //属性
const showAttr = () => {} const showAttr = () => { }
//导入模型 //导入模型
const importHeader = () => {} const importHeader = () => { }
//导入模型 //导入模型
const addXlsxs = () => {} const addXlsxs = () => { }
//导入模型 //导入模型
const addTrajectory = () => {} const addTrajectory = () => { }
//编辑 //编辑
const editNode = (eventBus) => { const editNode = (eventBus) => {
let selectNodes = getSelectedNodes(window.treeObj); let selectNodes = getSelectedNodes(window.treeObj);
if(selectNodes && selectNodes[selectNodes.length-1]) { if (selectNodes && selectNodes[selectNodes.length - 1]) {
let params = JSON.parse(selectNodes[selectNodes.length-1].params) let params = JSON.parse(selectNodes[selectNodes.length - 1].params)
eventBus.emit("openDialog", selectNodes[selectNodes.length-1].sourceType, params.id); eventBus.emit("openDialog", selectNodes[selectNodes.length - 1].sourceType, params.id);
} }
} }
//删除 //删除
@ -61,17 +61,17 @@ export const useRightOperate = () => {
}) })
} }
//添加BIM //添加BIM
const addBIM = () => {} const addBIM = () => { }
//重置透视 //重置透视
const resetPerspective = () => {} const resetPerspective = () => { }
const pressModel = () => {} const pressModel = () => { }
//设置视图 //设置视图
const setView = () => { const setView = () => {
let selectNodes = getSelectedNodes(window.treeObj); let selectNodes = getSelectedNodes(window.treeObj);
if(selectNodes && selectNodes[selectNodes.length-1]) { if (selectNodes && selectNodes[selectNodes.length - 1]) {
let node = selectNodes[selectNodes.length-1] let node = selectNodes[selectNodes.length - 1]
let params = JSON.parse(node.params) let params = JSON.parse(node.params)
let entityObject = window.earth.entityMap.get(params.id) let entityObject = window.earth.entityMap.get(params.id)
entityObject.setCustomView() entityObject.setCustomView()
@ -91,8 +91,8 @@ export const useRightOperate = () => {
//重置视图 //重置视图
const resetView = () => { const resetView = () => {
let selectNodes = getSelectedNodes(window.treeObj); let selectNodes = getSelectedNodes(window.treeObj);
if(selectNodes && selectNodes[selectNodes.length-1]) { if (selectNodes && selectNodes[selectNodes.length - 1]) {
let node = selectNodes[selectNodes.length-1] let node = selectNodes[selectNodes.length - 1]
let params = JSON.parse(node.params) let params = JSON.parse(node.params)
let entityObject = window.earth.entityMap.get(params.id) let entityObject = window.earth.entityMap.get(params.id)
entityObject.resetCustomView() entityObject.resetCustomView()
@ -107,19 +107,19 @@ export const useRightOperate = () => {
"isShow": node.isShow ? 1 : 0, "isShow": node.isShow ? 1 : 0,
} }
TreeApi.updateDirectoryInfo(params2) TreeApi.updateDirectoryInfo(params2)
cusUpdateNode({"id": params2.id, "sourceName": params2.sourceName, "params": JSON.stringify(params)}) cusUpdateNode({ "id": params2.id, "sourceName": params2.sourceName, "params": JSON.stringify(params) })
} }
} }
//提升图层 //提升图层
const layerRaise = () => {} const layerRaise = () => { }
//降低图层 //降低图层
const layerLower = () => {} const layerLower = () => { }
//置顶图层 //置顶图层
const layerToTop = () => {} const layerToTop = () => { }
//置底图层 //置底图层
const layerToBottom = () => {} const layerToBottom = () => { }
//切片 //切片
const tilesetClipping = () => {} const tilesetClipping = () => { }
const rightMenus: any = reactive({ const rightMenus: any = reactive({
addDirectory: { addDirectory: {
key: 'addDirectory', key: 'addDirectory',

View File

@ -416,9 +416,9 @@ export const useTree = () => {
} }
return 0; return 0;
}) })
for (let i = res.data.length-1; i >= 0; i--) { for (let i = res.data.length - 1; i >= 0; i--) {
if (!res.data[i].id) { if (!res.data[i].id) {
res.data.splice(i,1); res.data.splice(i, 1);
} }
} }
zNodes.value = res.data zNodes.value = res.data

View File

@ -24,7 +24,7 @@ export const initMapData = async (type, data) => {
case 'rendezvous': case 'rendezvous':
entityObject = new YJ.Obj.AssembleObject(window.earth, data) entityObject = new YJ.Obj.AssembleObject(window.earth, data)
break break
case 'attackArrow': case 'attackArrow':
entityObject = new YJ.Obj.AttackArrowObject(window.earth, data) entityObject = new YJ.Obj.AttackArrowObject(window.earth, data)
break break
case 'pincerArrow': case 'pincerArrow':

View File

@ -10,12 +10,18 @@
<firstMenu class="absolute zIndex9" ref="firstMenuRef"></firstMenu> <firstMenu class="absolute zIndex9" ref="firstMenuRef"></firstMenu>
<!--底部菜单--> <!--底部菜单-->
<bottomMenu class="absolute zIndex9" ref="bottomMenuRef"></bottomMenu> <bottomMenu class="absolute zIndex9" ref="bottomMenuRef"></bottomMenu>
<input type="file" id="fileInputlink" style="display: none;" multiple accept=".jpeg,.png,.jpg,.mp4,.pdf" <input
@input="uploadFile"> type="file"
id="fileInputlink"
style="display: none"
multiple
accept=".jpeg,.png,.jpg,.mp4,.pdf"
@input="uploadFile"
/>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { inject, shallowRef, ref } from "vue"; import { inject, shallowRef, ref } from 'vue'
import Headers from '../components/headers/index.vue' import Headers from '../components/headers/index.vue'
import Tree from '../components/tree/index.vue' import Tree from '../components/tree/index.vue'
import addStandText from '../components/propertyBox/addStandText.vue' import addStandText from '../components/propertyBox/addStandText.vue'
@ -35,85 +41,84 @@ import { GisApi } from '@/api/gisApi'
const firstMenuRef = ref(null) const firstMenuRef = ref(null)
const bottomMenuRef = ref(null) const bottomMenuRef = ref(null)
const eventBus: any = inject("bus"); const eventBus: any = inject('bus')
let currentComponent = shallowRef() let currentComponent = shallowRef()
let dynamicComponentRef = ref() let dynamicComponentRef = ref()
let addStandTextRef = ref() let addStandTextRef = ref()
let tree = ref() let tree = ref()
eventBus.on("openDialog", async (sourceType: any, id: any) => { eventBus.on('openDialog', async (sourceType: any, id: any) => {
switch (sourceType) { switch (sourceType) {
case 'addGroundText': case 'addGroundText':
currentComponent.value = addGroundText currentComponent.value = addGroundText
await nextTick() await nextTick()
dynamicComponentRef.value?.open() dynamicComponentRef.value?.open()
break; break
case 'groundText': case 'groundText':
currentComponent.value = groundText currentComponent.value = groundText
await nextTick() await nextTick()
dynamicComponentRef.value?.open() dynamicComponentRef.value?.open()
break; break
case 'addStandText': case 'addStandText':
currentComponent.value = addStandText currentComponent.value = addStandText
await nextTick() await nextTick()
dynamicComponentRef.value?.open() dynamicComponentRef.value?.open()
break; break
case 'standText': case 'standText':
currentComponent.value = standText currentComponent.value = standText
await nextTick() await nextTick()
dynamicComponentRef.value?.open() dynamicComponentRef.value?.open()
break; break
case 'point': case 'point':
currentComponent.value = billboardObject currentComponent.value = billboardObject
await nextTick() await nextTick()
dynamicComponentRef.value?.open(id) dynamicComponentRef.value?.open(id)
break; break
case 'line': case 'line':
currentComponent.value = polylineObject currentComponent.value = polylineObject
await nextTick() await nextTick()
dynamicComponentRef.value?.open(id) dynamicComponentRef.value?.open(id)
break; break
case 'curve': case 'curve':
currentComponent.value = curvelineObject currentComponent.value = curvelineObject
await nextTick() await nextTick()
dynamicComponentRef.value?.open(id) dynamicComponentRef.value?.open(id)
break; break
break; break
case 'panel': case 'panel':
currentComponent.value = polygonObject currentComponent.value = polygonObject
await nextTick() await nextTick()
dynamicComponentRef.value?.open(id) dynamicComponentRef.value?.open(id)
break; break
case 'circle': case 'circle':
break; break
case 'rectangle': case 'rectangle':
currentComponent.value = polygonObject currentComponent.value = polygonObject
await nextTick() await nextTick()
dynamicComponentRef.value?.open(id, 'rectangle') dynamicComponentRef.value?.open(id, 'rectangle')
break; break
case 'rendezvous': case 'rendezvous':
currentComponent.value = rendezvous currentComponent.value = rendezvous
await nextTick() await nextTick()
dynamicComponentRef.value?.open(id, 'rendezvous') dynamicComponentRef.value?.open(id, 'rendezvous')
break; break
case 'attackArrow': case 'attackArrow':
currentComponent.value = attackArrow currentComponent.value = attackArrow
await nextTick() await nextTick()
dynamicComponentRef.value?.open(id, 'attackArrow') dynamicComponentRef.value?.open(id, 'attackArrow')
break; break
case 'pincerArrow': case 'pincerArrow':
currentComponent.value = attackArrow currentComponent.value = attackArrow
await nextTick() await nextTick()
dynamicComponentRef.value?.open(id, 'pincerArrow') dynamicComponentRef.value?.open(id, 'pincerArrow')
break; break
default: default:
break; break
} }
}); })
eventBus.on("destroyComponent", () => { eventBus.on('destroyComponent', () => {
currentComponent.value = undefined currentComponent.value = undefined
}) })
const createEarth = async () => { const createEarth = async () => {
window.earth = await new YJ.YJEarth('earthContainer') window.earth = await new YJ.YJEarth('earthContainer')
tree.value.initTreeCallBack() tree.value.initTreeCallBack()
@ -134,16 +139,15 @@ eventBus.on('defineClickAddLinkCb', (fun) => {
clickAddLinkCb = fun clickAddLinkCb = fun
}) })
const uploadFile = (event) => { const uploadFile = (event) => {
let files = event.target.files let files = event.target.files
if (files.length > 0) { if (files.length > 0) {
const formData = new FormData(); const formData = new FormData()
for (let i = 0; i < files.length; i++) { for (let i = 0; i < files.length; i++) {
const element = files[i]; const element = files[i]
formData.append('files', element); formData.append('files', element)
} }
GisApi.linkFile(formData).then(res => { GisApi.linkFile(formData).then((res) => {
if (res.code == 0 || res.code == 200) { if (res.code == 0 || res.code == 200) {
ElMessage({ ElMessage({
message: '上传成功', message: '上传成功',