This commit is contained in:
2025-09-10 10:31:32 +08:00
parent a1f5a61252
commit 0e8793f01d
18 changed files with 1585 additions and 64 deletions

86
package-lock.json generated
View File

@ -13,9 +13,11 @@
"@electron-toolkit/utils": "^4.0.0",
"@ztree/ztree_v3": "^3.5.48",
"axios": "^1.11.0",
"clipboard": "^2.0.11",
"dayjs": "^1.11.18",
"echarts": "^6.0.0",
"electron-updater": "^6.3.9",
"element-plus": "^2.10.4",
"js-md5": "^0.8.3",
"mitt": "^3.0.1",
"pinia": "^3.0.3",
"pinia-plugin-persistedstate": "^4.4.1",
@ -30,7 +32,7 @@
"@electron-toolkit/eslint-config-ts": "^3.0.0",
"@electron-toolkit/tsconfig": "^1.0.1",
"@types/jquery": "^3.5.32",
"@types/node": "^22.16.5",
"@types/node": "^22.18.1",
"@types/plist": "^3.0.5",
"@types/verror": "^1.10.11",
"@types/vue-i18n": "^6.1.3",
@ -2649,9 +2651,9 @@
"license": "MIT"
},
"node_modules/@types/node": {
"version": "22.16.5",
"resolved": "https://registry.npmmirror.com/@types/node/-/node-22.16.5.tgz",
"integrity": "sha512-bJFoMATwIGaxxx8VJPeM8TonI8t579oRvgAuT8zFugJsJZgzqv0Fu8Mhp68iecjzG7cnN3mO2dJQ5uUM2EFrgQ==",
"version": "22.18.1",
"resolved": "https://registry.npmmirror.com/@types/node/-/node-22.18.1.tgz",
"integrity": "sha512-rzSDyhn4cYznVG+PCzGe1lwuMYJrcBS1fc3JqSa2PvtABwWo+dZ1ij5OVok3tqfpEBCBoaR4d7upFJk73HRJDw==",
"license": "MIT",
"dependencies": {
"undici-types": "~6.21.0"
@ -4647,6 +4649,17 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/clipboard": {
"version": "2.0.11",
"resolved": "https://registry.npmmirror.com/clipboard/-/clipboard-2.0.11.tgz",
"integrity": "sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==",
"license": "MIT",
"dependencies": {
"good-listener": "^1.2.2",
"select": "^1.1.2",
"tiny-emitter": "^2.0.0"
}
},
"node_modules/cliui": {
"version": "8.0.1",
"resolved": "https://registry.npmmirror.com/cliui/-/cliui-8.0.1.tgz",
@ -5196,9 +5209,9 @@
}
},
"node_modules/dayjs": {
"version": "1.11.13",
"resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz",
"integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==",
"version": "1.11.18",
"resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.18.tgz",
"integrity": "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==",
"license": "MIT"
},
"node_modules/de-indent": {
@ -5361,6 +5374,12 @@
"node": ">=0.4.0"
}
},
"node_modules/delegate": {
"version": "3.2.0",
"resolved": "https://registry.npmmirror.com/delegate/-/delegate-3.2.0.tgz",
"integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==",
"license": "MIT"
},
"node_modules/delegates": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/delegates/-/delegates-1.0.0.tgz",
@ -5610,6 +5629,16 @@
"dev": true,
"license": "MIT"
},
"node_modules/echarts": {
"version": "6.0.0",
"resolved": "https://registry.npmmirror.com/echarts/-/echarts-6.0.0.tgz",
"integrity": "sha512-Tte/grDQRiETQP4xz3iZWSvoHrkCQtwqd6hs+mifXcjrCuo2iKWbajFObuLJVBlDIJlOzgQPd1hsaKt/3+OMkQ==",
"license": "Apache-2.0",
"dependencies": {
"tslib": "2.3.0",
"zrender": "6.0.0"
}
},
"node_modules/ejs": {
"version": "3.1.10",
"resolved": "https://registry.npmmirror.com/ejs/-/ejs-3.1.10.tgz",
@ -7248,6 +7277,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/good-listener": {
"version": "1.2.2",
"resolved": "https://registry.npmmirror.com/good-listener/-/good-listener-1.2.2.tgz",
"integrity": "sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==",
"license": "MIT",
"dependencies": {
"delegate": "^3.1.2"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
@ -8453,11 +8491,6 @@
"dev": true,
"license": "BSD-3-Clause"
},
"node_modules/js-md5": {
"version": "0.8.3",
"resolved": "https://registry.npmmirror.com/js-md5/-/js-md5-0.8.3.tgz",
"integrity": "sha512-qR0HB5uP6wCuRMrWPTrkMaev7MJZwJuuw4fnwAzRgP4J4/F8RwtodOKpGp4XpqsLBFzzgqIO42efFAyz2Et6KQ=="
},
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz",
@ -10986,6 +11019,12 @@
"dev": true,
"license": "MIT"
},
"node_modules/select": {
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/select/-/select-1.1.2.tgz",
"integrity": "sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==",
"license": "MIT"
},
"node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
@ -12243,6 +12282,12 @@
"node": ">= 10.0.0"
}
},
"node_modules/tiny-emitter": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==",
"license": "MIT"
},
"node_modules/tiny-typed-emitter": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz",
@ -12461,6 +12506,12 @@
"typescript": ">=4.8.4"
}
},
"node_modules/tslib": {
"version": "2.3.0",
"resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
"license": "0BSD"
},
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmmirror.com/type-check/-/type-check-0.4.0.tgz",
@ -13886,6 +13937,15 @@
"engines": {
"node": ">= 10"
}
},
"node_modules/zrender": {
"version": "6.0.0",
"resolved": "https://registry.npmmirror.com/zrender/-/zrender-6.0.0.tgz",
"integrity": "sha512-41dFXEEXuJpNecuUQq6JlbybmnHaqqpGlbH1yxnA5V9MMP4SbohSVZsJIwz+zdjQXSSlR1Vc34EgH1zxyTDvhg==",
"license": "BSD-3-Clause",
"dependencies": {
"tslib": "2.3.0"
}
}
}
}

View File

