Compare commits

..

2 Commits

Author SHA1 Message Date
zh
ee44704bd6 Merge branch 'zyl' of http://xny.yj-3d.com:3000/zhouyulong/electron-4 into zyl 2025-10-09 17:50:07 +08:00
zh
027803f3e7 提交 2025-10-09 17:49:54 +08:00
17 changed files with 334 additions and 179 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 348 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 995 B

After

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 297 B

After

Width:  |  Height:  |  Size: 362 B

View File

@ -1,10 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 40 40">
<defs>
<style>
.cls-1 {
fill: aqua;
fill-rule: evenodd;
}
</style>
</defs>
<path id="形状_11" data-name="形状 11" class="cls-1" d="M26.129,12.422a1.707,1.707,0,1,0-.853-1.478A1.707,1.707,0,0,0,26.129,12.422Zm2.642,5.35H23.978l-5.925-5.787A1.079,1.079,0,0,0,16.537,12l-6.376,6.376A1.079,1.079,0,0,0,11.686,19.9l5.623-5.622,5.476,5.348a1.079,1.079,0,0,0,.754.307H28.77A1.079,1.079,0,1,0,28.77,17.772ZM39.947,21.6c-0.739-2.919-3.894-3.892-5.483-4.2V4.548A2.555,2.555,0,0,0,31.916,2H8.214A2.555,2.555,0,0,0,5.666,4.548V21.9a15.118,15.118,0,0,0-2.972,2.049C0.413,26-.444,28.32.216,30.664a5.955,5.955,0,0,0,2.325,3.215A11.711,11.711,0,0,0,6.666,35.66a28.784,28.784,0,0,0,6.722.689,51.979,51.979,0,0,0,5.207-.276c0.666-.064,1.331-0.147,1.992-0.243l-0.813,1.109a1.079,1.079,0,1,0,1.74,1.275L23.9,34.961l0.008-.011c0.011-.015.02-0.03,0.03-0.045l0-.006,0.007-.012,0.017-.029,0.009-.017,0.017-.032L24,34.792l0.015-.032,0.008-.018,0.013-.032,0.007-.019,0.01-.03,0.007-.022c0-.009.006-0.019,0.008-0.028l0.006-.024a0.136,0.136,0,0,1,.006-0.026c0-.009,0-0.017.005-0.026s0-.016,0-0.024l0-.029a0.085,0.085,0,0,1,0-.022,0.119,0.119,0,0,0,0-.03,0.169,0.169,0,0,0,0-.021V34.251a0.128,0.128,0,0,0,0-.029c0-.009,0-0.016,0-0.024a0.234,0.234,0,0,0,0-.027,0.1,0.1,0,0,1,0-.025l0-.026c0-.009,0-0.018-0.005-0.026l-0.005-.023-0.007-.027-0.006-.022-0.008-.029-0.007-.02-0.01-.029-0.007-.019L24.018,33.9l-0.008-.019L24,33.849l-0.009-.018L23.972,33.8l-0.011-.019-0.015-.026-0.013-.02-0.016-.024L23.9,33.694l-0.012-.021-0.017-.022-0.015-.019-0.02-.023-0.014-.016L23.8,33.569l-0.014-.014-0.025-.024-0.014-.013L23.722,33.5l-0.016-.012-0.027-.02-0.011-.008-0.008-.005-0.023-.016-0.024-.016-0.007-.005-3.413-2.15a1.079,1.079,0,1,0-1.15,1.825l1.017,0.64q-0.835.116-1.677,0.2a34.883,34.883,0,0,1-11.2-.36c-2.783-.682-4.427-1.854-4.887-3.487-0.426-1.509.183-3.022,1.809-4.494A12.075,12.075,0,0,1,5.667,24.4v0.052A2.555,2.555,0,0,0,8.215,27h23.7a2.555,2.555,0,0,0,2.548-2.548V19.606a8.192,8.192,0,0,1,1.073.336,3.415,3.415,0,0,1,2.317,2.186c0.514,2.029-.78,3.865-1.956,5.05a21.62,21.62,0,0,1-7.955,4.635,1.079,1.079,0,1,0,.732,2.029A23.731,23.731,0,0,0,37.429,28.7C39.679,26.437,40.549,23.98,39.947,21.6Zm-7.64,2.849a0.4,0.4,0,0,1-.391.391H8.214a0.4,0.4,0,0,1-.391-0.391V4.548a0.4,0.4,0,0,1,.391-0.391h23.7a0.4,0.4,0,0,1,.391.391v19.9Z"/>

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -1,10 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 40 40">
<defs>
<style>
.cls-1 {
fill: aqua;
fill-rule: evenodd;
}
</style>
</defs>
<path id="形状_14" data-name="形状 14" class="cls-1" d="M26.575,13.886a4.476,4.476,0,0,0,3.2-1.316A4.584,4.584,0,0,0,31.1,9.323a4.475,4.475,0,0,0-1.317-3.181,4.543,4.543,0,0,0-7.746,3.181,4.5,4.5,0,0,0,1.317,3.247A4.565,4.565,0,0,0,26.575,13.886Zm-1.6-6.164A2.239,2.239,0,0,1,26.6,7.064a2.283,2.283,0,0,1,1.646.658,2.386,2.386,0,0,1,0,3.291,2.371,2.371,0,0,1-3.27,0,2.347,2.347,0,0,1-.68-1.667A2.149,2.149,0,0,1,24.973,7.722Zm5.464,14.9a0.814,0.814,0,0,0-.593.257l-5.42,5.309-4.63-4.629,2.3-2.347a0.943,0.943,0,0,0-.066-1.25,0.9,0.9,0,0,0-1.229-.088l-2.326,2.369-4.542-4.519H13.847l-4.433-4.5a1.1,1.1,0,0,0-1.426.088,1.217,1.217,0,0,0,0,1.47l3.533,3.554-5.9,6.23a1.066,1.066,0,0,0-.11,1.36,1.108,1.108,0,0,0,1.361.154l6.145-6.34,4.037,3.993-9.48,9.389a0.965,0.965,0,0,0,.022,1.316,0.987,0.987,0,0,0,1.295.022l9.524-9.433,7.878,7.788a0.972,0.972,0,0,0,1.251-1.448l-1.8-1.821,5.4-5.4a0.951,0.951,0,0,0-.11-1.272A0.813,0.813,0,0,0,30.437,22.624Zm5.947-12.4a3.7,3.7,0,0,0-.329-0.812V9.3a9.059,9.059,0,0,0-2.721-6.537A9.394,9.394,0,0,0,26.772,0a9.284,9.284,0,0,0-6.517,2.7H20.211a9.084,9.084,0,0,0-2.282,3.729H5.245A5.244,5.244,0,0,0,0,11.693V34.245a5.178,5.178,0,0,0,5.245,5.243H31.38a5.267,5.267,0,0,0,3.687-1.514,5.461,5.461,0,0,0,1.58-3.729V11.737A5.213,5.213,0,0,0,36.384,10.223ZM21.879,4.5h0.044A6.923,6.923,0,0,1,33.728,9.433a7.194,7.194,0,0,1-1.207,3.949,7.352,7.352,0,0,1-3.27,2.545,0.814,0.814,0,0,0-.351.219l-2.085,2.589-2.129-2.589a0.549,0.549,0,0,0-.351-0.219,7.176,7.176,0,0,1-3.248-2.545A7,7,0,0,1,21.879,4.5Zm9.458,32.2H5.223a2.414,2.414,0,0,1-1.734-.724,2.3,2.3,0,0,1-.7-1.711V11.737a2.325,2.325,0,0,1,.7-1.711A2.5,2.5,0,0,1,5.223,9.3H17.512a9.411,9.411,0,0,0,1.624,5.287A9.3,9.3,0,0,0,23.283,17.9l2.809,3.444h0.022l0.11,0.11a0.812,0.812,0,0,0,1.185-.11L30.217,17.9a9,9,0,0,0,3.555-2.545v18.91h0.044A2.479,2.479,0,0,1,31.337,36.7Z"/>

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1,116 @@
<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>
<input class="input" v-model="entityOptions.name">
</div>
</div>
<div class="row">
<div class="col">
<span class="label">名称字段选择</span>
<el-select v-model="entityOptions.field">
<el-option v-for="item in keyData" :label="item.name" :value="item.key"></el-option>
</el-select>
</div>
</div>
</div>
</template>
<template #footer>
<button @click="confirm">确定</button>
<button @click="close">关闭</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { inject } from 'vue'
import { TreeApi } from '@/api/tree'
import { ElMessage, ElMessageBox } from 'element-plus'
import Dialog from '@/components/dialog/baseDialog.vue'
import { useTreeNode } from '../tree/hooks/treeNode'
const { cusUpdateNode, getSelectedNodes, cusRemoveNode } = useTreeNode()
const baseDialog: any = ref(null)
const eventBus: any = inject('bus')
const keyData: any = ref([])
const entityOptions: any = ref({});
let originalOptions: any
let that: any
const closeCallback = () => {
entityOptions.value.originalOptions = structuredClone(originalOptions)
entityOptions.value.reset()
eventBus.emit("destroyComponent")
}
const getKeys = () => {
for (let key in that.geojson.features[0].properties) {
let label = key
for (let index = 0; index < that.options.headTables.length; index++) {
if (that.options.headTables[index].key === key) {
label = that.options.headTables[index].label
break
}
}
keyData.value.push({
name: label,
value: label,
key: key
})
}
}
let node
const open = async (id: any) => {
that = window.earth.entityMap.get(id)
node = window.treeObj.getNodeByParam("id", id, null);
getKeys()
originalOptions = structuredClone(that.options)
entityOptions.value = that
baseDialog.value?.open()
await nextTick()
}
const confirm = () => {
originalOptions = structuredClone(that.options)
baseDialog.value?.close()
let params = {
name: entityOptions.value.name,
show: entityOptions.value.show,
id: entityOptions.value.options.id,
}
let params2 = {
"id": params.id,
"sourceName": params.name,
"params": params,
"isShow": params.show ? 1 : 0
}
TreeApi.updateDirectoryInfo(params2)
cusUpdateNode({ "id": params.id, "sourceName": params.name, "params": JSON.stringify(params) })
updateNode(node.children, entityOptions.value.field)
}
const updateNode = (children, field) => {
for(let i=0;i<children.length;i++) {
if(children[i].children) {
updateNode(children[i].children, field)
}
else {
if(children[i].params) {
cusUpdateNode({ "id": children[i].id, "sourceName": children[i].params.properties[field], "params": children[i].params })
}
}
}
}
const close = () => {
baseDialog.value?.close()
}
defineExpose({
open,
close
})
</script>
<style scoped lang="scss"></style>

