diff --git a/package.json b/package.json index c5c0559..527bb42 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "electron-updater": "^6.3.9", "element-plus": "^2.10.4", "express": "^5.1.0", + "file-saver": "^2.0.5", "mitt": "^3.0.1", "moment": "^2.30.1", "pinia": "^3.0.3", @@ -43,7 +44,8 @@ "vue-clipboard3": "^2.0.0", "vue-i18n": "^9.14.5", "vue-router": "^4.5.1", - "vuedraggable": "^2.24.3" + "vuedraggable": "^2.24.3", + "xlsx": "^0.18.5" }, "devDependencies": { "@electron-toolkit/eslint-config-prettier": "3.0.0", diff --git a/src/renderer/src/common/initMapData.ts b/src/renderer/src/common/initMapData.ts index 9eba644..06ca53b 100644 --- a/src/renderer/src/common/initMapData.ts +++ b/src/renderer/src/common/initMapData.ts @@ -1,4 +1,5 @@ import { leftClick, rightClick } from '../../src/views/components/tree/entityClick' +import { renderVector } from '../views/components/tree/components/hooks/renderVector' export const initMapData = async (type, data, cd) => { let entityObject let options @@ -133,6 +134,14 @@ export const initMapData = async (type, data, cd) => { case 'explosion': entityObject = new YJ.Obj.Explosion(window.earth, data) break + case 'geojson': + entityObject = new YJ.Obj.GeoJson(window.earth, data) + entityObject.on() + break + case 'vector': + let node = window.treeObj.getNodeByParam("id", data.id, null); + entityObject = renderVector(node, false) + break default: break } @@ -168,6 +177,9 @@ export const initMapData = async (type, data, cd) => { rightClick(getOptions()); }; + if (entityObject.options.id) { + (window as any)._entityMap.set(entityObject.options.id, entityObject) + } } // options = entityObject diff --git a/src/renderer/src/icons/svg/importHeader.svg b/src/renderer/src/icons/svg/importHeader.svg new file mode 100644 index 0000000..9786685 --- /dev/null +++ b/src/renderer/src/icons/svg/importHeader.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/src/icons/svg/showAttr.svg b/src/renderer/src/icons/svg/showAttr.svg new file mode 100644 index 0000000..4a62fc9 --- /dev/null +++ b/src/renderer/src/icons/svg/showAttr.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/src/main.ts b/src/renderer/src/main.ts index 789d8d4..85b64de 100644 --- a/src/renderer/src/main.ts +++ b/src/renderer/src/main.ts @@ -71,6 +71,7 @@ if (!localStorage.getItem("AMapKey")) { // 注册全局指令 (window as any)._winMap = new Map(); +(window as any)._entityMap = new Map(); const setApp = createApp(App) // 定义全局方法 diff --git a/src/renderer/src/utils/index.ts b/src/renderer/src/utils/index.ts index 3db5458..5761668 100644 --- a/src/renderer/src/utils/index.ts +++ b/src/renderer/src/utils/index.ts @@ -42,3 +42,26 @@ export const setIP = (url: string) => { export const getIP = () => { return localStorage.getItem('ip') || undefined } + +/** + * 切割路径返回名称 + * @param path + * @returns {*} + */ +export function getNamefromPath(path) { + let index = 1; + if (path.endsWith(".json")) { + index = 2; + } + let arr = path.split("/"); + let str = arr[arr.length - index]; + + let name = str; + if (!path.endsWith(".json")) { + let arr1 = str.split("."); + arr1.pop(); + name = arr1.join("."); + } + + return name; +} diff --git a/src/renderer/src/views/components/propertyBox/vector.vue b/src/renderer/src/views/components/propertyBox/vector.vue index 3eee1a0..c835a0c 100644 --- a/src/renderer/src/views/components/propertyBox/vector.vue +++ b/src/renderer/src/views/components/propertyBox/vector.vue @@ -13,7 +13,7 @@
名称字段选择 - +
@@ -57,8 +57,7 @@ const getKeys = () => { } } keyData.value.push({ - name: label, - value: label, + label: label, key: key }) } @@ -80,6 +79,11 @@ const confirm = () => { name: entityOptions.value.name, show: entityOptions.value.show, id: entityOptions.value.options.id, + path: entityOptions.value.options.path, + field: entityOptions.value.field, + headTables: entityOptions.value.options.headTables, + opacity: entityOptions.value.opacity, + color: entityOptions.value.color, } let params2 = { "id": params.id, diff --git a/src/renderer/src/views/components/propertyBox/vectorAttr.vue b/src/renderer/src/views/components/propertyBox/vectorAttr.vue index e69de29..d23485e 100644 --- a/src/renderer/src/views/components/propertyBox/vectorAttr.vue +++ b/src/renderer/src/views/components/propertyBox/vectorAttr.vue @@ -0,0 +1,266 @@ + + + + + \ No newline at end of file diff --git a/src/renderer/src/views/components/tree/components/hooks/renderVector.ts b/src/renderer/src/views/components/tree/components/hooks/renderVector.ts new file mode 100644 index 0000000..18e291b --- /dev/null +++ b/src/renderer/src/views/components/tree/components/hooks/renderVector.ts @@ -0,0 +1,65 @@ +import { useTreeNode } from '@/views/components/tree/hooks/treeNode' +const { cusAddNodes } = useTreeNode() +export function renderVector(node, ifFly = true) { + // if (node.detail != "") node.detail.field = node.detail.fieldName || "id"; + let params = JSON.parse(node.params) + let vectorParams = { + id: node.id, + path: params.path, + fileName: node.sourceName, + ...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 newnodes = Vector.getAllNode(); + console.log("newnodes1111", newnodes); + if (newnodes) { + if (newnodes.list.length) { + newnodes.list.forEach((it) => { + let childNode = { + id: new YJ.Tools().randomString(), + sourceType: 'FeatureCollection', + sourceName: it.name, + isShow: true + } + cusAddNodes(window.treeObj, node.id, [childNode]) + let zijiNodes: any = []; + if (it.features && it.features.length) { + it.features.forEach((item) => { + let ziNode = { + id: item.id, + sourceType: item.type, + sourcePath: params.path, + 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') + }; + }); + }); + return Vector +} \ No newline at end of file diff --git a/src/renderer/src/views/components/tree/components/hooks/rightOperate.ts b/src/renderer/src/views/components/tree/components/hooks/rightOperate.ts index b956156..e8f64c5 100644 --- a/src/renderer/src/views/components/tree/components/hooks/rightOperate.ts +++ b/src/renderer/src/views/components/tree/components/hooks/rightOperate.ts @@ -5,6 +5,8 @@ import { useTreeNode } from '@/views/components/tree/hooks/treeNode' import { initMapData } from '@/common/initMapData' import { GisApi } from '@/api/gisApi' import { addMapSource } from '@/common/addMapSource' +import { getNamefromPath } from '@/utils/index' +import { renderVector } from './renderVector' const { cusAddNodes } = useTreeNode() export const useRightOperate = () => { @@ -83,12 +85,16 @@ export const useRightOperate = () => { parentId: parentId, sourceName: name, sourceType: 'vector', - sourcePath: filePaths[0], + // sourcePath: filePaths[0], params: { id: id, path: filePaths[0], field: 'id', name: name, + headTables: [], + opacity: 1, + color: 'rgba(0,255,184,0.5)', + show: true }, } TreeApi.addOtherSource(params) @@ -97,6 +103,22 @@ export const useRightOperate = () => { cusAddNodes(window.treeObj, params.parentId, [params]) renderVector(params, true) } + else if (["geojson"].includes(sourceType)) { + let baseURL = localStorage.getItem('service') + await addMapSource({ + type: 'geojson', + id: id, + sourceName: name, + opt: { + host: baseURL, + id: id, + url: filePaths[0], + show: true, + width: 1, + color: "rgb(239, 6, 6, 1)", + } + }) + } else { // 获取最后一个点的位置 const lastDotIndex = filePaths[0].lastIndexOf('.'); @@ -246,11 +268,54 @@ export const useRightOperate = () => { } } //属性 - const showAttr = (eventBus, node) => { - console.log(eventBus, node) + const showAttr = (eventBus) => { + let node + let selectNodes = getSelectedNodes(window.treeObj); + if (selectNodes && selectNodes[selectNodes.length - 1]) { + node = selectNodes[selectNodes.length - 1] + } + if (node && (node.sourceType == 'Feature' || node.sourceType == 'vector')) { + eventBus.emit("openDialog", 'vectorAttr', node.id); + } + } + //导入表头 + const importHeader = () => { + let node + let selectNodes = getSelectedNodes(window.treeObj); + if (selectNodes && selectNodes[selectNodes.length - 1]) { + node = selectNodes[selectNodes.length - 1] + } + const dialogParams = { + properties: ["openFile", "multiSelections"], + filters: [ + { + name: "excel", + extensions: ["csv"], + }, + ], + }; + + openDirectoryDialog(dialogParams, (paths) => { + if (!paths.length) { + return; + } + let name = getNamefromPath(paths[0]); + let formData = new FormData(); + formData.append("file", paths[0]); + formData.append("id", node.id); + console.log(paths[0], node.id) + // importTablehead(formData).then((res) => { + // if (res.code == 0) { + // this.rightClickTreeNode.head_tables = JSON.stringify( + // res.data.list + // ); + // this.$message.success("导入成功"); + // } else { + // this.$message.error("导入失败"); + // } + // }); + }); } - //导入模型 - const importHeader = () => { } //导入模型 const addXlsxs = () => { } //导入模型 @@ -288,7 +353,7 @@ export const useRightOperate = () => { type: 'success' }) source_ids.forEach(item => { - let entity = window.earth.entityMap.get(item) + let entity = (window as any)._entityMap.get(item) entity?.remove?.(); // let node = window.treeObj.getNodeByParam("id", item, null); eventBus.emit("destroyComponent", item); @@ -325,7 +390,7 @@ export const useRightOperate = () => { id: node.id, } } - let entityObject = window.earth.entityMap.get(params.id) + let entityObject = (window as any)._entityMap.get(params.id) entityObject.setCustomView() params.customView = entityObject.customView let params2 = { @@ -346,7 +411,7 @@ export const useRightOperate = () => { if (selectNodes && selectNodes[selectNodes.length - 1]) { let node = selectNodes[selectNodes.length - 1] let params = JSON.parse(node.params) - let entityObject = window.earth.entityMap.get(params.id) + let entityObject = (window as any)._entityMap.get(params.id) entityObject.resetCustomView() params.customView = entityObject.customView let params2 = { @@ -475,7 +540,7 @@ export const useRightOperate = () => { let selectNodes = getSelectedNodes(window.treeObj); if (selectNodes && selectNodes[selectNodes.length - 1]) { let node = selectNodes[selectNodes.length - 1] - let layer = window.earth.entityMap.get(node.id); + let layer = (window as any)._entityMap.get(node.id); layer[key](); _updateLayerIndex(); } @@ -497,7 +562,7 @@ export const useRightOperate = () => { ]; nodes.forEach((item) => { if (arr.includes(item.sourceType) && item.isShow) { - let entityOptions = window.earth.entityMap.get(item.id) + let entityOptions = (window as any)._entityMap.get(item.id) let layerIndex = entityOptions.layerIndex; layers.push({ id: item.id, layerIndex }); // let params = { @@ -601,71 +666,7 @@ export const useRightOperate = () => { } } - 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 = []) { // 处理路径分隔符 @@ -677,6 +678,7 @@ export const useRightOperate = () => { // 检查是否匹配任何需要移除的后缀 for (const ext of extensionsToRemove) { + //@ts-ignore const extWithDot = ext.startsWith('.') ? ext : `.${ext}`; if (lastComponent.endsWith(extWithDot)) { return lastComponent.slice(0, -extWithDot.length); @@ -686,6 +688,14 @@ export const useRightOperate = () => { return lastComponent; } + function openDirectoryDialog(option, cb) { + const { ipcRenderer } = require('electron') + ipcRenderer.send("open-directory-dialog", option); + ipcRenderer.once("selectedItem", (e, paths) => { + cb(paths); + }); + } + return { rightMenus } diff --git a/src/renderer/src/views/components/tree/hooks/tree.ts b/src/renderer/src/views/components/tree/hooks/tree.ts index fd4778e..6ef8247 100644 --- a/src/renderer/src/views/components/tree/hooks/tree.ts +++ b/src/renderer/src/views/components/tree/hooks/tree.ts @@ -56,7 +56,7 @@ export const useTree = () => { const menus = showRightMenu(event, treeObj.value) console.log('menus', menus) if (menus.length == 0) { - $changeComponentShow('.rightMenu', false) + // $changeComponentShow('.rightMenu', false) return } nextTick(() => { @@ -71,13 +71,34 @@ export const useTree = () => { */ const onDblClick = (event: MouseEvent, treeId: string, treeNode: any) => { let entityObject - if (treeNode.sourceType == 'pressModel') { - entityObject = (window as any).pressModelEntities.get(treeNode.id) - } else { - entityObject = window.earth.entityMap.get(treeNode.id) + + if(treeNode.sourceType == 'Feature') { + const getEntityObject = (n) => { + if (n) { + let t = window.earth.entityMap.get(n.id) + if (t) { + return t + } + else { + if (n.parentId) { + return getEntityObject(window.treeObj.getNodeByParam("id", n.parentId, null)) + } + } + } + } + entityObject = getEntityObject(treeNode) + entityObject.flyTo(treeNode.id) + } + else { + if (treeNode.sourceType == 'pressModel') { + entityObject = (window as any).pressModelEntities.get(treeNode.id) + } else { + entityObject = (window as any)._entityMap.get(treeNode.id) + } + entityObject.flyTo() } console.log('entityObject', entityObject) - entityObject.flyTo() + } /** * 用于捕获节点拖拽操作结束的事件回调函数 @@ -235,7 +256,7 @@ export const useTree = () => { entityObject = (window as any).pressModelEntities.get(treeNode.id) if (!entityObject && treeNode.isShow) { - const entity = window.earth.entityMap.get(params.modelId).entity + const entity = (window as any)._entityMap.get(params.modelId).entity entityObject = new YJ.Analysis.Flat(window.earth, entity, { positions: params.positions, height: params.height, @@ -245,7 +266,7 @@ export const useTree = () => { } } else if (treeNode.sourceType != 'directory') { - entityObject = window.earth.entityMap.get(params.id) + entityObject = (window as any)._entityMap.get(params.id) } if (entityObject) { entityObject.show = treeNode.isShow; diff --git a/src/renderer/src/views/components/tree/hooks/treeNode.ts b/src/renderer/src/views/components/tree/hooks/treeNode.ts index 336f5f6..ae0e484 100644 --- a/src/renderer/src/views/components/tree/hooks/treeNode.ts +++ b/src/renderer/src/views/components/tree/hooks/treeNode.ts @@ -446,17 +446,16 @@ export const useTreeNode = () => { const cusNodeIcon = async (node) => { let availablePort = await ipcRenderer.invoke('get-available-port'); let type - if(node.sourcePath) { + if(node.sourcePath || node.sourceType === 'vector') { + let path = node.sourcePath ? node.sourcePath : JSON.parse(node.params).path // 获取最后一个点的位置 - const lastDotIndex = node.sourcePath.lastIndexOf('.'); - + const lastDotIndex = path.lastIndexOf('.'); // 如果没有点或者点是最后一个字符,则不是有效的文件后缀 - if (lastDotIndex === -1 || lastDotIndex === node.sourcePath.length - 1) { + if (lastDotIndex === -1 || lastDotIndex === path.length - 1) { return false; } - // 提取后缀并转换为小写进行比较 - const extension = node.sourcePath.slice(lastDotIndex + 1).toLowerCase(); + const extension = path.slice(lastDotIndex + 1).toLowerCase(); type = extension } else { @@ -534,7 +533,9 @@ export const useTreeNode = () => { allNodes = allNodes.concat(treeObj.transformToArray(node)) }) allNodes.forEach((node: any) => { - _idSet.add(node.id) + if(node.sourceType !== 'FeatureCollection' && node.sourceType !== 'Feature') { + _idSet.add(node.id) + } treeObj.removeNode(node) }) YJ.Global.splitScreen.setActiveId(); diff --git a/src/renderer/src/views/home/index.vue b/src/renderer/src/views/home/index.vue index ed142f5..084dcb4 100644 --- a/src/renderer/src/views/home/index.vue +++ b/src/renderer/src/views/home/index.vue @@ -119,6 +119,7 @@ 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 vectorAttr from '../components/propertyBox/vectorAttr.vue' import graphObject from '../components/propertyBox/graphObject.vue' import graph from '../components/propertyBox/graph.vue' @@ -306,6 +307,11 @@ eventBus.on('openDialog', async (sourceType: any, id: any) => { await nextTick() dynamicComponentRef.value?.open(id) break + case 'vectorAttr': + currentComponent.value = vectorAttr + await nextTick() + dynamicComponentRef.value?.open(id) + break default: break }