@ -25,6 +25,8 @@
"@electron-toolkit/utils": "^4.0.0",
"@ztree/ztree_v3": "^3.5.48",
"axios": "^1.11.0",
"clipboard": "^2.0.11",
"dayjs": "^1.11.18",
"echarts": "^6.0.0",
"electron-updater": "^6.3.9",
"element-plus": "^2.10.4",
@ -42,7 +44,7 @@
"@electron-toolkit/eslint-config-ts": "^3.0.0",
"@electron-toolkit/tsconfig": "^1.0.1",
"@types/jquery": "^3.5.32",
"@types/node": "^22.16.5",
"@types/node": "^22.18.1",
"@types/plist": "^3.0.5",
"@types/verror": "^1.10.11",
"@types/vue-i18n": "^6.1.3",

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="12" height="12" viewBox="0 0 12 12" fill="none">
<path d="M3.06995 0.0336822C3.30345 -0.0134909 3.72175 0.0203715 4.04432 0.0203715L8.80938 0.0203715C9.40915 0.0203715 10.1307 -0.0457695 10.6647 0.0603036C11.1902 0.1647 11.5443 0.463472 11.7725 0.858946C12.0226 1.29218 11.9994 1.8259 11.9994 2.52278L11.9994 10.1232C11.9994 11.3662 11.3459 12 10.0774 12L3.41699 12C3.05145 12 2.7978 11.9615 2.78966 11.6805C2.77859 11.2992 3.13767 11.3345 3.59051 11.3345L9.62358 11.3345C9.9666 11.3345 10.3532 11.3732 10.5979 11.3078C10.9435 11.2156 11.2516 10.9028 11.3187 10.5225C11.3785 10.1841 11.3321 9.80816 11.3321 9.41772L11.3321 2.70913C11.3321 2.34708 11.3626 1.95707 11.3321 1.59103C11.2915 1.1051 10.9141 0.772719 10.5312 0.699218C10.2419 0.643685 9.88335 0.685907 9.54349 0.685907L3.55046 0.685907C3.25907 0.685907 2.87412 0.72524 2.803 0.446314C2.74999 0.238375 2.86113 0.0758638 3.06995 0.0336822ZM4.9653 7.34125L2.00215 7.34125C1.65943 7.34125 1.32269 7.37425 1.04113 7.31463C0.477442 7.19527 0.00413877 6.69706 2.77496e-05 6.02349C-0.00437695 5.30309 0.516243 4.73537 1.24135 4.67911C1.82735 4.63364 2.47369 4.67911 3.11 4.67911L4.9653 4.67911C5.01246 4.16292 4.79863 2.94146 5.29899 2.94872C5.53703 2.95217 5.7177 3.11918 5.87293 3.24155C6.7027 3.89572 7.45568 4.47287 8.31552 5.11836C8.57959 5.3166 9.11366 5.62915 9.10303 6.05011C9.09247 6.46816 8.55953 6.78468 8.30218 6.98186C7.46283 7.62495 6.69288 8.19646 5.84623 8.83205C5.69609 8.94478 5.46648 9.11088 5.2456 9.05833C4.76802 8.9447 5.0393 7.88096 4.9653 7.34125Z" fill="#FFFFFF" >
</path>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,138 @@
export function processBase64Images(base64Data1, base64Data2, callback) {
if (!base64Data1 || !base64Data2) {
alert("请输入两个Base64图像数据");
return;
}
// 创建Image对象并加载第一个Base64图像
const img1 = new Image();
img1.onload = function () {
// 创建Image对象并加载第二个Base64图像
const img2 = new Image();
img2.onload = function () {
// 计算拼接后的Canvas尺寸这里示例为水平拼接垂直拼接可调整计算方式
const totalWidth = img1.width + img2.width;
const maxHeight = Math.max(img1.height, img2.height);
console.log("maxHeight", maxHeight);
const resultCanvas = document.createElement("canvas");
// 设置结果Canvas的尺寸
resultCanvas.width = totalWidth;
resultCanvas.height = maxHeight;
// 获取Canvas绘图上下文
const ctx = resultCanvas.getContext("2d");
// 绘制第一个图像(左上角开始)
ctx.drawImage(img1, 0, 0);
// 绘制第二个图像(第一个图像右侧)
ctx.drawImage(img2, img1.width, 0);
// 获取拼接后的Base64结果默认为PNG格式可指定其他格式如JPEG
const resultBase64Data = resultCanvas.toDataURL("image/png");
callback(resultBase64Data);
console.log("图像拼接完成Base64结果已生成");
};
img2.src = base64Data1;
};
img1.src = base64Data2;
}
/**
* 拼接两个Base64图像并返回新的Base64
* @param {string} base641 第一个Base64图像数据
* @param {number} width1 第一个图像要截取的宽度
* @param {string} base642 第二个Base64图像数据
* @param {number} width2 第二个图像要截取的宽度
* @param {string} [format='image/png'] 输出图像格式
* @param {number} [quality=1.0] 输出图像质量(0-1),仅对支持的格式有效
* @returns {Promise<string>} 拼接后的Base64图像数据
*/
export function combineBase64Images(
base641,
width1,
base642,
width2,
format = "image/png",
quality = 1.0
) {
return new Promise((resolve, reject) => {
// 创建canvas元素
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
// 设置canvas宽度和高度
canvas.width = width1 + width2;
canvas.height = 0; // 高度将在图像加载后确定
// 创建图像对象
const img1 = new Image();
const img2 = new Image();
// 错误处理
function handleError(error) {
reject(new Error(`图像处理错误: ${error.message}`));
}
// 监听两个图像都加载完成
let loadedCount = 0;
function checkAllLoaded() {
loadedCount++;
if (loadedCount === 2) {
drawAndResolve();
}
}
// 图像1加载事件
img1.onload = function () {
checkAllLoaded();
};
// 图像2加载事件
img2.onload = function () {
checkAllLoaded();
};
// 图像加载错误事件
img1.onerror = img2.onerror = handleError;
// 加载图像
img1.src = base641;
img2.src = base642;
// 绘制图像并解析为Base64
function drawAndResolve() {
try {
// 确定canvas高度为两个图像高度的最大值
const height1 = img1.height;
const height2 = img2.height;
canvas.height = Math.max(height1, height2);
// 清除画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 绘制第一个图像的左侧部分 (从左往右截取width1)
ctx.drawImage(img1, 0, 0, width1, height1, 0, 0, width1, canvas.height);
// 绘制第二个图像的右侧部分 (从右往左截取width2)
// 计算在原图上的截取起点 (从右侧开始)
const sourceX = img2.width - width2;
ctx.drawImage(
img2,
sourceX,
0,
width2,
height2,
width1,
0,
width2,
canvas.height
);
// 将canvas内容转换为Base64
const resultBase64 = canvas.toDataURL(format, quality);
resolve(resultBase64);
} catch (error) {
handleError(error);
}
}
});
}

View File