View File

@ -48,6 +48,56 @@ export const useRightOperate = () => {
return false;
}
let item = filePaths[0]
//@ts-ignore
let name = getLastPathComponent(item, ['clt', 'json', 'pak', 'kml', 'kmz', 'shp', 'geojson', 'geoJson', 'czml', 'jct', 'mif', 'tab', 'csv']);
let sourceType = "layer";
if (item.endsWith(".clt") || item.endsWith(".json")) {
sourceType = "tileset";
} else if (item.endsWith(".pak")) {
sourceType = "Terrain";
} else if (item.endsWith(".kml") || item.endsWith(".kmz")) {
sourceType = "kml";
} else if (item.endsWith(".shp")) {
sourceType = "shp";
} else if (item.endsWith(".geojson") || item.endsWith(".geoJson")) {
sourceType = "geojson";
} else if (item.endsWith(".czml")) {
sourceType = "czml";
} else if (item.endsWith(".jct")) {
sourceType = "bim";
} else if (item.endsWith(".mif")) {
sourceType = "shp";
} else if (item.endsWith(".tab")) {
sourceType = "shp";
} else if (item.endsWith(".csv")) {
sourceType = "csv";
}
if (["shp", "tab", "mif", "kml", "kmz"].includes(sourceType)) {
let params: any = {
id: id,
parentId: parentId,
sourceName: name,
sourceType: 'vector',
sourcePath: filePaths[0],
params: {
id: id,
path: filePaths[0],
field: 'id',
name: name,
},
}
TreeApi.addOtherSource(params)
params.isShow = true
params.params = JSON.stringify(params.params)
cusAddNodes(window.treeObj, params.parentId, [params])
renderVector(params, true)
}
else {
// 获取最后一个点的位置
const lastDotIndex = filePaths[0].lastIndexOf('.');
@ -56,19 +106,16 @@ export const useRightOperate = () => {
return false;
}
// 提取后缀并转换为小写进行比较
const extension = filePaths[0].slice(lastDotIndex + 1).toLowerCase();
let params2: any = {
id: id,
show: true,
}
if (extension === 'mbtiles') {
if (item.endsWith(".mbtiles")) {
params2.alpha = 1
params2.brightness = 1
params2.layerIndex = 99999
}
if (extension === 'apk') {
if (item.endsWith(".apk")) {
// params2.exaggeration = 1
}
@ -101,11 +148,13 @@ export const useRightOperate = () => {
entity.flyTo()
})
if (res.data.sourceType) { }
res.data.params = JSON.stringify(res.data.params)
res.data.detail = JSON.stringify(res.data.detail)
cusAddNodes(window.treeObj, params.parentId, [res.data])
}
}
}
});
}
//导入全景
@ -197,7 +246,9 @@ export const useRightOperate = () => {
}
}
//属性
const showAttr = () => { }
const showAttr = (eventBus, node) => {
console.log(eventBus, node)
}
//导入模型
const importHeader = () => { }
//导入模型
@ -213,7 +264,6 @@ export const useRightOperate = () => {
}
}
if (node) {
eventBus.emit("openDialog", node.sourceType, node.id);
if (node.sourceType == 'pressModel') {
eventBus.emit("openDialog", node.sourceType, node);
} else {
@ -551,117 +601,90 @@ export const useRightOperate = () => {
}
}
// function renderVector(node, ifFly = true) {
// // if (node.detail != "") node.detail.field = node.detail.fieldName || "id";
// let head_tables;
// if (node.head_tables) {
// head_tables == "" ? node.head_tables : JSON.parse(node.head_tables);
// }
// let vectorParams = {
// id: node.source_id,
// path: node.source_path,
// fileName: node.source_name,
// head_tables,
// ...node.detail,
// };
// console.log("node", node);
// console.log("vectorParams", vectorParams);
// let Vector = new YJ.Obj.Vector((window as any).Earth1, vectorParams);
// console.log("Vector", Vector);
// Vector.on().then((res) => {
// (window as any)._entityMap.set(node.source_id, Vector);
// let treeObj = $.fn.zTree.getZTreeObj("treeDemo");
// Vector.load(() => {
// let newnodes = Vector.getAllNode();
// console.log("newnodes1111", newnodes);
// if (newnodes) {
// if (newnodes.list.length) {
// newnodes.list.forEach((it) => {
// let arrt = node.detail.hasOwnProperty("fieldName")
// ? node.detail.fieldName
// : Vector.field;
// let zijiNodes:any = [];
// if (it.features && it.features.length) {
// it.features.forEach((item) => {
// let ziNode = {
// source_id: item.id,
// source_type: item.type,
// source_name:
// item.properties[arrt] || Object.keys(item.properties)[0] || '未知',
// detail: {
// ...item,
// info: { type: "richText" },
// },
// is_show: 1,
// fid: node.source_id,
// };
// zijiNodes.push(ziNode);
// });
// }
// let fuNode = {
// source_id:
// it.id || md5(new Date().getTime().toString() + Math.random()),
// source_type: it.type,
// source_name: it.name || '未知',
// detail: {
// defaultfieldName: Vector.field,
// ...node.detail,
// },
// is_show: 1,
// fid: node.source_id,
// children: zijiNodes.length > 0 ? zijiNodes : [], // 关键:把子节点挂到父节点
// };
// let parentNode = treeObj.getNodeByParam(
// "source_id",
// node.source_id,
// null
// );
// if (parentNode) {
// treeObj.addNodes(parentNode, [fuNode], true);
// }
// });
// } else {
// let arrt = node.detail.hasOwnProperty("fieldName")
// ? node.detail.fieldName
// : Vector.field;
// newnodes.list.forEach((it) => {
// let zijiNodes = [];
// let childNode = treeObj.getNodeByParam(
// "source_id",
// node.source_id,
// null
// );
// console.log("1111111111111111111111111111", it);
// if (it.features && it.features.length) {
// it.features.forEach((item) => {
// let ziNode = {
// source_id: item.id,
// source_type: item.type,
// source_name: item.properties[arrt] || "",
// detail: {
// ...item,
// info: { type: "richText" },
// },
// is_show: 1,
// fid: node.source_id,
// };
// zijiNodes.push(ziNode);
// });
// }
// console.log("zijiNodes", "childNode", childNode, zijiNodes);
// if (childNode) {
// treeObj.addNodes(childNode, zijiNodes, true);
// }
// });
// }
// }
// if (ifFly) Vector.flyTo();
function renderVector(node, ifFly = true) {
// if (node.detail != "") node.detail.field = node.detail.fieldName || "id";
let headTables;
if (node.headTables) {
headTables == "" ? node.headTables : JSON.parse(node.headTables);
}
let vectorParams = {
id: node.id,
path: node.sourcePath,
fileName: node.sourceName,
headTables,
...node.params,
};
console.log("node", node);
console.log("vectorParams", vectorParams);
let Vector = new YJ.Obj.Vector(window.earth, vectorParams);
console.log("Vector", Vector);
Vector.on().then((res) => {
Vector.load(() => {
let childNode = {
id: new YJ.Tools().randomString(),
sourceType: 'FeatureCollection',
sourceName: node.sourceName,
isShow: true
}
cusAddNodes(window.treeObj, node.id, [childNode])
let newnodes = Vector.getAllNode();
console.log("newnodes1111", newnodes);
if (newnodes) {
if (newnodes.list.length) {
newnodes.list.forEach((it) => {
let zijiNodes: any = [];
if (it.features && it.features.length) {
it.features.forEach((item) => {
let ziNode = {
id: item.id,
sourceType: item.type,
sourceName:
item.properties[Vector.field] || Object.keys(item.properties)[0] || '未知',
params: {
...item,
},
isShow: true
};
zijiNodes.push(ziNode);
});
}
cusAddNodes(window.treeObj, childNode.id, zijiNodes)
});
}
}
if (ifFly) Vector.flyTo();
// Vector.onClick = shpTotal;
// //鼠标右键点击事件
Vector.onClick = () => {
alert('left')
};
//鼠标右键点击事件
// Vector.onRightClick = shpSelect;
// });
// });
// }
Vector.onRightClick = () => {
alert('right')
};
});
});
}
function getLastPathComponent(path, extensionsToRemove = []) {
// 处理路径分隔符
const normalizedPath = path.replace(/\\/g, '/');
const lastComponent = normalizedPath.split('/').pop();
// 如果没有提供需要移除的后缀列表,直接返回原始名称
if (extensionsToRemove.length === 0) return lastComponent;
// 检查是否匹配任何需要移除的后缀
for (const ext of extensionsToRemove) {
const extWithDot = ext.startsWith('.') ? ext : `.${ext}`;
if (lastComponent.endsWith(extWithDot)) {
return lastComponent.slice(0, -extWithDot.length);
}
}
return lastComponent;
}
return {
rightMenus

View File

@ -56,6 +56,7 @@ export const useTree = () => {
const menus = showRightMenu(event, treeObj.value)
console.log('menus', menus)
if (menus.length == 0) {
$changeComponentShow('.rightMenu', false)
return
}
nextTick(() => {

View File

@ -330,7 +330,7 @@ export const useTreeNode = () => {
// detailFun: get_detail_fountain,
allowChildren: false
},
shp: {
vector: {
rightMenus: ['edit', 'del', 'setView', 'resetView', 'showAttr', 'importHeader']
// render: renderShp,
// detailFun: get_detail_shp,
@ -361,7 +361,7 @@ export const useTreeNode = () => {
// allowChildren: false
},
Feature: {
rightMenus: ['setView', 'resetView', 'showAttr']
rightMenus: ['showAttr']
// render: renderShp,
// detailFun: get_detail_shp,
// allowChildren: false,
@ -445,7 +445,23 @@ export const useTreeNode = () => {
const cusNodeIcon = async (node) => {
let availablePort = await ipcRenderer.invoke('get-available-port');
let type = node.sourceType || node.type;
let type
if(node.sourcePath) {
// 获取最后一个点的位置
const lastDotIndex = node.sourcePath.lastIndexOf('.');
// 如果没有点或者点是最后一个字符,则不是有效的文件后缀
if (lastDotIndex === -1 || lastDotIndex === node.sourcePath.length - 1) {
return false;
}
// 提取后缀并转换为小写进行比较
const extension = node.sourcePath.slice(lastDotIndex + 1).toLowerCase();
type = extension
}
else {
type = node.sourceType || node.type;
}
console.log("----------", type);
let name = [
"GDSLImagery",
@ -458,7 +474,7 @@ export const useTreeNode = () => {
if (type == "Terrain") name = "terrain";
if (type == "road" && node.detail.imageType == "arrowRoad")
name = "lineDrawing";
return type === 'directory' ? undefined : `http://localhost:${availablePort}/icon/${name}.png`;
return (type === 'directory' || type === 'FeatureCollection') ? undefined : `http://localhost:${availablePort}/icon/${name}.png`;
};
/**
* 获取选中节点
@ -608,7 +624,7 @@ export const useTreeNode = () => {
try {
arr = nodeType[selectedNodes[0].sourceType].rightMenus
} catch (e) {
console.log('e', e)
console.log('e', e, selectedNodes[0].sourceType)
arr = []
}
}

View File

@ -112,6 +112,7 @@ import modelObject from '../components/propertyBox/modelObject.vue'
import particleEffects from '../components/propertyBox/particleEffects.vue'
import flyLine from '../components/propertyBox/flyLine.vue'
import explosion from '../components/propertyBox/explosion.vue'
import vector from '../components/propertyBox/vector.vue'
import graphObject from '../components/propertyBox/graphObject.vue'
import graph from '../components/propertyBox/graph.vue'
@ -294,6 +295,11 @@ eventBus.on('openDialog', async (sourceType: any, id: any) => {
await nextTick()
dynamicComponentRef.value?.open(id)
break
case 'vector':
currentComponent.value = vector
await nextTick()
dynamicComponentRef.value?.open(id)
break
default:
break
}
@ -424,8 +430,9 @@ const getStatus = (time) => {
}
onMounted(async () => {
let baseURL = localStorage.getItem('service')
getAuthInfo()
await YJ.on()
await YJ.on({ host: baseURL })
createEarth()
})
</script>