@ -1,3 +1,4 @@
const { ipcRenderer } = require('electron')
export const $changeComponentShow = (selector: any, state: any, styleStr: any = false) => {
$(selector).css({ visibility: state ? 'visible' : 'hidden' })
if (styleStr) {
@ -17,3 +18,13 @@ export const $changeComponentPop = (selector: any, state: any, styleStr: any = f
if (str[0] === 'z-index') $(selector).css({ zIndex: str[1] })
}
}
export const $sendElectronChanel = (chanel: any, arg: any = null) => {
console.log('发送给electron', chanel, arg);
ipcRenderer.send(chanel, arg);
};
export const $recvElectronChanel = (chanel: any, cb: any) => {
console.log('接收来自electron', chanel);
ipcRenderer.once(chanel, cb);
};

View File

@ -128,28 +128,28 @@ const menuList: any = ref([
// fun: this.showSecondMenu,
key: 'tool',
children: [
// 'routePlan',
// 'clearRoute',
// 'graffiti',
// // stopGraffiti: "结束涂鸦",
// 'clearGraffiti',
// 'path',
// 'coorLocation',
// 'mouseLocation',
// 'annotationAggregation',
// 'annotation',
// 'screenShot',
// 'highQuality',
// 'videoRecord',
// 'pressModel',
// 'terrainDig',
// 'tilesetClipping',
// 'clearTilesetClipping',
// 'projConvert',
// 'projectionConvert',
// 'gdbImport',
// 'circleStatistics',
// 'polygonStatistics'
'routePlan',
'clearRoute',
'graffiti',
// stopGraffiti: "结束涂鸦",
'clearGraffiti',
'path',
'coorLocation',
'mouseLocation',
'annotationAggregation',
'annotation',
'screenShot',
'highQuality',
'videoRecord',
'pressModel',
'terrainDig',
'tilesetClipping',
'clearTilesetClipping',
'projConvert',
'projectionConvert',
'gdbImport',
'circleStatistics',
'polygonStatistics'
]
},
{

View File

@ -22,6 +22,11 @@ import { ref, reactive, getCurrentInstance } from 'vue'
import { useTreeNode } from '../tree/hooks/treeNode'
import { TreeApi } from '@/api/tree'
import { renderMethods } from '../tree/hooks/renderTreeNode'
import { processBase64Images, combineBase64Images } from '@/utils/HighDefinitionScreenshot'
import { $sendElectronChanel, $recvElectronChanel } from '@/utils/communication'
import { ElMessage } from 'element-plus'
import dayjs from 'dayjs'
import fs from 'fs'
const { proxy } = getCurrentInstance()
const { t } = useI18n()
const { findParentId, findTreeIndex, cusAddNodes } = useTreeNode()
@ -43,7 +48,7 @@ eventBus.on('graffitiObj', (data) => {
})
const methodMap = {
// 轨迹运动
trajectoryMotion: ()=>{
trajectoryMotion: () => {
// let draw = new YJ.Draw.DrawPolyline(window.earth)
// draw.start((err, positions) => {
// if (positions.length > 1) {}
@ -83,7 +88,7 @@ const methodMap = {
// console.log('addOtherSource', res)
// 上树
cusAddNodes(window.treeObj, params.parentId, [params])
eventBus.emit("openDialog", 'wallStereoscopic');
eventBus.emit('openDialog', 'wallStereoscopic')
}
})
},
@ -223,14 +228,70 @@ const methodMap = {
//卷帘对比
annotation() {
clickChange.annotation = !clickChange.annotation
// if (clickChange.annotation) {
// YJ.Global.splitScreen.on(window.earth)
// } else {
// YJ.Global.splitScreen.off()
// }
if (clickChange.annotation) {
YJ.Global.splitScreen.on(window.earth)
} else {
YJ.Global.splitScreen.off()
}
},
//屏幕截图
screenShot() {},
async screenShot() {
function downloadScreen(res) {
let base64 = res.replace(/^data:image\/\w+;base64,/, '')
console.log('base64', base64)
let dataBuffer = new Buffer(base64, 'base64')
$sendElectronChanel('saveFile', {
title: '保存图片',
filename: dayjs().format('YYYYMMDDHHmmss') + '截图',
filters: [{ name: '保存图片', extensions: ['jpg'] }]
})
$recvElectronChanel('selectedFileItem', (e, path) => {
console.log('path', fs.writeFile)
fs.writeFile(path, dataBuffer, (res) => {
console.log(res)
})
})
}
if (window.splitScreen || window.multiViewportMode) {
let res = ''
let res2 = ''
let sdk
if (window.splitScreen) {
sdk = YJ.Global.splitScreen.getSdk()
} else {
sdk = YJ.Global.multiViewportMode.getSdk()
}
await new YJ.Global.ScreenShot(sdk.sdkD, (data) => {
res = data
})
await new YJ.Global.ScreenShot(sdk.sdkP, (data) => {
res2 = data
})
if (window.multiViewportMode) {
processBase64Images(res, res2, (mergedBase64) => {
downloadScreen(mergedBase64)
// window.multiViewportMode = false;
})
} else {
let doms = document.querySelectorAll('.cesium-widget')
let leftWidth = doms[0].offsetWidth
let rightWidth = doms[1].offsetWidth
combineBase64Images(res2, leftWidth, res, rightWidth)
.then((result) => {
downloadScreen(result)
// window.splitScreen = false;
})
.catch((err) => console.error('拼接失败:', err))
}
} else {
let res = ''
await new YJ.Global.ScreenShot(window.earth, (data) => {
res = data
})
downloadScreen(res)
}
},
//高清出图
highQuality() {
// eventBus.emit('screenShotDialog')
@ -239,27 +300,130 @@ const methodMap = {
//视频录制
videoRecord() {
clickChange.videoRecord = !clickChange.videoRecord
let time = 3
this.$changeComponentShow('#secondMenu', false)
// const onKeyDown = (e) => {
// if (e.keyCode === 27) {
// item.status = !item.status;
// $sendElectronChanel("endRecoder");
// document.removeEventListener("keydown", onKeyDown);
// }
// };
if (clickChange.videoRecord) {
// document.addEventListener("keydown", onKeyDown);
let loading = $root_home.openLoading(time, {
background: 'rgba(0,0,0,0)',
fullscreen: false,
customClass: 'timer'
})
let timer = ''
const p = document.createElement('p')
p.style.color = '#fff'
p.innerHTML = '再次点击录制结束'
document.getElementsByClassName('el-loading-spinner')[0].appendChild(p)
let func = () => {
loading.setText(time--)
if (time == -1) {
clearInterval(timer)
loading.close()
console.log('开始了')
p.remove()
$sendElectronChanel('startRecoder')
}
}
func()
timer = setInterval(func, 1000)
} else {
$sendElectronChanel('endRecoder')
// document.removeEventListener("keydown", onKeyDown);
}
},
//压模
pressModel() {},
//地形开挖
terrainDig() {
// if (window.checkAuthIsValid) {
// new YJ.Analysis.TerrainExcavation(window.Earth1);
eventBus.emit('terrainExcavationDialog')
// } else {
// this.$message({
// message: '您没有该功能的权限',
// type: 'warning'
// })
// }
},
//剖切
tilesetClipping() {},
tilesetClipping() {
// if (window.checkAuthIsValid) {
let selectedNode = window.treeObj.getSelectedNodes()
if (selectedNode.length < 1) {
ElMessage({
message: '请在图层指挥舱选中对应模型进行操作',
type: 'warning'
})
return
}
if (!(selectedNode[0].sourceType === 'tileset' || selectedNode[0].sourceType === 'bim')) {
ElMessage({
message: '选中的节点不能进行剖切',
type: 'warning'
})
return
}
let tileset = window.earth.entityMap.get(selectedNode[0].id)
let draw = new YJ.Draw.DrawPolygon(window.earth)
draw.start((err, pos) => {
let section = new YJ.Analysis.Section(window.earth, tileset.entity, {
positions: pos
})
// _entityMap.set(selectedNode.source_id + 'pouqie', section)
})
// } else {
// this.$message({
// message: '您没有该功能的权限',
// type: 'warning'
// })
// }
},
//删除剖切
clearTilesetClipping() {},
clearTilesetClipping() {
YJ.Analysis.ClearSection()
},
//度分秒
projConvert() {},
projConvert() {
eventBus.emit('projConvertDialog')
},
//投影转换
projectionConvert() {},
projectionConvert() {
eventBus.emit('ProjectionConvertDialog')
},
//GDB导入
gdbImport() {},
//圆形统计
circleStatistics() {},
circleStatistics() {
// if (window.checkAuthIsValid) {
eventBus.emit('goodsSearchCircleDialog')
// } else {
// this.$message({
// message: '您没有该功能的权限',
// type: 'warning'
// })
// }
},
//多边形统计
polygonStatistics() {}
polygonStatistics() {
// if (window.checkAuthIsValid) {
eventBus.emit('goodsSearchPolgonDialog')
// } else {
// this.$message({
// message: "您没有该功能的权限",
// type: "warning",
// });
// }
}
}
const handleClick = (value = 'projectionDistanceMeasure') => {

View File

@ -13,7 +13,7 @@
<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" />
<input class="btn-switch show" type="checkbox" v-model="show" />
</div>
</div>
</div>
@ -145,6 +145,7 @@
</div>
</template>
<template #footer>
<button @click="sure">确定</button>
<button @click="close">取消</button>
</template>
</Dialog>
@ -158,16 +159,24 @@ import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog: any = ref(null)
const eventBus: any = inject('bus')
var show: any = ref(true)
eventBus.on('contourDialog', () => {
baseDialog.value?.open()
setTimeout(() => {
YJ.Global.Contour(window.earth)
})
})
const closeCallBack = (e) => {}
const closeCallBack = (e) => {
YJ.Global.ContourReset()
show.value = true
}
const close = (e) => {
baseDialog.value?.close()
}
const sure = (e) => {
YJ.Global.ContourStartDraw(window.earth, show.value)
baseDialog.value?.close()
}
</script>
<style scoped lang="scss"></style>

View File

@ -5,6 +5,7 @@
title="坐标定位"
left="180px"
top="100px"
width="418px"
:closeCallback="closeCallBack"
>
<template #content>

View File

@ -0,0 +1,340 @@
<template>
<Dialog
v-if="show"
ref="baseDialog"
title="物质统计"
left="180px"
top="100px"
:closeCallback="closeCallBack"
>
<template #content>
<div id="goodSearchEchart" style="width: 100%; height: 100%"></div>
</template>
<template #footer>
<button>绘制</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { inject } from 'vue'
import { nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog: any = ref(null)
const eventBus: any = inject('bus')
const shpTotalDict: any = reactive({
shlwz_jzzp: '救灾帐篷',
mb: '棉被',
mymdy: '棉衣、棉大衣',
mjb: '毛巾被',
mt: '毛毯',
dgnsd: '睡袋',
zdc: '折叠床',
jycs: '简易厕所',
xpct: '橡皮船(艇)',
cfz: '冲锋舟',
jsc: '救生船',
jsy: '救生衣',
jsq: '救生圈',
bzd: '编织袋',
md: '麻袋',
csb: '抽水泵',
fdj: '发电机',
yjd: '应急灯',
jzzp: '救灾帐篷',
jzyb: '救灾衣被',
jygj: '救援工具'
})
var draw: any = reactive([])
var show: any = ref(false)
eventBus.on('goodsSearchCircleDialog', () => {
console.log('kkkkkk')
// baseDialog.value?.open()
draw = new YJ.Draw.DrawCircle(window.earth)
draw.start((err, positions) => {
console.log('err, positions', err, positions)
if (!err && positions.center.lng) {
show.value = true
let nodes = booleanOverlaps(positions)
console.log('goodsSearchCircle', nodes)
renderCanvas(nodes)
}
})
})
function booleanOverlaps(positions1, flag = 'circle') {
let cross = undefined
function set3Array(positions) {
let arr = []
positions.forEach((item) => {
arr.push([item.lng, item.lat])
})
arr.push(arr[0])
return arr
}
let getNode = (types) => {
let treeObj = window.treeObj
let res = []
types.forEach((type) => {
let nodes = treeObj.getNodesByParam('sourceType', type, null)
// console.log("nodes",nodes)
res = res.concat(nodes)
})
return res
}
//绘制的区域
// console.log("[set3Array(positions1)]", [set3Array(positions1)])
// 获取物资处(特定的标注类型)
let allNodes = getNode(['point', 'vr', 'picture', 'Feature'])
console.log('allNodes', allNodes)
let itemInArea = [] //区域内的类型符合的标注
for (let i = 0; i < allNodes.length; i++) {
let item = allNodes[i]
let getAllItemInArea = (lng, lat) => {
if (flag == 'circle') {
let { center, radius } = positions1
let distance = new YJ.Tools().randomString(center, { lng, lat })
distance < radius && itemInArea.push(item)
} else {
let polygon1 = turf.polygon([set3Array(positions1)])
let pt = turf.point([lng, lat])
turf.booleanPointInPolygon(pt, polygon1) && itemInArea.push(item)
}
}
console.log(item, item.sourceType, 'ooooo')
switch (item.sourceType) {
case 'point':
case 'vr':
case 'picture':
let params = JSON.parse(item.params)
console.log('params', params)
let lng = params.position.lng
let lat = params.position.lat
getAllItemInArea(lng, lat)
break
case 'Feature':
if (item.detail.geometry.type == 'Point') {
lng = item.detail.geometry.coordinates[0]
lat = item.detail.geometry.coordinates[1]
getAllItemInArea(lng, lat)
}
break
}
}
return itemInArea
}
function renderCanvas(nodes) {
console.log('nodes', nodes)
let x: any = []
let y: any = []
nodes.forEach((item) => {
// shp物资统计
if (item.sourceType == 'Feature') {
let obj = JSON.parse(JSON.stringify(item.detail.properties))
for (const key in obj) {
let name = key
if (shpTotalDict[key]) {
name = shpTotalDict[key]
// 把相同名称的物资数量相加,名称相同时,累加数据
let index = x.findIndex((item) => item === name)
if (index !== -1) {
y[index] = y[index] + Number(obj[key])
} else {
x.push(name)
y.push(Number(obj[key]))
}
}
}
}
let params = JSON.parse(item.params)
if (params.attribute && params.attribute.goods) {
let goods = params.attribute.goods.content
console.log('goods', goods)
if (goods.length) {
// $root_home_index.goodSearchDialog = false;
goods.forEach((good) => {
// 把相同名称的物资数量相加,名称相同时,累加数据
let index = x.findIndex((item) => item === good.name)
if (index !== -1) {
y[index] = y[index] + Number(good.cnt)
} else {
x.push(good.name)
y.push(Number(good.cnt))
}
})
}
}
})
console.log('x,y')
console.log(x)
console.log(y)
let notZeroX = []
let notZeroY = []
for (let i = 0; i < y.length; i++) {
if (y[i] != 0) {
notZeroX.push(x[i])
notZeroY.push(y[i])
}
}
console.log(notZeroX)
console.log(notZeroY)
x = notZeroX
y = notZeroY
if (!x.length) show.value = false
if (show.value) {
nextTick(() => {
let option = {
grid: {
top: '20%',
left: '5%',
right: '5%',
bottom: '8%',
containLabel: true
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
label: {
show: true
}
},
formatter(params) {
var data = ''
for (var i = 0; i < params.length; i++) {
if (params[i].seriesName == '随访率') {
data += params[i].seriesName + ': ' + params[i].value + '%'
} else {
data += params[i].seriesName + ': ' + params[i].value + '<br/>'
}
}
return data
}
},
legend: {
data: ['总量'],
top: '5%',
left: '5%',
right: '5%',
bottom: '5%',
textStyle: {
color: '#fff'
}
},
xAxis: {
// type: "category",
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: true,
width: 40, //将内容的宽度固定
overflow: 'truncate', //超出的部分截断
truncate: '...', //截断的部分用...代替
rotate: 30,
interval: 0,
textStyle: {
color: '#fff' //X轴文字颜色
}
}
},
yAxis: [
{
type: 'value',
name: '(数量)',
nameTextStyle: {
color: '#fff'
},
splitLine: {
show: true,
lineStyle: {
color: '#eeeeee'
}
},
axisTick: {
show: false
},
axisLine: {
show: false
},
axisLabel: {
show: true,
textStyle: {
color: '#fff'
}
}
},
{
type: 'value',
gridIndex: 0,
min: 50,
max: 100,
splitNumber: 8,
splitLine: {
show: false
},
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: false
},
splitArea: {
show: false,
areaStyle: {
color: ['rgba(250,250,250,0.0)', 'rgba(250,250,250,0.05)']
}
}
}
],
series: [
{
name: '数量',
type: 'bar',
label: {
show: true,
position: 'top'
},
barWidth: 15,
itemStyle: {
normal: {
color: '#fdcb6c'
}
}
}
]
}
var dom = document.getElementById('goodSearchEchart')
var myChart = (window as any).echarts.init(dom)
option.xAxis.data = x
option.series[0].data = y
myChart.setOption(option)
})
} else {
ElMessage({
message: '该区域没有物资',
type: 'warning'
})
}
}
const closeCallBack = (e) => {}
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,328 @@
<template>
<Dialog
v-if="show"
ref="baseDialog"
title="物质统计"
left="180px"
top="100px"
:closeCallback="closeCallBack"
>
<template #content>
<div id="goodSearchEchart2" style="width: 100%; height: 100%"></div>
</template>
<template #footer>
<button>绘制</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { inject } from 'vue'
import { nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog: any = ref(null)
const eventBus: any = inject('bus')
const shpTotalDict: any = reactive({
shlwz_jzzp: '救灾帐篷',
mb: '棉被',
mymdy: '棉衣、棉大衣',
mjb: '毛巾被',
mt: '毛毯',
dgnsd: '睡袋',
zdc: '折叠床',
jycs: '简易厕所',
xpct: '橡皮船(艇)',
cfz: '冲锋舟',
jsc: '救生船',
jsy: '救生衣',
jsq: '救生圈',
bzd: '编织袋',
md: '麻袋',
csb: '抽水泵',
fdj: '发电机',
yjd: '应急灯',
jzzp: '救灾帐篷',
jzyb: '救灾衣被',
jygj: '救援工具'
})
var draw: any = reactive([])
var show: any = ref(false)
eventBus.on('goodsSearchPolgonDialog', () => {
draw = new YJ.Draw.DrawPolygon(window.earth)
draw.start((err, params) => {
if (!err && params.length > 2) {
show.value = true
let nodes = booleanOverlaps(params, 'polygon')
renderCanvas(nodes)
}
})
})
function booleanOverlaps(positions1, flag = 'circle') {
let cross = undefined
function set3Array(positions) {
let arr = []
positions.forEach((item) => {
arr.push([item.lng, item.lat])
})
arr.push(arr[0])
return arr
}
let getNode = (types) => {
let treeObj = window.treeObj
let res = []
types.forEach((type) => {
let nodes = treeObj.getNodesByParam('sourceType', type, null)
res = res.concat(nodes)
})
return res
}
//绘制的区域
// 获取物资处(特定的标注类型)
let allNodes = getNode(['point', 'vr', 'picture', 'Feature'])
let itemInArea = [] //区域内的类型符合的标注
for (let i = 0; i < allNodes.length; i++) {
let item = allNodes[i]
let getAllItemInArea = (lng, lat) => {
if (flag == 'circle') {
let { center, radius } = positions1
let distance = new YJ.Tools().randomString(center, { lng, lat })
distance < radius && itemInArea.push(item)
} else {
let polygon1 = turf.polygon([set3Array(positions1)])
let pt = turf.point([lng, lat])
turf.booleanPointInPolygon(pt, polygon1) && itemInArea.push(item)
}
}
switch (item.sourceType) {
case 'point':
case 'vr':
case 'picture':
let params = JSON.parse(item.params)
let lng = params.position.lng
let lat = params.position.lat
getAllItemInArea(lng, lat)
break
case 'Feature':
if (item.detail.geometry.type == 'Point') {
lng = item.detail.geometry.coordinates[0]
lat = item.detail.geometry.coordinates[1]
getAllItemInArea(lng, lat)
}
break
}
}
return itemInArea
}
function renderCanvas(nodes) {
let x: any = []
let y: any = []
nodes.forEach((item) => {
// shp物资统计
if (item.sourceType == 'Feature') {
let obj = JSON.parse(JSON.stringify(item.detail.properties))
for (const key in obj) {
let name = key
if (shpTotalDict[key]) {
name = shpTotalDict[key]
// 把相同名称的物资数量相加,名称相同时,累加数据
let index = x.findIndex((item) => item === name)
if (index !== -1) {
y[index] = y[index] + Number(obj[key])
} else {
x.push(name)
y.push(Number(obj[key]))
}
}
}
}
let params = JSON.parse(item.params)
if (params.attribute && params.attribute.goods) {
let goods = params.attribute.goods.content
if (goods.length) {
// $root_home_index.goodSearchDialog = false;
goods.forEach((good) => {
// 把相同名称的物资数量相加,名称相同时,累加数据
let index = x.findIndex((item) => item === good.name)
if (index !== -1) {
y[index] = y[index] + Number(good.cnt)
} else {
x.push(good.name)
y.push(Number(good.cnt))
}
})
}
}
})
console.log('x,y')
console.log(x)
console.log(y)
let notZeroX = []
let notZeroY = []
for (let i = 0; i < y.length; i++) {
if (y[i] != 0) {
notZeroX.push(x[i])
notZeroY.push(y[i])
}
}
console.log(notZeroX)
console.log(notZeroY)
x = notZeroX
y = notZeroY
if (!x.length) show.value = false
if (show.value) {
nextTick(() => {
let option = {
grid: {
top: '20%',
left: '5%',
right: '5%',
bottom: '8%',
containLabel: true
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
label: {
show: true
}
},
formatter(params) {
var data = ''
for (var i = 0; i < params.length; i++) {
if (params[i].seriesName == '随访率') {
data += params[i].seriesName + ': ' + params[i].value + '%'
} else {
data += params[i].seriesName + ': ' + params[i].value + '<br/>'
}
}
return data
}
},
legend: {
data: ['总量'],
top: '5%',
left: '5%',
right: '5%',
bottom: '5%',
textStyle: {
color: '#fff'
}
},
xAxis: {
// type: "category",
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: true,
width: 40, //将内容的宽度固定
overflow: 'truncate', //超出的部分截断
truncate: '...', //截断的部分用...代替
rotate: 30,
interval: 0,
textStyle: {
color: '#fff' //X轴文字颜色
}
}
},
yAxis: [
{
type: 'value',
name: '(数量)',
nameTextStyle: {
color: '#fff'
},
splitLine: {
show: true,
lineStyle: {
color: '#eeeeee'
}
},
axisTick: {
show: false
},
axisLine: {
show: false
},
axisLabel: {
show: true,
textStyle: {
color: '#fff'
}
}
},
{
type: 'value',
gridIndex: 0,
min: 50,
max: 100,
splitNumber: 8,
splitLine: {
show: false
},
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: false
},
splitArea: {
show: false,
areaStyle: {
color: ['rgba(250,250,250,0.0)', 'rgba(250,250,250,0.05)']
}
}
}
],
series: [
{
name: '数量',
type: 'bar',
label: {
show: true,
position: 'top'
},
barWidth: 15,
itemStyle: {
normal: {
color: '#fdcb6c'
}
}
}
]
}
var dom = document.getElementById('goodSearchEchart2')
var myChart = (window as any).echarts.init(dom)
option.xAxis.data = x
option.series[0].data = y
myChart.setOption(option)
})
} else {
ElMessage({
message: '该区域没有物资',
type: 'warning'
})
}
}
const closeCallBack = (e) => {}
</script>
<style scoped lang="scss"></style>

View File

@ -59,7 +59,7 @@ eventBus.on('graffitiDialog', () => {
graffiti = new YJ.Obj.Graffiti(window.earth, {
width: width.value
})
}, 0)
}, 10)
})
const closeCallBack = (e) => {}

View File

@ -0,0 +1,283 @@
<template>
<Dialog
ref="baseDialog"
class="proj-convert"
title="度分秒格式转换"
left="180px"
top="100px"
width="515px"
:closeCallback="closeCallBack"
>
<template #content v-if="status1">
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col input-select-box">
<span class="label" style="flex: 0 0 60px">输入格式</span>
<div class="input-select"></div>
</div>
</div>
</div>
<div class="div-item item" data-type="0">
<span class="custom-divider"></span>
<p style="font-size: 16px; padding-bottom: 6px; margin-top: 10px; margin-bottom: 5px">
<span style="margin-right: 10px"></span>
<span style="font-size: 12px; margin-bottom: 5px; color: #f16c55">例如116.6°, 39.9°</span>
</p>
<div class="row">
<div class="col">
<span class="label" style="flex: auto">经度</span>
<input class="input lng" type="number" min="-180" max="180" value="0" title="" />
</div>
<div class="col" style="margin: 0">
<span class="label">纬度</span>
<input class="input lat" type="number" min="-90" max="90" value="0" title="" />
</div>
<div class="col" style="flex: 0 0 24px">
<i
class="icon-copy-box"
title="复制"
data-clipboard-action="copy"
data-clipboard-target=".input"
style="cursor: pointer"
>
<svg class="icon-copy" style="margin: 4px; margin-bottom: 0px">
<use xlink:href="#yj-icon-copy"></use>
</svg>
</i>
<button class="convert" style="margin-left: 10px"> </button>
</div>
</div>
</div>
<div class="div-item item" data-type="1">
<span class="custom-divider"></span>
<p style="font-size: 16px; padding-bottom: 6px; margin-top: 10px; margin-bottom: 5px">
<span style="margin-right: 10px">度分</span>
<span style="font-size: 12px; margin-bottom: 5px; color: #f16c55"
>例如95°10.1702', 49°12.4015'</span
>
</p>
<div class="row">
<div class="col" style="flex-direction: column">
<div class="row" style="margin-bottom: 15px">
<span class="label">经度</span>
<input
class="input lng-dm-d"
style="flex: 1"
type="number"
min="-180"
max="180"
value="0"
title=""
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<input
class="input lng-dm-m"
style="flex: 1"
type="number"
min="0"
max="60"
value="0"
title=""
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<span class="top-line"></span>
</div>
<div class="row">
<span class="label">纬度</span>
<input
class="input lat-dm-d"
style="flex: 1"
type="number"
min="-90"
max="90"
value="0"
title=""
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<input
class="input lat-dm-m"
style="flex: 1"
type="number"
min="0"
max="60"
value="0"
title=""
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<span class="bottom-line"></span>
</div>
</div>
<div class="col" style="flex: 0 0 24px; margin: 0">
<i
class="icon-copy-box"
title="复制"
data-clipboard-action="copy"
data-clipboard-target=".input"
style="cursor: pointer; position: relative; left: -30px"
>
<svg class="icon-copy" style="margin: 4px; margin-bottom: 0px">
<use xlink:href="#yj-icon-copy"></use>
</svg>
</i>
<button class="convert" style="margin-left: 10px"> </button>
</div>
</div>
</div>
<div class="div-item item" data-type="2">
<span class="custom-divider"></span>
<p style="font-size: 16px; padding-bottom: 6px; margin-top: 10px; margin-bottom: 5px">
<span style="margin-right: 10px">度分秒</span>
<span style="font-size: 12px; margin-bottom: 5px; color: #f16c55"
>例如11°18'54.37", 39°13'46.57"</span
>
</p>
<div class="row">
<div class="col" style="flex-direction: column">
<div class="row" style="margin-bottom: 15px">
<span class="label">经度</span>
<input
class="input lng-dms-d"
style="flex: 1"
type="number"
min="-180"
max="180"
value="0"
title=""
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px">度</span>
<input
class="input lng-dms-m"
style="flex: 1"
type="number"
min="0"
max="60"
value="0"
title=""
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px">分</span>
<input
class="input lng-dms-s"
style="flex: 1"
type="number"
min="0"
max="60"
value="0"
title=""
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px">秒</span>
<span class="top-line"></span>
</div>
<div class="row">
<span class="label">纬度</span>
<input
class="input lat-dms-d"
style="flex: 1"
type="number"
min="-90"
max="90"
value="0"
title=""
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px">度</span>
<input
class="input lat-dms-m"
style="flex: 1"
type="number"
min="0"
max="60"
value="0"
title=""
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px">分</span>
<input
class="input lat-dms-s"
style="flex: 1"
type="number"
min="0"
max="60"
value="0"
title=""
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px">秒</span>
<span class="bottom-line"></span>
</div>
</div>
<div class="col" style="flex: 0 0 24px; margin: 0">
<i
class="icon-copy-box"
title="复制"
data-clipboard-action="copy"
data-clipboard-target=".input"
style="cursor: pointer; position: relative; left: -30px"
>
<svg class="icon-copy" style="margin: 4px; margin-bottom: 0px">
<use xlink:href="#yj-icon-copy"></use>
</svg>
</i>
<button class="convert" style="margin-left: 10px">转 换</button>
</div>
</div>
</div>
<span class="custom-divider" style="order: 10; margin-top: 12px"></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'
import Clipboard from 'clipboard'
import { ElMessage } from 'element-plus'
const baseDialog: any = ref(null)
const eventBus: any = inject('bus')
var status1: any = ref(false)
var tools: any = reactive([])
eventBus.on('projConvertDialog', () => {
baseDialog.value?.open()
if (status1.value) {
reset()
status1.value = false
}
status1.value = !status1.value
setTimeout(() => {
tools = new YJ.Tools(window.earth)
tools.projConvert(status1.value, () => {
status1.value = false
})
}, 100)
})
const closeCallBack = (e) => {
status1.value = false
}
const reset = () => {
let contentElm = document
.getElementsByClassName('proj-convert')[0]
.getElementsByClassName('content')[0]
contentElm.getElementsByClassName('lng-dms-d')[0].value = null
contentElm.getElementsByClassName('lng-dms-m')[0].value = null
contentElm.getElementsByClassName('lng-dms-s')[0].value = null
contentElm.getElementsByClassName('lat-dms-d')[0].value = null
contentElm.getElementsByClassName('lat-dms-m')[0].value = null
contentElm.getElementsByClassName('lat-dms-s')[0].value = null
contentElm.getElementsByClassName('lng')[0].value = null
contentElm.getElementsByClassName('lat')[0].value = null
}
const close = (e) => {
baseDialog.value?.close()
}
</script>
<style scoped lang="scss">
::v-deep .content > div {
display: flex !important;
flex-direction: column !important;
}
</style>

View File

@ -0,0 +1,171 @@
<template>
<Dialog
ref="baseDialog"
class="projection-convert"
title="投影转换"
left="180px"
top="100px"
width="634px"
:closeCallback="closeCallBack"
>
<template #content v-if="status1">
<span class="custom-divider"></span>
<div style="width: 585px; display: flex">
<div class="row left" style="flex: 1; margin-bottom: 0">
<div
style="
margin: 10px 0;
flex: 1;
display: flex;
align-items: center;
flex: 1;
justify-content: space-between;
"
>
<span class="lable-left-line">源坐标</span>
<button class="btn pick" style="margin-left: 15px">
<svg class="icon-edit"><use xlink:href="#yj-icon-edit"></use></svg>坐标拾取
</button>
<button
class="btn sourceCopy"
data-clipboard-action="copy"
data-clipboard-target=".input"
style="margin-left: 5px"
>
<svg class="icon-copy"><use xlink:href="#yj-icon-copy"></use></svg>复制
</button>
</div>
<div>
<div style="display: flex; margin-bottom: 12px; align-items: center">
<span class="label" style="flex: 0 0 60px">椭圆基准</span>
<div class="datalist_left"></div>
</div>
<div style="display: flex; margin-bottom: 12px; align-items: center">
<span class="label" style="flex: 0 0 60px">经度(x)</span>
<input class="input left-x" type="number" title="" />
</div>
<div style="display: flex; margin-bottom: 10px; align-items: center">
<span class="label" style="flex: 0 0 60px">纬度(y)</span>
<input class="input left-y" type="number" title="" />
</div>
</div>
</div>
<div
style="
display: flex;
flex-direction: column;
justify-content: center;
margin: 28px 15px 0 15px;
"
>
<button class="btn convert">
<svg-icon name="turn" :size="11" color="rgba(255, 255, 255, 1)"></svg-icon>
转换
</button>
</div>
<div class="row right" style="flex: 1; margin-bottom: 0">
<div
style="
margin: 10px 0;
height: 32px;
display: flex;
align-items: center;
flex: 1;
justify-content: space-between;
"
>
<span class="lable-left-line">目标坐标</span>
<button
class="btn copy"
data-clipboard-action="copy"
data-clipboard-target=".input"
style="margin-left: 20px"
>
<svg class="icon-copy"><use xlink:href="#yj-icon-copy"></use></svg>复制
</button>
</div>
<div>
<div style="display: flex; margin-bottom: 12px; align-items: center">
<span class="label" style="flex: 0 0 60px">椭圆基准</span>
<div class="datalist_right"></div>
</div>
<div style="display: flex; margin-bottom: 12px; align-items: center">
<span class="label" style="flex: 0 0 60px">经度(x)</span>
<input class="input right-x" readonly="readonly" />
</div>
<div style="display: flex; margin-bottom: 10px; align-items: center">
<span class="label" style="flex: 0 0 60px">纬度(y)</span>
<input class="input right-y" readonly="readonly" />
</div>
</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'
import Clipboard from 'clipboard'
import { ElMessage } from 'element-plus'
const baseDialog: any = ref(null)
const eventBus: any = inject('bus')
var status1: any = ref(false)
var tools: any = reactive([])
eventBus.on('ProjectionConvertDialog', () => {
baseDialog.value?.open()
if (status1.value) {
reset()
status1.value = false
tools && tools.projectionConvert(status1.value, () => {})
}
status1.value = !status1.value
setTimeout(() => {
tools = new YJ.Tools(window.earth)
tools.projectionConvert(status1.value, () => {
status1.value = false
})
}, 100)
})
const closeCallBack = (e) => {
status1.value = false
tools && tools.projectionConvert(status1.value, () => {})
}
const reset = () => {
let contentElm = document
.getElementsByClassName('projection-convert')[0]
.getElementsByClassName('content')[0]
contentElm.getElementsByClassName('left-x')[0].value = null
contentElm.getElementsByClassName('left-y')[0].value = null
contentElm.getElementsByClassName('right-x')[0].value = null
contentElm.getElementsByClassName('right-y')[0].value = null
}
const close = (e) => {
baseDialog.value?.close()
}
</script>
<style scoped lang="scss">
::v-deep .content > div {
display: flex !important;
flex-direction: column !important;
}
::v-deep .content .cy_datalist input {
background: rgba(var(--color-sdk-base-rgb), 0.2) !important;
border: unset;
}
::v-deep .content input[type='number'] {
font-size: 16px !important;
// font-weight: 700 !important;
color: var(--color-sdk-auxiliary-public) !important;
}
</style>

View File

@ -1,4 +1,4 @@
<!-- <template>
<template>
<Dialog ref="baseDialog" title="地形开挖" left="180px" top="100px" :closeCallback="closeCallBack">
<template #content>
<span class="custom-divider"></span>
@ -43,7 +43,7 @@
</div>
</template>
<template #footer>
<button @click="close">取消</button>
<button @click="close">关闭</button>
</template>
</Dialog>
</template>
@ -62,7 +62,7 @@ var excavation: any = reactive([])
eventBus.on('terrainExcavationDialog', () => {
baseDialog.value?.open()
excavation = new (window as any).YJ.Analysis.TerrainExcavation(this.sdk, { height: 10 })
excavation = new (window as any).YJ.Analysis.TerrainExcavation(window.earth, { height: 10 })
})
const changeHeight = () => {
@ -76,7 +76,9 @@ const heightInput = () => {
height.value = dom.max * 1
}
}
const closeCallBack = (e) => {}
const closeCallBack = (e) => {
height.value = 10
}
const close = (e) => {
baseDialog.value?.close()
}
@ -88,4 +90,4 @@ const clear = (e) => {
}
</script>
<style scoped lang="scss"></style> -->
<style scoped lang="scss"></style>

View File

@ -113,7 +113,7 @@ eventBus.on('viewShedDialog', () => {
e_horizontalViewAngle.removeEventListener('change', changeFun)
e_horizontalViewAngle.addEventListener('input', inputFun)
e_horizontalViewAngle.addEventListener('change', changeFun)
})
}, 10)
})
function inputFun() {
let contentElm = document.getElementsByClassName('view-shed')[0]

View File

@ -32,7 +32,11 @@
<!-- <FlyRoam ref="FlyRoam"></FlyRoam> -->
<CoorLocation ref="CoorLocation"></CoorLocation>
<ScreenShot ref="ScreenShot"></ScreenShot>
<!-- <TerrainExcavation ref="TerrainExcavation"></TerrainExcavation> -->
<TerrainExcavation ref="TerrainExcavation"></TerrainExcavation>
<ProjConvert ref="ProjConvert"></ProjConvert>
<ProjectionConvert ref="ProjectionConvert"></ProjectionConvert>
<GoodsSearchCircle ref="GoodsSearchCircle"></GoodsSearchCircle>
<GoodsSearchPolgon ref="GoodsSearchPolgon"></GoodsSearchPolgon>
</template>
<script setup lang="ts">
@ -66,6 +70,10 @@ import FlyRoam from '../components/propertyBox/FlyRoam.vue'
import CoorLocation from '../components/propertyBox/CoorLocation.vue'
import ScreenShot from '../components/propertyBox/ScreenShot.vue'
import TerrainExcavation from '../components/propertyBox/TerrainExcavation.vue'
import ProjConvert from '../components/propertyBox/ProjConvert.vue'
import ProjectionConvert from '../components/propertyBox/ProjectionConvert.vue'
import GoodsSearchCircle from '../components/propertyBox/GoodsSearchCircle.vue'
import GoodsSearchPolgon from '../components/propertyBox/GoodsSearchPolgon.vue'
import { GisApi } from '@/api/gisApi'
@ -123,7 +131,7 @@ eventBus.on('openDialog', async (sourceType: any, id: any) => {
currentComponent.value = circleObject
await nextTick()
dynamicComponentRef.value?.open(id, 'circle')
break;
break
case 'rectangle':
currentComponent.value = polygonObject
await nextTick()