Browse Source

aaaaaaaaaaaaaaaa

DESKTOP-CRQ4N2U\jintian 2 years ago
parent
commit
c5e70f6a2c
100 changed files with 27948 additions and 459 deletions
  1. 0 3
      index.html
  2. 1307 33
      package-lock.json
  3. 5 1
      package.json
  4. 0 0
      public/jt3dSDK/jt3d.es - 副本.js
  5. 61 0
      src/common/store/widget.d.ts
  6. 11 0
      src/common/store/widget.js
  7. 21 0
      src/common/uses/use-lifecycle.ts
  8. 6 2
      src/components/jt-popup/jt-popup.vue
  9. 12 8
      src/main.js
  10. 24 1
      src/store/index.ts
  11. 48 0
      src/views/Login/Login.vue
  12. 2 2
      src/views/Main/MainView.vue
  13. 159 0
      src/views/Map3d - 副本 (2)/Map3DMain.vue
  14. 158 0
      src/views/Map3d - 副本 (2)/Map3DMain.vue--filter
  15. 237 0
      src/views/Map3d - 副本 (2)/components/TrackRoam.vue
  16. 220 0
      src/views/Map3d - 副本 (2)/components/analysis-data.vue
  17. 517 0
      src/views/Map3d - 副本 (2)/components/analysis-space.vue
  18. 342 0
      src/views/Map3d - 副本 (2)/components/analysis-terrain.vue
  19. 386 0
      src/views/Map3d - 副本 (2)/components/coordsTool.vue
  20. 462 0
      src/views/Map3d - 副本 (2)/components/drawEdit.vue
  21. 79 0
      src/views/Map3d - 副本 (2)/components/index.js
  22. 387 0
      src/views/Map3d - 副本 (2)/components/location-region.vue
  23. 268 0
      src/views/Map3d - 副本 (2)/components/manage-basemap.vue
  24. 319 0
      src/views/Map3d - 副本 (2)/components/manage-layer.vue
  25. 394 0
      src/views/Map3d - 副本 (2)/components/map-compare.vue
  26. 305 0
      src/views/Map3d - 副本 (2)/components/map-split.vue
  27. 101 0
      src/views/Map3d - 副本 (2)/components/map.vue
  28. 242 0
      src/views/Map3d - 副本 (2)/components/measure.vue
  29. 278 0
      src/views/Map3d - 副本 (2)/components/navigation.vue
  30. 318 0
      src/views/Map3d - 副本 (2)/components/printmap.vue
  31. 465 0
      src/views/Map3d - 副本 (2)/components/query-graphics.vue
  32. 365 0
      src/views/Map3d - 副本 (2)/components/query-keyword.vue
  33. 300 0
      src/views/Map3d - 副本 (2)/components/queryResult.vue
  34. 401 0
      src/views/Map3d - 副本 (2)/components/special-effects.vue
  35. 234 0
      src/views/Map3d - 副本 (2)/components/toolbars.vue
  36. 316 0
      src/views/Map3d - 副本 (2)/components/viewerlabel.vue
  37. 1167 0
      src/views/Map3d - 副本 (2)/map.js
  38. 57 0
      src/views/Map3d - 副本 (2)/new_file.vue
  39. 43 0
      src/views/Map3d - 副本 (2)/widget.vue
  40. 128 0
      src/views/Map3d - 副本 (2)/备份/Map3DMain - 副本 (2).vue
  41. 172 0
      src/views/Map3d - 副本 (2)/备份/Map3DMain - 副本 (3).vue
  42. 90 0
      src/views/Map3d - 副本 (2)/备份/Map3DMain - 副本 (4).vue
  43. 474 0
      src/views/Map3d - 副本 (2)/备份/Map3DMain - 副本.vue
  44. 372 0
      src/views/Map3d - 副本 (2)/备份/toolbars - 副本 (2).vue
  45. 380 0
      src/views/Map3d - 副本 (2)/备份/toolbars - 副本 (3).vue
  46. 431 0
      src/views/Map3d - 副本 (2)/备份/toolbars - 副本 (4).vue
  47. 445 0
      src/views/Map3d - 副本 (2)/备份/toolbars - 副本.vue
  48. 181 0
      src/views/Map3d - 副本 (3)/Map3DMain.vue
  49. 237 0
      src/views/Map3d - 副本 (3)/components/TrackRoam.vue
  50. 220 0
      src/views/Map3d - 副本 (3)/components/analysis-data.vue
  51. 517 0
      src/views/Map3d - 副本 (3)/components/analysis-space.vue
  52. 342 0
      src/views/Map3d - 副本 (3)/components/analysis-terrain.vue
  53. 386 0
      src/views/Map3d - 副本 (3)/components/coordsTool.vue
  54. 462 0
      src/views/Map3d - 副本 (3)/components/drawEdit.vue
  55. 387 0
      src/views/Map3d - 副本 (3)/components/location-region.vue
  56. 266 0
      src/views/Map3d - 副本 (3)/components/manage-basemap.vue
  57. 334 0
      src/views/Map3d - 副本 (3)/components/manage-layer.vue
  58. 432 0
      src/views/Map3d - 副本 (3)/components/map-compare.vue
  59. 304 0
      src/views/Map3d - 副本 (3)/components/map-split.vue
  60. 101 0
      src/views/Map3d - 副本 (3)/components/map.vue
  61. 242 0
      src/views/Map3d - 副本 (3)/components/measure.vue
  62. 278 0
      src/views/Map3d - 副本 (3)/components/navigation.vue
  63. 318 0
      src/views/Map3d - 副本 (3)/components/printmap.vue
  64. 465 0
      src/views/Map3d - 副本 (3)/components/query-graphics.vue
  65. 365 0
      src/views/Map3d - 副本 (3)/components/query-keyword.vue
  66. 300 0
      src/views/Map3d - 副本 (3)/components/queryResult.vue
  67. 401 0
      src/views/Map3d - 副本 (3)/components/special-effects.vue
  68. 234 0
      src/views/Map3d - 副本 (3)/components/toolbars.vue
  69. 316 0
      src/views/Map3d - 副本 (3)/components/viewerlabel.vue
  70. 1137 0
      src/views/Map3d - 副本 (3)/map.js
  71. 42 0
      src/views/Map3d - 副本 (3)/widget.vue
  72. 474 0
      src/views/Map3d - 副本/Map3DMain - 副本.vue
  73. 433 0
      src/views/Map3d - 副本/Map3DMain.vue
  74. 0 0
      src/views/Map3d - 副本/components/ImageLayerSplit.vue
  75. 237 0
      src/views/Map3d - 副本/components/TrackRoam.vue
  76. 0 0
      src/views/Map3d - 副本/components/ViewerSplitScreen.vue
  77. 220 0
      src/views/Map3d - 副本/components/analysis-data.vue
  78. 517 0
      src/views/Map3d - 副本/components/analysis-space.vue
  79. 342 0
      src/views/Map3d - 副本/components/analysis-terrain.vue
  80. 0 0
      src/views/Map3d - 副本/components/basicLayer.vue
  81. 386 0
      src/views/Map3d - 副本/components/coordsTool.vue
  82. 462 0
      src/views/Map3d - 副本/components/drawEdit.vue
  83. 0 0
      src/views/Map3d - 副本/components/layer.vue
  84. 345 0
      src/views/Map3d - 副本/components/map.vue
  85. 0 0
      src/views/Map3d - 副本/components/mapNavigate.vue
  86. 242 0
      src/views/Map3d - 副本/components/measure.vue
  87. 278 0
      src/views/Map3d - 副本/components/navigation.vue
  88. 318 0
      src/views/Map3d - 副本/components/printmap.vue
  89. 465 0
      src/views/Map3d - 副本/components/query-graphics.vue
  90. 365 0
      src/views/Map3d - 副本/components/query-keyword.vue
  91. 300 0
      src/views/Map3d - 副本/components/queryResult.vue
  92. 401 0
      src/views/Map3d - 副本/components/special-effects.vue
  93. 445 0
      src/views/Map3d - 副本/components/toolbars - 副本.vue
  94. 386 0
      src/views/Map3d - 副本/components/toolbars.vue
  95. 316 0
      src/views/Map3d - 副本/components/viewerlabel.vue
  96. 43 0
      src/views/Map3d - 副本/index.js
  97. 49 0
      src/views/Map3d - 副本/new_file.vue
  98. 146 407
      src/views/Map3d/Map3DMain.vue
  99. 1 1
      src/views/Map3d/components/TrackRoam.vue
  100. 1 1
      src/views/Map3d/components/coordsTool.vue

+ 0 - 3
index.html

@@ -15,9 +15,6 @@
 		<script src="./ThirdParty/Cesium-1.93/Cesium.js"></script>
 		<!-- 引入生成热力图 -->
 		<script src="./ThirdParty/CesiumHeatmap.js"></script>
-		<script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script>
-		<script src="src/assets/js/plus.js"></script>
-		<script src="src/assets/js/mui.min.js"></script>
 
 	</head>
 

File diff suppressed because it is too large
+ 1307 - 33
package-lock.json


+ 5 - 1
package.json

@@ -8,6 +8,7 @@
   },
   "dependencies": {
     "@element-plus/icons-vue": "^2.0.10",
+    "@jintian/Map3dSDK": "^0.0.6",
     "axios": "^1.1.3",
     "cesium-navigation-es6": "^3.0.8",
     "echarts": "^5.4.0",
@@ -23,10 +24,12 @@
     "qs": "^6.11.0",
     "screenfull": "^5.2.0",
     "shapefile": "^0.6.6",
+    "uuid": "^9.0.0",
     "vite-plugin-cesium": "^1.2.18",
     "vue": "^3.2.25",
     "vue-router": "^4.0.16",
-    "vue3-print-nb": "^0.1.4"
+    "vue3-print-nb": "^0.1.4",
+    "vuex": "^4.1.0"
   },
   "devDependencies": {
     "@vitejs/plugin-vue": "^1.6.0",
@@ -44,6 +47,7 @@
     "optimizeDeps": {
       "include": [
         "@element-plus/icons-vue",
+        "@jintian/Map3dSDK",
         "axios",
         "cesium-navigation-es6",
         "echarts",

File diff suppressed because it is too large
+ 0 - 0
public/jt3dSDK/jt3d.es - 副本.js


+ 61 - 0
src/common/store/widget.d.ts

@@ -0,0 +1,61 @@
+import { Store, StoreOptions } from "vuex"
+import { InjectionKey, ComputedRef } from "vue"
+
+/**
+ * store 状态管理
+ * @copyright 火星科技 mars3d.cn
+ * @author 火星吴彦祖 2022-2-19
+ */
+declare module "common/store/widget" {
+  // 为 store state 声明类型
+  export interface DefaultOption {
+    autoDisable?: boolean
+    disableOther?: boolean | string[]
+    group?: string // group相同的widget一定是互斥的
+    meta?: any // 额外参数 不会在每次关闭后清除
+  }
+
+  export interface Widget {
+    name: string // 唯一标识
+    key?: string // 作为vue diff 环节的key,用于控制组件重载
+    component?: any // widget关联的异步组件
+    autoDisable?: boolean // 是否能够被自动关闭
+    disableOther?: boolean | string[] // 是否自动关闭其他widget,或通过数组指定需要被关闭的widget
+    group?: string // group相同的widget一定是互斥的
+    visible?: boolean // 显示隐藏
+    data?: any // 额外传参 会在每次关闭后清除
+    meta?: any // 额外参数 不会在每次关闭后清除
+  }
+
+  export interface WidgetState {
+    widgets: Widget[] // widget具体配置
+    openAtStart: string[] // 默认加载的widget
+    defaultOption?: DefaultOption // 支持配置默认参数
+  }
+
+  export const key: InjectionKey<Store<WidgetState>>
+
+  export const injectState: (options: StoreOptions<WidgetState>) => Store<WidgetState>
+
+  export const useWidgetStore: any
+
+  export const useWidget: () => {
+    currentWidget:any
+    // 本页面widget配置数组
+    widgets: ComputedRef<Widget[]>
+    // 默认开启的widget
+    openAtStart: ComputedRef<string[]>
+    // 获取指定的widget
+    getWidget: (name: string) => any
+    // 出发对应widget的onUpdate
+    updateWidget: (name: string, ...args: any[]) => any
+    // 获取widget的当前激活状态
+    isActivate: (name: string) => boolean
+    // 激活指定 widget模块
+    activate: (widget: string | Widget| (string | Widget)[], reload?:boolean) => void
+    // 释放指定的widget
+    disable: (name: string| string[]) => void
+    // 关闭释放所有widget ,hasAll传true值强制释放所有widget(默认autoDisable为false的widet不会释放)
+    disableAll: (hasAll?: boolean) => void
+  }
+}

File diff suppressed because it is too large
+ 11 - 0
src/common/store/widget.js


+ 21 - 0
src/common/uses/use-lifecycle.ts

@@ -0,0 +1,21 @@
+/**
+ * 组件中开启 map.ts 生命周期
+ * @copyright 火星科技 mars3d.cn
+ * @author 火星吴彦祖 2022-02-19
+ */
+import { inject, onBeforeMount, onBeforeUnmount } from "vue"
+
+export default function useLifecycle(mapWork: any): void {
+  const getMapInstance = inject<any>("getMapInstance")
+  onBeforeMount(() => {
+    if (mapWork.onMounted) {
+      const map = getMapInstance()
+      mapWork.onMounted(map)
+    }
+  })
+  onBeforeUnmount(() => {
+    if (mapWork.onUnmounted) {
+      mapWork.onUnmounted()
+    }
+  })
+}

+ 6 - 2
src/components/jt-popup/jt-popup.vue

@@ -33,7 +33,7 @@
 	export default {
 		data() {
 			return {
-				isshow: false,
+				isshow: true,
 				title: '',
 			}
 		},
@@ -78,7 +78,11 @@
 			longheader: { //是否是长背景图
 				type: String,
 				default: 0
-			}
+			},
+			// isshow: {
+			// 	type: Boolean,
+			// 	default: false
+			// },
 		},
 		methods: {
 			closebasicLayer() {

+ 12 - 8
src/main.js

@@ -31,20 +31,18 @@ import jtdrawer from './components/jt-drawer/drawer.vue'
 import jtcharts from './components/jt-charts/charts.vue'
 
 // 引入jt3dSDK
-import '/public/jt3dSDK/index.css';
-import * as jt3dSDK from '/public/jt3dSDK/jt3d.es.js';
-import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
-
+import "@jintian/Map3dSDK/lib/style.css"
+import "@jintian/Map3dSDK"
 
-// import 'amfe-flexible';//rem适配
 
 import Print from 'vue3-print-nb'; //引入打印模块
 
 
-
 // 创建 Pinia 实例
+import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
 const pinia = createPinia();
 pinia.use(piniaPluginPersistedstate);
+
 // 创建实例
 let app = createApp(App);
 for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
@@ -54,8 +52,6 @@ for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
 //挂载到vue根实例上
 app.config.globalProperties.$http = http
 app.config.globalProperties.$md5 = md5
-app.config.globalProperties.jt3dSDK = jt3dSDK
-
 
 app.directive('drag', drag)
 app.component("jt-popup",jtpopup)
@@ -68,4 +64,12 @@ app.use(router);
 app.use(ElementPlus);
 app.use(Print);
 
+// import comJs from '@/views/map3d/components/index.js'
+// app.use(comJs);
+
+
+import { injectState, key } from "@/common/store/widget"
+import storeWidget from "./widget-store"
+app.use(injectState(storeWidget), key)
+
 app.mount('#app');

+ 24 - 1
src/store/index.ts

@@ -18,7 +18,30 @@ export const Store = defineStore({
 			roleId: '',//用户权限ID
 			realName: '',//登录账号的用户名
 			keepAlives: ['Map3DMain'],//控制加载缓存页面
-			userport: ''
+			userport: '',
+			menuList:[],
+			aa:[],
+			
+			expandedKeys:[],
+			checkedkeys: [], 
+			
+			//底图数据
+			basemap:{
+				selectImg: 0, //选中的底图图片
+				selectBaseMap:{},//选中的底图数据
+			},
+			
+			//地形数据
+			terrain: {
+				isTerrain: false, //是否切换地形
+				terrainData: {}, //地形数据
+			},
+			
+			//标注数据
+			mark: {
+				isMark: false, //是否显示标注
+				markData: {}, //地形数据
+			}
 		}
 	},
 	getters: {

+ 48 - 0
src/views/Login/Login.vue

@@ -15,6 +15,13 @@
 	import sanwei from '@/assets/video/sanwei.mp4'
 	let route = undefined;
 	let router = undefined;
+	
+	//组件异步加载
+	import {
+		defineAsyncComponent,
+		markRaw,
+	} from 'vue';
+	
 </script>
 <template>
 	<div class="login-container">
@@ -96,6 +103,7 @@
 					if (res.data.length > 0) {
 						this.loginForm.id = res.data[0].id
 						store.realName = res.data[0].name;
+
 						this.storageAndgoTo()
 					} else {
 						ElMessage.error('账号或密码输入错误!')
@@ -116,6 +124,7 @@
 					console.log(res)
 					store.roleId = res.data[0].roleid
 					console.log(store.roleId)
+
 					if (
 						window.navigator.userAgent.match(
 							/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i
@@ -125,6 +134,10 @@
 					} else {
 						store.userport = 'PC'
 					}
+
+					//获取菜单
+					this.getMenu()
+
 					//跳转到Main3D页面			
 					this.$router.replace({
 						path: '/home'
@@ -147,6 +160,41 @@
 				}
 
 			},
+
+			//获取菜单并存储
+			getMenu() {
+				//获取角色id
+				let roleId = store.roleId
+				let sqlWhere = '"roleId"' + " = " + roleId + " and " + '"parentId"' + "='622'"
+				
+				//存储用户权限id
+				this.$http.get("/getTableList", {
+					tableName: "sys_role_menu",
+					// sqlWhere: '"roleId"' + " = '" + store.roleId + "'",
+					sqlWhere:sqlWhere,
+					orderByField: ''
+				}).then(res => {
+					store.menuList = res.data	
+					console.log('log-工具栏',store.menuList)
+					
+
+					// let bb=[]
+					// store.menuList.forEach(res => {
+					
+					// 	let aa = {
+					// 		// component: markRaw(defineAsyncComponent(() => import("@/views/map3d/components/" + res.router + ".vue"))),
+					// 		component: defineAsyncComponent(() => import("@/views/map3d/components/" + res.router + ".vue")),
+					// 		name: res.router,
+					// 		autoDisable: false,
+					// 		group: "manage",
+					// 	};
+					
+					// 	bb.push(aa);
+					// })
+					// store.aa=bb;
+					
+				})
+			}
 		},
 
 		mounted() {

+ 2 - 2
src/views/Main/MainView.vue

@@ -35,11 +35,11 @@
 			},
 		},
 		mounted() {
-
+			
 		}
 	}
 </script>
 
 <style lang="scss" scoped>
-	
+
 </style>

+ 159 - 0
src/views/Map3d - 副本 (2)/Map3DMain.vue

@@ -0,0 +1,159 @@
+<script setup>
+	//组件异步加载
+	import {
+		defineAsyncComponent,
+		markRaw,
+		computed,
+		provide,
+		ref
+	} from 'vue';
+
+	import {
+		Store
+	} from '@/store/index'
+	store = Store()
+
+	import {
+		useWidgetStore,
+		Widget
+	} from "@/common/store/widget"
+
+	import map3d from './components/map.vue';
+	import JtWidget from "./widget.vue"
+
+	const widgetStore = useWidgetStore()
+	// widgetStore.state.widgets = store.aa;
+
+	// widgetStore.state.widgets = [{
+	// 	component: markRaw(defineAsyncComponent(() => import("@/views/map3d/components/layer.vue"))),
+	// 	name: "layer",
+	// 	autoDisable: true,
+	// 	group: "manage",
+	// } ];
+
+	const widgets = computed(() => widgetStore.state.widgets);
+	const openAtStart = computed(() => widgetStore.state.openAtStart);
+
+	let jtMap3dInstance = null;
+	let isJTMap3DOnload = ref(false);
+	const jtMap3DOnload = (map) => {
+		console.log("map构造完成", map)
+		jtMap3dInstance = map;
+		isJTMap3DOnload.value = true
+	}
+	provide("getMapInstance", () => {
+		return jtMap3dInstance;
+	});
+</script>
+
+<template>
+	<div class="jt-map3dMain">
+
+		<!-- 地图组件 -->
+		<map3d @onload="jtMap3DOnload" ref="refMap3d" />
+
+		<!-- 地图加载完成后,在加载其他组件 -->
+		<template v-if="isJTMap3DOnload">
+
+			<template v-for="comp in widgets" :key="comp.key">
+				<jt-widget v-if="openAtStart.includes(comp.name) && comp.visible" v-model:visible="comp.visible" :widget="comp" />
+			</template>
+
+		</template>
+	</div>
+</template>
+
+<script>
+	import useLifecycle from "@/common/uses/use-lifecycle"
+	import * as mapWork from "./map"
+	let store = undefined
+
+	// 启用map.ts生命周期
+	useLifecycle(mapWork)
+
+	export default {
+		name: "JtMap3DMain",
+
+		/**
+		 *  数据 
+		 */
+		data() {
+			return {
+				layers: [],
+				basemaps: [],
+			}
+		},
+
+		/**
+		 *  方法 
+		 */
+		methods: {
+
+		},
+
+		mounted() {
+			let _self = this;
+
+			//获取地图图集id
+			let roleId = store.roleId
+			let atlasLayersSqlWhere = '"roleId"' + " = " + roleId + " "
+
+			//获取图集
+			_self.$http.get('/getTableList', {
+				tableName: 'sys_map_atlas_layers', //表名
+				sqlWhere: atlasLayersSqlWhere, //
+				orderByField: ''
+			}).then(res => {
+
+				store.layersList = res.data;
+				res.data.forEach((item, index) => {
+
+					if (item.atlastype === '图层') {
+						_self.layers.push(item);
+
+						if (item.isinit === '1') {
+							mapWork.setLayersControl(window.viewer, item, true);
+						}
+					}
+
+					if (item.atlastype === '底图') {
+						_self.basemaps.push(item);
+
+						if (item.layertype === '地形') {
+							// store.terrain.terrainData = item;
+
+							if (item.isinit === '1') {
+								// store.terrain.isTerrain = true;
+								//默认加载的地形
+								mapWork.setLayersControl(window.viewer, item, true);
+							}
+						} else if (item.layertype === '标注') {
+							// store.mark.markData = item;
+
+							if (item.isinit === '1') {
+								// store.mark.isMark = true;
+
+								//默认加载的标注
+								mapWork.setLayersControl(window.viewer, item, true);
+							}
+						} else {
+							if (item.isinit === '1') {
+								// store.basemap.basemapData = item;
+								// store.basemap.selectImg = item.layerorder;
+
+								//默认加载的底图
+								mapWork.setLayersControl(window.viewer, item, true);
+							}
+						}
+					}
+				})
+
+				store.layers = _self.layers;
+				store.basemaps = _self.basemaps;
+			});
+		}
+	};
+</script>
+<style lang="scss" scoped>
+
+</style>

+ 158 - 0
src/views/Map3d - 副本 (2)/Map3DMain.vue--filter

@@ -0,0 +1,158 @@
+<script setup>
+	//组件异步加载
+	import {
+		defineAsyncComponent,
+		markRaw,
+		computed,
+		provide,
+		ref
+	} from 'vue';
+
+	import {
+		Store
+	} from '@/store/index'
+	store = Store()
+
+	import {
+		useWidgetStore,
+		Widget
+	} from "@/common/store/widget"
+
+	import map3d from './components/map.vue';
+	import JtWidget from "./widget.vue"
+
+	const widgetStore = useWidgetStore()
+	// widgetStore.state.widgets = store.aa;
+
+	// widgetStore.state.widgets = [{
+	// 	component: markRaw(defineAsyncComponent(() => import("@/views/map3d/components/layer.vue"))),
+	// 	name: "layer",
+	// 	autoDisable: true,
+	// 	group: "manage",
+	// } ];
+
+	const widgets = computed(() => widgetStore.state.widgets);
+	const openAtStart = computed(() => widgetStore.state.openAtStart);
+
+	let jtMap3dInstance = null;
+	let isJTMap3DOnload = ref(false);
+	const jtMap3DOnload = (map) => {
+		console.log("map构造完成", map)
+		jtMap3dInstance = map;
+		isJTMap3DOnload.value = true
+	}
+	provide("getMapInstance", () => {
+		return jtMap3dInstance;
+	});
+</script>
+
+<template>
+	<div class="jt-map3dMain">
+
+		<!-- 地图组件 -->
+		<map3d @onload="jtMap3DOnload" ref="refMap3d" />
+
+		<!-- 地图加载完成后,在加载其他组件 -->
+		<template v-if="isJTMap3DOnload">
+
+			<template v-for="comp in widgets" :key="comp.key">
+				<jt-widget v-if="openAtStart.includes(comp.name) && comp.visible" v-model:isshow="comp.visible" :widget="comp" />
+			</template>
+
+		</template>
+	</div>
+</template>
+
+<script>
+	import useLifecycle from "@/common/uses/use-lifecycle"
+	import * as mapWork from "./map"
+	let store = undefined
+
+	// 启用map.ts生命周期
+	useLifecycle(mapWork)
+
+	export default {
+		name: "JtMap3DMain",
+
+		/**
+		 *  数据 
+		 */
+		data() {
+
+		},
+
+		/**
+		 *  方法 
+		 */
+		methods: {
+
+		},
+
+		mounted() {
+
+			//获取地图图集id
+			let roleId = store.roleId
+			let atlasLayersSqlWhere = '"roleId"' + " = " + roleId + " "
+
+			//获取图集
+			this.$http.get('/getTableList', {
+				tableName: 'sys_map_atlas_layers', //表名
+				sqlWhere: atlasLayersSqlWhere, //
+				orderByField: ''
+			}).then(res => {
+
+				//图层控制
+				store.layers = res.data.filter(item => {
+
+					// if (item.atlastype === '底图') {
+					// 	if (item.layertype === '地形') {
+					// 		store.terrain.terrainData = item;
+
+					// 		if (item.isinit === '1') {
+					// 			store.terrain.isTerrain = true;
+					// 			//默认加载的地形
+					// 			mapWork.setLayersControl(window.layer, item, true);
+					// 		}
+					// 	} else if (item.layertype === '标注') {
+					// 		store.mark.markData = item;
+					// 		if (item.isinit === '1') {
+					// 			store.mark.isMark = true;
+					// 			store.mark.markID = store.serviceMark + "_" + item.layercode + item.layerorder;
+
+					// 			//默认加载的标注
+					// 			mapWork.setLayersControl(window.layer, item, true);
+					// 		}
+					// 	} else {
+					// 		if (item.isinit === '1') {
+					// 			store.selectImg = item.layerorder;
+					// 			store.layerID = store.serviceMark + "_" + item.layercode + item.layerorder;
+
+					// 			//默认加载的底图
+					// 			mapWork.setLayersControl(window.layer, item, true);
+					// 		}
+					// 	}
+					// }
+
+					return item.atlasname !== '底图图集'
+				})
+
+				//底图切换
+				store.basemaps = res.data.filter(item => {
+
+					// if (item.atlastype === '图层') {
+					// 	if (item.isinit === '1') {
+					// 		mapWork.setLayersControl(window.layer, res, true);
+					// 	}
+					// }
+					return item.atlasname !== '图层图集'
+				})
+				
+				console.log('log-store.layers2', store.layers)
+				console.log('log-store.basemaps2', store.basemaps)
+			})
+		}
+	};
+</script>
+<style lang="scss" scoped>
+
+</style>

+ 237 - 0
src/views/Map3d - 副本 (2)/components/TrackRoam.vue

@@ -0,0 +1,237 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-TrackRoam">
+
+		<el-row style="margin-bottom: 5px;">
+			<el-button type="danger" v-if="isNew" @click="drawLine()">
+				<el-icon>
+					<Plus />
+				</el-icon>新增漫游
+			</el-button>
+			<el-button type="danger" v-if="!isNew" @click="flightRoaming('remove')">
+				<el-icon>
+					<Delete />
+				</el-icon>
+				退出漫游
+			</el-button>
+		</el-row>
+
+		<el-row style="margin-bottom: 5px;" v-if="!isNew">
+
+			<el-button type="danger" v-if="isBackward" @click="flightRoaming('playReverse')">
+				<el-icon>
+					<Back />
+				</el-icon>向后飞行
+			</el-button>
+			<el-button type="danger" v-if="!isBackward" @click="flightRoaming('playForward')">
+				<el-icon>
+					<Right />
+				</el-icon>向前飞行
+			</el-button>
+
+			<el-button type="danger" v-if="isPause" @click="flightRoaming('pause')">
+				<el-icon>
+					<VideoPause />
+				</el-icon>暂停漫游
+			</el-button>
+			<el-button type="danger" v-if="!isPause" @click="flightRoaming('pause')">
+				<el-icon>
+					<VideoPlay />
+				</el-icon>继续漫游
+			</el-button>
+		</el-row>
+
+		<el-row style="margin-bottom: 5px;" v-if="!isNew">
+			<el-button type="danger" @click="flightRoaming(0)">
+				自由漫游
+			</el-button>
+			<el-button type="danger" @click="flightRoaming(1)">
+				相机跟随
+			</el-button>
+		</el-row>
+		<el-row style="margin-bottom: 5px;" v-if="!isNew">
+			<el-button type="danger" @click="flightRoaming(2)">
+				第一视角
+			</el-button>
+			<el-button type="danger" @click="flightRoaming(3)">
+				上帝视角
+			</el-button>
+		</el-row>
+
+		<el-form label-width="130rem">
+			<el-form-item label="飞行速度:" v-if="!isNew">
+				<el-slider v-model="roam.speed" @input="handleSpeedChange" :max="100" :min="1" :step="1" />
+			</el-form-item>
+			<el-form-item label="距离运动点的距离(后方):" v-if="roam.role===2">
+				<el-slider v-model="roam.followedX" @input="handleFollowedXChange" :max="10000" :min="1" :step="1" />
+			</el-form-item>
+			<el-form-item label="距离运动点的距离(上方):" v-if="roam.role===2">
+				<el-slider v-model="roam.followedZ" @input="handleFollowedZChange" :max="10000" :min="1" :step="1" />
+			</el-form-item>
+		</el-form>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+
+	export default {
+		data() {
+			return {
+				isNew: true,
+				isPause: true,
+				isBackward: true,
+				Roaming: undefined,
+
+				roam: {
+					role: 0,
+					speed: 10,
+					followedX: 50,
+					followedZ: 10
+				}
+			}
+		},
+
+		/* 方法 */
+		methods: {
+
+			handleFollowedXChange(followedX) {
+				this.Roaming.followedX = followedX;
+			},
+			handleFollowedZChange(followedZ) {
+				this.Roaming.followedZ = followedZ;
+			},
+
+			handleSpeedChange(speed) {
+				this.Roaming.ChangeRoamingSpeed(speed);
+			},
+
+			/**
+			 * 绘制飞行路线
+			 */
+			drawLine() {
+				let _self = this;
+
+				jt3d.DrawTools.draw('polyline', {
+					isEdit: false,
+					onComplete(cartesian3d, points) {
+						//清除绘制
+						jt3d.DrawTools.Clear();
+
+						_self.Roaming = new jt3dSDK.Roaming(jt3d._viewer, cartesian3d, {
+							time: 360,
+							role: 2,
+							label: {
+								text: "lineName",
+							}
+						});
+						_self.isPause = true;
+						_self.isNew = false;
+						_self.roam.role = 2;
+						_self.Roaming.PauseOrContinue(_self.isPause);
+					}
+				});
+
+			},
+
+			/**
+			 * 飞行漫游
+			 * @param {Object} type
+			 */
+			flightRoaming(type) {
+
+				let _self = this;
+
+				switch (type) {
+					case "pause": //暂停飞行
+						this.isPause = !this.isPause;
+						this.Roaming.PauseOrContinue(this.isPause);
+						break;
+					case "playForward": //向前飞行
+						this.isPause = true;
+						this.isBackward = !this.isBackward;
+						this.Roaming.forwardFly();
+						break;
+					case "playReverse": //向后飞行
+						this.isPause = true;
+						this.isBackward = !this.isBackward;
+						this.Roaming.backwardsFly();
+						break;
+					case "remove": //向后飞行
+						this.isNew = true;
+						this.roam.role = Number(type);
+						this.Roaming.EndRoaming();
+						// //获取被clock监听的全部事件数量
+						// let len = jt3d._viewer.clock.onTick.numberOfListeners;
+						// for (let i = 0; i < len; i++) {
+						// 	//将被监听的方法移除来停止方法
+						// 	jt3d._viewer.clock.onTick.removeEventListener(jt3d._viewer.clock.onTick._listeners[i]);
+						// }
+						break;
+					case 0:
+						this.roam.role = Number(type);
+						this.Roaming.initRole(0);
+						break;
+					case 1:
+						this.roam.role = Number(type);
+						this.Roaming.initRole(1);
+						break;
+					case 2:
+						this.roam.role = Number(type);
+						this.Roaming.initRole(2);
+						break;
+					case 3:
+						this.roam.role = Number(type);
+						this.Roaming.initRole(3);
+						break;
+				}
+			},
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	::v-deep .el-table .cell {
+		line-height: 23rem !important;
+		padding: 0 12rem !important;
+		font-size: 14rem;
+	}
+
+	//整体样式
+	.jt-TrackRoam {
+		width: 90%;
+		margin-top: 16rem;
+		margin-left: 5%;
+		text-align: left;
+
+		--el-bg-color: rgb(0 44 126 / 60%);
+		--el-fill-color-blank: rgb(0 44 126 / 60%);
+		--el-text-color-secondary: rgb(216 240 255); //title
+		--el-text-color-regular: rgb(216 240 255); //内容
+		--el-fill-color-light: rgb(30 130 255);
+
+		.el-icon {
+			margin-right: 5rem;
+			color: #fff;
+		}
+	}
+</style>

+ 220 - 0
src/views/Map3d - 副本 (2)/components/analysis-data.vue

@@ -0,0 +1,220 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-analysisData">
+		<el-collapse v-model="activeName" accordion>
+			<el-upload drag :auto-upload=false action="" accept="shp" :on-preview="handlePreview" :on-remove="handleRemove" :on-change="bind">
+				<i class="el-icon-upload"></i>
+				<div class="el-upload__text">将shp文件拖到此处,或<em>点击上传</em></div>
+
+				<!-- <div class="el-upload__tip" slot="tip">必须是shp文件</div> -->
+				<span>
+					<el-icon>
+						<WarnTriangleFilled />
+					</el-icon>必须是shp文件
+				</span>
+			</el-upload>
+			<!-- <el-button style="margin-left: 10rem;" size="small" type="success" @click="config">生成GeoJson数据</el-button> -->
+		</el-collapse>
+	</div>
+</template>
+
+<script>
+	import {
+		open
+	} from 'shapefile'
+
+	let jt3d = undefined;
+
+	export default {
+		props: {},
+		watch: {
+
+		},
+		name: "Config",
+		data() {
+			return {
+				file: {},
+				filelist: [],
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			/* shp文件解析生成图形 */
+			config() {
+				let _this = this
+				const name = this.file.name
+				const extension = name.split('.')[1]
+				console.log(extension)
+				if ('shp' !== extension) {
+					this.$alert('文件不是shp文件!请重新选择文件', {
+						confirmButtonText: '确定'
+					})
+				} else {
+					const reader = new FileReader()
+					const fileData = this.file.raw
+					reader.readAsArrayBuffer(fileData)
+					reader.onload = function(e) {
+						open(this.result).then(source => source.read().then(function log(result) {
+							if (result.done) return;
+							console.log(result)
+							console.log(result.value);
+
+							let promise = Cesium.GeoJsonDataSource.load(result.value, {
+								clampToGround: true
+							});
+							promise.then((dataSource) => {
+
+								window["viewer"].dataSources.add(dataSource); // 加载这个geojson资源
+								dataSource.name = name.split('.')[0];
+								console.log(dataSource)
+								const entities = dataSource.entities.values;
+								for (let index = 0; index < entities.length; index++) {
+									const entity = entities[index];
+									entity.polygon.material = Cesium.Color.fromBytes(50, 160, 255, 77)
+									entity.polygon.outlineWidth = 3;
+									entity.polygon.outline = false;
+									entity.polygon.outlineColor = Cesium.Color.RED;
+									entity.polyline = {
+										positions: entity.polygon.hierarchy._value.positions,
+										width: entity.polygon.outlineWidth,
+										material: Cesium.Color.fromBytes(0, 255, 180, 255),
+										clampToGround: true
+									}
+								}
+
+								let options = {};
+								// 初始化参数默认值
+								options.duration = Cesium.defaultValue(options.duration, 2);
+								options.heading = Cesium.defaultValue(options.heading, 0);
+								options.pitch = Cesium.defaultValue(options.pitch, -60);
+								options.range = Cesium.defaultValue(options.range, 0.0);
+								let flyPromise = window["viewer"].flyTo(entities, {
+									duration: options.duration,
+									offset: {
+										heading: Cesium.Math.toRadians(options.heading),
+										pitch: Cesium.Math.toRadians(options.pitch),
+										range: options.range
+									}
+								});
+
+							});
+
+							return source.read().then(log);
+
+						})).catch(error => console.error(error.stack));
+					}
+				}
+
+			},
+			remove() {
+
+			},
+
+			//移除
+			handleRemove(file, fileList) {
+
+				/* 清除图形 */
+				console.log(file, fileList);
+				let list = window["viewer"].dataSources.getByName(file.name.split('.')[0])
+				// for(let i=0;i<list.length;i++){
+				// 	console.log(list.length)
+				// 	window["viewer"].dataSources.remove(list[i])
+				// }
+				list.forEach(res => {
+					console.log(res)
+					window["viewer"].dataSources.remove(res)
+				})
+
+				// window["viewer"].dataSources.remove(window["viewer"].dataSources.getByName(file.name.split('.')[0]))
+
+			},
+
+			//定位
+			handlePreview(file) {
+				console.log(file)
+				this.file = file;
+				// this.config();
+
+				let list = window["viewer"].dataSources.getByName(file.name.split('.')[0])
+				list.forEach(res => {
+					const entities = res.entities.values;
+					
+					let options = {};
+					// 初始化参数默认值
+					options.duration = Cesium.defaultValue(options.duration, 2);
+					options.heading = Cesium.defaultValue(options.heading, 0);
+					options.pitch = Cesium.defaultValue(options.pitch, -60);
+					options.range = Cesium.defaultValue(options.range, 0.0);
+					let flyPromise = window["viewer"].flyTo(entities, {
+						duration: options.duration,
+						offset: {
+							heading: Cesium.Math.toRadians(options.heading),
+							pitch: Cesium.Math.toRadians(options.pitch),
+							range: options.range
+						}
+					});
+				})
+
+			},
+			bind(files, fileList) {
+				//绑定文件
+				this.file = fileList[fileList.length - 1]
+				//console.log(this.file)
+				this.config();
+			}
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.el-upload-dragger .el-upload__text{
+		font-size: 16rem;
+	}
+	
+	.upload_demo {
+		text-align: center;
+		margin-top: 50rem;
+	}
+
+	.el-button {
+		margin-top: 10rem;
+	}
+
+	::v-deep .el-upload-dragger {
+		padding: 0rem;
+		margin-top: 10rem;
+		color: #606266;
+		font-size: 12rem;
+
+	}
+
+	::v-deep .el-upload-list__item-name {
+		color: #fff;
+		margin-left: -21rem;
+	}
+
+	::v-deep .el-icon svg {
+		color: #409eff;
+		font-size: smaller;
+	}
+</style>

+ 517 - 0
src/views/Map3d - 副本 (2)/components/analysis-space.vue

@@ -0,0 +1,517 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-analysisSpace">
+		<el-collapse v-model="activeName" accordion>
+			<el-collapse-item name="光照分析">
+				<template #title>
+					<i class='iconfont icon-svgguangzhaofenxi' />光照分析
+				</template>
+				<div class="el-collapse-item__content">
+					<el-button color="rgb(20 136 255)" @click="SunShine('start')">开启光照分析</el-button>
+					<el-button color="rgb(255 100 100)" @click="SunShine('remove')"><span style="color: #fff;">移除光照分析</span></el-button>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="方量分析">
+				<template #title>
+					<i class='iconfont icon-svgfangliangfenxi' />方量分析
+				</template>
+				<div class="el-collapse-item__content">
+					<el-form label-width="100rem">
+						<el-form-item label="挖方填方高度:">
+							<el-input v-model="cutFill.height" />
+						</el-form-item>
+						<el-form-item label="挖方填方精度:">
+							<el-input v-model="cutFill.precision" />
+						</el-form-item>
+					</el-form>
+					<div class="jt-btn" style="margin: 10rem;">
+						<el-button color="rgb(255 100 100)" @click="CutFill('draw')"><span style="color: #fff;">绘制挖方填方区域</span></el-button>
+						<el-button color="rgb(255 100 100)" @click="CutFill('remove')"><span style="color: #fff;">清除分析结果</span></el-button>
+					</div>
+					<el-form label-width="120rem">
+						<el-form-item label="总分析面积(㎡):">
+							<el-input v-model="cutFill.result.allArea" />
+						</el-form-item>
+						<el-form-item label="填方面积(㎡):">
+							<el-input v-model="cutFill.result.fillArea" />
+						</el-form-item>
+						<el-form-item label="填方体积(m³):">
+							<el-input v-model="cutFill.result.fillVolume" />
+						</el-form-item>
+						<el-form-item label="挖方面积(㎡):">
+							<el-input v-model="cutFill.result.cutArea" />
+						</el-form-item>
+						<el-form-item label="挖方体积(m³):">
+							<el-input v-model="cutFill.result.cutVolume" />
+						</el-form-item>
+					</el-form>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="剖面分析">
+				<template #title>
+					<i class='iconfont icon-svgpoumianfenxi' />剖面分析
+				</template>
+				<div class="el-collapse-item__content">
+					<div style="line-height: 2em; table-layout: fixed; word-wrap: break-word; word-break: normal; text-align:justify; text-justify: inter-ideograph;color: #ffffff99;">
+						提示:单击【剖面分析】按钮触发,然后在实景三维或地形上左键单击开始,左键双击结束
+					</div>
+					<el-button color="rgb(20 136 255)" @click="SectionAnalysis">剖面分析</el-button>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="通视分析">
+				<template #title>
+					<i class='iconfont icon-svgtongshifenxi' />通视分析
+				</template>
+				<div class="el-collapse-item__content">
+					<div style="line-height: 2em; table-layout: fixed; word-wrap: break-word; word-break: normal; text-align:justify; text-justify: inter-ideograph;color: #ffffff99;">
+						提示:红色代表不可视,绿色代表可视;
+					</div>
+					<el-button color="rgb(20 136 255)" @click="SightLine('activate')">添加通视分析</el-button>
+					<el-button color="rgb(255 100 100)" @click="SightLine('deactivate')"><span style="color: #fff;">清除通视分析</span></el-button>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="视域分析">
+				<template #title>
+					<i class='iconfont icon-svgshiyufenxi' />视域分析
+				</template>
+				<div class="el-collapse-item__content">
+					<div style="line-height: 2em; table-layout: fixed; word-wrap: break-word; word-break: normal; text-align:justify; text-justify: inter-ideograph;color: #ffffff99;">
+						提示:点击“添加视域”按钮后在场景中点击两个点添加视域,红色代表不可视,绿色代表可视;
+					</div>
+					<el-button color="rgb(20 136 255)" @click="ViewShed('activate')">添加视域</el-button>
+					<el-button color="rgb(255 100 100)" @click="ViewShed('deactivate')"><span style="color: #fff;">清除视域</span></el-button>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="限高分析">
+				<template #title>
+					<i class='iconfont icon-svgxiangaofenxi' />限高分析
+				</template>
+				<div class="el-collapse-item__content">
+					<el-form ref="form" label-width="100rem" label-position="right" size="mini">
+						<el-form-item label="地表海拔:">
+							<span>{{heightLimit.baseHeight}}</span>米&nbsp;&nbsp;<el-button color="rgb(20 136 255)" @click="HeightLimit('pickUp')">图上选点</el-button>
+						</el-form-item>
+						<el-form-item label="限制高度:">
+							<el-slider v-model="heightLimit.height" :min="0" :max="300" :step="1" @input="changeHeight"></el-slider>
+						</el-form-item>
+						<el-form-item label="当前高度:">
+							{{heightLimit.height}}米
+						</el-form-item>
+					</el-form>
+					<div class="jt-btn" style="margin-bottom: 10rem;">
+						<el-button color="rgb(20 136 255)" @click="HeightLimit('activate')">绘制限高区域</el-button>
+						<el-button color="rgb(255 100 100)" @click="HeightLimit('deactivate')"><span style="color: #fff;">清除限高分析</span></el-button>
+					</div>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="剖切展示">
+				<template #title>
+					<i class='iconfont icon-svgpouqiezhanshi' />剖切展示
+				</template>
+				<div class="el-collapse-item__content">
+					<div style="line-height: 2em; table-layout: fixed; word-wrap: break-word; word-break: normal; text-align:justify; text-justify: inter-ideograph;color: #ffffff60;">
+						目前仅支持凸多边形,如果绘制的是凹多边形,可能裁剪结果不正确
+					</div>
+					<el-button color="rgb(20 136 255)" @click="Cutting('activate')">添加剖切多边形</el-button>
+				</div>
+			</el-collapse-item>
+			<!-- <el-collapse-item name="视频融合">
+				<template #title>
+					<i class='iconfont icon-svgshipinronghe' />视频融合
+				</template>
+				<div class="el-collapse-item__content">
+					<div style="line-height: 2em; table-layout: fixed; word-wrap: break-word; word-break: normal; text-align:justify; text-justify: inter-ideograph;color: #ffffff60;">
+						请先打开【牟平中心城实景三维】
+					</div>
+					<el-button color="rgb(20 136 255)" @click="PolygonHierarchy">视频融合</el-button>
+				</div>
+			</el-collapse-item> -->
+		</el-collapse>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+
+	export default {
+		props: {},
+		watch: {},
+
+		/* 数据 */
+		data() {
+			return {
+				activeName: "光照分析",
+
+				// 限高分析
+				heightLimit: {
+					height: 20,
+					baseHeight: 0,
+				},
+
+				//方量分析	
+				cutFill: {
+					height: 10, //挖方填方高度
+					precision: 1256, //挖方填方精度
+					result: { //挖方填方结果
+						allArea: "",
+						cutArea: "",
+						cutVolume: "",
+						fillArea: "",
+						fillVolume: "",
+					},
+				},
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			/**
+			 * 光照分析
+			 */
+			SunShine(type) {
+				let _self = this;
+				switch (type) {
+					case "start":
+						jt3d.statusBar.show = false;
+						jt3d.SpatialAnalysis.SunshineShadow.start();
+
+						break;
+					case "remove":
+						jt3d.statusBar.show = true;
+						jt3d.SpatialAnalysis.SunshineShadow.remove();
+						break;
+				}
+			},
+
+			/**
+			 * 方量分析
+			 */
+			CutFill(type) {
+				let _self = this;
+
+				//功能初始化
+				_self.init();
+
+				switch (type) {
+					case "draw":
+						jt3d.DrawTools.draw('polygon', {
+							isEdit: false,
+							onComplete(cartesian3d, points) {
+								//清除绘制
+								jt3d.DrawTools.Clear();
+
+								let pointsArray = [];
+								points.forEach((coordinate, index) => {
+									pointsArray.push([
+										coordinate.lng,
+										coordinate.lat,
+										coordinate.height
+									]);
+								});
+
+								jt3d.SpatialAnalysis.CutFill.createPolygonGeo(pointsArray, {
+									height: _self.height,
+									precision: _self.precision,
+								}).then(res => {
+									_self.cutFill.result = res;
+								});
+
+							}
+						});
+
+						break;
+					case "remove":
+						jt3d.SpatialAnalysis.CutFill.remove();
+						this.cutFill.result = {
+							allArea: "",
+							cutArea: "",
+							cutVolume: "",
+							fillArea: "",
+							fillVolume: "",
+						}
+
+						//还原左键单击事件
+						this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+						break;
+				}
+			},
+
+			/**
+			 * 视频融合
+			 */
+			PolygonHierarchy() {
+				let videoElement = document.getElementById('trailer');
+				var videopolygon = jt3d._viewer.entities.add({
+					polygon: {
+						height: 0.1,
+						hierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights([121.600444, 37.398272, 37.95, 121.600443, 37.398272, 33, 121.600443, 37.398341, 33, 121.600444, 37.398341, 37.95])),
+						material: videoElement,
+						perPositionHeight: true,
+					}
+				});
+
+				let flyToEntity = jt3d.LocateUtil.flyToEntity(videopolygon, {
+					heading: 90, //方向
+					pitch: -32, //倾斜角度
+					range: 72
+				});
+				flyToEntity.then(function(vehicleEntity) {
+					jt3d._viewer.trackedEntity = vehicleEntity; //获取或设置摄像机当前正在跟踪的Entity实例。
+					vehicleEntity.viewFrom = new Cesium.Cartesian3(0, 1, 0.3);
+				});
+			},
+
+			/**
+			 * 剖切分析
+			 */
+			Cutting(type) {
+				let _self = this;
+				//功能初始化
+				_self.init();
+
+				switch (type) {
+					case "activate":
+						if (window["my3dtiles"]) {
+							jt3d.DrawTools.draw('polygon', {
+								isEdit: false,
+								onComplete(cartesian3d, points) {
+									//清除绘制
+									jt3d.DrawTools.Clear();
+							
+									let pointsArray = [];
+									points.forEach((coordinate, index) => {
+										pointsArray.push([
+											coordinate.lng,
+											coordinate.lat,
+											coordinate.height
+										]);
+									});
+							
+									jt3d.SpatialAnalysis.Cutting.addTiles(window["my3dtiles"], pointsArray);
+							
+								}
+							});
+						} else {
+							ElMessage.error("请先勾选3D模型");
+						}
+						break;
+					case "deactivate":
+						//还原左键单击事件
+						this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+						break;
+				}
+			},
+
+			/**
+			 * 限高分析
+			 */
+			HeightLimit(type) {
+				let _self = this;
+				//功能初始化
+				_self.init();
+
+				switch (type) {
+					case "pickUp": //图上选点,获取地表高度
+						jt3d.CommonTools._sketchViewModel.sketchTools('point', {
+							onComplete(cPoint, gPoint) {
+								_self.heightLimit.baseHeight = Number(gPoint.height.toFixed(2));
+							},
+							onError(message) {
+								
+							}
+						});
+						break;
+					case "activate":
+						jt3d.DrawTools.draw('polygon', {
+							isEdit: false,
+							onComplete(cartesian3d, points) {
+								//清除绘制
+								// jt3d.DrawTools._entities.remove(jt3d.DrawTools._drawEntity.polygon);
+								jt3d.DrawTools.Clear();
+
+								let pointsArray = [];
+								points.forEach((coordinate, index) => {
+									pointsArray.push([
+										coordinate.lng,
+										coordinate.lat,
+										coordinate.height
+									]);
+								});
+
+								jt3d.SpatialAnalysis.HeightLimit.addPrimitive(pointsArray, {
+									height: _self.heightLimit.height,
+									baseHeight: _self.heightLimit.baseHeight,
+								});
+							}
+						});
+						break;
+					case "deactivate":
+						jt3d.SpatialAnalysis.HeightLimit.removePrimitive();
+						jt3d.CommonTools._sketchViewModel.sketchClear();
+						//还原左键单击事件
+						this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+						break;
+				}
+			},
+			changeHeight(val) {
+				jt3d.SpatialAnalysis.HeightLimit.changeHeight(val);
+			},
+
+			/**
+			 * 通视分析
+			 * @param {Object} type
+			 */
+			SightLine(type) {
+				let _self = this;
+				//功能初始化
+				_self.init();
+
+				switch (type) {
+					case "activate":
+						jt3d.SpatialAnalysis.SightLine.startSightLine();
+						break;
+					case "deactivate":
+						jt3d.SpatialAnalysis.SightLine.clearAll();
+						//还原左键单击事件
+						this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+						break;
+				}
+			},
+
+			/**
+			 * 视域分析
+			 */
+			ViewShed(type) {
+				let _self = this;
+				//功能初始化
+				_self.init();
+
+				switch (type) {
+					case "activate":
+						jt3d.SpatialAnalysis.ViewShed.createViewshed(10);
+						break;
+					case "deactivate":
+						jt3d.SpatialAnalysis.ViewShed.clearAll();
+						//还原左键单击事件
+						this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+						break;
+				}
+			},
+
+			/**
+			 * 剖面分析
+			 */
+			SectionAnalysis() {
+				let _self = this;
+				//功能初始化
+				_self.init();
+
+				jt3d.DrawTools.draw('polyline', {
+					isEdit: false,
+					onComplete(cartesian3d, points) {
+						let pointsArray = [];
+						points.forEach((coordinate, index) => {
+							pointsArray.push([
+								coordinate.lng,
+								coordinate.lat,
+								coordinate.height
+							]);
+						});
+
+						let ProfileAnalysis = jt3d.SpatialAnalysis.Profile.startProfileAnalysis(pointsArray, jt3d.DrawTools._drawEntity.polyline);
+						ProfileAnalysis.then(function(result) {
+							_self.$parent.$parent.$refs.refDrawerSectionAnalysis.drawerVisible = true;
+							_self.$parent.$parent.initEchartsData(result);
+						});
+
+					}
+				});
+			},
+
+			/**
+			 * 功能初始化
+			 */
+			init() {
+				//移除左键单击事件
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); //移除事件
+				}
+
+				jt3d.DrawTools.Clear();
+				jt3d.CommonTools._sketchViewModel.sketchClear();
+
+				jt3d.SpatialAnalysis.CutFill.remove(); //清除方量分析
+				jt3d.SpatialAnalysis.Profile.removeProfileAnalysis(); //移除剖面分析
+				jt3d.SpatialAnalysis.SightLine.clearAll(); //清除通视分析
+				jt3d.SpatialAnalysis.ViewShed.clearAll(); //清除视域分析
+				jt3d.SpatialAnalysis.HeightLimit.removePrimitive(); //清除限高分析		
+			}
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.jt-analysisSpace {
+		position: relative;
+
+		.iconfont {
+			padding: 0 10rem;
+		}
+
+		.el-collapse {
+			--el-collapse-border-color: rgb(0 44 126 / 0%);
+
+			--el-collapse-header-text-color: #ffffff;
+			--el-collapse-header-font-size: 13rem;
+			--el-collapse-content-bg-color: rgb(0 44 126 / 0%);
+			--el-collapse-content-font-size: 13rem;
+			--el-collapse-content-text-color: rgb(216 240 255);
+
+			--el-collapse-header-height: 40rem;
+			--el-collapse-header-bg-color: rgb(30 130 255);
+
+			--el-fill-color-blank: rgb(0 44 126 / 68%);
+			--el-text-color-regular: rgb(216 240 255);
+			--el-border-color: rgb(35 135 255);
+
+			.el-collapse-item__content {
+				padding: 10rem;
+				// padding-bottom: 0rem;
+			}
+		}
+	}
+
+	::v-deep .el-collapse-item__content {
+		padding: 10rem;
+		// padding-bottom: 0rem;
+		overflow-y: hidden;
+	}
+
+	::v-deep .el-collapse-item__header {
+		background: url(@/assets/images/bg_collapse_title.png) no-repeat;
+		background-size: 350rem 40rem;
+		// background-color: rgb(22 90 190);
+		// background-color: rgb(5 45 100 /60%);
+		background-color: rgb(30 130 255);
+		border-bottom: 0;
+	}
+</style>

+ 342 - 0
src/views/Map3d - 副本 (2)/components/analysis-terrain.vue

@@ -0,0 +1,342 @@
+<script setup>
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-analysisTerrain">
+		<el-collapse v-model="activeName" accordion>
+			<el-collapse-item name="地下模式">
+				<template #title>
+					<i class='iconfont icon-svgdixiamoshi' />地下模式
+				</template>
+				<div class="el-collapse-item__content">
+					<div style="line-height: 2em; table-layout: fixed; word-wrap: break-word; word-break: normal; text-align:justify; text-justify: inter-ideograph;color: #ffffff60;">
+						提示:可以透明地表,进入地下模式,可以看地下管网数据。
+					</div>
+					<el-form label-width="130rem">
+						<el-form-item label="地下模式开启状态:">
+							<el-switch v-model="underground.boolUnderground" active-text="已开启" inactive-text="已关闭" @change="handleUndergroundChange">
+							</el-switch>
+						</el-form-item>
+						<el-form-item label="地表透明度:">
+							<el-slider v-model="underground.alpha" :min="0" :max="1" :step="0.1" :disabled="!underground.boolUnderground" @input="handleAlphaChange">
+							</el-slider>
+						</el-form-item>
+					</el-form>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="地形开挖">
+				<template #title>
+					<i class='iconfont icon-svgdixingkaiwa' />地形开挖
+				</template>
+				<div class="el-collapse-item__content">
+					<el-form ref="form" label-width="100rem" label-position="right" size="mini">
+						<el-form-item label="开挖深度:">
+							<el-input v-model="terrainExcavation.excavateDepth" />
+						</el-form-item>
+					</el-form>
+					<div class="jt-btn" style="margin-bottom: 10rem;">
+						<el-button color="rgb(20 136 255)" @click="terrainExcavate('add')">绘制开挖区域</el-button>
+						<el-button color="rgb(255 100 100)" @click="terrainExcavate('remove')"><span style="color: #fff;">清除开挖分析</span></el-button>
+					</div>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="坡度分析">
+				<template #title>
+					<i class='iconfont icon-svgpodufenxi' />坡度分析
+				</template>
+				<div class="el-collapse-item__content">
+					<div class="jt-btn" style="margin-top: 10rem;">
+						<el-button color="rgb(20 136 255)" @click="SlopeAspect('Num')">坡度等分</el-button>
+						<el-button color="rgb(20 136 255)" @click="SlopeAspect('Distance')">坡度等距</el-button>
+						<el-button color="rgb(255 100 100)" @click="removeSlopeAspect"><span style="color: #fff;">移除</span></el-button>
+					</div>
+				</div>
+			</el-collapse-item>
+			<!-- <el-collapse-item name="深度检测">
+					<template #title>
+						<i class='iconfont icon-tianqizitiku43' />深度检测
+					</template>
+					<div class="el-collapse-item__content">
+						深度检测
+					</div>
+				</el-collapse-item>
+				<el-collapse-item name="等高线">
+					<template #title>
+						<i class='iconfont icon-tianqizitiku43' />等高线
+					</template>
+					<div class="el-collapse-item__content">
+						等高线
+					</div>
+				</el-collapse-item> -->
+		</el-collapse>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+
+	export default {
+		props: {
+
+		},
+		watch: {
+		},
+
+		/* 数据 */
+		data() {
+			return {
+				activeName: "地下模式",
+				
+				//地下模式
+				underground: {
+					alpha: 0.5,
+					boolUnderground: false,
+				},
+				
+				//地形开挖
+				terrainExcavation:{
+					excavateDepth: 10, //开挖深度
+				}
+				
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			/**
+			 * 是否开启地下模式
+			 * @param {Object} bool
+			 */
+			handleUndergroundChange(bool) {
+				window["viewer"].scene.screenSpaceCameraController.enableCollisionDetection = !bool; //相机与地形的碰撞检测
+				window["viewer"].scene.globe.translucency.frontFaceAlphaByDistance = new Cesium.NearFarScalar(1.5e2, 0.5, 8.0e6, 1.0);
+				window["viewer"].scene.globe.translucency.enabled = bool; //是否开启透明
+				this.handleAlphaChange(this.underground.alpha);
+			},
+			/**
+			 * el-slider 值改变时触发
+			 * 设置地表透明度
+			 * @param {Object} alpha
+			 */
+			handleAlphaChange(alpha) {
+				const frontFaceAlphaByDistance = window["viewer"].scene.globe.translucency.frontFaceAlphaByDistance;
+				frontFaceAlphaByDistance.nearValue = alpha;
+				frontFaceAlphaByDistance.farValue = alpha;
+			},
+
+			/**
+			 * 移除坡度分析
+			 */
+			removeSlopeAspect() {
+				jt3d.TerrainAnalysis.SlopeAspect.clearAll();
+				//还原左键单击事件
+				this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+			},
+			/**
+			 * 坡度坡向分析
+			 * @param {Object} type
+			 */
+			SlopeAspect(type) {
+				let _self = this;
+				//功能初始化
+				_self.init();
+
+				switch (type) {
+					case "Num":
+						jt3d.DrawTools.draw('polygon', {
+							isEdit: false,
+							onComplete(cartesian3d, points) {
+
+								let pointsArray = [];
+								points.forEach((coordinate, index) => {
+									pointsArray.push([
+										coordinate.lng,
+										coordinate.lat,
+										coordinate.height
+									]);
+								});
+
+								jt3d.TerrainAnalysis.SlopeAspect.createNew4Num(pointsArray, jt3d.DrawTools._drawEntity.polygon, {
+									num: 10
+								});
+
+								//清除绘制
+								// jt3d.DrawTools._entities.remove(jt3d.DrawTools._drawEntity.polygon);
+								jt3d.DrawTools.Clear();
+							}
+						});
+
+						break;
+					case "Distance":
+						jt3d.DrawTools.draw('polygon', {
+							isEdit: false,
+							onComplete(cartesian3d, points) {
+
+								let pointsArray = [];
+								points.forEach((coordinate, index) => {
+									pointsArray.push([
+										coordinate.lng,
+										coordinate.lat,
+										coordinate.height
+									]);
+								});
+
+								jt3d.TerrainAnalysis.SlopeAspect.createNew4Distance(pointsArray, jt3d.DrawTools._drawEntity.polygon, {
+									distance: 0.05
+								});
+
+								//清除绘制
+								// jt3d.DrawTools._entities.remove(jt3d.DrawTools._drawEntity.polygon);
+								jt3d.DrawTools.Clear();
+							}
+						});
+						break;
+				}
+			},
+
+			/**
+			 * 移除地形开挖
+			 */
+			removeTerrainExcavate() {
+				jt3d.TerrainAnalysis.TerrainExcavation.clear();
+				//还原左键单击事件
+				this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+			},
+			/**
+			 * 地形开挖
+			 */
+			terrainExcavate(type) {
+				let _self = this;
+				//功能初始化
+				_self.init();
+				
+				if (type === "add") {
+					jt3d.DrawTools.draw('polygon', {
+						onComplete(aa, points) {
+							jt3d.DrawTools.Clear();
+							let pointsArray = [];
+							points.forEach((coordinate, index) => {
+								pointsArray.push([
+									coordinate.lng,
+									coordinate.lat,
+									coordinate.height
+								]);
+							});
+							jt3d.TerrainAnalysis.TerrainExcavation.add(pointsArray, {
+								excavateDepth: _self.terrainExcavation.excavateDepth
+							});
+
+						}
+					});
+				} else if (type === "remove") {
+					_self.removeTerrainExcavate();
+				}
+			},
+
+			/**
+			 * 功能初始化
+			 */
+			init() {
+				//移除左键单击事件
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); //移除事件
+				}
+
+				jt3d.DrawTools.Clear();
+
+				jt3d.TerrainAnalysis.TerrainExcavation.clear();; //清除地形开挖
+				jt3d.TerrainAnalysis.SlopeAspect.clearAll(); //移除坡度坡向分析	
+			}
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.el-switch{
+		font-size: 14rem !important;
+		line-height: 20rem !important;
+		align-items: self-start !important;
+	}
+	::v-deep .is-checked .el-switch__core .el-switch__action{
+		margin-left: calc(-1rem - 14rem);
+	}
+	
+	::v-deep .el-switch__core .el-switch__action{
+		top:1rem;
+	}
+	
+	::v-deep .el-switch__core .el-switch__action{
+		width: 14rem;
+		height: 14rem;
+	}
+	
+	::v-deep .el-switch__core{
+		width: 40rem !important;
+		height: 20rem !important;
+	}
+	::v-deep .el-switch__label{
+		height: 20rem !important;
+		font-size: 14rem !important;
+	}
+	::v-deep .el-switch__label *{
+		font-size: 14rem !important;
+	}
+	
+	::v-deep .el-switch__label--left{
+		margin-right: 10rem;
+	}
+	
+	.jt-analysisTerrain {
+		position: relative;
+		.iconfont {
+			padding: 0 10rem;
+		}
+
+		.el-collapse {
+			--el-collapse-border-color: rgb(0 44 126 / 0%);
+
+			--el-collapse-header-text-color: #ffffff;
+			--el-collapse-header-font-size: 13rem;
+			--el-collapse-content-bg-color: rgb(0 44 126 / 0%);
+			--el-collapse-content-font-size: 13rem;
+			--el-collapse-content-text-color: rgb(216 240 255);
+
+			--el-collapse-header-height: 40rem;
+			--el-collapse-header-bg-color: rgb(30 130 255);
+
+			--el-fill-color-blank: rgb(0 44 126 / 68%);
+			--el-text-color-regular: rgb(216 240 255);
+			--el-border-color: rgb(35 135 255);
+
+			.el-collapse-item__content {
+				padding: 10rem;
+				// padding-bottom: 0rem;
+			}
+		}
+	}
+
+	::v-deep .el-collapse-item__content {
+		padding: 10rem;
+		// padding-bottom: 0rem;
+		overflow-y: hidden;
+	}
+
+	::v-deep .el-collapse-item__header {
+		background: url(@/assets/images/bg_collapse_title.png) no-repeat;
+		background-size: 350rem 40rem;
+		// background-color: rgb(22 90 190);
+		// background-color: rgb(5 45 100 /60%);
+		background-color: rgb(30 130 255);
+		border-bottom: 0;
+	}
+</style>

+ 386 - 0
src/views/Map3d - 副本 (2)/components/coordsTool.vue

@@ -0,0 +1,386 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+<template>
+	<div class="jt-coordsTool">
+		<el-collapse v-model="activeName" accordion>
+			<el-collapse-item name="坐标定位">
+				<template #title>
+					<i class='iconfont icon-dituzuobiao' />坐标定位
+				</template>
+				<div class="el-collapse-item__content">
+					<div style="line-height: 2em; table-layout: fixed; word-wrap: break-word; word-break: normal; text-align:justify; text-justify: inter-ideograph;color: #ffffff60;">
+						提示: 填写格式:x1,y1,z1;x2,y2,z2;x3,y3,z3;......;标点符号必须采用英文半角。
+					</div>
+					<el-form label-width="80rem">
+						<el-form-item label="定位类型:">
+							<el-radio-group v-model="position.locationType">
+								<el-radio label="point">点</el-radio>
+								<el-radio label="polyline">线</el-radio>
+								<el-radio label="polygon">多边形</el-radio>
+							</el-radio-group>
+						</el-form-item>
+					</el-form>
+					<el-input v-model="position.locationCoords" type="textarea" :autosize="{ minRows: 6, maxRows: 6 }" />
+					<div class="jt-btn" style="margin-top: 10rem;">
+						<el-button color="rgb(20 136 255)" @click="Position">坐标定位</el-button>
+						<el-button color="rgb(255 100 100)" @click="emptyLoc"><span style="color: #fff;">清除定位</span></el-button>
+					</div>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="坐标拾取">
+				<template #title>
+					<i class='iconfont icon-chaxunzuobiaozhi' />坐标拾取
+				</template>
+				<div class="el-collapse-item__content">
+					<div style="line-height: 2em; table-layout: fixed; word-wrap: break-word; word-break: normal; text-align:justify; text-justify: inter-ideograph;color: #ffffff60;">
+						提示:点击【坐标拾取】按钮,在地图上点击获取坐标。
+					</div>
+					<el-input v-model="pickCoords" type="textarea" :autosize="{ minRows: 6, maxRows: 6 }" />
+					<div class="jt-btn" style="margin-top: 10rem;">
+						<el-button color="rgb(20 136 255)" @click="pickUp">坐标拾取</el-button>
+						<el-button color="rgb(20 136 255)" @click="undo">撤销</el-button>
+						<el-button color="rgb(255 100 100)" @click="emptyPic"><span style="color: #fff;">清空</span></el-button>
+					</div>
+				</div>
+			</el-collapse-item>
+		</el-collapse>
+	</div>
+</template>
+<script>
+	let jt3d = undefined;
+
+	export default {
+		props: {
+
+		},
+		watch: {
+			pickCoordsLable: function(val) {
+				this.setPickCoordsLable(val);
+			},
+
+		},
+
+		/* 数据 */
+		data() {
+			return {
+				activeName: "坐标定位",
+
+				position: {
+					locationType: "point", //定位类型
+					locationCoords: "", //定位坐标
+				},
+
+				pickCoords: "", //坐标拾取
+				pickCoordsArray: [],
+				pickCoordsLable: 1,
+
+				pointEntities: []
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			/**
+			 * 设置点的lable
+			 */
+			setPickCoordsLable(val) {
+				jt3d.CommonTools._sketchViewModel._lineLabel = val.toString();
+			},
+
+			/**
+			 * 坐标拾取
+			 */
+			pickUp() {
+				let _self = this;
+
+				//移除左键单击事件
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
+				}
+
+				jt3d.CommonTools._sketchViewModel._lineLabel = _self.pickCoordsLable.toString();
+				jt3d.CommonTools._sketchViewModel.sketchTools('point', {
+					onComplete(cPoint, gPoint) {
+						_self.pickCoordsArray.push(gPoint.lng.toFixed(6) + ',' + gPoint.lat.toFixed(6) + ',' + gPoint.height.toFixed(2)) + ";";
+						_self.pickCoords = _self.pickCoordsArray.join(";\n");
+						_self.pickCoordsLable++;
+
+						//还原左键单击事件
+						_self.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+					},
+					onError(message) {
+						
+					}
+				});
+			},
+
+			/**
+			 * 坐标拾取 - 撤销
+			 */
+			undo() {
+				this.pickCoordsArray.pop();
+				this.pickCoords = this.pickCoordsArray.join(";\n");
+				this.pickCoordsLable--;
+
+				//移除最后一个元素
+				let lastPointEntity = jt3d.CommonTools._sketchViewModel._pointEntitys[jt3d.CommonTools._sketchViewModel._pointEntitys.length - 1];
+				jt3d._entities.remove(lastPointEntity);
+				jt3d.CommonTools._sketchViewModel._pointEntitys.pop();
+			},
+
+			/**
+			 * 坐标拾取 - 清空
+			 */
+			empty() {
+				this.pickCoords = "";
+				this.pickCoordsArray = [];
+				this.pickCoordsLable = 1;
+				jt3d.CommonTools._sketchViewModel.sketchClear();
+				jt3d.CommonTools._sketchViewModel._clearEvent();
+				jt3d.CommonTools._sketchViewModel._clearEvent(jt3d.CommonTools._sketchViewModel._sketchEventHandler);
+
+				this.position.locationCoords = "";
+				jt3d._viewer.entities.remove(jt3d.LocateUtil._locationEntity);
+
+				for (let i = 0; i < this.pointEntities.length; i++) {
+					jt3d._viewer.entities.remove(this.pointEntities[i]);
+				}
+				this.pointEntities = []; //脏数据,存储entities
+			},
+			
+			/**
+			 * 坐标拾取 - 清空
+			 */
+			emptyPic() {
+				this.pickCoords = "";
+				this.pickCoordsArray = [];
+				this.pickCoordsLable = 1;
+				jt3d.CommonTools._sketchViewModel.sketchClear();
+				jt3d.CommonTools._sketchViewModel._clearEvent();
+				jt3d.CommonTools._sketchViewModel._clearEvent(jt3d.CommonTools._sketchViewModel._sketchEventHandler);
+			
+				jt3d._viewer.entities.remove(jt3d.LocateUtil._locationEntity);
+			
+				for (let i = 0; i < this.pointEntities.length; i++) {
+					jt3d._viewer.entities.remove(this.pointEntities[i]);
+				}
+				this.pointEntities = []; //脏数据,存储entities
+			},
+			
+			/**
+			 * 坐标定位 - 清空
+			 */
+			emptyLoc() {
+				this.pickCoordsArray = [];
+				this.pickCoordsLable = 1;
+				jt3d.CommonTools._sketchViewModel.sketchClear();
+				jt3d.CommonTools._sketchViewModel._clearEvent();
+				jt3d.CommonTools._sketchViewModel._clearEvent(jt3d.CommonTools._sketchViewModel._sketchEventHandler);
+			
+				this.position.locationCoords = "";
+				jt3d._viewer.entities.remove(jt3d.LocateUtil._locationEntity);
+			
+				for (let i = 0; i < this.pointEntities.length; i++) {
+					jt3d._viewer.entities.remove(this.pointEntities[i]);
+				}
+				this.pointEntities = []; //脏数据,存储entities
+			},
+
+			/**
+			 * 坐标定位
+			 */
+			Position() {
+				let _self = this;
+
+				let endstring = _self.position.locationCoords.substring(_self.position.locationCoords.length - 1);
+				if (endstring != ";") {
+					ElMessage("最后一位请用;结束!");
+					return false;
+				}
+
+				let coords = _self.position.locationCoords.substr(0, _self.position.locationCoords.length - 1);
+				let coordArray = coords.split(';');
+				let pointArray = [];
+				coordArray.forEach((coordinate, index) => {
+					let xyArray = coordinate.split(',');
+					if (xyArray.length != 2 && xyArray.length != 3) {
+						ElMessage("坐标不是成对出现,请检查!");
+						throw Error(); //forEach()本身无法跳出循环,所以,这里使用了抛异常的方法来终止它。
+					} else {
+						let longitude = xyArray[0];
+						let latitude = xyArray[1];
+
+						if (xyArray[2]) {
+							let height = xyArray[2];
+							let point = [Number(longitude), Number(latitude), Number(height)];
+
+							pointArray.push(point);
+							//点标记
+							jt3d.CommonTools._sketchViewModel._lineLabel = (index + 1).toString();
+							jt3d.CommonTools._sketchViewModel.sketchDrawFeacture(point, 'drawPoint');
+
+							if (index === (coordArray.length - 1)) {
+								loc();
+							}
+						} else {
+
+							let terrainAltitude = jt3dSDK.common.getHeigthByPointsMostDetailed(jt3d._viewer, [
+								[Number(longitude), Number(latitude)]
+							]);
+							terrainAltitude.then(function(updatedPositions) {
+								let point = [Number(longitude), Number(latitude), Number(updatedPositions[0].height)];
+								pointArray.push(point);
+								//点标记
+								jt3d.CommonTools._sketchViewModel._lineLabel = (index + 1).toString();
+								jt3d.CommonTools._sketchViewModel.sketchDrawFeacture(point, 'drawPoint');
+
+								if (index === (coordArray.length - 1)) {
+									loc();
+								}
+							});
+						}
+					}
+				});
+
+				function loc() {
+					switch (_self.position.locationType) {
+						case "point":
+							if (coordArray.length === 1) {
+
+								let point = jt3d.PointObject.generatePoint(
+									pointArray[0]
+								);
+								point.then(function(entity) {
+									_self.flyToEntity(entity);
+								});
+							} else {
+								let line = jt3d.PolylineObject.drawSpecifyColorLine(pointArray, {
+									color: [255, 0, 0, 0]
+								});
+								line.then(function(entity) {
+									_self.flyToEntity(entity);
+								});
+							}
+							break;
+						case "polyline":
+							let line = jt3d.PolylineObject.drawSpecifyColorLine(pointArray, {
+								color: [255, 255, 0, 0.8]
+							});
+							line.then(function(entity) {
+								_self.flyToEntity(entity);
+							});
+
+							break;
+						case "polygon":
+							let polygon = jt3d.PolygonObject.generatePolygonByPoints(pointArray, {
+								color: [255, 255, 0, 0.8]
+							});
+							polygon.then(function(entity) {
+								_self.flyToEntity(entity);
+							});
+							break;
+					}
+
+				}
+
+			},
+
+			flyToEntity(entity) {
+				let flyToEntity = jt3d.LocateUtil.flyToEntity(entity, {
+					duration: 3,
+					heading: -45,
+					pitch: -20,
+					range: 6000
+				});
+				flyToEntity.then(function(entity) {
+					if (entity.point) {
+						jt3d._viewer.entities.remove(entity);
+					}
+				});
+			},
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.el-radio-group {
+		height: 32rem;
+		line-height: 32rem;
+		flex-wrap: nowrap;
+	}
+
+	::v-deep .el-radio__label {
+		font-size: 14rem !important;
+		padding-left: 8rem !important;
+	}
+
+	.jt-coordsTool {
+		position: relative;
+
+		.iconfont {
+			padding: 0 10rem;
+		}
+
+		.el-collapse {
+			--el-collapse-border-color: rgb(0 44 126 / 0%);
+
+			--el-collapse-header-text-color: #ffffff;
+			--el-collapse-header-font-size: 13rem;
+			--el-collapse-content-bg-color: rgb(0 44 126 / 0%);
+			--el-collapse-content-font-size: 13rem;
+			--el-collapse-content-text-color: rgb(216 240 255);
+
+			--el-collapse-header-height: 40rem;
+			--el-collapse-header-bg-color: rgb(30 130 255);
+
+			--el-fill-color-blank: rgb(0 44 126 / 68%);
+			--el-text-color-regular: rgb(216 240 255);
+			--el-border-color: rgb(35 135 255);
+
+			.el-collapse-item__content {
+				padding: 10rem;
+				// padding-bottom: 0rem;
+			}
+		}
+	}
+
+	::v-deep .el-collapse-item__content {
+		padding: 10rem;
+		// padding-bottom: 0rem;
+		overflow-y: hidden;
+	}
+
+	::v-deep .el-collapse-item__header {
+		background: url(@/assets/images/bg_collapse_title.png) no-repeat;
+		background-size: 350rem 40rem;
+		// background-color: rgb(22 90 190);
+		// background-color: rgb(5 45 100 /60%);
+		background-color: rgb(30 130 255);
+		border-bottom: 0;
+	}
+
+	::v-deep .el-form-item {
+		margin-bottom: 10rem;
+	}
+
+	::v-deep .el-radio {
+		margin-right: 10rem;
+	}
+</style>

+ 462 - 0
src/views/Map3d - 副本 (2)/components/drawEdit.vue

@@ -0,0 +1,462 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+	import {
+		inject
+	} from "vue";
+	import {
+		ArrowLeft,
+		ArrowRight,
+		Delete,
+		Edit,
+		Share
+	} from '@element-plus/icons-vue';
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-drawTool">
+		<div style="margin-bottom: 0rem;">
+			<el-select class="selectInfo" v-model="value" @change="handleClick" placeholder="请选择" style="width: 65%; margin-bottom: 10rem;margin-right: 10rem;">
+				<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
+			</el-select>
+			<el-button type="danger" :icon="Delete" style="margin-top: 8rem;width: 30%;" @click="removeAll()">清除</el-button>
+		</div>
+		<div v-show="value=='二维平面类'">
+			<el-row :gutter="20" style="margin-left: 0rem; margin-right: 0rem">
+				<el-col v-for="(item,index) in towDimension" :span="8" @click="createGraphics(item.drawType,index)">
+					<el-avatar shape="circle" :size="70" :class="currentIndex===index?'selectStyle':'defaultStyle'">
+						<i :class="[item.icon,currentIndex===index?'selectFontStyle':'']" />
+					</el-avatar>
+					<div style="margin-top: 5rem; font-size: 14rem;" :class="currentIndex===index?'selectFontStyle':''">{{item.label}}</div>
+				</el-col>
+			</el-row>
+		</div>
+		<div v-show="value=='三维立体类'">
+			<el-row :gutter="20" style="margin-left: 0rem; margin-right: 0rem">
+				<el-col v-for="(item,index) in threeDimension" :span="8" @click="createGraphics(item.drawType,index)">
+					<el-avatar shape="circle" :size="70" :class="currentIndex===index?'selectStyle':'defaultStyle'">
+						<i :class="[item.icon,currentIndex===index?'selectFontStyle':'']" />
+					</el-avatar>
+					<div style="margin-top: 5rem; font-size: 14rem;" :class="currentIndex===index?'selectFontStyle':''">{{item.label}}</div>
+				</el-col>
+			</el-row>
+		</div>
+		<div v-show="value=='军事标绘类'">
+			<el-row :gutter="20" style="margin-left: 0rem; margin-right: 0rem">
+				<el-col v-for="(item,index) in militaryPlotting" :span="8" @click="createMilitaryPlot(item.drawType,index)">
+					<el-avatar shape="circle" :size="70" :class="currentIndex===index?'selectStyle':'defaultStyle'">
+						<i :class="[item.icon,currentIndex===index?'selectFontStyle':'']" />
+					</el-avatar>
+					<div style="margin-top: 5rem; font-size: 14rem;" :class="currentIndex===index?'selectFontStyle':''">{{item.label}}</div>
+				</el-col>
+			</el-row>
+		</div>
+		<div v-show="value=='点标绘类'">
+			<el-row :gutter="20" style="margin-left: 0rem; margin-right: 0rem">
+				<el-col v-for="(item,index) in point" :span="8" @click="createDrawPoint(item.drawType,index)">
+					<el-avatar shape="circle" :size="70" :class="currentIndex===index?'selectStyle':'defaultStyle'">
+						<i :class="[item.icon,currentIndex===index?'selectFontStyle':'']" />
+					</el-avatar>
+					<div style="margin-top: 5rem; font-size: 14rem;" :class="currentIndex===index?'selectFontStyle':''">{{item.label}}</div>
+				</el-col>
+			</el-row>
+		</div>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+	let tipEntity = undefined;
+	export default {
+		props: {},
+		watch: {},
+		/* 数据 */
+		data() {
+			return {
+				currentIndex: -1,
+				value: "二维平面类",
+				options: [{
+						value: '点标绘类',
+						label: '点标绘类',
+					}, {
+						value: '二维平面类',
+						label: '二维平面类',
+					},
+					{
+						value: '三维立体类',
+						label: '三维立体类',
+					},
+					{
+						value: '军事标绘类',
+						label: '军事标绘类',
+					},
+				],
+				towDimension: [{
+						label: '贴地线',
+						drawType: 'polyline',
+						number: 0,
+						icon: 'iconfont icon-svgtiedixian'
+					},
+					{
+						label: '箭头线',
+						drawType: 'arrowPolyline',
+						number: 1,
+						icon: 'iconfont icon-svgjiantouxian'
+					},
+					{
+						label: '贴地面',
+						drawType: 'polygon', //polygon
+						number: 2,
+						icon: 'iconfont icon-svgtiedimian'
+					},
+					{
+						label: '动态线',
+						drawType: 'dynamicPolyline',
+						number: 3,
+						icon: 'iconfont icon-svgliudongxian'
+					},
+					{
+						label: '发光线',
+						drawType: '发光线',
+						number: 4,
+						icon: 'iconfont icon-svgfaguangxian'
+					},
+					{
+						label: '描边线',
+						drawType: 'outlinePolyline',
+						number: 5,
+						icon: 'iconfont icon-svgmiaobianxian'
+					},
+					{
+						label: '动态圆',
+						drawType: 'dynamicCircle',
+						number: 6,
+						icon: 'iconfont icon-svgdongtaiyuan'
+					},
+					{
+						label: '普通圆',
+						drawType: 'circle',
+						number: 7,
+						icon: 'iconfont icon-svgputongyuan'
+					},
+					{
+						label: '矩形',
+						drawType: 'rectangle',
+						number: 8,
+						icon: 'iconfont icon-svgjuxing'
+					},
+
+				],
+				threeDimension: [{
+						label: '空间线',
+						drawType: 'spatialLine',
+						number: 0,
+						icon: 'iconfont icon-svgkongjianxian'
+					},
+					{
+						label: '动态墙',
+						drawType: 'dynamicWall',
+						number: 1,
+						icon: 'iconfont icon-svgdongtaiqiang'
+					},
+					{
+						label: '房屋',
+						drawType: 'house',
+						number: 2,
+						icon: 'iconfont icon-svgfangwu'
+					},
+					{
+						label: '文字',
+						drawType: 'text',
+						number: 3,
+						icon: 'iconfont icon-svgzi'
+					},
+					{
+						label: '视频墙',
+						drawType: 'videoWall',
+						number: 4,
+						icon: 'iconfont icon-svgshipinqiang'
+					},
+					{
+						label: '普通墙',
+						drawType: 'normalWall',
+						number: 5,
+						icon: 'iconfont icon-svgputongqiang'
+					},
+				],
+				militaryPlotting: [{
+						label: '直线箭头',
+						drawType: 'straightArrow',
+						number: 1,
+						icon: 'iconfont icon-zhijiantou'
+					},
+					{
+						label: '攻击箭头',
+						drawType: 'attackArrow',
+						number: 2,
+						icon: 'iconfont icon-tujifangxiang'
+					},
+					{
+						label: '钳击箭头',
+						drawType: 'pincerArrow',
+						number: 3,
+						icon: 'iconfont icon-qianji'
+					}
+				],
+				point: [{
+						label: '小模型',
+						drawType: 'model',
+						number: 1,
+						icon: 'iconfont icon-jihedi'
+					}, {
+						label: '文字',
+						drawType: 'label',
+						number: 2,
+						icon: 'iconfont icon-jihedi'
+					},
+					{
+						label: '点',
+						drawType: 'point',
+						number: 3,
+						icon: 'iconfont icon-jihedi'
+					},
+					{
+						label: '点及文字',
+						drawType: 'point2Label',
+						number: 4,
+						icon: 'iconfont icon-jihedi'
+					},
+					{
+						label: '广告牌',
+						drawType: 'billboard',
+						number: 5,
+						icon: 'iconfont icon-jihedi'
+					},
+					{
+						label: '广告牌及文字',
+						drawType: 'billboard2Label',
+						number: 6,
+						icon: 'iconfont icon-jihedi'
+					}
+				],
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			//清除全部
+			removeAll() {
+				jt3d.DrawToolsEdit.Clear();
+				jt3d.DrawMilitaryPlot.clearAll();
+				jt3d.DrawPointEdit.clearAll();
+
+				this.currentIndex = -1;
+
+				//还原左键单击事件
+				this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+			},
+
+			//选择绘制类型
+			//头部标题点击事件
+			handleClick(val) {
+				console.log(val)
+				this.currentIndex = -1;
+				this.value = val
+			},
+
+			//创建军事标会
+			createMilitaryPlot(type, index) {
+				let _self = this;
+				this.currentIndex = index;
+
+				//移除左键单击事件
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
+				}
+
+				/* 创建监听 */
+				jt3d.DrawMilitaryPlot.onEditProperty = {};
+				// 开始绘制
+				jt3d.DrawMilitaryPlot.draw(type, {
+					onComplete(cPoint, gPoint) {
+						// _self.$parent.$parent.param = param;
+						// _self.$parent.$parent.showDialog = true;
+					}
+				});
+			},
+
+			//创建二维标会和三维标会
+			createGraphics(type, index) {
+				let _self = this;
+				this.currentIndex = index;
+
+				//移除左键单击事件
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
+				}
+
+				/* 创建监听 */
+				jt3d.DrawToolsEdit.onEditProperty = {};
+				// 开始绘制
+				jt3d.DrawToolsEdit.draw(type, {
+					isEdit: true,
+					onComplete(cPoint, gPoint) {
+
+					},
+					onError(message) {
+						console.log('错误原因', message)
+					}
+				});
+			},
+
+			//创建点类标绘
+			createDrawPoint(type, index) {
+				let _self = this;
+				this.currentIndex = index;
+
+				//移除左键单击事件
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
+				}
+
+				/* 创建监听 */
+				jt3d.DrawPointEdit.onEditProperty = {};
+				// 开始绘制
+				jt3d.DrawPointEdit.draw(type, {
+					isEdit: true,
+					onComplete(cPoint, gPoint) {
+
+					},
+					onError(message) {
+						console.log('错误原因', message)
+					}
+				});
+			}
+
+		},
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.el-avatar {
+		width: 70rem !important;
+		height: 70rem !important;
+		font-size: 14px !important;
+		cursor: pointer;
+	}
+
+	// .el-popper{
+	// 	padding: 5rem 11rem;
+	// 	font-size: 12rem;
+	// 	line-height: 20rem;
+	// 	min-height: 10rem;
+	// 	width: 322rem;
+	// 	height: 311rem;
+	// 	left: 15rem !important;
+	// 	top: 175rem !important;
+	// }
+
+	::v-deep .el-scrollbar {
+		background-color: gainsboro !important;
+	}
+
+	.el-select-dropdown__item {
+		color: #409eff !important;
+		padding: 0 32rem 0 20rem;
+		height: 34rem;
+		line-height: 34rem;
+		font-size: 14rem;
+	}
+
+	.jt-drawTool {
+		--el-avatar-size: 70rem !important;
+
+
+		.el-col {
+			padding: 10rem;
+			// color: rgba(90, 172, 255, 1.0);
+			color: #fff;
+		}
+
+		i {
+			display: inline-block;
+			width: 100%;
+			height: 36rem;
+			line-height: 36rem;
+			text-align: center;
+			border-radius: 5rem;
+			font-size: 40rem;
+			// color: rgba(90, 172, 255, 1.0);
+			color: #fff;
+			transition: all .3s;
+			-webkit-transition: all .3s
+		}
+
+		.selectStyle {
+			// background: rgba(135, 182, 254, 0.5);
+			background: rgb(0 44 126);
+			--el-avatar-size: 70rem !important;
+		}
+
+		.defaultStyle {
+			background: #ffffff00;
+			--el-avatar-size: 70rem !important;
+		}
+
+		.selectFontStyle {
+			color: #fff;
+		}
+
+		.el-button.is-text {
+			background-color: rgba(255, 255, 255, 0.5);
+		}
+
+		el-option {
+			margin-top: -15rem !important;
+		}
+
+		.iconactive {
+			box-shadow: 0 0 3rem 3rem rgba(12, 123, 200, .6);
+		}
+
+		.active {
+			color: #409eff
+		}
+
+		::v-deep .el-input__wrapper {
+			background-color: rgba(255, 255, 255, 0);
+			color: #fff;
+		}
+
+		::v-deep .el-input__inner {
+			color: #fff;
+		}
+
+		.selectInfo {
+			top: 10rem !important;
+		}
+
+		.el-select-dropdown__wrap {
+			margin-top: 10rem;
+		}
+
+		.el-select-dropdown__item {
+			background-color: rgba(255, 255, 255, 1) !important;
+
+		}
+
+		.el-select-dropdown__item:hover {
+			background-color: rgba(255, 255, 235, 1) !important;
+		}
+
+	}
+</style>

+ 79 - 0
src/views/Map3d - 副本 (2)/components/index.js

@@ -0,0 +1,79 @@
+// import {
+// 	defineAsyncComponent
+// } from 'vue';
+// export default {
+// 	install(app) {
+// 		// const req = require.context('./', false, /\.vue$/) //获取当前文件夹下的所有.vue文件,并返回一个对象
+// 		const req =
+// 			import.meta.glob('./*.vue'); // //获取当前文件夹下的所有.vue文件,并返回一个对象
+// 			debugger
+// 		Object.keys(req).forEach(item => { // Object.keys遍历,返回一个包含所有属性名的数组,对数组遍历,根据属性名,通过obj[属性名]的方式拿取到属性值,相较于for in的优势在于只遍历了属性名,而非属性名和属性值全部遍历,性能有优化
+// 			debugger
+// 			const com = req(item).default //在default包裹层下拿到属性名
+// 			app.component(com.name, com)
+// 		})
+// 	}
+// }
+
+
+/*
+ **全局注册组件
+ */
+import {
+	defineAsyncComponent
+} from 'vue';
+const components =import.meta.glob('./*.vue'); // 异步方式,获取当前文件夹下的所有.vue文件,并返回一个对象
+export default function install(app) {
+	for (const [key, value] of Object.entries(components)) {
+	  const name = key.slice(key.lastIndexOf('/') + 1, key.lastIndexOf('.'));
+	  app.component(name, defineAsyncComponent(value));
+	}
+}
+
+
+/*
+ **全局注册组件
+ */
+// import { defineAsyncComponent } from 'vue';
+// //获取components目录下所有的文件信息
+// const modulesFiles = import.meta.globEager('./*.vue')// 异步方式,获取当前文件夹下的所有.vue文件,并返回一个对象
+// const pathList = []
+// //遍历拿到所有的文件名称
+// for (const path in modulesFiles) {
+//     pathList.push(path)
+// }
+// //全局批量注册components下所有组件
+// export default {
+//     install(app) {
+//         pathList.forEach((path) => {
+// 			debugger
+//             const component = modulesFiles[path].default;
+// 			const name = path.slice(path.lastIndexOf('/') + 1, path.lastIndexOf('.'));
+//             app.component(component.name, component)
+// 			 // app.component(name, defineAsyncComponent(component))
+//         })
+//     }
+// }
+
+
+// const app = createApp(App);
+// function registerGlobalAsyncComponents(app: VueApp) {
+//   const modules = import.meta.glob('./**/*.vue');
+//   for (const path in modules) {
+//     const result = path.match(/.*\/(.+).vue$/);
+//     if (result) {
+//       const name = result[1];
+//       const component = modules[path];
+//       app.component(name, defineAsyncComponent(component));
+//     }
+//   }
+// }
+
+
+// const modules = import.meta.glob('./components-new/*.vue');
+// const components: any = ref({});
+// Object.entries(modules).forEach(([path, asyncCom]) => {
+//   const name = path.replace(/\.\/components-new\/(.*)\.vue/, '$1');
+//   components.value[name] = markRaw(defineAsyncComponent(asyncCom));
+// });
+

+ 387 - 0
src/views/Map3d - 副本 (2)/components/location-region.vue

@@ -0,0 +1,387 @@
+<script setup>
+	import {
+		ref
+	} from 'vue';
+	import {
+		inject
+	} from "vue";
+	import selshi from '@/assets/images/selshi.png';
+	import selcun from '@/assets/images/selcun.png';
+	import cun from '@/assets/images/cun.png';
+	import shi from '@/assets/images/shi.png';
+	import xian from '@/assets/images/xian.png';
+	import selxian from '@/assets/images/selxian.png';
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<jt-popup title="空间分析" ref="refAnalysisSpace" >
+		<div class="tabs">
+			<el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
+				<i v-for="(item,index) in cityList">
+					<el-tab-pane :name="item.number">
+						<template #label>
+							<span class="custom-tabs-label">
+								<img v-if="index==0" :src="isindex==0?selshi:shi">
+								<img v-if="index==1" :src="isindex==1?selxian:xian">
+								<img v-if="index==2" :src="isindex==2?selcun:cun">
+								<span>{{item.label}}</span>
+							</span>
+						</template>
+						<template #default>
+							<div class="content">
+								<div :class="dj == 1?'item':'item2'" v-for="(res,num) in ALLlist" @click="selectCity(res.label,index+1,res.regioncode,res.dj)">
+									<div :class="addcolor(num)" @click="currentidx(num)">
+										<span>{{res.label}}</span>
+									</div>
+								</div>
+							</div>
+						</template>
+					</el-tab-pane>
+				</i>
+			</el-tabs>
+		</div>
+		<div class="Ficons">
+			<!-- <span>遮罩</span> -->
+			<!-- <el-icon color="#ffffff" class="icons" @click="hide" :size="20">
+			<View v-show="!hideicon" />
+			<Hide v-show="hideicon" />
+		</el-icon> -->
+		</div>
+	</jt-popup>
+</template>
+
+<script>
+	let jt3d = undefined;
+	let entities = undefined;
+	export default {
+		data() {
+			return {
+				currentIndex: -1,
+				isindex: 0, //判断选中第几个标题
+				cityList: [{ //tab数组展示列表
+					label: '牟平',
+					number: 0,
+					dj: 1
+				}],
+				activeName: 0, //选中的下标牵引
+				ALLlist: [], //所有子集城市
+				downlist: [], //村集
+				dj: 1, //控制列表样式
+				entities: undefined,
+				hideicon: false, //控制遮罩层显示
+				acolor: true, //是否展示颜色
+			}
+		},
+		watch: {
+			//改变高度值
+			activeName() {
+				this.acolor = false
+			}
+		},
+		methods: {
+			currentidx(index) {
+				this.currentIndex = index
+				this.acolor = true
+			},
+
+			//添加颜色样式
+			addcolor(index) {
+				if (this.currentIndex == index) {
+					return {
+						active: this.acolor
+					}
+				}
+			},
+
+			/**
+			 *控制遮罩层
+			 */
+			hide() {
+				this.hideicon = !this.hideicon
+				if (this.hideicon) {
+					entities[0].polygon.material = Cesium.Color.fromBytes(50, 160, 255, 1)
+				} else {
+					entities[0].polygon.material = Cesium.Color.fromBytes(50, 160, 255, 77)
+				}
+			},
+			/**
+			 * 移除定位样式
+			 */
+			remove() {
+				if (window["viewer"].dataSources.getByName('标绘区')) {
+					window["viewer"].dataSources.remove(window["viewer"].dataSources.getByName('标绘区')[0])
+				}
+			},
+
+			//头部标题点击事件
+			handleClick(data) {
+				let index = Number(data.index)
+				//判断点击的是否是第一个标题
+				if (index == 0) {
+					this.getcityList()
+					this.cityList = this.cityList.slice(0, index + 1)
+					this.isindex = index
+					this.activeName = index
+
+					this.remove();
+					//全图事件
+					this.$parent.$parent.$refs.refMap3d.fullMap(jt3d);
+				}
+			},
+
+			/* 
+			 *** label  城镇村庄名字
+			 * * index  选中下标
+			 * * regioncode  编号
+			 * * dj  村镇等级
+			 */
+			selectCity(label, index, regioncode, dj) {
+
+				let _this = this
+
+				if (!regioncode) {
+					return
+				}
+
+				//如果等级为1,代表点击的乡镇,需要重新设置ALLlist为村庄列表,并在头部添加乡镇名称
+				if (dj == 1) {
+					this.cityList.push({
+						label: label,
+						number: index,
+						dj: 2
+					})
+
+					var id = regioncode.slice(0, 9)
+
+					this.isindex = index
+					this.activeName = index
+					this.$http.get('/getTableList', {
+						tableName: 'map_region', //
+						sqlWhere: "dj = 2 and regioncode like '" + id + "%'",
+						orderByField: ''
+					}).then(res => {
+						if (res.data.length == 0) return
+						this.dj = 2
+						this.ALLlist = []
+						res.data.forEach(
+							item => {
+								this.ALLlist.push({
+									label: item.regionname,
+									regioncode: item.regioncode,
+									dj: 2
+								})
+							}
+						)
+					})
+				}
+
+				//根据等级与id获取乡镇或者村庄的面坐标
+				this.$http.get('/getGeoJson', {
+					tableName: 'map_region', //
+					sqlWhere: "dj = " + dj + " and regioncode like '" + regioncode + "%'",
+					orderByField: ''
+				}).then(res => {
+
+					if (window["viewer"].dataSources.getByName('标绘区')) {
+						window["viewer"].dataSources.remove(window["viewer"].dataSources.getByName('标绘区')[0])
+					}
+					let promise = Cesium.GeoJsonDataSource.load(res.data, {
+						clampToGround: true
+					});
+					promise.then((dataSource) => {
+						window["viewer"].dataSources.add(dataSource); // 加载这个geojson资源 
+						dataSource.name = '标绘区'
+						entities = dataSource.entities.values;
+						const entity = entities[0];
+						entity.polygon.material = Cesium.Color.fromBytes(50, 160, 255, 77)
+						entity.polygon.outlineWidth = 3;
+						entity.polygon.outline = false;
+						entity.polygon.outlineColor = Cesium.Color.RED;
+						entity.polyline = {
+							positions: entity.polygon.hierarchy._value.positions,
+							width: entity.polygon.outlineWidth,
+							material: Cesium.Color.fromBytes(0, 255, 180, 255),
+							clampToGround: true
+						}
+
+						_this.hideicon = false;
+
+						let options = {};
+						// 初始化参数默认值
+						options.duration = Cesium.defaultValue(options.duration, 2);
+						options.heading = Cesium.defaultValue(options.heading, 0);
+						options.pitch = Cesium.defaultValue(options.pitch, -60);
+						options.range = Cesium.defaultValue(options.range, 0.0);
+
+						let colorList = [
+							[90, 120, 255, 153],
+							[150, 255, 90, 153],
+							[255, 150, 50, 153],
+							[50, 160, 255, 77]
+						]
+
+						let flyPromise = window["viewer"].flyTo(entity, {
+							duration: options.duration,
+							offset: {
+								heading: Cesium.Math.toRadians(options.heading),
+								pitch: Cesium.Math.toRadians(options.pitch),
+								range: options.range
+							}
+						});
+						flyPromise.then(res => {
+							//面首次加载颜色
+							const entity = entities[0];
+							entity.polygon.material = Cesium.Color.fromBytes(colorList[0][0],
+								colorList[0][1], colorList[0][2], colorList[0][3])
+
+							let idx = 1
+							let timer = setInterval(res => {
+								const entity = entities[0];
+								entity.polygon.material = Cesium.Color.fromBytes(colorList[idx][0], colorList[idx][1], colorList[idx][2], colorList[idx][3]);
+								idx++
+							}, 500)
+							setTimeout(res => {
+								clearInterval(timer)
+
+								_this.hide();
+							}, 2100)
+						})
+					});
+				})
+			},
+
+			//获取一级街道
+			getcityList() {
+
+				this.dj = 1
+				this.ALLlist = []
+				this.$http.get("/getTableList", {
+					tableName: "map_region",
+					sqlWhere: "dj = 1",
+					orderByField: ''
+				}).then(res => {
+					if (res.data.length > 0) {
+						res.data.forEach(
+							item => {
+								console.log('街道信息', item)
+								this.ALLlist.push({
+									label: item.regionname,
+									regioncode: item.regioncode,
+									dj: 1
+								})
+							}
+						)
+					}
+				})
+
+			}
+		},
+		mounted() {
+			this.getcityList()
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.Ficons {
+		position: absolute;
+		top: 10rem;
+		left: 20rem;
+	}
+
+	.active {
+		color: #409eff;
+	}
+
+	//整体样式
+	.tabs {
+		width: 90%;
+		margin-left: 5%;
+		text-align: left;
+
+		--el-font-size-base: 16rem;
+
+		.item {
+			// width: 135rem;
+			width: 80rem;
+			display: inline-block;
+			height: 42rem;
+			margin-right: 15rem;
+			color: #ffffff;
+			font-size: 16rem;
+			cursor: pointer;
+			white-space: nowrap;
+			/*显示的行数;如果要设置2行加...则设置为2*/
+			overflow: hidden;
+			/*超出的文本隐藏*/
+			text-overflow: ellipsis;
+			/* 溢出用省略号*/
+
+			font-style: normal;
+		}
+
+		.item2 {
+			width: 65rem;
+			display: inline-block;
+			height: 35rem;
+			margin-right: 10rem;
+			color: #ffffff;
+			font-size: 16rem;
+			cursor: pointer;
+			white-space: nowrap;
+			/*显示的行数;如果要设置2行加...则设置为2*/
+			overflow: hidden;
+			/*超出的文本隐藏*/
+			text-overflow: ellipsis;
+			/* 溢出用省略号*/
+
+			font-style: normal;
+		}
+
+		.content {
+			width: 100%;
+			margin: 10rem 0;
+			overflow-y: auto;
+		}
+
+		img {
+			width: 18rem;
+			height: 18rem;
+			vertical-align: -10%;
+			margin-right: 2rem;
+		}
+	}
+
+
+
+	.demo-tabs>.el-tabs__content {
+		padding: 32rem;
+		color: #6b778c;
+		font-size: 32rem;
+		font-weight: 600;
+	}
+
+	//未选择tabs标题样式
+	::v-deep .el-tabs__item {
+		color: #ffffff !important;
+	}
+
+	//选中tabs标签样式
+	::v-deep .el-tabs__item.is-active {
+		color: var(--el-color-primary) !important;
+	}
+
+	//选中下划线样式
+	::v-deep .el-tabs__active-bar {
+		bottom: -1rem !important;
+		height: 4rem !important;
+	}
+
+	//下横线样式
+	::v-deep .el-tabs__nav-wrap::after {
+		height: 1rem !important;
+		background-color: darkgrey;
+	}
+</style>

+ 268 - 0
src/views/Map3d - 副本 (2)/components/manage-basemap.vue

@@ -0,0 +1,268 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	import {
+		Store
+	} from '@/store/index'
+	store = Store();
+
+	import no_img from '@/assets/images/no_img.png';
+</script>
+
+<template>
+	<jt-popup title="底图切换" >
+		<div class="jt-basemap">
+			<div class="top">
+				<div class="onceLayer" v-for="(item,index) in basemap.layerList" :key="index" @click="changeBasicLayer(item)">
+					<img v-if="item.imageurl" :src="item.imageurl" :class="item.layerorder===basemap.selectImg?'selectImg':''" />
+				</div>
+			</div>
+			<div class="bottom">
+				<el-switch v-model="terrain.isTerrain" @change="changeTerrain" />
+				<span>显示地形</span>
+				<span> </span>
+				<el-switch v-model="mark.isMark" @change="changeMark" />
+				<span>显示标注</span>
+			</div>
+		</div>
+	</jt-popup>
+
+</template>
+
+<script>
+	let store = undefined
+
+	import * as mapWork from "../map"
+
+	export default {
+		data() {
+			return {
+				// basemap: {
+				// 	layerList: [], //图层列表
+				// basemapData:{},
+				// 	selectImg: store.basemap.selectImg, //选中的底图图片
+				// 	isTerrain: store.terrain.isTerrain, //是否显示地形
+				// 	isMark: store.mark.isMark, //是否显示标注
+				// },
+
+				
+
+				//底图数据
+				basemap: {
+					layerList: [], //图层列表
+					selectImg: 0, //选中的底图图片
+					basemapData: {} //底图数据
+				},
+
+				//地形数据
+				terrain: {
+					isTerrain: false, //是否切换地形
+					terrainData: {}, //地形数据
+				},
+
+				//标注数据
+				mark: {
+					isMark: false, //是否显示标注
+					markID: '', //标注服务ID
+					markData: {}, //地形数据
+				}
+
+			}
+		},
+		methods: {
+
+			/**
+			 * 切换地形事件
+			 */
+			changeTerrain() {
+				store.terrain.isTerrain = this.terrain.isTerrain;
+				mapWork.setLayersControl(window.layer, this.terrain.terrainData, this.terrain.isTerrain);
+			},
+
+			/**
+			 * 切换标注
+			 */
+			changeMark() {
+				store.mark.isMark = this.mark.isMark;
+				mapWork.setLayersControl(window.layer, this.mark.markData, this.mark.isMark);
+			},
+
+			/**
+			 * 切换底图事件
+			 * @param {Object} item
+			 */
+			changeBasicLayer(item) {
+
+				this.basemap.selectImg = item.layerorder;
+				store.basemap.selectImg = item.layerorder;
+
+				//删除底图后再添加
+				mapWork.setLayersControl(window.layer, this.basemap.basemapData, false).then(res => {
+					mapWork.setLayersControl(window.layer, item, true);
+					this.basemap.basemapData = item;
+				});
+			},
+
+			/**
+			 * 添加底图图集
+			 */
+			initBaseMap() {
+				let _self = this;
+
+				store.basemaps.forEach(item => {
+					let parameterset = item.parameterset;
+					if (item.parameterset instanceof Object) {
+						parameterset = item.parameterset;
+					} else if (item.parameterset != "" && item.parameterset != null && item.parameterset != undefined) {
+						parameterset = JSON.parse(item.parameterset);
+					}
+
+					if (item.layertype === '地形') {
+						_self.terrain.terrainData = item;
+
+						if (item.isinit === '1') {
+							_self.terrain.isTerrain = true;
+						}
+					} else if (item.layertype === '标注') {
+						_self.mark.markData = item;
+						if (item.isinit === '1') {
+							_self.mark.isMark = true;
+						}
+					} else {
+						if (item.isinit === '1') {
+							_self.basemap.basemapData = item;
+							_self.basemap.selectImg = item.layerorder;
+						}
+					}
+
+					if (item.datasource && item.datasource != '#' && item.layertype != '地形' && item.layertype != '标注') {
+						if (parameterset) {
+							if (parameterset.imgurl) {
+								item.imageurl = parameterset.imgurl;
+							} else {
+								item.imageurl = no_img;
+								ElMessage("请检查底图图层表parameterset字段是否设置imgurl");
+							}
+							_self.basemap.layerList.push(item);
+						}
+					}
+				});
+
+				//底图组件高度不变
+				if (_self.basemap.layerList.length % 3 == 1) {
+					_self.basemap.layerList.push({}, {})
+				} else if (_self.basemap.layerList.length % 3 == 2) {
+					_self.basemap.layerList.push({})
+				} else if (_self.layerList.length % 3 == 0) {
+					_self.basemap.layerList.push({}, {}, {})
+				}
+
+			}
+		},
+		mounted() {
+			this.initBaseMap();
+		}
+	}
+</script>
+
+<style scoped lang="scss">
+	@charset "UTF-8";
+
+	@font-face {
+		font-family: "TTTGB-Medium";
+		src: url("@/assets/fonts/fonts/TTTGB-Medium.ttf") format("truetype"),
+			url("@/assets/fonts/fonts/TTTGB-Medium.eot") format("embedded-opentype"),
+			url("@/assets/fonts/fonts/TTTGB-Medium.svg") format("svg");
+		font-weight: normal;
+		font-style: normal;
+	}
+
+	::v-deep .is-checked .el-switch__core .el-switch__action {
+		margin-left: calc(-1rem - 14rem);
+	}
+
+	::v-deep .el-switch__core .el-switch__action {
+		top: 1rem;
+	}
+
+	::v-deep .el-switch__core .el-switch__action {
+		width: 14rem;
+		height: 14rem;
+	}
+
+	::v-deep .el-switch__core {
+		width: 40rem !important;
+		height: 20rem !important;
+	}
+
+	.jt-basemap {
+		position: absolute;
+		width: 350rem;
+		height: calc(100% - 105rem);
+
+		.top {
+			height: calc(100% - 50rem);
+			padding: 10rem;
+			flex-wrap: wrap;
+			justify-content: space-around;
+			overflow-y: scroll; // 设置y轴方向的滚动条
+			overflow: hidden; // 超出部分隐藏
+
+			.onceLayer {
+				display: inline-block;
+				padding: 5rem;
+				width: 100rem;
+				height: 120rem;
+
+				img {
+					height: 100%;
+					width: 100%;
+					border-radius: 5rem;
+				}
+
+				img:hover {
+					cursor: pointer;
+					height: calc(100% - 0rem);
+					width: calc(100% - 0rem);
+					border: 0rem solid rgba(255, 255, 255, .8);
+					box-shadow: 0 0 2rem 2rem rgba(255, 255, 255, .5);
+					transition: all .2s;
+				}
+
+				//选中图片样式
+				.selectImg {
+					border: 0rem solid rgba(255, 255, 255, .8);
+					box-shadow: 0 0 3rem 3rem rgba(255, 255, 255, .5);
+				}
+
+				span {
+					font-size: 14rem;
+					display: inline-block;
+				}
+			}
+		}
+
+		.bottom {
+			width: 100%;
+			height: 40rem;
+			line-height: 40rem;
+			text-align: left;
+			padding-left: 10rem;
+			border: 0px solid red;
+
+			el-switch {
+				margin: 3rem 0rem;
+				width: 36rem !important;
+			}
+
+			span {
+				margin: 4rem 4rem;
+			}
+		}
+	}
+</style>

+ 319 - 0
src/views/Map3d - 副本 (2)/components/manage-layer.vue

@@ -0,0 +1,319 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+
+	import {
+		Store
+	} from '@/store/index'
+	store = Store();
+
+	import {
+		deepTree
+	} from "@/utils/deepTree.js";
+
+	import {
+		useWidget
+	} from "@/common/store/widget"
+
+	// const {
+	// 	activate,
+	// 	disable,
+	// 	currentWidget
+	// } = useWidget()
+	// currentWidget.onUpdate(() => {
+	// 	treeData = []
+	// 	expandedKeys = []
+	// 	checkedKey = []
+	// 	initTree()
+	// })
+</script>
+
+<template>
+	<jt-popup title="图层控制">
+		<div class="jt-layer">
+			<!-- :default-checked-keys="checkedkeys"  默认勾选的节点的 key 的数组-->
+			<!-- :default-expanded-keys="expandedKeys" 默认展开的节点的 key 的数组-->
+			<!-- @node-click 节点单击事件 -->
+			<el-tree :data="layers.treeData" :default-expanded-keys="layers.expandedKeys" :default-checked-keys="layers.checkedkeys" node-key="id" class="tree-line" ref="treeRef">
+				<template #default="{ node, data }">
+					<!-- 复选框 -->
+					<el-checkbox v-if="data.ischeck == '1' && store.userport == 'PC'" v-model="node.checked" :indeterminate="node.indeterminate" :disabled="!!node.disabled" @change="handleCheckBoxChange($event, data, node)">
+					</el-checkbox>
+					<el-switch v-else-if="data.ischeck == 1 && store.userport == 'APP'" width="30rem" size="small" v-model="node.checked" @change="handleCheckBoxChange($event, data, node)" />
+					<span class="custom-tree-node" @click="handleClick(data)" style="width: 150rem;text-align: left;">
+						<!-- 字体、图标 -->
+						<!-- <span>
+						<img src="@/assets/images/logo16x16.ico" />
+					</span> -->
+						<span class="overflowtext">
+							{{ data.layername }}
+						</span>
+
+					</span>
+
+					<!-- 透明度 -->
+					<template v-if="node.checked && data.opacity >0">
+						<div style="width: 80rem; padding: 0 20rem; position: absolute; right: 0">
+							<el-slider v-model="data.opacity" @input="handleSliderChange($event, data)" :max="1" :min="0.1" :step="0.1" />
+						</div>
+					</template>
+				</template>
+			</el-tree>
+		</div>
+	</jt-popup>
+</template>
+
+<script>
+	let store = undefined
+
+	import * as mapWork from "../map"
+
+	export default {
+
+		/* 数据 */
+		data() {
+			return {
+				layers: {
+					treeData: [], //树结构
+					expandedKeys: [], //对应要展开的节点id
+					checkedkeys: [], //默认打开节点的id
+				}
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			/**
+			 * 单击图层名称触发服务定位
+			 * @param {Object} data 传递给 data 属性的数组中该节点所对应的对象
+			 */
+			handleClick(data) {
+				store.serviceMark = 'service';
+				mapWork.setLayersLocation(window.viewer, data);
+			},
+
+			/**
+			 * el-slider 值改变时触发
+			 * 地图服务的透明度调整
+			 */
+			handleSliderChange($event, data) {
+				store.serviceMark = 'service';
+				mapWork.setLayersAlpha(window.viewer, $event, data)
+			},
+
+			/**
+			 * el-checkbox 当绑定值变化时触发的事件
+			 * @param {Object} checked 复选框状态
+			 * @param {Object} data 对应于节点点击的节点对象
+			 * @param {Object} node TreeNode 的 node 属性
+			 */
+			handleCheckBoxChange(checked, data, node) {
+
+				store.serviceMark = 'service';
+				let _node = this.$refs.treeRef.getNode(data);
+				if (_node.isLeaf) {
+					mapWork.setLayersControl(window.viewer, data, checked);
+					this.$refs.treeRef.setChecked(_node, checked); //是否设置子节点,默认为false,利用tree组件渲染后带有的isLeaf(是否为叶子节点)属性,如果为叶子节点就选中。利用tree的API就实现了正确的回显效果	
+
+				} else {
+					//控制子节点
+					this.childNodesChange(node, checked);
+				}
+			},
+
+			/**
+			 * 控制子节点
+			 * @param {Object} node
+			 * @param {Object} checked
+			 */
+			childNodesChange(node, checked) {
+				let _self = this;
+				node.childNodes.forEach(item => {
+					mapWork.setLayersControl(window.viewer, item.data, checked);
+					_self.$refs.treeRef.setChecked(item, checked);
+					_self.childNodesChange(item, checked);
+				});
+			},
+
+
+			/**
+			 * 初始化图层控制树
+			 */
+			initLayerTree() {
+				let _self = this;
+
+				//初始图层列表
+				_self.inittree = store.layers;
+
+				init().then(item => {
+
+					//复选框初始化选中
+					// _self.$nextTick(() => {
+					// 	_self.$refs.treeRef.setCheckedKeys(_self.checkedkeys, true);
+					// });
+				})
+
+				//Promise回调
+				function init() {
+					return new Promise((resolve, reject) => {
+						_self.inittree.forEach(res => {
+							let num = Number(res.layerorder)
+							if (num < 10) {
+								res.layerorder = '0' + res.layerorder
+							}
+
+							//透明度
+							res.opacity = Number(res.opacity);
+
+							// //默认展开
+							// if (res.isexpand === '1') {
+							// 	_self.layers.expandedKeys.push(res.id);
+							// }
+
+							// // 复选框默认选中
+							// if (res.isinit === '1') {
+							// 	_self.layers.checkedkeys.push(res.id);
+							// }
+						})
+						_self.layers.treeData = deepTree(_self.inittree)
+
+
+						resolve(true)
+					})
+				}
+			}
+		},
+		created() {
+			debugger
+			this.layers.treeData = []
+		},
+		mounted() {
+
+debugger
+			if (this.layers.treeData.length === 0) {
+				this.initLayerTree();
+			}
+		},
+
+		unMounted() {
+			debugger
+			alert(111)
+		}
+	};
+</script>
+
+<style lang="scss">
+	.el-switch--small .el-switch__core .el-switch__action {
+		width: 12rem;
+		height: 12rem;
+	}
+
+	.el-switch--small.is-checked .el-switch__core .el-switch__action {
+		margin-left: calc(-1rem - 12rem);
+	}
+
+	.el-switch__core .el-switch__action {
+		top: 0;
+	}
+
+	.el-slider__button {
+		width: 20rem;
+		height: 20rem;
+	}
+
+	.el-tree-node__content {
+		height: 26rem;
+	}
+
+	.el-switch--small .el-switch__core {
+		height: 16rem;
+	}
+
+	.el-switch--small {
+		padding: 0 5rem;
+	}
+
+	.jt-layer {
+		padding-left: 10rem;
+
+		.el-tree {
+			background: none;
+			color: #fff;
+			--el-tree-node-hover-bg-color: #2a67c3;
+
+			.overflowtext {
+				width: auto !important;
+				padding: 0;
+			}
+		}
+
+		.tree-line {
+			.el-tree-node {
+				position: relative;
+				// padding-left: 16rem; // 缩进量
+			}
+
+			.el-tree-node__children {
+				padding-left: 16rem !important; // 缩进量
+
+				.el-tree-node__content {
+					padding-left: 18rem !important;
+				}
+			}
+
+			// 竖线
+			.el-tree-node::before {
+				content: "";
+				height: 100%;
+				width: 1rem;
+				position: absolute;
+				left: -3rem;
+				top: -26rem;
+				border-width: 1rem;
+				border-left: 1rem dashed rgba(255, 255, 255, .8);
+			}
+
+			// 当前层最后一个节点的竖线高度固定
+			.el-tree-node:last-child::before {
+				height: 38rem; // 可以自己调节到合适数值
+			}
+
+			// 横线
+			.el-tree-node::after {
+				content: "";
+				width: 24rem;
+				height: 20rem;
+				position: absolute;
+				left: -3rem;
+				top: 12rem;
+				border-width: 1rem;
+				border-top: 1rem dashed rgba(255, 255, 255, .8);
+			}
+
+			// 去掉最顶层的虚线,放最下面样式才不会被上面的覆盖了
+			&>.el-tree-node::after {
+				border-top: none;
+			}
+
+			&>.el-tree-node::before {
+				border-left: none;
+			}
+
+			// 展开关闭的icon
+			.el-tree-node__expand-icon {
+				font-size: 16rem;
+
+				// 叶子节点(无子节点)
+				&.is-leaf {
+					color: transparent;
+					display: none; // 也可以去掉
+				}
+			}
+		}
+	}
+</style>

+ 394 - 0
src/views/Map3d - 副本 (2)/components/map-compare.vue

@@ -0,0 +1,394 @@
+<script setup>
+	import {
+		inject
+	} from "vue";
+	const getMapInstance = inject("getMapInstance");
+	jt3dRight = getMapInstance();
+
+	import {
+		Store
+	} from '@/store/index'
+	store = Store();
+
+	import {
+		deepTree
+	} from "@/utils/deepTree.js";
+</script>
+
+<template>
+	<jt-popup title="分屏对比" animationClass="fadein-left" :isEmit="true" @closeJTPopup="closeJTPopup">
+		<div class="jt-map-compare">
+			<el-tree :data="treeData" :default-expanded-keys="expandedKeys" :default-checked-keys="checkedkeys" node-key="id" class="tree-line" ref="treeRef">
+				<template #default="{ node, data }">
+					<!-- 复选框 -->
+					<el-checkbox v-if="data.ischeck === '1' && store.userport == 'PC'" v-model="node.checked" :indeterminate="node.indeterminate" :disabled="!!node.disabled" @change="handleCheckBoxChange($event, data, node)">
+					</el-checkbox>
+					<el-switch v-else-if="data.ischeck == 1 && store.userport == 'APP'" width="30rem" size="small" v-model="node.checked" @change="handleCheckBoxChange($event, data, node)" />
+					<span class="custom-tree-node" @click="handleClick(data)" style="width: 150rem;text-align: left;">
+						<!-- 字体、图标 -->
+						<!-- <span>
+						<img src="@/assets/images/logo16x16.ico" />
+					</span> -->
+						<span class="overflowtext">
+							{{ data.layername }}
+						</span>
+					</span>
+
+					<!-- 透明度 -->
+					<template v-if="node.checked && data.opacity >0">
+						<div style="width: 80rem; padding: 0 20rem; position: absolute; right: 0">
+							<el-slider v-model="data.opacity" @input="handleSliderChange($event, data)" :max="1" :min="0.1" :step="0.1" />
+						</div>
+					</template>
+				</template>
+			</el-tree>
+		</div>
+	</jt-popup>
+</template>
+
+<script>
+	let store = undefined;
+	let jt3dRight = undefined;
+	let jt3dLeft = undefined;
+
+	import * as mapWork from "../map"
+
+	export default {
+
+		/* 数据 */
+		data() {
+			return {
+				treeData: [],
+				inittree: [], //初始化图层数组
+				expandedKeys: [], //对应要展开的节点id
+				checkedkeys: [] //默认打开节点的id
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			/**
+			 * 单击图层名称触发服务定位
+			 * @param {Object} data 传递给 data 属性的数组中该节点所对应的对象
+			 */
+			handleClick(data) {
+				store.serviceMark = 'serviceLeft';
+				mapWork.setLayersLocation(window.layerLeft, data);
+			},
+
+			/**
+			 * el-slider 值改变时触发
+			 * 地图服务的透明度调整
+			 */
+			handleSliderChange($event, data) {
+				store.serviceMark = 'serviceLeft';
+				mapWork.setLayersAlpha(window.layerLeft, $event, data)
+			},
+			/**
+			 * el-checkbox 当绑定值变化时触发的事件
+			 * @param {Object} checked 复选框状态
+			 * @param {Object} data 对应于节点点击的节点对象
+			 * @param {Object} node TreeNode 的 node 属性
+			 */
+			handleCheckBoxChange(checked, data, node) {
+				store.serviceMark = 'serviceLeft';
+
+				let _node = this.$refs.treeRef.getNode(data);
+				if (_node.isLeaf) {
+					mapWork.setLayersControl(window.layerLeft, data, checked);
+					//是否设置子节点,默认为false,利用tree组件渲染后带有的isLeaf(是否为叶子节点)属性,如果为叶子节点就选中。利用tree的API就实现了正确的回显效果	
+					this.$refs.treeRef.setChecked(_node, checked);
+				}
+
+				//控制子节点
+				this.childNodesChange(node, checked);
+			},
+			/**
+			 * 控制子节点
+			 * @param {Object} node
+			 * @param {Object} checked
+			 */
+			childNodesChange(node, checked) {
+				let _self = this;
+				node.childNodes.forEach(item => {
+					mapWork.setLayersControl(window.layerLeft, item.data, checked);
+					_self.$refs.treeRef.setChecked(item, checked);
+					_self.childNodesChange(item, checked);
+				});
+			},
+
+			/**
+			 * 分屏对比初始化
+			 */
+			initSplitScreen() {
+				let mapView1 = document.getElementById("cesiumContainer");
+				let mapView2 = document.getElementById("cesiumContainer2");
+				mapView1.className = "ViewerSplitScreen";
+				mapView2.style.display = "block";
+
+				//加载分屏左侧大球
+				this.initMap3d();
+				//同步相机状态
+				this.syncViewer();
+				//绑定图层控制
+				this.initLayerTree();
+			},
+
+			/**
+			 * 加载分屏左侧大球
+			 */
+			initMap3d() {
+				jt3dLeft = new jt3dSDK.jtMap3d({
+					container: "cesiumContainer2",
+				});
+
+				//底部工具
+				jt3dLeft.statusBar.show = true;
+				//图层
+				jt3dLeft.layer = new jt3dSDK.layer(jt3dLeft._viewer);
+
+				window["layerLeft"] = jt3dLeft.layer;
+
+				window["viewerLeft"] = jt3dLeft._viewer;
+				window["viewerLeft"].scene.terrainExaggeration = 100;
+
+				//显示帧率
+				window["viewerLeft"].scene.debugShowFramesPerSecond = true;
+
+			},
+
+			/**
+			 * 同步相机状态
+			 */
+			syncViewer() {
+				let _self = this;
+
+				let viewerL = jt3dLeft._viewer;
+				let viewerR = jt3dRight._viewer;
+
+				var sceneL = viewerL.scene;
+				var sceneR = viewerR.scene;
+
+				var handlerL = new Cesium.ScreenSpaceEventHandler(sceneL.canvas);
+				var ellipsoidL = sceneL.globe.ellipsoid;
+				var handlerR = new Cesium.ScreenSpaceEventHandler(sceneR.canvas);
+				var ellipsoidR = sceneR.globe.ellipsoid;
+
+				handlerL.setInputAction((movement) => {
+					this.isLeftTrigger = true;
+					this.isRightTrigger = false;
+				}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+				handlerR.setInputAction((movement) => {
+					this.isLeftTrigger = false;
+					this.isRightTrigger = true;
+				}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+				var syncViewerL = function() {
+					if (_self.isLeftTrigger) {
+						viewerR.camera.flyTo({
+							destination: viewerL.camera.position,
+							orientation: {
+								heading: viewerL.camera.heading,
+								pitch: viewerL.camera.pitch,
+								roll: viewerL.camera.roll
+							},
+							duration: 0.0
+						});
+					}
+				}
+				viewerR.camera.changed.addEventListener(syncViewerL);
+				viewerR.scene.preRender.addEventListener(syncViewerL);
+
+				var syncViewerR = function() {
+					if (_self.isRightTrigger) {
+						viewerL.camera.flyTo({
+							destination: viewerR.camera.position,
+							orientation: {
+								heading: viewerR.camera.heading,
+								pitch: viewerR.camera.pitch,
+								roll: viewerR.camera.roll
+							},
+							duration: 0.0
+						});
+					}
+				}
+				viewerR.camera.changed.addEventListener(syncViewerR);
+				viewerR.scene.preRender.addEventListener(syncViewerR);
+			},
+
+			/**
+			 * 初始化图层控制树
+			 */
+			initLayerTree() {
+				let _self = this;
+
+				//初始图层列表
+				_self.inittree = store.layersList;
+
+
+				init().then(item => {
+
+					//复选框初始化选中
+					_self.$nextTick(() => {
+						_self.$refs.treeRef.setCheckedKeys(_self.checkedkeys, true);
+					});
+				})
+
+				//Promise回调
+				function init() {
+					return new Promise((resolve, reject) => {
+						_self.inittree.forEach(res => {
+							let num = Number(res.layerorder)
+							if (num < 10) {
+								res.layerorder = '0' + res.layerorder
+							}
+
+							//透明度
+							res.opacity = Number(res.opacity);
+
+							//默认展开
+							if (res.isexpand === '1') {
+								_self.expandedKeys.push(res.id);
+							}
+
+							// 复选框默认选中
+							if (res.isinit === '1') {
+								_self.checkedkeys.push(res.id);
+								mapWork.setLayersControl(window.layerLeft, res, true);
+							}
+						})
+						_self.treeData = deepTree(_self.inittree)
+
+						resolve(true)
+					})
+				}
+			},
+
+			closeJTPopup() {
+				mapWork.removeSplitScreen(window.viewerLeft);
+			}
+		},
+
+		mounted() {
+			this.initSplitScreen();
+		},
+		
+		beforeDestroy()
+		{
+			alert(111)
+			this.closeJTPopup();
+		}
+	};
+</script>
+
+<style lang="scss">
+	.el-switch--small .el-switch__core .el-switch__action {
+		width: 12rem;
+		height: 12rem;
+	}
+
+	.el-switch--small.is-checked .el-switch__core .el-switch__action {
+		margin-left: calc(-1rem - 12rem);
+	}
+
+	.el-switch__core .el-switch__action {
+		top: 0;
+	}
+
+	.el-slider__button {
+		width: 20rem;
+		height: 20rem;
+	}
+
+	.el-tree-node__content {
+		height: 26rem;
+	}
+
+	.el-switch--small .el-switch__core {
+		height: 16rem;
+	}
+
+	.el-switch--small {
+		padding: 0 5rem;
+	}
+
+	.jt-map-compare {
+		padding-left: 10rem;
+
+		.el-tree {
+			background: none;
+			color: #fff;
+			--el-tree-node-hover-bg-color: #2a67c3;
+
+			.overflowtext {
+				width: auto !important;
+				padding: 0;
+			}
+		}
+
+		.tree-line {
+			.el-tree-node {
+				position: relative;
+				// padding-left: 16rem; // 缩进量
+			}
+
+			.el-tree-node__children {
+				padding-left: 16rem !important; // 缩进量
+
+				.el-tree-node__content {
+					padding-left: 18rem !important;
+				}
+			}
+
+			// 竖线
+			.el-tree-node::before {
+				content: "";
+				height: 100%;
+				width: 1rem;
+				position: absolute;
+				left: -3rem;
+				top: -26rem;
+				border-width: 1rem;
+				border-left: 1rem dashed rgba(255, 255, 255, .8);
+			}
+
+			// 当前层最后一个节点的竖线高度固定
+			.el-tree-node:last-child::before {
+				height: 38rem; // 可以自己调节到合适数值
+			}
+
+			// 横线
+			.el-tree-node::after {
+				content: "";
+				width: 24rem;
+				height: 20rem;
+				position: absolute;
+				left: -3rem;
+				top: 12rem;
+				border-width: 1rem;
+				border-top: 1rem dashed rgba(255, 255, 255, .8);
+			}
+
+			// 去掉最顶层的虚线,放最下面样式才不会被上面的覆盖了
+			&>.el-tree-node::after {
+				border-top: none;
+			}
+
+			&>.el-tree-node::before {
+				border-left: none;
+			}
+
+			// 展开关闭的icon
+			.el-tree-node__expand-icon {
+				font-size: 16rem;
+
+				// 叶子节点(无子节点)
+				&.is-leaf {
+					color: transparent;
+					display: none; // 也可以去掉
+				}
+			}
+		}
+	}
+</style>

+ 305 - 0
src/views/Map3d - 副本 (2)/components/map-split.vue

@@ -0,0 +1,305 @@
+<script setup>
+
+	import {
+		Store
+	} from '@/store/index'
+	store = Store();
+	
+	import {
+		deepTree
+	} from "@/utils/deepTree.js";
+
+</script>
+
+<template>
+	<jt-popup title="卷帘对比" :showfooter="isshowfooter" height="120rem" width="620rem" :isEmit="true" @closeJTPopup="closeJTPopup">
+		<div class="jt-map-split">
+			<div class="_left">
+				<div style="line-height: 30rem;float: left;">左侧图层:</div>
+				<el-tree-select v-model="leftModel" :data="leftData" :render-after-expand="true" @change="handleClickLeft" style="width: 200rem; float: left;" />
+			</div>
+			<div class="_right">
+				<div style="line-height: 30rem;float: left;">右侧图层:</div>
+				<el-tree-select v-model="rightModel" :data="rightData" :render-after-expand="true" @change="handleClickRight" style="width: 200rem; float: left;" />
+			</div>
+		</div>
+	</jt-popup>
+</template>
+
+<script>
+	let store = undefined;
+
+	let earthAtLeft = undefined;
+	let earthAtRight = undefined;
+
+	import * as mapWork from "../map"
+
+	//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
+	//例如:import 《组件名称》 from '《组件路径》';
+
+	export default {
+		//import引入的组件需要注入到对象中才能使用
+		components: {},
+
+		//这里存放数据
+		data() {
+
+			return {
+				leftModel: {},
+				leftData: [],
+				leftValue: [],
+				rightModel: {},
+				rightData: [],
+				rightValue: [],
+			};
+		},
+
+		//监听属性 类似于data概念
+		computed: {},
+
+		//监控data中的数据变化
+		watch: {},
+
+		//方法集合
+		methods: {
+			/**
+			 * 左侧图层控制
+			 * @param {Object} item
+			 */
+			handleClickLeft(item) {
+				let _self = this;
+				store.serviceMark = 'service';
+				let _serviceId = store.serviceMark + "_" + item.layercode + item.layerorder;
+
+				//移除
+				if (earthAtLeft) {
+					mapWork.setLayersControl(window.viewer, _self.leftValue, false);
+				} 
+				
+				//添加
+				mapWork.setLayersControl(window.viewer, item, true).then(res => {
+					//定位
+					mapWork.setLayersLocation(window.viewer, item);
+				
+					_self.leftValue = item;
+				
+					earthAtLeft = window[_serviceId];
+					earthAtLeft.splitDirection = Cesium.SplitDirection.LEFT;
+				});
+			},
+			/**
+			 * 
+			 * 
+			 * 右侧图层控制
+			 * @param {Object} item
+			 */
+			handleClickRight(item) {
+				let _self = this;
+				store.serviceMark = "service";
+				let _serviceId = store.serviceMark + "_" + item.layercode + item.layerorder;
+
+				//移除
+				if (earthAtRight) {
+					mapWork.setLayersControl(window.viewer, _self.rightValue, false);
+				}
+
+				//添加
+				mapWork.setLayersControl(window.viewer, item, true).then(res => {
+					
+					//定位
+					mapWork.setLayersLocation(window.viewer, item);
+
+					_self.rightValue = item;
+
+					earthAtRight = window[_serviceId];
+					earthAtRight.splitDirection = Cesium.SplitDirection.RIGHT;
+				});
+
+			},
+
+			/**
+			 * 卷帘对比初始化
+			 */
+			initSplitLayer() {
+				let _self = this;
+				this.viewer = window.viewer;
+
+				let sliderDiv = document.getElementById("image_slider");
+				if (sliderDiv == null) {
+					//创建画布
+					sliderDiv = document.createElement('div');
+					sliderDiv.id = "image_slider";
+					sliderDiv.style.position = "absolute";
+					sliderDiv.style.left = "50%";
+					sliderDiv.style.top = "70rem";
+					sliderDiv.style.backgroundColor = "#d3d3d3";
+					sliderDiv.style.width = "5rem";
+					sliderDiv.style.height = "calc(100% - 70rem)";
+					sliderDiv.style.zIndex = "9999";
+
+					sliderDiv.onmouseover = function() {
+						//设置其背景颜色为黄色
+						this.style.cursor = "ew-resize";
+					};
+
+					/* 加入到页面 */
+					document.body.appendChild(sliderDiv);
+				}
+
+				// 设置图像拆分位置
+				this.viewer.scene.splitPosition = sliderDiv.offsetLeft / sliderDiv.parentElement.offsetWidth; //确定分割点位置,占据父级容器的比例
+
+				if (this.handler) {
+					this.handler.destroy();
+					this.handler = null;
+				}
+				//处理用户输入事件。可以添加自定义功能以在用户输入时执行;参数为任意
+				this.handler = new Cesium.ScreenSpaceEventHandler(sliderDiv);
+				var moveActive = false;
+
+				// 计算拆分
+				function move(movement) {
+					if (!moveActive) {
+						return;
+					}
+
+					//捕获滑动停止的位置
+					var relativeOffset = movement.endPosition.x;
+					var splitPosition = (sliderDiv.offsetLeft + relativeOffset) / sliderDiv.parentElement.offsetWidth;
+					sliderDiv.style.left = `${100.0 * splitPosition}%`;
+					viewer.scene.splitPosition = splitPosition;
+				}
+
+				//对分割条的操作
+				this.handler.setInputAction(function() {
+					moveActive = true;
+				}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
+				this.handler.setInputAction(function() {
+					moveActive = true;
+				}, Cesium.ScreenSpaceEventType.PINCH_START);
+
+				this.handler.setInputAction(move, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+				this.handler.setInputAction(move, Cesium.ScreenSpaceEventType.PINCH_MOVE);
+
+				this.handler.setInputAction(function() {
+					moveActive = false;
+				}, Cesium.ScreenSpaceEventType.LEFT_UP);
+				this.handler.setInputAction(function() {
+					moveActive = false;
+				}, Cesium.ScreenSpaceEventType.PINCH_END);
+
+				_self.handleClickLeft(_self.leftModel);
+				_self.handleClickRight(_self.rightModel);
+			},
+
+			/**
+			 * 初始化图层控制树
+			 */
+			initLayerTree() {
+				let _self = this;
+
+				//初始图层列表
+				_self.initData = store.layers;
+				init().then(item => {
+
+				})
+
+				//Promise回调
+				function init() {
+					return new Promise((resolve, reject) => {
+						_self.initData.forEach((res, index) => {
+							let num = Number(res.layerorder)
+							if (num < 10) {
+								res.layerorder = '0' + res.layerorder
+							}
+
+							res.value = res;
+							res.label = res.layername;
+
+							if (res.layername === "牟平中心城") {
+								_self.leftModel = res;
+							}
+							if (res.layername === "牟平区") {
+								_self.rightModel = res;
+							}
+
+						})
+						_self.leftData = _self.rightData = deepTree(_self.initData)
+
+						resolve(true)
+					})
+				}
+			},
+			
+			/**
+			 * 移除卷帘
+			 */
+			removeSplitLayer() {
+				let sliderDiv = document.getElementById("image_slider");
+				if (sliderDiv) {
+					document.body.removeChild(sliderDiv);
+				}
+			
+				if (earthAtLeft) {
+					mapWork.setLayersControl(window.viewer, this.leftValue, false);
+					earthAtLeft.splitDirection = Cesium.SplitDirection.NONE;
+				}
+			
+				if (earthAtRight) {
+					mapWork.setLayersControl(window.viewer, this.rightValue, false);
+					earthAtRight.splitDirection = Cesium.SplitDirection.NONE;
+				}
+			},
+
+			closeJTPopup() {
+				if(window.viewerLeft)
+				{
+					mapWork.removeSplitScreen(window.viewerLeft);
+				}
+				// mapWork.removeSplitLayer(window.viewer, earthAtLeft, earthAtRight,_self.leftValue,_self.rightValue);
+				this.removeSplitLayer();
+			}
+		},
+
+		//生命周期 - 创建完成(可以访问当前this实例)
+		created() {},
+
+		//生命周期 - 挂载完成(可以访问DOM元素)
+		mounted() {
+			this.initLayerTree();
+			this.initSplitLayer();
+		},
+
+		beforeCreate() {}, //生命周期 - 创建之前
+		beforeMount() {}, //生命周期 - 挂载之前
+		beforeUpdate() {}, //生命周期 - 更新之前
+		updated() {}, //生命周期 - 更新之后
+		beforeDestroy() {}, //生命周期 - 销毁之前
+		destroyed() {}, //生命周期 - 销毁完成
+		activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+	};
+</script>
+
+<style lang="scss" scoped>
+	//整体样式
+	.jt-map-split {
+		// padding: 10rem;
+
+		//左侧
+		._left {
+			width: 300rem;
+			float: left;
+		}
+
+		//右侧
+		._right {
+			width: 300rem;
+			float: left;
+			margin-left: 10rem;
+		}
+
+		.el-tree {
+			width: 300rem !important;
+		}
+	}
+</style>

+ 101 - 0
src/views/Map3d - 副本 (2)/components/map.vue

@@ -0,0 +1,101 @@
+<template>
+	<div id="cesiumContainer2" class="ViewerSplitScreen" style="display: none; border-right: 5rem solid #fff"></div>
+	<div id="cesiumContainer" class="jt-map" ref="cesiumContainer"></div>
+</template>
+
+<script>
+	import * as mapWork from "../map"
+
+	let jt3d = undefined;
+	export default {
+
+		/* 数据 */
+		data() {
+			return {
+
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			/**
+			 * 初始化
+			 */
+			init(el) {
+				//初始化大球
+				this.initMap3d(el);
+				//调用父组件的方法,onload是在父组件的的动态组件component上面的方法,并将jt3d传过去
+				this.$emit("onload", jt3d);
+
+				//设置默认视图
+				mapWork.setView(jt3d);
+
+				// 初始化项目区域范围视角
+				mapWork.fullMap(jt3d);
+
+				//加载天空盒子
+				mapWork.addSkybox(jt3d);	
+
+				//单击事件
+				// mapWork.clickEntity(jt3d);
+
+				//添加镇街边界线——精灵线
+				mapWork.addBoundaryLine(jt3d);
+
+			},
+
+			/**
+			 * 创建大球
+			 */
+			initMap3d(el) {
+
+				jt3d = new jt3dSDK.jtMap3d({
+					container: el,
+				});
+
+				jt3d.statusBar.show = true;
+
+				window["viewer"] = jt3d._viewer;
+				window["viewer"].scene.terrainExaggeration = 100;
+
+				//显示帧率
+				window["viewer"].scene.debugShowFramesPerSecond = true;
+			},
+
+		},
+
+		mounted() {
+			this.init("cesiumContainer");
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.lk-status-bar {
+		font-size: 16rem !important;
+	}
+
+	.jt-map {
+		// width: calc(100% - 0rem);
+		// height: calc(100vh - 70rem);
+		height: 100vh;
+		margin: 0;
+		padding: 0;
+		overflow: hidden;
+		background-color: blue;
+		border: 0rem solid red;
+	}
+
+	//分屏样式
+	.ViewerSplitScreen {
+		float: left;
+		width: calc(50% - 2.5rem);
+		// height: calc(100vh - 70rem);
+		height: 100vh;
+		margin: 0;
+
+		.lk-status-bar {
+			width: calc(50% - 0rem) !important;
+		}
+	}
+</style>

+ 242 - 0
src/views/Map3d - 副本 (2)/components/measure.vue

@@ -0,0 +1,242 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-measure">
+		<el-row :gutter="20" style="margin-left: 0rem; margin-right: 0rem; ">
+			<el-col :span="8" v-for="(item,index) in measure" @click="handleMeasure(item.type,index)">
+				<el-avatar shape="circle" :size="70" :class="currentIndex===index?'selectStyle':'defaultStyle'">
+					<i :class="[item.icon,currentIndex===index?'selectFontStyle':'']" />
+				</el-avatar>
+				<div style="margin-top: 5rem; font-size: 14rem;" :class="currentIndex===index?'selectFontStyle':''">{{item.label}}</div>
+			</el-col>
+		</el-row>
+		<div class="jt-btn" style="margin: 8rem;">
+			<el-button color="rgb(255 100 100)" @click="clearMeasurementData"><span style="color: #fff;width: 300rem;">清空测量数据</span></el-button>
+		</div>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+	let popup = undefined;
+
+	export default {
+		props: {
+
+		},
+		watch: {
+
+		},
+
+		/* 数据 */
+		data() {
+			return {
+				currentIndex: -1,
+				measure: [{
+						label: '长度测量(贴地)',
+						type: 'measureLength',
+						number: 0,
+						icon: 'iconfont icon-thin-_pencil_rul'
+					},
+					{
+						label: '面积测量(贴地)',
+						type: 'measureArea',
+						number: 1,
+						icon: 'iconfont icon-svgmianjiceliang'
+					},
+					{
+						label: '高度测量',
+						type: 'measureHeight',
+						number: 2,
+						icon: 'iconfont icon-svggaoduceliang'
+					},
+					{
+						label: '空间距离',
+						type: 'measureSpatialLength',
+						number: 3,
+						icon: 'iconfont icon-svgkongjianceliang'
+					},
+					{
+						label: '三角测量',
+						type: 'measureTriangle',
+						number: 4,
+						icon: 'iconfont icon-svgsanjiaoceliang'
+					},
+					{
+						label: '坐标测量',
+						type: 'pickUp',
+						number: 5,
+						icon: 'iconfont icon-svgzuobiaoceliang'
+					},
+				],
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			/**
+			 * 测量事件
+			 * @param {Object} type 测量类型
+			 * @param {Object} index 第几个被选中
+			 */
+			handleMeasure(type, index) {
+				this.currentIndex = index;
+
+				//移除左键单击事件
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
+				}
+
+				jt3d.CommonTools.clear();
+
+				switch (type) {
+					case "measureLength": //长度测量(贴地)
+						jt3d.CommonTools.measureLength(function(error) {
+							ElMessage.error(error)
+						});
+						break;
+					case "measureArea": //面积测量(贴地)
+						jt3d.CommonTools.measureArea(function(error) {
+							ElMessage.error(error)
+						});
+						break;
+					case "measureHeight": //高度测量
+						jt3d.CommonTools.measureHeight()
+						break;
+					case "measureSpatialLength": //空间距离
+						jt3d.CommonTools.measureSpatialLength(function(error) {
+							ElMessage.error(error)
+						});
+						break;
+					case "measureTriangle": //三角测量
+						jt3d.CommonTools.measureTriangle()
+						break;
+					case "pickUp": //坐标测量
+						ElMessage("点击位置开始测量");
+						this.pickUp();
+						break;
+				}
+			},
+
+			/**
+			 * 坐标测量
+			 */
+			pickUp() {
+				let _self = this;
+
+				if (popup) {
+					popup.close();
+				}
+
+				jt3d.SketchViewModel.sketchTools('point', {
+					onComplete(cPoint, gPoint) {
+						if (gPoint.lng) {
+							let html = "";
+							html += "<div style='text-align: left;'>";
+							html += "<p>经度:" + gPoint.lng.toFixed(6) + "</p>";
+							html += "<p>纬度:" + gPoint.lat.toFixed(6) + "</p>";
+							html += "<p>高度:" + gPoint.height.toFixed(2) + "米</p>";
+							html += "</div>";
+
+							let position = {
+								x: Number(gPoint.lng),
+								y: Number(gPoint.lat),
+								z: Number(gPoint.height)
+							}
+
+							// popup = new jt3dSDK.PopupWindow.HtmlWindow(window["viewer"], position, "位置信息", html,40);
+							popup = new jt3dSDK.PopupWindow.HtmlWindow(window["viewer"], cPoint, "位置信息", html, -30);
+						}
+					},
+					onError(message) {
+						
+					}
+				});
+			},
+
+			/**
+			 * 清空测量数据
+			 */
+			clearMeasurementData() {
+				this.currentIndex = -1;
+				jt3d.CommonTools.clear();
+				if (popup) {
+					popup.close();
+				}
+
+				//还原左键单击事件
+				this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+			},
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.el-avatar{
+		width: 70rem !important;
+		height: 70rem !important;
+		font-size: 14px !important;
+		cursor: pointer;
+	}
+	
+	.el-button{
+		height: 32rem;
+		font-size: 16rem;
+		padding: 8rem 15rem;
+	}
+	
+	.jt-measure {
+		.el-col {
+			padding: 10rem;
+			// color: rgba(90, 172, 255, 1.0);
+			color: #fff;
+		}
+
+		i {
+			display: inline-block;
+			width: 100%;
+			height: 36rem;
+			line-height: 36rem;
+			text-align: center;
+			border-radius: 5rem;
+			font-size: 40rem;
+			// color: rgba(90, 172, 255, 1.0);
+			color: #fff;
+			transition: all .3s;
+			-webkit-transition: all .3s
+		}
+
+		.selectStyle {
+			// background: rgba(135, 182, 254, 0.5);
+			background: rgb(0 44 126);
+			--el-avatar-size: 70rem !important;
+		}
+
+		.defaultStyle {
+			background: #ffffff00;
+			--el-avatar-size: 70rem !important;
+		}
+
+		.selectFontStyle {
+			color: #fff;
+		}
+	}
+</style>

+ 278 - 0
src/views/Map3d - 副本 (2)/components/navigation.vue

@@ -0,0 +1,278 @@
+<script setup>
+
+	import jt3dNavigation from 'cesium-navigation-es6';
+
+	import {
+		inject
+	} from "vue";
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	
+</template>
+
+<script>
+	let jt3d = undefined;
+	export default {
+		props: {
+
+		},
+
+		/**
+		 * 数据
+		 */
+		data() {
+			return {
+		
+			}
+		},
+
+		/**
+		 * 方法
+		 */
+		methods: {
+			/**
+			 * 比例尺、指南针
+			 */
+			initNavigation(jt3d) {
+				let options = {};
+				// 用于在使用重置导航重置地图视图时设置默认视图控制。接受的值是Cesium.Cartographic 和 Cesium.Rectangle.
+				options.defaultResetView = Cesium.Rectangle.fromDegrees(121.13766, 36.99670, 121.94984, 37.55286);
+				// options.defaultResetView = Cesium.Cartographic.fromDegrees(103.84,31.15,24000);
+				// options.defaultResetView = Cesium.Cartographic.fromDegrees(Cesium.Math.toRadians(103.84),Cesium.Math.toRadians(31.15),Cesium.Math.toRadians(24000));
+				options.orientation = {
+					heading: Cesium.Math.toRadians(0),
+					pitch: Cesium.Math.toRadians(-90),
+					roll: 0
+				};
+			
+				//相机延时
+				options.duration = 4; //默认为3s
+			
+				// 用于启用或禁用罗盘。
+				options.enableCompass = true;
+				// 用于启用或禁用指南针外环。
+				options.enableCompassOuterRing = true;
+				// 用于启用或禁用缩放控件。
+				options.enableZoomControls = true;
+				// 用于启用或禁用距离图例。
+				options.enableDistanceLegend = false;
+			
+				//修改重置视图的tooltip
+				options.resetTooltip = "重置视图";
+				//修改放大按钮的tooltip
+				options.zoomInTooltip = "放大";
+				//修改缩小按钮的tooltip
+				options.zoomOutTooltip = "缩小";
+			
+				//如需自定义罗盘控件,请看下面的自定义罗盘控件
+				new jt3dNavigation(jt3d._viewer, options);
+			},
+
+		},
+
+		mounted() {
+			//比例尺、指南针
+			this.initNavigation(jt3d);
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	$jt3d-text-color:#fff;
+	$jt3d-content-color:#fff;
+
+	$jt3d-select-bg:red;
+
+	.query-keyword {
+		position: absolute;
+		top: 80rem;
+		width: 200rem;
+		left: 10rem;
+		border: 1rem solid rgb(0 44 126 / 100%);
+
+		.el-input {
+			--el-input-bg-color: rgb(0 44 126 / 50%);
+			--el-input-border-color: rgb(0 44 126 / 50%);
+			--el-input-placeholder-color: #fff;
+
+			--el-fill-color-blank: rgb(0 44 126 / 80%);
+			--el-text-color-regular: #fff;
+			--el-color-primary: #fff --el-border-radius-base:0rem;
+			--el-border-radius-base: 0rem;
+
+			.el-button {
+				background-color: rgb(0 44 126 / 100%);
+				color: #fff;
+			}
+		}
+
+		.autocomplete {
+			--el-fill-color-blank: rgb(0 44 126 / 0%);
+		}
+	}
+
+	.autocomplete ul {
+		font-family: sans-serif;
+		position: absolute;
+		list-style: none;
+		background: rgb(0 44 126 / 30%);
+		margin: 0;
+		width: 80%;
+		margin-top: 1rem;
+		margin-left: -1rem;
+		border: 1rem solid rgb(0 44 126 / 100%);
+	}
+
+	.autocomplete ul li {
+		text-decoration: none;
+		display: block;
+		background: rgb(0 44 126 / 30%);
+		color: #fff;
+		padding: 5rem;
+		margin-left: -40rem;
+		text-align: left;
+	}
+
+	.autocomplete ul li:hover,
+	.autocomplete ul li.focus-list {
+		color: white;
+		background: #2F9AF7;
+	}
+
+	.query-result {
+		position: absolute;
+		border-top: none;
+		padding-bottom: 0rem;
+		width: 100%;
+		z-index: 100;
+		border: 1rem solid rgb(0 44 126 / 100%);
+		background: rgb(0 44 126 / 30%);
+		margin-left: -1rem;
+
+		--el-fill-color-blank: rgb(0 44 126 / 0%);
+		--color: #fff;
+		--el-color-primary: #fff;
+
+		.query-result__item {
+			height: 80rem;
+			padding: 0 10rem;
+			display: flex;
+			justify-content: flex-start;
+			align-items: center;
+			margin-left: -40rem;
+			text-align: left;
+
+			&:hover {
+				// background-color: var(--mars-select-bg);
+			}
+
+			.query-result__context {
+				flex-grow: 1;
+				width: 90%;
+
+				.query-result-text {
+					font-size: 16rem;
+					width: 200rem;
+					font-family: Source Han Sans CN;
+					font-weight: 400;
+					// color: var($jt3d-text-color);
+					color: $jt3d-text-color;
+
+					.query-result-text_num {
+						width: 20rem;
+						height: 20rem;
+						margin-right: 5rem;
+						display: inline-block;
+						text-align: center;
+						background: rgb(0 44 126 / 100%);
+					}
+				}
+
+				.query-result-sub {
+					font-size: 14rem;
+					width: 200rem;
+					margin-left: 19rem;
+					font-family: Source Han Sans CN;
+					font-weight: 400;
+					// color: var($jt3d-content-color);
+					color: $jt3d-content-color;
+				}
+			}
+
+			.query-result__more {
+				font-size: 14rem;
+				font-family: Source Han Sans CN;
+				font-weight: 400;
+				// color: var($jt3d-content-color);
+				color: $jt3d-content-color;
+			}
+		}
+
+		.query-result__page {
+			display: flex;
+			justify-content: space-between;
+			padding: 5rem;
+
+			.query-result-allcount {
+				font-size: 14rem;
+				// color: var($jt3d-text-color);
+				color: $jt3d-text-color;
+			}
+		}
+	}
+	
+	/* 四个边角样式 */
+	// .borderstyle {
+	// 	position: relative;
+	// 	width: 100%;
+	// 	height: 490rem;
+	// 	padding: 10rem;
+	// 	border: 1rem solid #008aff70 !important;
+	// 	background-color: rgba(5, 45, 115, 0.7) !important;
+	// 	box-shadow: 0 4rem 15rem 1rem #02213bb3;
+	
+
+		.angle-border {
+			position: absolute;
+			width: 12rem;
+			height: 12rem;
+		}
+	
+		.angle-border-blue {
+			position: absolute;
+			width: 70rem;
+			height: 30rem;
+		}
+	
+		.left-top-border {
+			top: -2rem;
+			left: -2rem;
+			border-left: 2rem solid #008affdd;
+			border-top: 2rem solid #008affdd;
+		}
+	
+		.right-top-border {
+			top: -2rem;
+			right: -2rem;
+			border-right: 2rem solid #008affdd;
+			border-top: 2rem solid #008affdd;
+		}
+	
+		.left-bottom-border {
+			bottom: -2rem;
+			left: -2rem;
+			border-bottom: 2rem solid #FFFFFF;
+			border-left: 2rem solid #FFFFFF;
+		}
+	
+		.right-bottom-border {
+			bottom: -2rem;
+			right: -2rem;
+			border-right: 2rem solid #FFFFFF;
+			border-bottom: 2rem solid #FFFFFF;
+		}
+	// }
+</style>

+ 318 - 0
src/views/Map3d - 副本 (2)/components/printmap.vue

@@ -0,0 +1,318 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	import {
+		ref
+	} from "vue";
+	import {
+		inject
+	} from "vue";
+	import html2canvas from "html2canvas";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-MapPrinting">
+		<div class="middleviewer">
+			<el-input v-model="inputValue.mapname" placeholder="请输入地图名称" @focus="getfous" @blur="onblur" />
+			<div class="viewer">
+				<div id="printbox" ref="print"></div>
+				<div class="viewertop" display='block' ref="thumbnailmap"></div>
+				<div style="display:none" ref="originalmap"></div>
+			</div>
+		</div>
+		<div class="viewerbottom">
+			<!-- <el-button color="rgb(20 136 255)" v-print="printObj"><span style="color: #fff;font-size: 16rem;">打 印</span></el-button> -->
+			<el-button color="rgb(255 100 100)" @click="download"><span style="color: #fff;font-size: 16rem;">下 载</span></el-button>
+		</div>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+	export default {
+		data() {
+			return {
+				inputValue: {
+					mapname: "默认地图",
+				},
+
+				printObj: {
+					id: "printbox",
+					popTitle: "", // 打印配置页上方的标题
+					extraCss: "background-color:red",
+					preview: false, // 是否启动预览模式,默认是false
+					previewTitle: " 关闭预览", // 打印预览的标题
+					previewPrintBtnLabel: "点击打印", // 打印预览的标题下方的按钮文本,点击可进入打印
+					zIndex: 20002, // 预览窗口的z-index,默认是20002,最好比默认值更高
+					previewBeforeOpenCallback() {
+						console.log("正在加载预览窗口!")
+					}, // 预览窗口打开之前的callback
+					previewOpenCallback() {
+						console.log("已经加载完预览窗口,预览打开了!");
+					}, // 预览窗口打开时的callback
+					beforeOpenCallback() {
+						console.log("开始打印之前!");
+					}, // 开始打印之前的callback
+					openCallback() {
+						console.log("执行打印了!");
+					}, // 调用打印时的callback
+					closeCallback() {
+						console.log("关闭了打印工具!");
+					},
+					clickMounted() {
+						console.log("点击v-print绑定的按钮了!");
+					},
+					standard: "",
+					extarCss: "",
+				},
+			};
+		},
+		methods: {
+			//当选择器的输入框获得焦点时触发,标题获取焦点清空输入框
+			getfous() {
+				this.inputValue.mapname = ""
+			},
+
+			//当选择器的输入框失去焦点时触发
+			onblur() {
+				//删除print组件的内容
+				this.$refs.print.innerHTML = "";
+				// 获取标题
+				let value = this.inputValue.mapname;
+
+				//获取输入框的缺省内容
+				let text = value.length > 0 ? value : '默认地图标题';
+				let canvas = this.changcanvastitile(this.$refs.originalmap.lastChild, text);
+				let url = canvas.toDataURL('image/png', 5.0)
+				let img = document.createElement('img');
+				img.style.display = "block"
+				img.style.width = canvas.style.width;
+				img.style.height = canvas.style.height;
+				img.src = url
+				this.$refs.print.appendChild(img);
+			},
+
+			//下载按钮
+			download() {
+				if (this.$refs.originalmap.children.length <= 0) {
+					ElMessage.error("截图未成功");
+					return
+				}
+				let value = this.inputValue.mapname;
+				//获取输入框的缺省内容
+				let text = value.length > 0 ? value : '默认地图标题';
+
+				let img = this.$refs.print.lastChild;
+				let a = document.createElement('a');
+				a.style.display = 'none';
+				a.download = text + '.png';
+				a.href = img.src;
+				document.body.appendChild(a);
+				a.click();
+				document.body.removeChild(a);
+			},
+
+			//更新打印标题
+			changcanvastitile(canvas, text) {
+
+				//清理标题位置区域
+				let width = parseInt(canvas.style.width.slice(0, -2));
+				let height = parseInt(canvas.style.height.slice(0, -2));
+				//获取上下文
+				const ctx = canvas.getContext('2d');
+				//清理标题问题
+				ctx.clearRect(0, 0, width, 160)
+				//设置字体
+				ctx.font = "bold 50rem arial";
+				document.fonts.load(ctx.font);
+				//设置填充颜色
+				ctx.fillStyle = "black";
+				//循环输入标题,字间距50rem
+				for (let i = 0; i < text.length; i++) {
+					//第I个字的水平位置=((canvs.leght)/2-(text.legth)*letterspace/2+i*letterspace)
+					let x = Math.ceil(width / 2) - (text.length - 1) * 50 + i * 100
+					//水平绘制填充文本
+					ctx.fillText(text[i], x, 100);
+				}
+				return canvas;
+			},
+
+			//打印地图截屏
+			screenshot() {
+				this.$refs.print.innerHTML = "";
+				this.$refs.thumbnailmap.innerHTML = ""
+				this.$refs.originalmap.innerHTML = '';
+				this.inputValue.mapname = "默认地图"
+				html2canvas(this.$parent.$parent.$refs.refMap3d.$refs.cesiumContainer, {
+
+					// backgroundColor: null, //画出来的图片有白色的边框,不要可设置背景为透明色(null)
+					useCORS: true, //支持图片跨域
+					scale: 1, //设置放大的倍数
+					// tainTest:false,
+					// foreignObjectRendering: true,//// 是否在浏览器支持的情况下使用ForeignObject渲染
+					dpi: 300,
+					// width:1920,
+					// height:1080
+
+				}).then(
+					(canvas) => {
+						let url = canvas.toDataURL('image/png', 5.0)
+						let img = document.createElement('img');
+						img.style.display = "block"
+						img.style.width = "calc(100% - 0rem)"
+						img.style.height = "calc(100% - 0rem)";
+						img.src = url
+						//缩略图
+						this.$refs.thumbnailmap.appendChild(img);
+						//创建新的canvas
+						let canvasnew = this.createmap(canvas)
+						let urla = canvasnew.toDataURL('image/png', 5.0)
+						let imga = document.createElement('img');
+						imga.style.display = "block"
+						imga.style.width = canvas.style.width / 2;
+						imga.style.height = canvas.style.height / 2;
+						imga.src = urla
+						//原图
+						this.$refs.originalmap.appendChild(canvasnew);
+						//打印图
+						this.$refs.print.appendChild(imga)
+					}
+				)
+			},
+
+			createmap(img) {
+				//渲染之前先清理掉所有所有指定canvas
+				if (document.getElementById('canvasid')) {
+					document.getElementById('canvasid').remove();
+				}
+				let width = parseInt(img.style.width.slice(0, -2));
+				let height = parseInt(img.style.height.slice(0, -2));
+
+				let canvas = this.createHDCanvas(width + 60, height + 160, 'block')
+
+				//获取上下文
+				const ctx = canvas.getContext('2d');
+				//获取图片对象
+				ctx.drawImage(img, 30, 120, width, height)
+				// let value = this.$refs.refinput.value;
+				let value = this.inputValue.mapname;
+				let text = value.length > 0 ? value : '默认地图标题';
+				console.log("text")
+				console.log(text)
+				ctx.clearRect(0, 0, width, 120)
+				//设置字体
+				ctx.font = "bold 50rem arial";
+				//设置填充颜色
+				ctx.fillStyle = "black";
+				//循环输入标题,字间距50rem
+				for (let i = 0; i < text.length; i++) {
+					//第I个字的水平位置=((canvs.leght)/2-(text.legth)*letterspace/2+i*letterspace)
+					let x = Math.ceil(width / 2) - (text.length - 1) * 50 + i * 100
+					//水平绘制填充文本
+					ctx.fillText(text[i], x, 100);
+				}
+				return canvas;
+			},
+			createHDCanvas(w = 300, h = 150, display = 'block') {
+				let ratio = window.devicePixelRatio * 1 || 1;
+				let canvas = document.createElement('canvas');
+				canvas.id = "canvasid";
+				canvas.width = w * ratio; // 实际渲染像素
+				canvas.height = h * ratio; // 实际渲染像素
+				canvas.style.display = display;
+				canvas.style.width = `${w}rem`; // 控制显示大小
+				canvas.style.height = `${h}rem`; // 控制显示大小
+				canvas.style.backgroundColor = "red";
+				// setTransform() 允许您缩放、旋转、移动并倾斜当前的环境
+				canvas.getContext('2d').setTransform(ratio, 0, 0, ratio, 0, 0);
+				return canvas;
+			},
+		},
+
+		mounted() {
+			// //获取角色
+			// this.info = JSON.parse(localStorage.getItem("person"));
+			// //获取角色id
+			// this.id = this.info.id;
+			// this.$bus.on("screenshot", (e) => {
+			// 	console.log("aaaaa")
+			// 	this.screenshot()
+			// })
+		},
+	};
+</script>
+
+<style lang="scss" scoped>
+	.jt-MapPrinting {
+		width: 100%;
+		height: 100%;
+		overflow: hidden;
+
+		--el-fill-color-blank: rgb(0 44 126 / 68%);
+		--el-text-color-regular: rgb(216 240 255);
+		--el-border-color: rgb(35 135 255);
+
+		.middleviewer {
+			height: 92%;
+
+			.viewer {
+				position: relative;
+				width: 100% !important;
+				height: calc(100% - 29rem) !important;
+				overflow: hidden;
+
+				.viewertop {
+					width: calc(100% - 2rem);
+					height: calc(100% - 2rem);
+					border: 1rem solid rgb(35 135 255);
+					position: absolute;
+					top: 0;
+					left: 0;
+				}
+			}
+		}
+
+		.viewerbottom {
+			margin: 10rem;
+		}
+	}
+
+	::v-deep .el-input {
+		flex-grow: 0 !important;
+		width: calc(100%);
+		height: 30rem !important;
+		letter-spacing: 100rem;
+	}
+
+	//输入框文字颜色
+	::v-deep .el-input__inner {
+		color: rgb(255, 255, 255);
+		text-align: center;
+	}
+
+	//输入框背景色
+	::v-deep .el-input__wrapper {
+		background-color: rgba(255, 255, 255, 0) !important;
+	}
+
+	::v-deep .el-button {
+		border-radius: 3rem !important;
+		height: 32rem;
+	}
+
+	::v-deep .el-button--primary {
+		background-color: rgba(64, 158, 255, 0.6) !important;
+	}
+
+	::-webkit-scrollbar {
+		width: 0rem;
+	}
+</style>

+ 465 - 0
src/views/Map3d - 副本 (2)/components/query-graphics.vue

@@ -0,0 +1,465 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage,
+		ElLoading
+	} from 'element-plus';
+
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-query-graphics">
+		<el-row :gutter="20" style="margin-left: 0rem; margin-right: 0rem">
+			<el-col :span="8" v-for="(item,index) in queryGraphics" @click="handleQueryGraphics(item.type,index)">
+				<el-avatar shape="circle" :size="70" :class="currentIndex===index?'selectStyle':'defaultStyle'">
+					<i :class="[item.icon,currentIndex===index?'selectFontStyle':'']" />
+				</el-avatar>
+				<div style="margin-top: 5rem; font-size: 14rem;" :class="currentIndex===index?'selectFontStyle':''">{{item.label}}</div>
+			</el-col>
+		</el-row>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+	let loading = undefined;
+
+	import {
+		Store
+	} from '@/store/index'
+	let store = Store();
+
+	import {
+		deepTree
+	} from "@/utils/deepTree.js";
+
+	export default {
+		props: {
+
+		},
+		watch: {
+
+		},
+
+		/* 数据 */
+		data() {
+			return {
+				currentIndex: -1,
+				queryGraphics: [{
+						label: '点查询',
+						type: 'Point',
+						number: 0,
+						icon: 'iconfont icon-svgdianchaxun'
+					},
+					{
+						label: '线查询',
+						type: 'Line',
+						number: 1,
+						icon: 'iconfont icon-svgxianchaxun'
+					},
+					{
+						label: '圆形查询',
+						type: 'Circle',
+						number: 2,
+						icon: 'iconfont icon-svgyuanxingchaxun'
+					},
+					{
+						label: '矩形查询',
+						type: 'Rectangle',
+						number: 3,
+						icon: 'iconfont icon-svgjuxingchaxun'
+					},
+					{
+						label: '多边形',
+						type: 'Polygon',
+						number: 4,
+						icon: 'iconfont icon-svgduobianxingchaxun'
+					},
+					{
+						label: '清除',
+						type: 'clear',
+						number: 5,
+						icon: 'iconfont icon-shanchu'
+					},
+				],
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			/**
+			 * 查询事件
+			 * @param {Object} type 查询类型
+			 * @param {Object} index 第几个被选中
+			 */
+			handleQueryGraphics(type, index) {
+				let _self = this;
+				this.currentIndex = index;
+
+				//移除左键单击事件
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); //移除事件
+				}
+
+				jt3d.CommonTools.clear();
+				switch (type) {
+					case "Point": //点查询
+						jt3d.CommonTools.queryByPoint(function(coordinates) {
+							console.log(coordinates)
+
+							//还原左键单击事件
+							_self.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+
+							/* 转换坐标 */
+							let points = coordinates.split(',');
+
+							_self.initQuery({
+								spatialType: '点',
+								coordinate: Number(points[0]) + " " + Number(points[1]),
+								buffer: ''
+							});
+
+						});
+						break;
+					case "Line": //线查询
+						jt3d.CommonTools.queryByLine(function(coordinates) {
+							console.log(coordinates)
+
+							//还原左键单击事件
+							_self.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+
+							/* 转换坐标 */
+							let points = coordinates.split(',');
+							let pointsArray = [];
+							for (let i = 0; i < points.length;) {
+								pointsArray.push(Number(points[i]) + " " + Number(points[i + 1]));
+								i = i + 2;
+							}
+
+							_self.initQuery({
+								spatialType: '线',
+								coordinate: pointsArray.join(','),
+								buffer: ''
+							});
+						});
+						break;
+					case "Circle": //圆形查询
+						jt3d.CommonTools.queryByCircle(function(coordinates, radius) {
+							console.log("圆点:" + coordinates + ",半径:" + radius)
+
+							//还原左键单击事件
+							_self.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+
+							/* 转换坐标 */
+							let points = coordinates.split(',');
+
+							_self.initQuery({
+								spatialType: '点',
+								coordinate: Number(points[0]) + " " + Number(points[1]),
+								buffer: radius
+							});
+
+						});
+						break;
+					case "Rectangle": //矩形查询
+						jt3d.CommonTools.queryByRectangle(function(coordinates) {
+							console.log(coordinates)
+
+							//还原左键单击事件
+							_self.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+
+							/* 转换坐标 */
+							let points = coordinates.split(',');
+							let pointsArray = [];
+							for (let i = 0; i < points.length;) {
+								pointsArray.push(Number(points[i]) + " " + Number(points[i + 1]));
+								i = i + 2;
+							}
+
+							_self.initQuery({
+								spatialType: '面',
+								coordinate: pointsArray.join(','),
+								buffer: ''
+							});
+
+						});
+						break;
+					case "Polygon": //多边形查询
+						jt3d.CommonTools.queryByPolygon(function(coordinates) {
+							console.log(coordinates)
+
+							//还原左键单击事件
+							_self.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+
+							/* 转换坐标 */
+							let points = coordinates.split(',');
+							let pointsArray = [];
+							for (let i = 0; i < points.length;) {
+								pointsArray.push(Number(points[i]) + " " + Number(points[i + 1]));
+								i = i + 2;
+							}
+
+							_self.initQuery({
+								spatialType: '面',
+								coordinate: pointsArray.join(','),
+								buffer: ''
+							});
+
+						});
+						break;
+					case "clear": //清除查询效果
+						this.currentIndex = -1;
+
+						//清除绘制
+						jt3d.CommonTools.clear();
+
+						//还原左键单击事件
+						this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+
+						//清除高亮显示
+						let list = jt3d._dataSources.getByName("单击高亮显示")
+						list.forEach(res => {
+							jt3d._dataSources.remove(res)
+						})
+
+						//清除定位样式
+						if (jt3d.LocateUtil._locationEntity) {
+							window["viewer"].entities.remove(jt3d.LocateUtil._locationEntity);
+						}
+						break;
+				}
+			},
+
+			/**
+			 * @param {Object} options
+			 */
+			initQuery(options) {
+				let _self = this;
+				let treeNodes = [];
+
+				//清除高亮显示
+				let list = jt3d._dataSources.getByName("单击高亮显示")
+				list.forEach(res => {
+					jt3d._dataSources.remove(res)
+				})
+
+				//清除定位样式
+				if (jt3d.LocateUtil._locationEntity) {
+					window["viewer"].entities.remove(jt3d.LocateUtil._locationEntity);
+				}
+
+				const getData = () => {
+
+					if (store.queryMapTables.length > 0) {
+						//查询等待框
+						loading = ElLoading.service({
+							lock: true,
+							text: 'Loading',
+							background: 'rgba(0, 0, 0, 0.7)',
+						});
+
+						let data = [];
+						store.queryMapTables.forEach((itemTable, index) => {
+							let result = getAxios(itemTable, options);
+							data.push(result);
+						})
+
+						Promise.all(data).then(itemList => {
+
+							console.log("itemList", itemList) //itemList返回的数据是按顺序的
+							//执行自己接下来的操作
+							//doSomething
+
+							itemList.forEach((item, index) => {
+								let field = item.table;
+								let tableName = item.table[0].tableName;
+								let tableDescription = item.table[0].tableDescription;
+
+								if (item.data.features.length > 0) {
+									//添加父节点
+									let parentNode = {
+										id: tableName,
+										parentid: "CIM",
+										label: tableDescription + "(" + item.data.features.length + ")",
+									};
+									treeNodes.push(parentNode);
+
+									item.data.features.forEach((itemData, index) => {
+
+										//**************高亮显示****************
+
+										// /* 转换坐标 */
+										// let positions = itemData.geometry.coordinates[0][0].map(point => {
+										// 	return Cesium.Cartesian3.fromDegrees(point[0], point[1], point[2] || 0);
+										// });
+
+										// //先创建一个CustomDataSource源,然后把entity存入这里面
+										// let Polygon = new Cesium.CustomDataSource("单击高亮显示");
+										// jt3d._dataSources.add(Polygon);
+										// //添加数据的方式
+										// Polygon.entities.add({
+										// 	polygon: {
+										// 		hierarchy: new Cesium.PolygonHierarchy(positions),
+										// 		material: Cesium.Color.fromCssColorString("rgba(255,0,255,.7)"),
+										// 		classificationType: Cesium.ClassificationType.BOTH,
+										// 	},
+										// });
+
+										//**************高亮显示****************
+
+										let childNode = {
+											id: itemData.properties["id"],
+											parentid: tableName,
+											field: field,
+											data: itemData,
+										};
+
+										switch (tableName) {
+											//==============规划管理数据-重要控制线=========================
+											case "yjjbnt": //永久基本农田
+												childNode.label = itemData.properties["cfzr"] + "(" + itemData.properties["zzsxmc"] + ")"
+												break;
+											case "yjtz": //永久基本农田调整
+												childNode.label = itemData.properties["zldwmc"] + "(" + itemData.properties["dlmc"] + ")"
+												break;
+											case "bnrgdbh": //不纳入耕地保护目标
+												childNode.label = itemData.properties["zldwmc"] + "(" + itemData.properties["dlmc"] + ")"
+												break;
+											case "gdbhrw": //耕地保护任务
+												childNode.label = itemData.properties["zldwmc"] + "(" + itemData.properties["dlmc"] + ")"
+												break;
+
+												//==============规划管理数据-历史规划==============
+											case "tdzgh": //土地利用总体规划
+												childNode.label = itemData.properties["ghdlmc"]
+												break;
+											case "jsyd": //建设用地管制区
+												childNode.label = itemData.properties["id"]
+												break;
+
+												//==============现状类数据-森林资源-森林资源调查==============
+											case "slyzt": //2019年森林资源管理一张图
+												childNode.label = itemData.properties["id"]
+												break;
+
+												//==============现状类数据-国土调查==============
+											case "ed2009": //二调
+												childNode.label = itemData.properties["zldwmc"] + "(" + itemData.properties["dlmc"] + ")"
+												break;
+											case "ed2020": //二调2020
+												childNode.label = itemData.properties["zldwmc"] + "(" + itemData.properties["dlmc"] + ")"
+												break;
+											case "ed2021": //二调2021
+												childNode.label = itemData.properties["zldwmc"] + "(" + itemData.properties["dlmc"] + ")"
+												break;
+											case "sddltb": //三调   
+												childNode.label = itemData.properties["zldwmc"] + "(" + itemData.properties["dlmc"] + ")"
+												break;
+										}
+
+										treeNodes.push(childNode);
+									});
+								}
+							});
+
+							//处理查询结果树
+							if (treeNodes.length > 0) {
+
+								_self.$parent.$parent.$refs.refQueryResult.expandedKeys = []
+								_self.$parent.$parent.$refs.refQueryResultPopup.isshow = true;
+								_self.$parent.$parent.$refs.refQueryResult.treeData = deepTree(treeNodes);
+
+								//默认选中第一个节点并赋予选中样式
+								_self.$nextTick(function() {
+									let currentNode = _self.$parent.$parent.$refs.refQueryResult.treeData[0].children[0];
+									let currentKey = currentNode.id;
+									_self.$parent.$parent.$refs.refQueryResult.currentKey = currentKey;
+									_self.$parent.$parent.$refs.refQueryResult.$refs.tree.setCurrentKey(currentKey);
+									_self.$parent.$parent.$refs.refQueryResult.handleNodeClick(currentNode);
+								});
+
+								//expandedKeys默认展开treedata第一层,加载第一层数据
+								_self.$parent.$parent.$refs.refQueryResult.expandedKeys.push(_self.$parent.$parent.$refs.refQueryResult.treeData[0].id)
+							}
+
+							//清除绘制
+							jt3d.CommonTools.clear();
+
+							//关闭等待框
+							loading.close()
+
+						})
+					}
+				}
+
+				const getAxios = (itemTable, options) => {
+					return new Promise(function(resolve, reject) {
+						_self.$http.get('/getSpatialQuery', {
+							tableName: itemTable,
+							spatialType: options.spatialType,
+							coordinate: options.coordinate,
+							buffer: options.buffer
+						}).then(res => {
+							resolve(res)
+						});
+					}).catch(err => {
+
+					})
+				}
+
+				getData();
+			},
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.jt-query-graphics {
+		.el-col {
+			padding: 10rem;
+			// color: rgba(90, 172, 255, 1.0);
+			//color: #55ffff;
+			color: #fff;
+		}
+
+		i {
+			display: inline-block;
+			width: 100%;
+			height: 36rem;
+			line-height: 36rem;
+			text-align: center;
+			border-radius: 5rem;
+			font-size: 40rem;
+			// color: rgba(90, 172, 255, 1.0);
+			// color: #55ffff;
+			color: #fff;
+			transition: all .3s;
+			-webkit-transition: all .3s
+		}
+
+		.selectStyle {
+			// background: rgba(135, 182, 254, 0.5);
+			background: rgb(0 44 126);
+		}
+
+		.defaultStyle {
+			background: #ffffff00;
+		}
+
+		.selectFontStyle {
+			color: #fff;
+		}
+	}
+</style>

+ 365 - 0
src/views/Map3d - 副本 (2)/components/query-keyword.vue

@@ -0,0 +1,365 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	/**
+	 * element-plus字体
+	 */
+	import {
+		Search,
+		DArrowRight
+	} from '@element-plus/icons-vue';
+	import {
+		inject
+	} from "vue";
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="query-keyword fadein-left">
+		<el-input v-model="search.searchKey" placeholder="请输入查询关键字" @change="searchKeyChange" @input="searchKeyChange" clearable>
+			<template #append>
+				<el-button :icon="Search" @click="btnSearchClick" />
+			</template>
+		</el-input>
+		<div class="autocomplete " v-if="search.searchListShow">
+			<ul>
+				<li v-for="(item,index) in search.searchCompleteData" :key="index" @click="SearchSelect(index)">
+					{{ item }}
+				</li>
+			</ul>
+		</div>
+		<div class="query-result" v-if="resultListShow">
+			<template v-if="resultCompleteData && resultCompleteData.length">
+				<ul>
+					<li v-for="(item, i) in resultCompleteData" :key="i" class="query-result__item" @click.stop="flyTo(item)">
+						<div class="query-result__context">
+							<p class="query-result-text" :title="item.name">
+								<span class="query-result-text_num">{{ i + 1 }}</span>
+								{{ item.name }}
+							</p>
+							<p class="query-result-sub">{{ item.label }}</p>
+						</div>
+						<p class="query-result__more">
+							<el-icon>
+								<DArrowRight />
+							</el-icon>
+						</p>
+					</li>
+				</ul>
+				<div class="query-result__page">
+					<p class="query-result-allcount">共{{ resultCompleteData.length }}条结果</p>
+					<el-pagination layout="prev, pager, next" size="small" :total="resultCompleteData.length" pageSize="1" :simple="true" />
+				</div>
+			</template>
+		</div>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+	export default {
+		props: {
+
+		},
+
+		/**
+		 * 数据
+		 */
+		data() {
+			return {
+				search: {
+					searchKey: "", // input框输入的值,用v-model双向绑定
+					searchDataList: [], // autocomplete查询数据,一般由后端返回
+					searchCompleteData: [], // autocomplete查询到的数据
+					searchListShow: false,
+				},
+				resultCompleteData: [], // 查询结果
+				resultListShow: false,
+				pagination: {
+					size: "small",
+					total: 0,
+					pageSize: 6,
+					simple: true
+				}
+			}
+		},
+
+		/**
+		 * 方法
+		 */
+		methods: {
+			
+			/**
+			 * 在 Input 值改变时触发
+			 * 当 modelValue 改变时,当输入框失去焦点或用户按Enter时触发
+			 */
+			searchKeyChange() {
+				let _self = this;
+				this.search.searchListShow = true;
+				this.resultListShow = false;
+				let searchRegex = new RegExp(this.search.searchKey, 'i');
+				this.search.searchCompleteData = []; // 先把原有的数据清空,重新查询
+				if (this.search.searchKey === '') return; //如果什么都没有输入,则不用查找
+				this.search.searchDataList.forEach((item) => {
+					if (searchRegex.test(item.label)) {
+						_self.search.searchCompleteData.push(item.label)
+					}
+				});
+			},
+
+			/**
+			 * 选中联想查询数据
+			 * @param {Object} index
+			 */
+			SearchSelect(index) {
+				this.search.searchListShow = false;
+				console.log(this.search.searchCompleteData[index]);
+				this.getSearchData(this.search.searchCompleteData[index]);
+			},
+
+			/**
+			 * 查询按钮
+			 */
+			btnSearchClick() {
+				if (this.search.searchKey === "") {
+					ElMessage("请输入查询关键字");
+					return;
+				}
+				this.getSearchData(this.search.searchKey);
+			},
+
+			/**
+			 * 数据查询
+			 * @param {Object} queryString
+			 */
+			getSearchData(queryString) {
+				let _self = this;
+				_self.$http.get('/getTableList', {
+					tableName: 'base_sys_role',
+					sqlWhere: " label like '%" + queryString + "%'",
+					orderByField: ''
+				}).then(res => {
+					console.log('从服务端搜索数据', res.data)
+					_self.resultCompleteData = res.data;
+					_self.resultListShow = true;
+					_self.search.searchListShow = false;
+				});
+			}
+		},
+
+		mounted() {
+			let _self = this;
+			_self.$http.get('/getTableList', {
+				tableName: 'base_sys_role',
+				sqlWhere: '',
+				orderByField: ''
+			}).then(res => {
+				console.log('从服务端搜索数据', res.data)
+				_self.search.searchDataList = res.data;
+			});
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	$jt3d-text-color:#fff;
+	$jt3d-content-color:#fff;
+
+	$jt3d-select-bg:red;
+
+	.query-keyword {
+		position: absolute;
+		top: 80rem;
+		width: 200rem;
+		left: 10rem;
+		border: 1rem solid rgb(0 44 126 / 100%);
+
+		.el-input {
+			--el-input-bg-color: rgb(0 44 126 / 50%);
+			--el-input-border-color: rgb(0 44 126 / 50%);
+			--el-input-placeholder-color: #fff;
+
+			--el-fill-color-blank: rgb(0 44 126 / 80%);
+			--el-text-color-regular: #fff;
+			--el-color-primary: #fff --el-border-radius-base:0rem;
+			--el-border-radius-base: 0rem;
+
+			.el-button {
+				background-color: rgb(0 44 126 / 100%);
+				color: #fff;
+			}
+		}
+
+		.autocomplete {
+			--el-fill-color-blank: rgb(0 44 126 / 0%);
+		}
+	}
+
+	.autocomplete ul {
+		font-family: sans-serif;
+		position: absolute;
+		list-style: none;
+		background: rgb(0 44 126 / 30%);
+		margin: 0;
+		width: 80%;
+		margin-top: 1rem;
+		margin-left: -1rem;
+		border: 1rem solid rgb(0 44 126 / 100%);
+	}
+
+	.autocomplete ul li {
+		text-decoration: none;
+		display: block;
+		background: rgb(0 44 126 / 30%);
+		color: #fff;
+		padding: 5rem;
+		margin-left: -40rem;
+		text-align: left;
+	}
+
+	.autocomplete ul li:hover,
+	.autocomplete ul li.focus-list {
+		color: white;
+		background: #2F9AF7;
+	}
+
+	.query-result {
+		position: absolute;
+		border-top: none;
+		padding-bottom: 0rem;
+		width: 100%;
+		z-index: 100;
+		border: 1rem solid rgb(0 44 126 / 100%);
+		background: rgb(0 44 126 / 30%);
+		margin-left: -1rem;
+
+		--el-fill-color-blank: rgb(0 44 126 / 0%);
+		--color: #fff;
+		--el-color-primary: #fff;
+
+		.query-result__item {
+			height: 80rem;
+			padding: 0 10rem;
+			display: flex;
+			justify-content: flex-start;
+			align-items: center;
+			margin-left: -40rem;
+			text-align: left;
+
+			&:hover {
+				// background-color: var(--mars-select-bg);
+			}
+
+			.query-result__context {
+				flex-grow: 1;
+				width: 90%;
+
+				.query-result-text {
+					font-size: 16rem;
+					width: 200rem;
+					font-family: Source Han Sans CN;
+					font-weight: 400;
+					// color: var($jt3d-text-color);
+					color: $jt3d-text-color;
+
+					.query-result-text_num {
+						width: 20rem;
+						height: 20rem;
+						margin-right: 5rem;
+						display: inline-block;
+						text-align: center;
+						background: rgb(0 44 126 / 100%);
+					}
+				}
+
+				.query-result-sub {
+					font-size: 14rem;
+					width: 200rem;
+					margin-left: 19rem;
+					font-family: Source Han Sans CN;
+					font-weight: 400;
+					// color: var($jt3d-content-color);
+					color: $jt3d-content-color;
+				}
+			}
+
+			.query-result__more {
+				font-size: 14rem;
+				font-family: Source Han Sans CN;
+				font-weight: 400;
+				// color: var($jt3d-content-color);
+				color: $jt3d-content-color;
+			}
+		}
+
+		.query-result__page {
+			display: flex;
+			justify-content: space-between;
+			padding: 5rem;
+
+			.query-result-allcount {
+				font-size: 14rem;
+				// color: var($jt3d-text-color);
+				color: $jt3d-text-color;
+			}
+		}
+	}
+	
+	/* 四个边角样式 */
+	// .borderstyle {
+	// 	position: relative;
+	// 	width: 100%;
+	// 	height: 490rem;
+	// 	padding: 10rem;
+	// 	border: 1rem solid #008aff70 !important;
+	// 	background-color: rgba(5, 45, 115, 0.7) !important;
+	// 	box-shadow: 0 4rem 15rem 1rem #02213bb3;
+	
+
+		.angle-border {
+			position: absolute;
+			width: 12rem;
+			height: 12rem;
+		}
+	
+		.angle-border-blue {
+			position: absolute;
+			width: 70rem;
+			height: 30rem;
+		}
+	
+		.left-top-border {
+			top: -2rem;
+			left: -2rem;
+			border-left: 2rem solid #008affdd;
+			border-top: 2rem solid #008affdd;
+		}
+	
+		.right-top-border {
+			top: -2rem;
+			right: -2rem;
+			border-right: 2rem solid #008affdd;
+			border-top: 2rem solid #008affdd;
+		}
+	
+		.left-bottom-border {
+			bottom: -2rem;
+			left: -2rem;
+			border-bottom: 2rem solid #FFFFFF;
+			border-left: 2rem solid #FFFFFF;
+		}
+	
+		.right-bottom-border {
+			bottom: -2rem;
+			right: -2rem;
+			border-right: 2rem solid #FFFFFF;
+			border-bottom: 2rem solid #FFFFFF;
+		}
+	// }
+</style>

+ 300 - 0
src/views/Map3d - 副本 (2)/components/queryResult.vue

@@ -0,0 +1,300 @@
+<script setup>
+	import {
+		formattingTime
+	} from '@/assets/js/localtime.js';
+
+	import {
+		inject
+	} from "vue";
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+<template>
+	<div class="jt-queryResult">
+		<div class="_left">
+			<el-tree class="tree-line queryResultTree" ref="tree" node-key="id" :data="treeData" :default-expanded-keys="expandedKeys" :current-node-key="currentKey" @node-click="handleNodeClick" highlight-current />
+		</div>
+		<div class="_right">
+			<div id="detailDiv"></div>
+		</div>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+
+	export default {
+		props: {
+			tree: {
+				type: Object,
+				default () {
+					return []
+				}
+			}
+		},
+		data() {
+			return {
+				treeData: this.tree,
+				currentKey: "",
+				expandedKeys: [], //对应要展开的节点id
+			}
+		},
+		methods: {
+			/**
+			 * 树单击事件
+			 */
+			handleNodeClick(treeNode) {
+
+				let _self = this;
+
+				return new Promise((resolve, reject) => {
+
+					if (treeNode.parentid != 'CIM') {
+
+						//清除高亮显示
+						let list = jt3d._dataSources.getByName("单击高亮显示")
+						list.forEach(res => {
+							jt3d._dataSources.remove(res)
+						})
+
+						//高亮显示并定位显示详细信息
+						jt3d.PolygonObject.generatePolygonByPoints(treeNode.data.geometry.coordinates[0][0], {
+							color: [255, 0, 255, 0],
+							outline: true,
+							outlineWidth: 5,
+							outlineColor: [0, 255, 180, 1]
+						}).then((locationEntity) => {
+							// 初始化定位参数
+							let options = {};
+							options.duration = Cesium.defaultValue(options.duration, 2);
+							options.heading = Cesium.defaultValue(options.heading, 0);
+							options.pitch = Cesium.defaultValue(options.pitch, -60);
+							options.range = Cesium.defaultValue(options.range, 800.0);
+
+							let flyToEntity = jt3d.LocateUtil.flyToEntity(locationEntity, options);
+							flyToEntity.then(function(flag) {
+								//详细信息
+								let strHtml = "";
+								strHtml += "<table>";
+								strHtml += "<thead>";
+								strHtml += "<tr>";
+								strHtml += "<th>属性名</th>";
+								strHtml += "<th>属性值</th>";
+								strHtml += "</tr> ";
+								strHtml += " </thead>";
+								strHtml += "<tbody>";
+
+								var field = treeNode.field;
+								var properties = treeNode.data.properties
+								field.forEach(itemField => {
+									if (itemField.isDisplay === 1) {
+										var fieldDesc = itemField.fieldDescription || itemField
+											.fieldName;
+										var fieldVals = properties[itemField.fieldName];
+
+										//日期格式
+										if (itemField.fieldType === 1) {
+											let time = new Date(fieldVals).getTime();
+											fieldVals = formattingTime(time);
+										}
+
+										if (fieldVals != null && fieldVals != "" && fieldVals !=
+											undefined) {
+											strHtml += "<tr>";
+											strHtml += "<td>" + fieldDesc + "</td>";
+											strHtml += "<td>" + fieldVals + "</td>";
+											strHtml += "</tr>";
+										}
+									}
+								});
+
+								strHtml += "</tbody>";
+								strHtml += "</table>";
+
+								let divb = document.getElementById('detailDiv')
+								divb.innerHTML = strHtml; //设置显示的数据,可以是标签.
+
+							});
+
+						});
+					}
+
+					resolve(1)
+				})
+			},
+
+		},
+		mounted() {}
+	}
+</script>
+
+<style lang="scss">
+	.jt-queryResult {
+		overflow: hidden;
+
+		//左侧树
+		&>div:nth-child(1) {
+			width: 220rem;
+			height: 380rem;
+			float: left;
+			overflow: auto;
+			border-right: 5rem solid #ddd;
+
+			.el-tree {
+				background: rgb(28 59 112 / 0%);
+				height: calc(100% - 2rem);
+				color: #fff;
+				--el-tree-node-hover-bg-color: #2a67c3;
+				--el-font-size-base: 14rem;
+
+				.overflowtext {
+					width: auto !important;
+					padding: 0;
+				}
+			}
+
+
+
+			.tree-line {
+				.el-tree-node {
+					position: relative;
+				}
+
+				.el-tree-node__children {
+					padding-left: 16rem !important; // 缩进量
+
+					.el-tree-node__content {
+						padding-left: 18rem !important;
+					}
+				}
+
+				//高亮显示选中样式
+				.el-tree-node.is-current>.el-tree-node__content {
+					background: #2a67c3;
+				}
+
+				// 竖线
+				.el-tree-node::before {
+					content: "";
+					height: 100%;
+					width: 1rem;
+					position: absolute;
+					left: -3rem;
+					top: -26rem;
+					border-width: 1rem;
+					border-left: 1rem dashed rgba(255, 255, 255, .8);
+				}
+
+				// 当前层最后一个节点的竖线高度固定
+				.el-tree-node:last-child::before {
+					height: 38rem; // 可以自己调节到合适数值
+				}
+
+				// 横线
+				.el-tree-node::after {
+					content: "";
+					width: 24rem;
+					height: 20rem;
+					position: absolute;
+					left: -3rem;
+					top: 12rem;
+					border-width: 1rem;
+					border-top: 1rem dashed rgba(255, 255, 255, .8);
+				}
+
+				// 去掉最顶层的虚线,放最下面样式才不会被上面的覆盖了
+				&>.el-tree-node::after {
+					border-top: none;
+				}
+
+				&>.el-tree-node::before {
+					border-left: none;
+				}
+
+				// 展开关闭的icon
+				.el-tree-node__expand-icon {
+					font-size: 16rem;
+
+					// 叶子节点(无子节点)
+					&.is-leaf {
+						color: transparent;
+						display: none; // 也可以去掉
+					}
+				}
+			}
+
+		}
+
+		//右侧基本信息
+		&>div:nth-child(2) {
+			width: calc(100% - 240rem);
+			height: calc(100% - 0rem);
+			float: left;
+			margin-left: 10rem;
+			font-size: 14rem;
+			padding-top: 5rem;
+
+			table {
+				border-collapse: collapse;
+				margin: 0 auto;
+				text-align: center;
+				width: 100%;
+			}
+
+			table td,
+			table th {
+				// border: 1rem solid #ddd;
+				color: #fff;
+				height: 30rem;
+			}
+
+			table thead th {
+				background-color: rgb(28 59 112 / 100%);
+				border: 2rem solid #ddd;
+			}
+
+			table tr:nth-child(odd) {
+				background: rgb(40 89 172 / 60%);
+				border-left: 2rem solid #ddd;
+				border-right: 2rem solid #ddd;
+				border-bottom: 1rem solid #ddd;
+			}
+
+			table tr:nth-child(even) {
+				background: rgb(28 59 112 / 60%);
+				border-left: 2rem solid #ddd;
+				border-right: 2rem solid #ddd;
+				border-bottom: 1rem solid #ddd;
+			}
+
+			// thead 表头固定,tbody 滚动
+			table>thead>tr {
+				display: table;
+				width: 100%;
+				table-layout: fixed;
+			}
+
+			table>tbody {
+				display: block;
+				height: 340rem;
+				/* 隐藏水平溢出内容 */
+				overflow-x: hidden;
+				/* 当垂直内容超出显示高度时以滚动条形式展示 */
+				overflow-y: auto;
+			}
+
+			table>tbody>tr {
+				/* 将tr设置为table元素,以此达到内容沾满table的效果 */
+				display: table;
+				/* 将tr宽度设置为100%,以此达到内容沾满table的效果 */
+				width: 100%;
+				/* 设置table-layout为fixed以达到首行和内容行对其的效果 */
+				table-layout: fixed;
+			}
+
+			table>tbody>tr>td {
+				border-right: 2rem solid #ddd;
+			}
+		}
+	}
+</style>

+ 401 - 0
src/views/Map3d - 副本 (2)/components/special-effects.vue

@@ -0,0 +1,401 @@
+<script setup>
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-weather-effects">
+		<el-collapse v-model="activeName" accordion>
+			<el-collapse-item name="特效效果">
+				<template #title>
+					<span class='iconfont icon-tianqizitiku43' />天气特效
+				</template>
+				<el-row :gutter="20">
+					<el-col :span="8" v-for="(item,index) in weather" @click="handleWeatherEffects(item.type,index)">
+						<el-avatar shape="circle" style="width:70rem;height: 70rem;" :class="currentIndex===index?'selectStyle':'defaultStyle'">
+							<i :class="[item.icon,currentIndex===index?'selectFontStyle':'']" />
+						</el-avatar>
+						<div style="margin-top: 5rem; font-size: 14rem;" :class="currentIndex===index?'selectFontStyle':''">{{item.label}}</div>
+					</el-col>
+				</el-row>
+			</el-collapse-item>
+			<el-collapse-item name="天空样式">
+				<template #title>
+					<span class='iconfont icon-tianqizitiku43' />天空样式
+				</template>
+				<el-row :gutter="20">
+					<el-col :span="8" v-for="(item,index) in skybox" @click="handleSkybox(item.type,index)">
+						<!-- <el-avatar :src="item.url" /> -->
+						<el-avatar shape="circle" src="https://empty" style="width:70rem;height: 70rem;">
+							<img :src="item.url" />
+						</el-avatar>
+						<div style="margin-top: 5rem; font-size: 14rem;" :class="currentIndex===index?'selectFontStyle':''">{{item.label}}</div>
+					</el-col>
+				</el-row>
+			</el-collapse-item>
+			<!-- <el-collapse-item name="粒子效果">
+				<template #title>
+					<span class='iconfont icon-tianqizitiku43' />粒子效果
+				</template>
+				<div class="el-collapse-item__content">
+					<el-button color="rgb(20 136 255)" @click="ParticleSystem('add')">加载粒子效果</el-button>
+					<el-button color="rgb(255 100 100)" @click="ParticleSystem('remove')"><span style="color: #fff;">清除粒子效果</span></el-button>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="热力图">
+				<template #title>
+					<span class='iconfont icon-tianqizitiku43' />热力图
+				</template>
+				<div class="el-collapse-item__content">
+					<el-button color="rgb(20 136 255)" @click="HeatMap('add')">添加热力图</el-button>
+					<el-button color="rgb(255 100 100)" @click="HeatMap('remove')"><span style="color: #fff;">清除热力图</span></el-button>
+				</div>
+			</el-collapse-item> -->
+		</el-collapse>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+
+	export default {
+		data() {
+			return {
+				activeName: "特效效果",
+				currentIndex: -1,
+				weather: [{
+						label: '雨天',
+						type: 'rain',
+						number: 0,
+						icon: 'iconfont icon-yu'
+					},
+					{
+						label: '雪天',
+						type: 'snow',
+						number: 1,
+						icon: 'iconfont icon-huaban'
+					},
+					{
+						label: '雾天',
+						type: 'fog',
+						number: 2,
+						icon: 'iconfont icon-tianqizitiku43'
+					},
+					{
+						label: '关闭天气',
+						type: 'remove',
+						number: 3,
+						icon: 'iconfont icon-cloudofftianqiguanbi'
+					},
+				],
+				skybox: [{
+						label: '晚霞',
+						type: '晚霞',
+						number: 0,
+						url: 'jt3dSDK/imgs/skybox/01/py.png'
+					},
+					{
+						label: '蓝天',
+						type: '蓝天',
+						number: 1,
+						url: 'jt3dSDK/imgs/skybox/03/py.jpg'
+					},
+					{
+						label: '阴天',
+						type: '阴天',
+						number: 2,
+						url: 'jt3dSDK/imgs/skybox/02/py.jpg'
+					},
+					{
+						label: '蓝色星空',
+						type: '蓝色星空',
+						number: 3,
+						url: 'jt3dSDK/imgs/skybox/05/pz.jpg'
+					},
+					{
+						label: '紫色星空',
+						type: '紫色星空',
+						number: 4,
+						url: 'jt3dSDK/imgs/skybox/04/ny.jpg'
+					},
+				],
+			}
+		},
+		props: {},
+		watch: {},
+
+		/* 方法 */
+		methods: {
+			/**
+			 * 天空盒子事件
+			 * @param {Object} type 天空盒子类型
+			 * @param {Object} index 第几个被选中
+			 */
+			handleSkybox(type, index) {
+				this.currentIndex = index;
+
+				jt3d.SceneEffects.SkyBox.setGroundSkyBox({
+					type: type
+				});
+			},
+
+			/**
+			 * 天气特效事件
+			 * @param {Object} type 天气类型
+			 * @param {Object} index 第几个被选中
+			 */
+			handleWeatherEffects(type, index) {
+				this.currentIndex = index;
+				switch (type) {
+					case "rain": //雨天
+						jt3d.SceneEffects.Weather.removeEffect();
+						jt3d.SceneEffects.Weather.addRainEffect({
+							tiltAngle: 0.3,
+							rainSize: 0.5,
+							rainSpeed: 70
+						});
+						break;
+					case "snow": //雪天
+						jt3d.SceneEffects.Weather.removeEffect();
+						jt3d.SceneEffects.Weather.addSnowEffect();
+						break;
+					case "fog": //雾天
+						jt3d.SceneEffects.Weather.removeEffect();
+						jt3d.SceneEffects.Weather.addFogEffect();
+						break;
+					case "remove": //移除天气特效
+						this.currentIndex = -1;
+						jt3d.SceneEffects.Weather.removeEffect()
+						break;
+
+				}
+			},
+
+			/**
+			 * 粒子效果
+			 */
+			ParticleSystem(type) {
+				let options = {};
+				// 初始化参数默认值
+				options.duration = Cesium.defaultValue(options.duration, 2);
+				options.heading = Cesium.defaultValue(options.heading, 0.5); //指向,默认值0.0(北)
+				options.pitch = Cesium.defaultValue(options.pitch, -40); //俯仰角, 垂直向下。默认值-90(向下看)。
+				options.range = Cesium.defaultValue(options.range, 150); //距目标点距离
+
+				const position = {
+					x: 121.554042,
+					y: 37.395186,
+					z: 25.60
+				};
+
+				// 定位到点
+				let flyToPoint = jt3d.LocateUtil.flyToPoint({
+					longitude: position.x,
+					latitude: position.y,
+					height: position.z,
+					duration: options.duration,
+					heading: options.heading,
+					pitch: options.pitch,
+					range: options.range,
+				});
+				flyToPoint.then(function() {
+					// alert(1111)
+				});
+
+				if (type === "add") {
+
+					const positionF = {
+						x: 121.554042,
+						y: 37.395186,
+						z: 25.60
+					};
+
+					this.fireArr = [];
+					this.waterArr = [];
+
+					let fireEntity = jt3d.SceneEffects.ParticleSystem.createParticleFire([positionF.x, positionF.y, positionF.z])
+					this.fireArr.push(fireEntity)
+
+					const positionW = {
+						x: 121.553975,
+						y: 37.395075,
+						z: 18.10
+					};
+
+					let waterEntity = jt3d.SceneEffects.ParticleSystem.createParticleWater([positionW.x, positionW.y, positionW.z])
+					this.waterArr.push(waterEntity)
+
+				}
+				if (type === "remove") {
+					for (var i = 0; i < this.fireArr.length; i++) {
+						this.fireArr[i].remove()
+					}
+					for (var i = 0; i < this.waterArr.length; i++) {
+						this.waterArr[i].remove()
+					}
+				}
+			},
+
+			/**
+			 * 热力图
+			 */
+			HeatMap(type) {
+
+				if (type === "add") {
+					let viewer = this.viewer = window["viewer"];
+
+					// 矩形坐标
+					var bounds = {
+						west: 121.563298,
+						south: 37.284514,
+						east: 121.565298,
+						north: 37.286514,
+					};
+
+					// 初始化CesiumHeatmap
+					var heatMap = this.heatMap = CesiumHeatmap.create(
+						viewer, // 视图层
+						bounds, // 矩形坐标
+						// heatmap相应参数
+						{
+							backgroundColor: "rgba(0, 0, 0, 0)",
+							radius: 50,
+							maxOpacity: .5,
+							minOpacity: 0,
+							blur: .75
+						}
+					);
+
+					//加载数据,生成热力图
+					// 添加数据 最小值,最大值,数据集
+					heatMap.setWGS84Data(0, 100, getData(300));
+					viewer.zoomTo(viewer.entities);
+
+					if (this._layer) {
+						//移除热力图
+						this.viewer.entities.remove(this.heatMap._layer);
+					} else {
+						this._layer = this.heatMap._layer;
+					}
+
+					// 数据格式:动态数据 [{x: -97.6433525165054, y: 45.61443064377248, value: 11.409122369106317}]
+					function getData(length) {
+						var data = [];
+						for (var i = 0; i < length; i++) {
+							var x = 121.563298 + Math.random() * (121.565298 - 121.563298);
+							var y = 37.284514 + Math.random() * (37.286514 - 37.284514);
+							var value = Math.random() * 100;
+							data.push({
+								x: x,
+								y: y,
+								value: value
+							});
+						}
+						return data;
+					}
+				}
+				if (type === "remove") {
+
+					//移除热力图
+					this.viewer.entities.remove(this.heatMap._layer);
+				}
+			}
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.el-avatar{
+		width: 70rem !important;
+		height: 70rem !important;
+		font-size: 14px !important;
+		cursor: pointer;
+	}
+	
+	::v-deep .el-collapse-item__content {
+		padding: 10rem;
+		// padding-bottom: 0rem;
+		overflow-y: hidden;
+	}
+
+	::v-deep .el-collapse-item__header {
+		background: url(@/assets/images/bg_collapse_title.png) no-repeat;
+		background-size: 350rem 40rem;
+		// background-color: rgb(22 90 190);
+		// background-color: rgb(5 45 100 /60%);
+		background-color: rgb(30 130 255);
+		border-bottom: 0;
+	}
+
+	.el-col {
+		padding: 10rem;
+		// color: rgba(90, 172, 255, 1.0);
+		color: #fff;
+	}
+
+	.jt-weather-effects {
+		position: relative;
+
+		.iconfont {
+			padding: 0 10rem;
+		}
+
+		.el-collapse {
+			--el-collapse-border-color: rgb(0 44 126 / 0%);
+
+			--el-collapse-header-text-color: #ffffff;
+			--el-collapse-header-font-size: 13rem;
+			--el-collapse-content-bg-color: rgb(0 44 126 / 0%);
+			--el-collapse-content-font-size: 13rem;
+			--el-collapse-content-text-color: rgb(216 240 255);
+
+			--el-collapse-header-height: 40rem;
+			--el-collapse-header-bg-color: rgb(30 130 255);
+
+			--el-fill-color-blank: rgb(0 44 126 / 68%);
+			--el-text-color-regular: rgb(216 240 255);
+			--el-border-color: rgb(35 135 255);
+
+			.el-collapse-item__content {
+				padding: 10rem;
+				// padding-bottom: 0rem;
+			}
+		}
+
+		i {
+			display: inline-block;
+			width: 100%;
+			height: 36rem;
+			line-height: 36rem;
+			text-align: center;
+			border-radius: 5rem;
+			font-size: 40rem;
+			// color: rgba(90, 172, 255, 1.0);
+			color: #fff;
+			transition: all .3s;
+			-webkit-transition: all .3s
+		}
+
+		.selectStyle {
+			// background: rgba(135, 182, 254, 0.5);
+			background: rgb(0 44 126);
+		}
+
+		.defaultStyle {
+			background: #ffffff00;
+		}
+
+		.selectFontStyle {
+			// color: #fff;
+			color: #55ffff;
+		}
+	}
+</style>

+ 234 - 0
src/views/Map3d - 副本 (2)/components/toolbars.vue

@@ -0,0 +1,234 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	/**
+	 * element-plus字体
+	 */
+	import {
+		ArrowDown
+	} from '@element-plus/icons-vue';
+
+	import {
+		inject
+	} from "vue";
+
+	import {
+		Store
+	} from '@/store/index'
+	store = Store()
+	
+	const getMapInstance = inject("getMapInstance");
+	let jt3d = getMapInstance();
+	
+	import * as mapWork from "../map"
+
+	import {
+		useWidget
+	} from "@/common/store/widget"
+
+
+	const {
+		activate
+	} = useWidget()
+
+	const showWidget = (widget) => {
+		//全图
+		if (widget === "fullMap") {
+			mapWork.fullMap(jt3d);
+		}
+		//绕点自旋
+		else if (widget === "rotateCamera") {
+			ElMessage.warning('在地图上单击进行自旋,再次单击停止自旋')
+			mapWork.setMapSpin(jt3d);
+		}
+		//清除所有
+		else if (widget === "clearAll") {
+
+		} else {
+			activate(widget)
+		}
+	}
+</script>
+
+<template>
+	<div class="jt-toolbars fadein-right">
+		<template v-for="(item, i) in toolDatas" :key="i">
+			<div v-if="item.router && !item.children" class="toolbar-item" @click="showWidget(item.router)">
+				<i :class="item.icon" />
+				<span class="title">{{ item.name }}</span>
+			</div>
+			<el-dropdown v-if="item.children && !item.router" class="toolbar-item">
+				<span class="el-dropdown-link">
+					<i :class="item.icon" />
+					<span class="title">{{ item.name }}</span>
+					<el-icon class="el-icon--right">
+						<ArrowDown />
+					</el-icon>
+				</span>
+				<template #dropdown>
+					<span slot="slot" class="text"></span>
+					<el-dropdown-menu>
+						<el-dropdown-item v-for="child in item.children" :title="child.name" @click="showWidget(child.router)">
+							<i :class="child.icon" />
+							<span>{{ child.name }}</span>
+						</el-dropdown-item>
+					</el-dropdown-menu>
+				</template>
+			</el-dropdown>
+		</template>
+	</div>
+</template>
+
+<script>
+	let store = undefined;
+	export default {
+		name: "jt-toolbars",
+		data() {
+			return {
+				// toolDatas:store.menuList,
+				toolDatas: [{
+						name: "绕点自旋",
+						icon: "iconfont icon-chaxunzuobiaozhi",
+						router: "rotateCamera"
+					},
+					{
+						name: "全图",
+						icon: "iconfont icon-chaxunzuobiaozhi",
+						router: "fullMap"
+					},
+					{
+						name: "底图",
+						icon: "iconfont icon-dituzuobiao",
+						router: "manage-basemap"
+					},
+					{
+						name: "图层",
+						icon: "iconfont icon-winfo-icon-tucengkongzhi",
+						router: "manage-layer"
+					},
+					{
+						name: "工具",
+						icon: "iconfont icon-xitong1",
+						children: [{
+								name: "卷帘对比",
+								icon: "iconfont maxsize icon-juanlian",
+								router: "map-split"
+							},
+							{
+								name: "分屏对比",
+								icon: "iconfont minsize icon-fenping",
+								router: "map-compare"
+							},
+							{
+								name: "地区导航",
+								icon: "iconfont icon-zhijiantou",
+								router: "location-region"
+							},
+							{
+								name: "视角标签",
+								icon: "iconfont icon-fushi",
+								router: "viewerlabel"
+							},
+						]
+					},
+					{
+						name: "清除",
+						icon: "iconfont icon-shanchu",
+						router: "clearAll"
+					},
+				]
+			}
+		},
+		/* 方法 */
+		methods: {},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.text::before {
+		position: absolute;
+		width: 0rem;
+		height: 0rem;
+		left: calc(50% - 5rem);
+		top: -5rem;
+		content: '';
+		transform: rotate(45deg);
+		z-index: 10;
+		box-sizing: border-box;
+		border-bottom: 5rem solid transparent;
+		border-right: 5rem solid transparent;
+		border-top: 5rem solid rgba(255, 255, 255, 1);
+		border-left: 5rem solid rgba(255, 255, 255, 1);
+		// background: rgba(5, 45, 115, .8) !important;
+	}
+
+	.jt-toolbars {
+		position: absolute;
+		top: 80rem;
+		width: auto;
+		right: 20rem;
+		cursor: pointer !important;
+		padding: 0rem 10rem !important;
+		margin: 0rem !important;
+		background-image: none !important;
+		border: 1rem solid;
+		border: none;
+		border-radius: 2rem !important;
+		background-color: rgb(0 44 126 / 65%);
+		height: 40rem;
+		box-sizing: border-box;
+		line-height: 38rem;
+		text-align: left;
+		user-select: none;
+
+		cursor: default;
+
+		.toolbar-item {
+			display: inline-block;
+			padding: 0rem 10rem;
+
+			margin: 0rem;
+			height: calc(100% - 4rem);
+			color: #fff;
+			font-size: 15rem;
+			vertical-align: middle;
+
+			&:hover {
+				background-color: rgba(255, 255, 255, 0.3);
+			}
+
+			.title {
+				font-size: 16rem;
+			}
+		}
+
+		.toolbar-item:nth-last-child(1) {
+			padding-right: 0rem;
+		}
+		
+		.iconfont{
+			margin-right: 5rem;
+		}
+
+		.el-icon {
+			margin-right: 5rem;
+			color: #fff;
+		}
+
+		.el-dropdown {
+			// vertical-align: middle;
+			height: 40rem;
+			line-height: 38rem;
+			box-sizing: border-box;
+		}
+	}
+</style>

+ 316 - 0
src/views/Map3d - 副本 (2)/components/viewerlabel.vue

@@ -0,0 +1,316 @@
+<script setup>
+	import {
+		inject
+	} from "vue";
+	import html2canvas from 'html2canvas';
+	import {Store} from '@/store/index';
+	store = Store()
+	import {
+		blobToBase64,
+		base64ToBlob
+	} from '@/assets/js/blobtobase64';
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="mainview">
+		<div class="header">
+			<input @input="getName()" id="inputValue" type="text" placeholder="创建视角标签" />
+			<el-button v-if="store.userport=='PC'" type="primary" @click="addviewer" size="small">添加</el-button>
+			<el-button type="primary" @click="searchviewer" size="small">查询</el-button>
+		</div>
+		<div class="middleviewer">
+			<div class="viewer" v-for="(res,index) in ImgurlList" :key="index">
+				<div class="viewertop">
+					<img :src="res.url" @click="flyto(res.info)">
+				</div>
+				<div class="viewerbottom">
+					{{res.name}}
+					<img src="@/assets/images/delete.png" class="deleteImg" @click="deleteviewer(res,index)" />
+				</div>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script>
+	let store = undefined;
+	let jt3d = undefined;
+	export default {
+		data() {
+			return {
+				viewersName: '', //视角标签名称
+				ImgurlList: [], //截图地址列表
+			}
+		},
+		methods: {
+			//获取输入框值
+			getName() {
+				this.viewersName = document.getElementById("inputValue").value;
+			},
+
+			//跳转方法
+			flyto(options) {
+				jt3d.LocateUtil.flyToPoint(options)
+			},
+
+			//删除方法,传keyvalue以及需要修改属性
+			deleteviewer(item, index) {
+				//删除对应数组内的对象
+				this.ImgurlList.splice(index, 1)
+				if (item.id) {
+					this.$http.get('/delete', {
+						tableName: 'map_angle',
+						keyValue: item.id,
+					}).then(res => {
+						console.log(res.data)
+					})
+				}
+			},
+
+			//添加视角标签,当前页存数组,向数据库传入相机参数
+			addviewer() {
+				//获取当前界面截图方法
+				html2canvas(
+					this.$parent.$parent.$refs.refMap3d.$refs.cesiumContainer, {
+						// backgroundColor: null, //画出来的图片有白色的边框,不要可设置背景为透明色(null)
+						useCORS: true, //支持图片跨域
+						scale: 1 / 8, //设置放大的倍数
+					}
+				).then(canvas => {
+					//截图用img元素承装,显示在页面的上
+					let url = canvas.toDataURL('image/png')
+					//经纬度、高度
+					// 获取 相机姿态信息
+					let heading = window["viewer"].scene.camera.heading
+					let pitch = window["viewer"].scene.camera.pitch
+					let roll = window["viewer"].scene.camera.roll
+					let position = window["viewer"].scene.camera.positionCartographic
+					let longitude = Cesium.Math.toDegrees(position.longitude) //y
+					let latitude = Cesium.Math.toDegrees(position.latitude) //x
+					let height = position.height
+					let info = {
+						latitude: latitude,
+						longitude: longitude,
+						height: height,
+						pitch: Cesium.Math.toDegrees(pitch),
+						roll: Cesium.Math.toDegrees(roll),
+						heading: Cesium.Math.toDegrees(heading)
+					}
+					//dom for循环渲染列表
+					this.ImgurlList.unshift({
+						url: url,
+						name: this.viewersName,
+						info: info
+					})
+
+					//base64转换为二进制文件
+					// let blob = base64ToBlob(url)
+					// //文件转为文件流
+					// let formData = new FormData();
+					// formData.append('file',blob)
+
+					let data = {
+						name: this.viewersName,
+						x: latitude,
+						y: longitude,
+						z: height,
+						pitch: Cesium.Math.toDegrees(pitch),
+						roll: Cesium.Math.toDegrees(roll),
+						heading: Cesium.Math.toDegrees(heading),
+						screenshot: url,
+						// screenshot: '',
+						userId: this.id,
+						// id:0
+					}
+
+					//添加数据接口
+					this.$http.post('/postSubmit', {
+						tableName: 'map_angle',
+						keyValue: '',
+						formData: data,
+					}).then(res => {
+						console.log(res)
+						if (res.success == true) {
+							console.log('添加成功')
+							document.getElementById("inputValue").value = ''
+						}
+					})
+				}).catch(err => {
+					console.log(err)
+				})
+			},
+			searchviewer() {
+				this.info = JSON.parse(localStorage.getItem('person'))
+				this.id = this.info.id
+				//获取所有图片数据
+				this.$http.get('/getTableList', {
+					tableName: 'map_angle', //
+					sqlWhere: "name like '%" + this.viewersName + "%'",
+					orderByField: ''
+				}).then(res => {
+					console.log('获取图片', res.data)
+					this.ImgurlList = [];
+					res.data.forEach(item => {
+						let info = {
+							latitude: item.x,
+							longitude: item.y,
+							height: item.z,
+							pitch: item.pitch,
+							roll: item.roll,
+							heading: item.heading
+						}
+						// let url = blobToBase64(item.screenshot)
+						//dom for循环渲染列表
+						this.ImgurlList.push({
+							url: item.screenshot,
+							name: item.name,
+							info: info,
+							id: item.id
+						})
+					})
+
+					// console.log('img列表',this.ImgurlList)
+				})
+			}
+		},
+
+		mounted() {
+			this.info = JSON.parse(localStorage.getItem('person'))
+			this.id = this.info.id
+			//获取所有图片数据
+			this.$http.get('/getTableList', {
+				tableName: 'map_angle', //
+				sqlWhere: '', //+ this.loginForm.id
+				orderByField: ''
+			}).then(res => {
+				console.log('获取图片', res.data)
+				if(res.data.length == 0) return
+				res.data.forEach(item => {
+					let info = {
+						latitude: item.x,
+						longitude: item.y,
+						height: item.z,
+						pitch: item.pitch,
+						roll: item.roll,
+						heading: item.heading
+					}
+					// let url = blobToBase64(item.screenshot)
+					//dom for循环渲染列表
+					this.ImgurlList.push({
+						url: item.screenshot,
+						name: item.name,
+						info: info,
+						id: item.id
+					})
+				})
+
+				// console.log('img列表',this.ImgurlList)
+			})
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.el-button--small{
+		--el-button-size:24rem;
+		font-size:12rem;
+		padding: 5rem 12rem;
+	}
+	
+	.mainview {
+		width: 100%;
+		height: 100%;
+
+		.header {
+			width: 100%;
+			display: flex;
+
+			input,
+			input:focus {
+				outline: none;
+				width: 185rem !important;
+				border: 1rem solid rgba(255, 255, 255, 0.8);
+				margin-right: 10rem;
+				height: 26rem !important;
+				color: rgba(255, 255, 255, 1);
+				background-color: rgba(255, 255, 255, 0) !important;
+				border-radius: 3rem;
+			}
+		}
+
+		.middleviewer {
+			width: 322rem;
+			height: 100%;
+			margin-left: 7rem;
+
+			.viewer {
+				width: 322rem !important;
+				height: 240rem !important;
+				margin-top: 15rem;
+				border: 1rem solid #ffffff !important;
+				border-radius: 1rem !important;
+
+				.viewertop {
+					width: 322rem !important;
+					height: 210rem !important;
+
+					img {
+						width: 100% !important;
+						height: 100% !important;
+					}
+				}
+
+				.viewerbottom {
+					line-height: 30rem !important;
+					text-align: center !important;
+					width: 322rem !important;
+					height: 30rem !important;
+					position: relative;
+					background-color: rgba(15, 145, 185, 0.7);
+
+					.deleteImg {
+						width: 24rem;
+						height: 24rem;
+						right: 5rem;
+						top: 3rem;
+						position: absolute;
+					}
+				}
+			}
+		}
+	}
+
+	::v-deep .el-input {
+		flex-grow: 0 !important;
+		width: 200rem !important;
+		// display: inline !important;
+		// margin-left: 5rem;
+		margin-right: 10rem;
+		height: 30rem !important;
+	}
+
+	//输入框文字颜色
+	::v-deep .el-input__inner {
+		color: rgba(255, 255, 255, 1)
+	}
+
+	//输入框背景色
+	::v-deep .el-input__wrapper {
+		background-color: rgba(255, 255, 255, 0) !important;
+	}
+
+	::v-deep .el-button {
+		border-radius: 3rem !important;
+
+	}
+
+	::v-deep .el-button--primary {
+		background-color: rgba(64, 158, 255, 0.6) !important;
+	}
+
+	::-webkit-scrollbar {
+		width: 0rem;
+	}
+</style>

+ 1167 - 0
src/views/Map3d - 副本 (2)/map.js

@@ -0,0 +1,1167 @@
+import {
+	Store
+} from '@/store/index'
+let store = Store();
+
+// import * as jt3dSDK from '/public/jt3dSDK/jt3d.es.js';
+
+import map_xzqh_zj from '@/assets/dataFile/map_xzqh_zj.json';
+
+let jtMap3d = undefined; // 地图对象
+
+/**
+ * 初始化地图业务,生命周期钩子函数(必须)
+ * 框架在地图初始化完成后自动调用该函数
+ * @param  mapInstance 地图对象
+ */
+export function onMounted(mapInstance) {
+	jtMap3d = mapInstance // 记录首次创建的map
+
+	debugger
+}
+
+export function getLayers() {
+  let _self = this;
+  debugger
+  
+  	//获取地图图集id
+  	let roleId = store.roleId
+  	let atlasLayersSqlWhere = '"roleId"' + " = " + roleId + " "
+  
+  	//获取图集
+  	_self.$http.get('/getTableList', {
+  		tableName: 'sys_map_atlas_layers', //表名
+  		sqlWhere: atlasLayersSqlWhere, //
+  		orderByField: ''
+  	}).then(res => {
+  
+  		store.layersList = res.data;
+  		res.data.forEach((item, index) => {
+  
+  			if (item.atlastype === '图层') {
+  				_self.layers.push(item);
+  
+  				if (item.isinit === '1') {
+  					mapWork.setLayersControl(window.viewer, item, true);
+  				}
+  			}
+  
+  			if (item.atlastype === '底图') {
+  				_self.basemaps.push(item);
+  
+  				if (item.layertype === '地形') {
+  					// store.terrain.terrainData = item;
+  
+  					if (item.isinit === '1') {
+  						// store.terrain.isTerrain = true;
+  						//默认加载的地形
+  						mapWork.setLayersControl(window.viewer, item, true);
+  					}
+  				} else if (item.layertype === '标注') {
+  					// store.mark.markData = item;
+  
+  					if (item.isinit === '1') {
+  						// store.mark.isMark = true;
+  
+  						//默认加载的标注
+  						mapWork.setLayersControl(window.viewer, item, true);
+  					}
+  				} else {
+  					if (item.isinit === '1') {
+  						// store.basemap.basemapData = item;
+  						// store.basemap.selectImg = item.layerorder;
+  
+  						//默认加载的底图
+  						mapWork.setLayersControl(window.viewer, item, true);
+  					}
+  				}
+  			}
+  		})
+  
+  		// store.layers = _self.layers;
+  		// store.basemaps = _self.basemaps;
+  	});
+}
+
+/**
+ * 单击事件
+ */
+export function clickEntity(jt3d) {
+
+	if (jt3d.handlerLeftClick) {
+		jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); //移除事件
+	}
+
+	jt3d.handlerLeftClick = new Cesium.ScreenSpaceEventHandler(
+		jt3d._viewer.scene.canvas
+	);
+	//注册大球单机事件
+	jt3d.handlerLeftClick.setInputAction(function(e) {
+		var pick = jt3d._viewer.scene.pick(e.position); //拾取当前的entity对象
+		var cartesian = jt3d._viewer.scene.pickPosition(e.position); //获取当前点坐标
+		if (Cesium.defined(cartesian)) {
+			//将笛卡尔坐标转换为地理坐标
+			let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
+			//将弧度转为度的十进制度表示
+			let lng = Cesium.Math.toDegrees(cartographic.longitude);
+			let lat = Cesium.Math.toDegrees(cartographic.latitude);
+			let alt = cartographic.height; //高度
+
+			initQuery({
+				spatialType: '点',
+				coordinate: lng + " " + lat,
+				buffer: ''
+			});
+		}
+	}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+}
+
+
+/**
+ * 设置默认视图-初始化中国区域范围视角
+ */
+export function setView(jt3d) {
+	// jt3d.flytoChina();
+
+	//初始化中国区域范围视角
+	jt3d.setViewChina();
+
+	// jt3d.setView({
+	// 	longitude: 103.84, //经度
+	// 	latitude: 31.15, // 维度
+	// 	height: 24000000, // 高度
+	// 	heading: 0, // 偏航
+	// 	pitch: -90, // 俯仰,人如果在赤道上空,俯仰角为0可见地球。如果在北纬,俯仰角为负才能见地球
+	// 	roll: 0.0 // 翻滚
+	// });
+}
+
+/**
+ * 全图-飞行到项目区域范围视角
+ */
+export function fullMap(jt3d) {
+	// 初始化项目区域范围视角
+	let optionsS = {
+		west: 121.563298,
+		south: 37.284514,
+		east: 121.565298,
+		north: 37.286514,
+		isRemove: false, //定位完成后是否删除
+		duration: 3, //飞行时间
+		heading: 0,
+		pitch: -90,
+		range: 115000
+	};
+
+	let optionsE = {
+		west: 121.563298,
+		south: 37.284514,
+		east: 121.565298,
+		north: 37.286514,
+		isRemove: true, //定位完成后是否删除
+		duration: 3, //飞行时间
+		heading: 0,
+		pitch: -60,
+		range: 115000
+	};
+
+	var fullMapPromise = jt3d.fullMap(optionsS);
+	fullMapPromise.then(function(flyPromise) {
+		jt3d.fullMap(optionsE);
+	});
+}
+
+/**
+ * 设置天空盒子
+ */
+export function addSkybox(jt3d) {
+	//设置天空盒子,默认蓝天
+	let SceneEffects = new jt3dSDK.SceneEffects.SkyBox(window.viewer);
+	SceneEffects.setGroundSkyBox();
+}
+
+/**
+ * 添加镇街边界线——精灵线
+ */
+export function addBoundaryLine(jt3d) {
+	let PolylineObject = new jt3dSDK.PolylineObject(jt3d._viewer);
+	PolylineObject.drawPolylineByGeoJson(map_xzqh_zj, {
+		width: 5,
+		color: '#04FFFF',
+		isImageAlpha: true, //用图片自带颜色
+		duration: 3000,
+		imgUrl: "jt3dSDK/imgs/polylinematerial/spriteline1.png"
+	});
+}
+
+/**
+ * 控制地图服务的显示及隐藏
+ * @param {Object} data 传递给 data 属性的数组中该节点所对应的对象
+ * @param {Object} checked 节点本身是否被选中
+ */
+export function setLayersControl(viewer, data, checked) {
+
+	let layer = new jt3dSDK.layer(viewer);
+	var imageryLayers = viewer.imageryLayers;
+
+	let _serviceId = store.serviceMark + "_" + data.layercode + data.layerorder;
+	let layername = data.layername;
+
+	//透明度
+	let _opacity = null;
+	if (data.opacity == null) {
+		_opacity = 1;
+	} else {
+		_opacity = Number(data.opacity);
+		data.opacity = _opacity;
+
+		if (_opacity == 0) {
+			_opacity = 1;
+		}
+	}
+
+	//参数集
+	let parameterset = data.parameterset;
+	if (data.parameterset instanceof Object) {
+		parameterset = data.parameterset;
+	} else if (data.parameterset != "" && data.parameterset != null && data.parameterset != undefined) {
+		parameterset = JSON.parse(data.parameterset);
+	}
+
+	return new Promise((resolve, reject) => {
+		switch (data.loadtype) {
+			case "GeoJsonPoint": //GeoJsonPoint
+				if (checked) {
+					data.isinit = '1';
+
+					//设置参数
+					let _options = {
+						id: _serviceId,
+						url: data.datasource,
+					}
+
+					if (parameterset) {
+						if (parameterset.billboard instanceof Object) {
+							let billboard = parameterset.billboard;
+							_options.billboard = billboard;
+						}
+
+						if (parameterset.label instanceof Object) {
+							let label = parameterset.label;
+							_options.label = label;
+						}
+					}
+
+					layer.addBillboardByJson(_options, function(serviceId) {
+						resolve(true);
+					});
+
+				} else {
+					layer.removeDataSources({
+						serviceId: _serviceId,
+					}).then(res => {
+						data.isinit = '0';
+						resolve(true);
+					});
+				}
+				break;
+			case "GeoJsonPolyline": //GeoJsonPolyline
+				if (checked) {
+					data.isinit = '1';
+
+					//设置参数
+					let _options = {
+						id: _serviceId,
+						url: data.datasource,
+					}
+
+					if (parameterset) {
+
+						if (parameterset.clampToGround) { //是否贴地
+							_options.clampToGround = parameterset.clampToGround;
+						}
+						if (parameterset.isImageAlpha) { //是否采用图片颜色
+							_options.isImageAlpha = parameterset.isImageAlpha;
+						}
+						if (parameterset.imgUrl) { //精灵线图片
+							_options.imgUrl = parameterset.imgUrl;
+						}
+						if (parameterset.color) { //指定线的颜色
+							_options.color = parameterset.color;
+						}
+						if (parameterset.width) { //线宽
+							_options.width = parameterset.width;
+						}
+						if (parameterset.duration) { //持续时间 毫秒,越小越快
+							_options.duration = parameterset.duration;
+						}
+						if (parameterset.count) { //重复次数
+							_options.count = parameterset.count;
+						}
+						if (parameterset
+							.direction) { //direction=vertical 纵,order='-'(由下到上) , '+"(由上到下)
+							_options.direction = parameterset.direction;
+						}
+						if (parameterset
+							.order) { //direction=horizontal 横,order='-'(顺时针) , '+'(逆时针)
+							_options.order = parameterset.order;
+						}
+					}
+
+					layer.addPolylineByGeoJson(_options, function(serviceId) {
+						resolve(true);
+					});
+				} else {
+					layer.removeDataSources({
+						serviceId: _serviceId,
+					}).then(res => {
+						data.isinit = '0';
+						resolve(true);
+					});
+				}
+				break;
+			case "GeoJsonWall": //GeoJson Wall
+				if (checked) {
+
+					//设置参数
+					let _options = {
+						id: _serviceId,
+						url: data.datasource,
+					}
+
+					if (parameterset) {
+
+						if (parameterset.clampToGround) { //是否贴地
+							_options.clampToGround = parameterset.clampToGround;
+						}
+						if (parameterset.minimunHeights) { //最低高度
+							_options.minimunHeights = parameterset.minimunHeights;
+						}
+						if (parameterset.maximumHeights) { //最高高度
+							_options.maximumHeights = parameterset.maximumHeights;
+						}
+						if (parameterset.color) { //指定墙体的颜色
+							_options.color = parameterset.color;
+						}
+						if (parameterset.trailImage) { //墙体图片
+							_options.trailImage = parameterset.trailImage;
+						}
+						if (parameterset.duration) { //持续时间 毫秒,越小越快
+							_options.duration = parameterset.duration;
+						}
+						if (parameterset.count) { //重复次数
+							_options.count = parameterset.count;
+						}
+						if (parameterset.direction) { //direction=vertical 纵,order='-'(由下到上) , '+"(由上到下)
+							_options.direction = parameterset.direction;
+						}
+						if (parameterset.order) { //direction=horizontal 横,order='-'(顺时针) , '+'(逆时针)
+							_options.order = parameterset.order;
+						}
+					}
+
+					// .json文件需要放到public文件夹下,直接调用,
+					layer.addWallByJson(_options, function(serviceId) {
+						resolve(true);
+					});
+				} else {
+					layer.removeDataSources({
+						serviceId: _serviceId,
+					}).then(res => {
+						data.isinit = '0';
+						resolve(true);
+					});
+				}
+				break;
+			case "entitiesGltf": //gltf/glb
+				if (checked) {
+					data.isinit = '1';
+
+					//设置参数
+					let _options = {
+						id: _serviceId,
+						url: data.datasource,
+						points: [],
+					}
+
+					if (parameterset) {
+						if (parameterset.points) { //模型位置
+							_options.points = parameterset.points;
+
+							if (parameterset.minimumPixelSize) { //模型最小刻度
+								_options.minimumPixelSize = parameterset.minimumPixelSize;
+							}
+							if (parameterset.maximumScale) { //模型的最大比例尺大小,设置模型最大放大大小
+								_options.maximumScale = parameterset.maximumScale;
+							}
+							if (parameterset.silhouetteColor) { //模型轮廓颜色
+								_options.silhouetteColor = parameterset.silhouetteColor;
+							}
+							if (parameterset.alpha) { //模型透明度
+								_options.alpha = parameterset.alpha;
+							}
+							if (parameterset.heading) { //以弧度为单位的航向分量
+								_options.heading = parameterset.heading;
+							}
+							if (parameterset.pitch) { //以弧度为单位的航向分量
+								_options.pitch = parameterset.pitch;
+							}
+							if (parameterset.roll) { //以弧度为单位的滚动分量
+								_options.roll = parameterset.roll;
+							}
+
+							layer.addEntitiesGltf(_options, function(serviceId) {
+
+								resolve(true);
+							});
+
+						} else {
+							ElMessage("请检测图层表parameterset字段是否设置points");
+						}
+					} else {
+						ElMessage("请检测图层表parameterset字段是否设置points");
+					}
+				} else {
+					layer.removeEntity({
+						serviceId: _serviceId,
+					}).then(res => {
+						data.isinit = '0';
+						resolve(true);
+					});
+				}
+				break;
+			case "scenePrimitivesGltf": //加载gltf/glb
+				if (checked) {
+					data.isinit = '1';
+
+					//设置参数
+					let _options = {
+						id: _serviceId,
+						url: data.datasource,
+						points: [],
+					}
+
+					if (parameterset) {
+						if (parameterset.points) { //模型位置
+							_options.points = parameterset.points;
+
+							if (parameterset.scale) { //放大倍数
+								_options.scale = parameterset.scale;
+							}
+
+							layer.addScenePrimitivesGltf(_options, function(serviceId) {
+
+								resolve(true);
+							});
+
+						} else {
+							ElMessage("请检测图层表parameterset字段是否设置points");
+						}
+					} else {
+						ElMessage("请检测图层表parameterset字段是否设置points");
+					}
+				} else {
+					layer.removeScenePrimitives({
+						serviceId: _serviceId,
+					}).then(res => {
+						data.isinit = '0';
+						resolve(true);
+					});
+				}
+				break;
+			case "PolygonImageMaterial": //图片材质
+				if (checked) {
+					data.isinit = '1';
+
+					if (parameterset) {
+						if (parameterset.points) {
+							layer.addPolygonImageMaterial({
+								id: _serviceId,
+								points: parameterset.points,
+								url: data.datasource,
+								alpha: _opacity
+							}, function(serviceId) {
+								resolve(true);
+							});
+						} else {
+							ElMessage("请检测图层表parameterset字段是否设置points");
+						}
+					} else {
+						ElMessage("请检测图层表parameterset字段是否设置points");
+					}
+				} else {
+					layer.removeEntity({
+						serviceId: _serviceId,
+					}).then(res => {
+						data.isinit = '0';
+						resolve(true);
+					});
+				}
+				break;
+			case "CrImageServerLayer": //贴地所有地形、模型的规划图、网格地图
+
+				if (checked) {
+					data.isinit = '1';
+
+					let floatLayer = new jt3dSDK.CrImageServerLayer({
+						viewer: viewer,
+						url: data.datasource,
+						opacity: _opacity,
+						show: true
+					});
+					window[_serviceId] = floatLayer;
+					//添加网格地图
+					// window[_serviceId].show();
+					resolve(true);
+				} else {
+					window[_serviceId].hide();
+					data.isinit = '0';
+					resolve(true);
+				}
+				break;
+			case "DEM": //地形服务(DEM)
+				if (checked) {
+					data.isinit = '1';
+
+					//设置参数
+					let _options = {
+						url: data.datasource,
+					}
+					if (parameterset) {
+						if (parameterset.terrainExaggeration) { //地形夸张系数
+							_options.terrainExaggeration = parameterset.terrainExaggeration;
+						}
+					}
+					layer.addTerrain(_options);
+					resolve(true);
+				} else {
+					layer.removeTerrain().then(res => {
+						data.isinit = '0';
+						resolve(true);
+					});
+				}
+				break;
+			case "UrlTemplateImageryProvider": //加载URL模板服务
+				if (checked) {
+					data.isinit = '1';
+
+					//设置参数
+					let _options = {
+						id: _serviceId,
+						url: data.datasource,
+						alpha: _opacity
+					}
+					if (parameterset) {
+						if (parameterset.CRS) { //坐标系
+							_options.CRS = parameterset.CRS;
+						}
+						if (parameterset.minimumLevel) { //最小层级
+							_options.minimumLevel = parameterset.minimumLevel;
+						}
+						if (parameterset.maximumLevel) { //最大层级
+							_options.maximumLevel = parameterset.maximumLevel;
+						}
+					}
+
+					//加载服务
+					layer.addUrlTemplateImagery(_options, function(serviceId) {
+						//重置图层顺序
+						setLayerNumber(imageryLayers, data, serviceId)
+						resolve(true);
+					});
+				} else {
+					layer.removeImageryProvider({
+						serviceId: _serviceId
+					}).then(res => {
+						data.isinit = '0';
+						resolve(true);
+					});
+				}
+
+				break;
+			case "WebMapTileServiceImageryProvider": // WMTS地图服务
+				if (checked) {
+					data.isinit = '1';
+
+					//设置参数
+					let _options = {
+						id: _serviceId,
+						url: data.datasource,
+						layers: 'cia',
+						style: 'default',
+						tileMatrixSetID: 'w',
+						alpha: _opacity
+					}
+					if (parameterset) {
+						if (parameterset.layers) { //WMTS请求的层名
+							_options.layers = parameterset.layers;
+
+							if (parameterset.style) { //WMTS请求的样式名
+								_options.style = parameterset.style;
+
+								if (parameterset.tileMatrixSetID) { //用于WMTS请求的TileMatrixSet的标识符
+									_options.tileMatrixSetID = parameterset.tileMatrixSetID;
+
+									if (parameterset.minimumLevel) { //最小层级
+										_options.minimumLevel = parameterset.minimumLevel;
+									}
+									if (parameterset.maximumLevel) { //最大层级
+										_options.maximumLevel = parameterset.maximumLevel;
+									}
+
+									layer.addWebMapTileService(_options, function(serviceId) {
+
+										//重置图层顺序
+										setLayerNumber(imageryLayers, data, serviceId)
+										resolve(true);
+									});
+
+								} else {
+									ElMessage("请检测图层表parameterset字段是否设置tileMatrixSetID");
+								}
+
+							} else {
+								ElMessage("请检测图层表parameterset字段是否设置style");
+							}
+
+						} else {
+							ElMessage("请检测图层表parameterset字段是否设置layers");
+						}
+					} else {
+						ElMessage("请检测图层表parameterset字段是否设置layers,style,tileMatrixSetID");
+					}
+
+				} else {
+					layer.removeImageryProvider({
+						serviceId: _serviceId
+					}).then(res => {
+						data.isinit = '0';
+						resolve(true);
+					});
+				}
+				break;
+			case "WebMapServiceImageryProvider": //WMS地图服务
+				if (checked) {
+					data.isinit = '1';
+
+					//设置参数
+					let _options = {
+						id: _serviceId,
+						url: data.datasource,
+						alpha: _opacity
+					}
+					if (parameterset) {
+						if (parameterset.layers) { //WMTS请求的层名
+							_options.layers = parameterset.layers;
+
+							if (parameterset.minimumLevel) { //最小层级
+								_options.minimumLevel = parameterset.minimumLevel;
+							}
+							if (parameterset.maximumLevel) { //最大层级
+								_options.maximumLevel = parameterset.maximumLevel;
+							}
+
+							layer.addWebMapService(_options, function(serviceId) {
+
+								//重置图层顺序
+								setLayerNumber(imageryLayers, data, serviceId)
+								resolve(true);
+							});
+						} else {
+							ElMessage("请检测图层表parameterset字段是否设置layers");
+						}
+					} else {
+						ElMessage("请检测图层表parameterset字段是否设置layers");
+					}
+				} else {
+					layer.removeImageryProvider({
+						serviceId: _serviceId
+					}).then(res => {
+						data.isinit = '0';
+						resolve(true);
+					});
+				}
+				break;
+			case "ArcGisMapServerImageryProvider": // ArcGIS Online和Server的相关服务
+				if (checked) {
+					data.isinit = '1';
+
+					//设置参数
+					let _options = {
+						id: _serviceId,
+						url: data.datasource,
+						alpha: _opacity
+					}
+					if (parameterset) {
+						if (parameterset.layers) {
+							_options.layers = parameterset.layers;
+						}
+					}
+
+					//加载服务
+					layer.addArcGisMapServer(_options, function(serviceId) {
+
+						//重置图层顺序
+						setLayerNumber(imageryLayers, data, serviceId)
+						resolve(true);
+					})
+				} else {
+					layer.removeImageryProvider({
+						serviceId: _serviceId
+					}).then(res => {
+						data.isinit = '0';
+						resolve(true);
+					});
+				}
+				break;
+			case "TileMapServiceImageryProvider": // 2.5维度地图
+				if (checked) {
+					data.isinit = '1';
+
+					//设置参数
+					let _options = {
+						id: _serviceId,
+						url: data.datasource,
+						alpha: _opacity
+					}
+					if (parameterset) {
+						if (parameterset.minimumLevel) { //最小层级
+							_options.minimumLevel = parameterset.minimumLevel;
+						}
+						if (parameterset.maximumLevel) { //最大层级
+							_options.maximumLevel = parameterset.maximumLevel;
+						}
+					}
+
+					layer.addTileMapServiceImagery(_options, function(serviceId) {
+
+						//重置图层顺序
+						setLayerNumber(imageryLayers, data, serviceId)
+						resolve(true);
+					});
+				} else {
+					layer.removeImageryProvider({
+						serviceId: _serviceId
+					}).then(res => {
+						data.isinit = '0';
+						resolve(true);
+					});
+				}
+				break;
+			case "Cesium3DTileset": //加载3DTileset地图服务--实景
+
+				if (checked) {
+					data.isinit = '1';
+
+					if (window[_serviceId]) {
+						window[_serviceId].show = true;
+					} else {
+						//设置参数
+						let _options = {
+							id: _serviceId,
+							url: data.datasource,
+						}
+						if (parameterset) {
+							if (parameterset.height) {
+								_options.height = parameterset.height;
+							}
+							if (parameterset.alpha) {
+								_options.alpha = parameterset.alpha;
+							}
+						}
+						//加载实景
+						layer.addCesium3DTileset(_options, function(serviceId) {
+							window[_serviceId].show = true;
+							resolve(true);
+						});
+					}
+				} else {
+					if (window[_serviceId]) {
+						//3DTileset数据量比较大,会报很多cesium错误
+						// layer.removeScenePrimitives({
+						// 	serviceId: _serviceId
+						// }).then(res => {
+						// 	data.isinit = '0';
+						// });
+
+						window[_serviceId].show = false;
+						data.isinit = '0';
+						resolve(true);
+					}
+				}
+
+				break;
+			case "Cesium3DTileset_BM": //加载3DTileset地图服务--白膜
+			debugger
+				if (checked) {
+					data.isinit = '1';
+
+					if (window[_serviceId]) {
+						window[_serviceId].show = true;
+					} else {
+						//设置参数
+						let _options = {
+							id: _serviceId,
+							url: data.datasource,
+						}
+						if (parameterset) {
+							if (parameterset.color) {
+								_options.color = parameterset.color;
+							}
+						}
+
+						//加载白膜
+						layer.addCesium3DTilesetBm(_options, function(serviceId) {
+							window[_serviceId].show = true;
+							resolve(true);
+						});
+					}
+				} else {
+					if (window[_serviceId]) {
+						// layer.removeScenePrimitives({
+						// 	serviceId: _serviceId
+						// }).then(res => {
+						// 	data.isinit = '0';
+						// });
+
+						window[_serviceId].show = false;
+						data.isinit = '0';
+						resolve(true);
+					}
+				}
+				break;
+			default:
+				break;
+		}
+	})
+}
+
+/**
+ * 服务定位
+ * @param {Object} data
+ */
+export function setLayersLocation(viewer, data) {
+
+	let _serviceId = store.serviceMark + "_" + data.layercode + data.layerorder;
+	let layername = data.layername;
+
+	//透明度
+	let _opacity = null;
+	if (data.opacity == null) {
+		_opacity = 1;
+	} else {
+		_opacity = Number(data.opacity);
+		data.opacity = _opacity;
+
+		if (_opacity == 0) {
+			_opacity = 1;
+		}
+	}
+
+	//参数集
+	let parameterset = data.parameterset;
+	if (data.parameterset instanceof Object) {
+		parameterset = data.parameterset;
+	} else if (data.parameterset != "" && data.parameterset != null && data.parameterset != undefined) {
+		parameterset = JSON.parse(data.parameterset);
+	}
+
+	if (data.isinit === '1') {
+		return new Promise((resolve, reject) => {
+			switch (data.loadtype) {
+				case "GeoJsonPolyline": //GeoJsonPolyline
+
+					break;
+				case "GeoJsonWall": //GeoJsonWall
+
+					break;
+				case "entitiesGltf": //gltf/glb
+
+					if (parameterset) {
+						if (parameterset.points) { //模型位置
+
+							// let LocateUtil = new jt3dSDK.LocateUtil(viewer);
+							// let flyToEntity = LocateUtil.flyToEntityByPoints([
+							// 	parameterset.points,
+							// ], 'point', {
+							// 	heading: '0',
+							// 	pitch: -90,
+							// 	range: 8880
+							// });
+							viewer.scene.camera.flyTo({
+								//定位坐标点
+								destination: Cesium.Cartesian3.fromDegrees(parameterset.points[0], parameterset.points[1], parameterset.points[2] || 0),
+								duration: 2, //定位的时间间隔
+								orientation: {
+									heading: Cesium.Math.toRadians(56), //方向
+									pitch: Cesium.Math.toRadians(-11), //倾斜角度
+									roll: 0
+								}
+							});
+
+							resolve(true);
+						} else {
+							ElMessage("请检测图层表parameterset字段是否设置points");
+						}
+					} else {
+						ElMessage("请检测图层表parameterset字段是否设置points");
+					}
+
+					break;
+				case "scenePrimitivesGltf": //gltf/glb
+
+					if (parameterset) {
+						if (parameterset.points) { //模型位置
+
+							viewer.scene.camera.flyTo({
+								//定位坐标点
+								destination: Cesium.Cartesian3.fromDegrees(parameterset.points[0], parameterset.points[1], parameterset.points[2] || 0),
+								duration: 2, //定位的时间间隔
+								orientation: {
+									// heading: Cesium.Math.toRadians(56), //方向
+									// pitch: Cesium.Math.toRadians(-11), //倾斜角度
+									// roll: 0
+								}
+							});
+
+							resolve(true);
+						} else {
+							ElMessage("请检测图层表parameterset字段是否设置points");
+						}
+					} else {
+						ElMessage("请检测图层表parameterset字段是否设置points");
+					}
+
+					break;
+				case "PolygonImageMaterial": //图片材质
+
+					break;
+				case "CrImageServerLayer": //地形服务(DEM)
+
+					break;
+				case "DEM": //地形服务(DEM)
+
+					break;
+				case "UrlTemplateImageryProvider": //加载URL模板服务
+
+					break;
+				case "WebMapTileServiceImageryProvider": // WMTS地图服务
+
+					break;
+				case "WebMapServiceImageryProvider": //WMS地图服务
+
+					break;
+				case "ArcGisMapServerImageryProvider": // ArcGIS Online和Server的相关服务
+
+					break;
+				case "TileMapServiceImageryProvider": // 2.5维度地图
+
+					break;
+				case "Cesium3DTileset": //加载3DTileset地图服务--实景
+
+					if (window[_serviceId]) {
+						viewer.flyTo(window[_serviceId]);
+						resolve(true);
+					}
+					break;
+				case "Cesium3DTileset_BM": //加载3DTileset地图服务--白膜
+
+					break;
+				default:
+					break;
+			}
+		})
+	}
+}
+
+/**
+ * 设置服务透明度
+ * @param {Object} data
+ * @param {Object} alpha
+ */
+export function setLayersAlpha(viewer, data, alpha) {
+	let layer = new jt3dSDK.layer(viewer);
+
+	let _serviceId = store.serviceMark + "_" + data.layercode + data.layerorder;
+	if (data.loadtype === "Cesium3DTileset") {
+		//设置实景透明度
+		layer.set3DTileStyle({
+			serviceId: _serviceId,
+			alpha: alpha,
+		});
+	} else if (data.loadtype === "CrImageServerLayer") {
+		let floatLayer = window[_serviceId];
+		floatLayer.setOpacity(alpha)
+	} else if (data.loadtype === "PolygonImageMaterial") {
+		//设置透明度
+		layer.setPolygonImageMaterial({
+			serviceId: _serviceId,
+			alpha: alpha,
+		});
+	} else if (data.loadtype === "entitiesGltf") {
+		//设置透明度
+		layer.setModelStyle({
+			serviceId: _serviceId,
+			alpha: alpha,
+		});
+	} else {
+		layer.setLayersStyle({
+			serviceId: _serviceId,
+			alpha: alpha,
+		});
+	}
+}
+
+/**
+ * 设置图层顺序
+ * @param {Object} data
+ * @param {Object} serviceId
+ */
+export function setLayerNumber(imageryLayers, data, serviceId) {
+
+	// var imageryLayers = viewer.imageryLayers;
+
+	//设置图层初始顺序
+	imageryLayers.lowerToBottom(window[serviceId]);
+	imageryLayers.raise(window[serviceId]);
+	imageryLayers.raise(window[serviceId]);
+
+	store.layersList.forEach(res => {
+		if (res.layercode && res.layerorder) {
+			let id = store.serviceMark + "_" + res.layercode + res.layerorder
+			let startid = Number(res.layercode + res.layerorder)
+			let strid = Number(serviceId.replace(store.serviceMark + "_", ""))
+
+			if (imageryLayers.contains(window[id])) {
+				if (startid <= strid) {
+					imageryLayers.raise(window[serviceId])
+				}
+			}
+		}
+	})
+
+	if (data.atlastype === "底图") {
+		imageryLayers.lowerToBottom(window[serviceId]);
+		imageryLayers.raise(window[serviceId]);
+		if (data.layertype === '标注') {
+			imageryLayers.raiseToTop(window[serviceId]);
+		}
+	}
+}
+
+/**
+ * 移除分屏对比
+ */
+export function removeSplitScreen(viewer) {
+	let mapView1 = document.getElementById("cesiumContainer");
+	let mapView2 = document.getElementById("cesiumContainer2");
+
+	mapView1.className = "jt-map";
+	mapView2.style.display = "none";
+	mapView2.innerHTML = "";
+
+	if (viewer) {
+		viewer.entities.removeAll(); // 删除全部
+		viewer.imageryLayers.removeAll();
+		viewer.scene.primitives.removeAll(); //谨慎使用,可能删除不必要的primitive
+		viewer.destroy();
+	}
+}
+
+/**
+ * 地图绕点自旋
+ */
+export function setMapSpin(jt3d) {
+	//移除左键单击事件
+	if (jt3d.handlerLeftClick) {
+		jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
+	}
+
+	let SketchViewModel = new jt3dSDK.SketchViewModel(window.viewer, {
+		isClear: true,
+		isDrawPoint: false, //是否标记参考点
+		isRetainDrawPoint: false, //绘制完成是否保留绘制点
+		iconType: 'blue',
+	}, );
+
+	SketchViewModel.sketchTools('point', {
+		onComplete(cPoint, gPoint) {
+			jt3d.setMapSpinByPoint(cPoint, {
+				// height: 100000
+			});
+		},
+		onError(message) {}
+	});
+}
+
+/**
+ * 地图指北
+ */
+export function setMapNorth(jt3d) {
+	jt3d.setMapNorth();
+	jt3d.isSpan = false;
+}
+
+
+/**
+ * 移除卷帘
+ */
+export function removeSplitLayer(viewer, earthAtLeft, earthAtRight) {
+	let sliderDiv = document.getElementById("image_slider");
+	if (sliderDiv) {
+		document.body.removeChild(sliderDiv);
+	}
+	removeSplitLayerLeft(viewer, earthAtLeft);
+	removeSplitLayerRight(viewer, earthAtRight);
+
+	if (earthAtLeft) {
+		earthAtLeft.splitDirection = Cesium.SplitDirection.NONE;
+	}
+
+	if (earthAtRight) {
+		earthAtRight.splitDirection = Cesium.SplitDirection.NONE;
+	}
+}
+/**
+ * 移除左侧图层
+ */
+export function removeSplitLayerLeft(viewer, leftValue) {
+	setLayersControl(viewer,leftValue, false);
+	
+	// if (earthAtLeft) {
+	// 	if (earthAtLeft instanceof Cesium.ImageryLayer) {
+	// 		viewer.imageryLayers.remove(earthAtLeft);
+	// 	}
+
+	// 	if (earthAtLeft instanceof Cesium.Cesium3DTileset) {
+	// 		viewer.scene.primitives.remove(earthAtLeft);
+	// 	}
+
+	// 	if (earthAtLeft instanceof Array) {
+	// 		earthAtLeft.forEach((res, index) => {
+	// 			viewer.scene.primitives.remove(res);
+	// 		})
+	// 	}
+	// }
+}
+/**
+ * 移除右侧图层
+ */
+export function removeSplitLayerRight(viewer, rightValue) {
+	setLayersControl(viewer,rightValue, false);
+	// if (earthAtRight) {
+	// 	if (earthAtRight instanceof Cesium.ImageryLayer) {
+	// 		viewer.imageryLayers.remove(earthAtRight);
+	// 	}
+
+	// 	if (earthAtRight instanceof Cesium.Cesium3DTileset) {
+	// 		viewer.scene.primitives.remove(earthAtRight);
+	// 	}
+
+	// 	if (earthAtRight instanceof Array) {
+	// 		earthAtRight.forEach((res, index) => {
+	// 			viewer.scene.primitives.remove(res);
+	// 		});
+	// 	}
+	// }
+}

+ 57 - 0
src/views/Map3d - 副本 (2)/new_file.vue

@@ -0,0 +1,57 @@
+<template>
+	<component :is="componentKey" ref="custom"></component>
+</template>
+<script>
+	import {
+		reactive,
+		ref,
+		shallowReactive,
+		onActivated,
+		defineAsyncComponent,
+	} from 'vue';
+
+	//声明componentkey,用于告诉component当前挂载什么组件,components为一个对象,存放多个不确定的自定义组件。
+	const componentKey = ref(null);
+	const components: any = shallowReactive({});
+
+	// 组件挂载
+	const initTableConfig = (gridId, type) => {
+		queryTableConfig({
+			gridId
+		}).then(({
+			data
+		}) => {
+			if (type === 'main') {
+				Object.assign(mainConfig, data);
+				tabsKey.value = -1;
+			} else {
+				tabsDetail.value.push(data);
+				tabsKey.value = tabsDetail.value.length - 1;
+			}
+			// 涉及到自定义组件的部分,这里需要提前挂载,在用到时不至于ref为null
+			XEUtils.objectEach(data.action, (action, key) => {
+				if (
+					action.modalCfg &&
+					action.modalCfg.type === 'CustomModal' &&
+					action.modalCfg.src
+				) {
+					components[action.actionId] = defineAsyncComponent(
+						() => import(`../../../${action.modalCfg.src}`)
+					);
+					//注意:这里的路径后端只能返回相对路径,不能使用@/xxx/xxx.vue ,不能使用src/xxx/xxx.vue,只能./xxx.vue或者../../xxx/xxx.vue。由于并不确定组件在什么位置,避免容易出错的原则,我在前端通过../../../的形式将路径回退到src下,后端只需要从src下配置路径即可,不用考虑那么多了。如后端src的值为src/xxx/xxx/xxx.vue 则在前端合成的路径就为../../../src/xx/xxx/xxx.vue
+					componentKey.value = components[action.actionId];
+					// 为什么componentKey.vue在这里赋值,在后面点击窗口后又赋值,这里能不能省略。
+					//	答:这里省略的话,到点击按钮触发时会报错,第一次点击会报错,第二次点击不会报错,窗口正常弹出。可能是因为,组件挂载时并没有引入组件,只在使用时才引入,如果上面不提前将挂载好的组件引入进来,后面触发事件触发时引入在调用ref,执行太快,costom就会报错,所以才会点两次才弹窗。
+				}
+			});
+		});
+	};
+</script>
+
+
+<!-- 		} else if (action.modalCfg.type === 'CustomModal') {
+  		// 这里的actionid和组件是对应的,所以在按钮触发后,通过按钮携带的actionid能取到对应的组件。
+          componentKey.value = components[action.actionId];
+          custom.value.init(row);
+        } -->
+

+ 43 - 0
src/views/Map3d - 副本 (2)/widget.vue

@@ -0,0 +1,43 @@
+<template>
+  <component :is="widget.component" v-bind="getWidgetAttr(widget)" />
+</template>
+<script lang="ts">
+import { useAttrs, defineComponent, provide } from "vue"
+import type { Widget } from "@/common/store/widget"
+
+export default defineComponent({
+  name: "jt-widget",
+  props: ["widget"],
+  setup(props) {
+    const attrs = useAttrs()
+
+    provide("getCurrentWidget", () => {
+      return props.widget.name
+    })
+
+    const getWidgetAttr = (widget: Widget) => {
+		debugger
+      let attr = {}
+      if (widget.meta && widget.meta.props) {
+        attr = {
+          ...attr,
+          ...widget.meta.props
+        }
+      }
+      if (widget.data && widget.data.props) {
+        attr = {
+          ...attr,
+          ...widget.data.props
+        }
+      }
+      return attr
+    }
+
+    return {
+      attrs,
+      getWidgetAttr
+    }
+  }
+})
+</script>
+

+ 128 - 0
src/views/Map3d - 副本 (2)/备份/Map3DMain - 副本 (2).vue

@@ -0,0 +1,128 @@
+<script setup>
+	//组件异步加载
+	// import {
+	// 	defineAsyncComponent
+	// } from 'vue';
+
+	import map3d from './components/map.vue';
+	// const navigation = defineAsyncComponent(() => import('./components/navigation.vue'));
+	import queryKeyword from './components/query-keyword.vue';
+	import toolbars from './components/toolbars.vue';
+
+
+	import {
+		ref,
+		computed
+	} from "vue"
+	import {
+		useWidgetStore
+	} from "@/common/store/widget"
+	import JtWidget from "./widget.vue"
+
+	const widgetStore = useWidgetStore()
+	debugger
+	const widgets = computed(() => widgetStore.state.widgets)
+	const openAtStart = computed(() => widgetStore.state.openAtStart)
+
+
+	/**
+	 * 通过provide/inject可以轻松实现跨级访问父组件的数据
+	 * provide和inject是成对出现的
+	 * 必须放在setup内
+	 * 简单的来说就是在父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量
+	 * provide 和 inject 绑定并不是可响应的。这是刻意为之的。
+	 * 代码执行顺序data->provide->created->mounted
+	 */
+	import {
+		provide
+	} from "vue";
+	provide("getMapInstance", () => {
+		return jt3d;
+	});
+</script>
+
+<template>
+	<div class="jt-mapMain">
+
+		<!-- 地图组件 -->
+		<map3d @onload="jtMap3DOnload" ref="refMap3d" />
+
+		<!-- 地图加载完成后,在加载其他组件 -->
+		<template v-if="isJTMap3DOnload">
+			<!-- 比例尺、指南针 -->
+			<!-- <navigation ref="refNavigation" /> -->
+
+			<!-- 关键字查询组件 -->
+			<queryKeyword ref="queryword" />
+
+			<!-- 工具栏组件 -->
+			<toolbars />
+
+			<!-- <template v-for="comp in toolDatas" :key="comp.widget">
+				<jt-popup :title="comp.name" :isshow="comp.visible">
+					<component :is="comp.widget" :ref="comp.widget"  />
+				</jt-popup>
+			</template> -->
+
+			<template v-for="comp in widgets" :key="comp.key">
+				<jt-widget v-if="openAtStart.includes(comp.name) && comp.visible" v-model:visible="comp.visible" :widget="comp" />
+			</template>
+
+		</template>
+	</div>
+</template>
+
+<script>
+
+	let jt3d = undefined;
+
+	export default {
+		name: "Map3DMain",
+
+		/**
+		 *  数据 
+		 */
+		data() {
+			return {
+				isJTMap3DOnload: false,
+				toolDatas: [{
+						name: "底图",
+						icon: "iconfont icon-dituzuobiao",
+						widget: "basicLayer",
+						visible: true
+					},
+					{
+						name: "图层222222222",
+						icon: "iconfont icon-winfo-icon-tucengkongzhi",
+						widget: "layer",
+						visible: true
+					},
+				]
+			}
+		},
+
+		/**
+		 *  方法 
+		 */
+		methods: {
+
+			/**
+			 * 地图初始化
+			 * @param {Object} map
+			 */
+			jtMap3DOnload(map) {
+				jt3d = map;
+				this.isJTMap3DOnload = true;
+			},
+		},
+		created() {
+
+		},
+		mounted() {
+
+		}
+	};
+</script>
+<style lang="scss" scoped>
+
+</style>

+ 172 - 0
src/views/Map3d - 副本 (2)/备份/Map3DMain - 副本 (3).vue

@@ -0,0 +1,172 @@
+<script setup>
+	//组件异步加载
+	import {
+		defineAsyncComponent,
+		markRaw,
+		computed
+	} from 'vue';
+
+	import map3d from './components/map.vue';
+	const navigation = defineAsyncComponent(() => import('./components/navigation.vue'));
+	import queryKeyword from './components/query-keyword.vue';
+	import toolbars from './components/toolbars.vue';
+	
+	import {
+		Store
+	} from '@/store/index'
+	let store = Store()
+			//获取地图图集id
+			let roleId = store.roleId
+			let atlasLayersSqlWhere = '"roleId"' + " = " + roleId + " and " + '"atlasType"' + "='图层'"
+
+	import {
+		useWidgetStore
+	} from "@/common/store/widget"
+	import JtWidget from "./widget.vue"
+
+	const widgetStore = useWidgetStore()
+	
+	console.log('log',11111111111)
+	
+	//获取图集
+	// this.$http.get('/getTableList', {
+	// 	tableName: 'sys_map_atlas_layers', //表名
+	// 	sqlWhere: atlasLayersSqlWhere, //查询条件
+	// 	orderByField: '' //排序字段
+	// }).then(res => {
+	// 	console.log('log', res)
+	// 	//初始图层列表
+	// 	// this.inittree = res.data
+	// // 	init(res.data).then(item => {
+	// // 		console.log('log', _this.treeData)
+	
+	// // 		//复选框初始化选中
+	// // 		_this.$nextTick(() => {
+	// // 			_this.$refs.treeRef.setCheckedKeys(_this.checkedkeys, true);
+	// // 		});
+	// // 	})
+	// })
+	
+	widgetStore.state.widgets = [{
+			component: markRaw(defineAsyncComponent(() => import("@/views/map3d/components/layer.vue"))),
+			name: "layer",
+			autoDisable: true,
+			group: "manage",
+		},
+	];
+	
+	const widgets = computed(() => widgetStore.state.widgets);
+	const openAtStart = computed(() => widgetStore.state.openAtStart);
+
+	/**
+	 * 通过provide/inject可以轻松实现跨级访问父组件的数据
+	 * provide和inject是成对出现的
+	 * 必须放在setup内
+	 * 简单的来说就是在父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量
+	 * provide 和 inject 绑定并不是可响应的。这是刻意为之的。
+	 * 代码执行顺序data->provide->created->mounted
+	 */
+	import {
+		provide
+	} from "vue";
+	provide("getMapInstance", () => {
+		return jt3d;
+	});
+</script>
+
+<template>
+	<div class="jt-mapMain">
+
+		<!-- 地图组件 -->
+		<map3d @onload="jtMap3DOnload" ref="refMap3d" />
+
+		<!-- 地图加载完成后,在加载其他组件 -->
+		<template v-if="isJTMap3DOnload">
+			<!-- 比例尺、指南针 -->
+			<!-- <navigation ref="refNavigation" /> -->
+
+			<!-- 关键字查询组件 -->
+			<queryKeyword ref="queryword" />
+
+			<!-- 工具栏组件 -->
+			<toolbars />
+
+			<!-- <template v-for="comp in toolDatas" :key="comp.widget">
+				<jt-popup :title="comp.name" :isshow="comp.visible">
+					<component :is="comp.widget" :ref="comp.widget"  />
+				</jt-popup>
+			</template> -->
+
+			<template v-for="comp in widgets" :key="comp.key">
+				<jt-widget v-if="openAtStart.includes(comp.name) && comp.visible" v-model:isshow="comp.visible" :widget="comp" />
+			</template>
+			
+			<!-- <layer></layer>
+			<basicLayer></basicLayer> -->
+
+		</template>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+
+	// const widgets = undefined;
+	// const openAtStart = undefined;
+
+	export default {
+		name: "Map3DMain",
+
+		/**
+		 *  数据 
+		 */
+		data() {
+			return {
+				isJTMap3DOnload: false,
+				toolDatas: [{
+						name: "底图",
+						icon: "iconfont icon-dituzuobiao",
+						widget: "basicLayer",
+						visible: true
+					},
+					{
+						name: "图层222222222",
+						icon: "iconfont icon-winfo-icon-tucengkongzhi",
+						widget: "layer",
+						visible: true
+					},
+				]
+			}
+		},
+
+		/**
+		 *  方法 
+		 */
+		methods: {
+
+			/**
+			 * 地图初始化
+			 * @param {Object} map
+			 */
+			jtMap3DOnload(map) {
+				jt3d = map;
+				this.isJTMap3DOnload = true;
+			},
+		},
+		beforeCreate(){
+			console.log('log',2222)
+			
+		},
+		created() {
+console.log('log',3333)
+	
+		},
+		mounted() {
+console.log('log',444)
+	
+		}
+	};
+</script>
+<style lang="scss" scoped>
+
+</style>

+ 90 - 0
src/views/Map3d - 副本 (2)/备份/Map3DMain - 副本 (4).vue

@@ -0,0 +1,90 @@
+<script setup>
+	//组件异步加载
+	import {
+		defineAsyncComponent,
+		markRaw,
+		computed,
+		provide
+	} from 'vue';
+
+	import {
+		useWidgetStore,
+		Widget
+	} from "@/common/store/widget"
+
+	import map3d from './components/map.vue';
+	import JtWidget from "./widget.vue"
+
+	const widgetStore = useWidgetStore()
+	// widgetStore.state.widgets = store.aa;
+
+	// widgetStore.state.widgets = [{
+	// 	component: markRaw(defineAsyncComponent(() => import("@/views/map3d/components/layer.vue"))),
+	// 	name: "layer",
+	// 	autoDisable: true,
+	// 	group: "manage",
+	// } ];
+
+	const widgets = computed(() => widgetStore.state.widgets);
+	const openAtStart = computed(() => widgetStore.state.openAtStart);
+
+	provide("getMapInstance", () => {
+		return jt3d;
+	});
+</script>
+
+<template>
+	<div class="jt-mapMain">
+
+		<!-- 地图组件 -->
+		<map3d @onload="jtMap3DOnload" ref="refMap3d" />
+
+		<!-- 地图加载完成后,在加载其他组件 -->
+		<template v-if="isJTMap3DOnload">
+
+			<template v-for="comp in widgets" :key="comp.key">
+				<jt-widget v-if="openAtStart.includes(comp.name) && comp.visible" v-model:isshow="comp.visible" :widget="comp" />
+			</template>
+
+		</template>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+
+	export default {
+		name: "Map3DMain",
+
+		/**
+		 *  数据 
+		 */
+		data() {
+			return {
+				isJTMap3DOnload: false,
+			}
+		},
+
+		/**
+		 *  方法 
+		 */
+		methods: {
+
+			/**
+			 * 地图初始化
+			 * @param {Object} map
+			 */
+			jtMap3DOnload(map) {
+				jt3d = map;
+				this.isJTMap3DOnload = true;
+			},
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+<style lang="scss" scoped>
+
+</style>

+ 474 - 0
src/views/Map3d - 副本 (2)/备份/Map3DMain - 副本.vue

@@ -0,0 +1,474 @@
+<script setup>
+	/**
+	 * 业务组件,在components中进行注册
+	 */
+	//组件异步加载
+	import {
+		defineAsyncComponent
+	} from 'vue';
+	// const TrackRoam = defineAsyncComponent(() => import('./components/TrackRoam.vue'));
+	// const ImageLayerSplit = defineAsyncComponent(() => import('./components/ImageLayerSplit.vue'));
+	// const ViewerSplitScreen = defineAsyncComponent(() => import('./components/ViewerSplitScreen.vue'));
+	// const viewerlabel = defineAsyncComponent(() => import('./components/viewerlabel.vue'));
+	// const printmap = defineAsyncComponent(() => import('./components/printmap.vue'));
+	// const dialogEdit = defineAsyncComponent(() => import('./components/drawEdit.vue'));
+	// const queryResult = defineAsyncComponent(() => import('./components/queryResult.vue'));
+	// const analysisSpace = defineAsyncComponent(() => import('./components/analysis-space.vue'));
+	// const analysisTerrain = defineAsyncComponent(() => import('./components/analysis-terrain.vue'));
+	// const analysisData = defineAsyncComponent(() => import('./components/analysis-data.vue'));
+	// const layer = defineAsyncComponent(() => import('./components/layer.vue'));
+	// const measure = defineAsyncComponent(() => import('./components/measure.vue'));
+	// const queryGraphics = defineAsyncComponent(() => import('./components/query-graphics.vue'));
+	// const SpecialEffects = defineAsyncComponent(() => import('./components/special-effects.vue'));
+	// const coordsTool = defineAsyncComponent(() => import('./components/coordsTool.vue'));
+	// const basicLayer = defineAsyncComponent(() => import('./components/basicLayer.vue'));
+	// const queryKeyword = defineAsyncComponent(() => import('./components/query-keyword.vue'));
+	// const toolbars = defineAsyncComponent(() => import('./components/toolbars.vue'));
+	// const map3d = defineAsyncComponent(() => import('./components/map.vue'));
+
+	// const navigation = defineAsyncComponent(() => import('./components/navigation.vue'));
+	// import map3d from './components/map.vue';
+	// import queryKeyword from './components/query-keyword.vue';
+	// import toolbars from './components/toolbars.vue';
+	// import layer from './components/layer.vue';
+	// import measure from './components/measure.vue';
+	// import queryGraphics from './components/query-graphics.vue';
+	// import SpecialEffects from './components/special-effects.vue';
+	// import coordsTool from './components/coordsTool.vue';
+	// import basicLayer from './components/basicLayer.vue'
+	// import analysisSpace from './components/analysis-space.vue';
+	// import analysisTerrain from './components/analysis-terrain.vue';
+	// import analysisData from './components/analysis-data.vue';
+	// import mapNavigate from './components/mapNavigate.vue';
+	// import TrackRoam from './components/TrackRoam.vue';
+	// import ImageLayerSplit from './components/ImageLayerSplit.vue';
+	// import ViewerSplitScreen from './components/ViewerSplitScreen.vue';
+	// import viewerlabel from './components/viewerlabel.vue';
+	// import printmap from './components/printmap.vue';
+	// import dialogEdit from "./components/drawEdit.vue";
+	// import queryResult from "./components/queryResult.vue";
+
+
+	import {
+		Store
+	} from '@/store/index'
+	store = Store()
+
+	/**
+	 * 通过provide/inject可以轻松实现跨级访问父组件的数据
+	 * provide和inject是成对出现的
+	 * 必须放在setup内
+	 * 简单的来说就是在父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量
+	 * provide 和 inject 绑定并不是可响应的。这是刻意为之的。
+	 * 代码执行顺序data->provide->created->mounted
+	 */
+	import {
+		provide
+	} from "vue";
+	provide("getMapInstance", () => {
+		return jt3d;
+	});
+</script>
+
+<template>
+	<div class="jt-mapMain">
+
+		<!-- 地图组件 -->
+		<map3d @onload="jtMap3DOnload" ref="refMap3d" />
+
+		<!-- 地图加载完成后,在加载其他组件 -->
+		<template v-if="mapLoaded">
+			<!-- 底图组件 -->
+			<basicLayer v-show="showbasicLayer" ref="basicLayers"></basicLayer>
+
+			<!-- 弹出框组件,tabs组件测试 -->
+			<jt-popup title="地区导航" ref="refmapNavigate" :isEmit="true" @closeJTPopup="closeMapNavigate">
+				<mapNavigate ref="_refmapNavigate"></mapNavigate>
+			</jt-popup>
+
+			<!-- 关键字查询组件 -->
+			<queryKeyword ref="queryword" />
+
+			<!-- 比例尺、指南针 -->
+			<navigation ref="refNavigation" />
+
+			<!-- 视角标签 -->
+			<jt-popup title="视角标签" ref="refviewerlabel">
+				<viewerlabel ref="_refviewerlabel"></viewerlabel>
+			</jt-popup>
+
+			<!-- 打印地图 -->
+			<jt-popup :showfooter="isshowfooter" longheader="1" right="calc(50% - 480rem)" width="960rem" top="calc(50% - 270rem)" height="600rem" title="打印地图" ref="refprintmap">
+				<printmap ref="_refprintmap"></printmap>
+			</jt-popup>
+
+			<!-- 工具栏组件 -->
+			<toolbars />
+
+			<!-- 图上量算组件 -->
+			<jt-popup title="图上量算" ref="refMeasure" :isEmit="true" @closeJTPopup="closeMeasure">
+				<measure ref="_refMeasure" />
+			</jt-popup>
+
+			<!-- 数据分析组件 -->
+			<jt-popup title="数据分析" ref="refAnalysisData">
+				<analysisData />
+			</jt-popup>
+
+			<!-- 空间分析组件 -->
+			<jt-popup title="空间分析" ref="refAnalysisSpace">
+				<analysisSpace />
+			</jt-popup>
+
+			<!-- 剖面分析结果组件 -->
+			<jt-drawer ref="refDrawerSectionAnalysis" title="剖面分析结果" direction="btt" size="30vh" @closeJTDrawer="closeDrawerSectionAnalysis">
+				<jt-charts id="sectionAnalysisChart" width='98vw' height="20vh" :option='ChartTestData' />
+			</jt-drawer>
+
+			<!-- 图形查询组件 -->
+			<jt-popup title="图形查询" ref="refQueryGraphics" :isEmit="true" @closeJTPopup="closeQuery">
+				<queryGraphics ref="_refQueryGraphics" />
+			</jt-popup>
+
+			<!-- 特效组件 -->
+			<jt-popup title="特效效果" ref="refSpecialEffects">
+				<SpecialEffects />
+			</jt-popup>
+
+			<!-- 坐标定位拾取组件 -->
+			<jt-popup title="坐标定位拾取" ref="refCoordsTool">
+				<coordsTool />
+			</jt-popup>
+
+			<!-- 地形分析组件 -->
+			<jt-popup title="地形分析" ref="refAnalysisTerrain" :isEmit="true" @closeJTPopup="closeAnalysisTerrain">
+				<analysisTerrain ref="_refAnalysisTerrain" />
+			</jt-popup>
+
+			<!-- 跟踪漫游组件 -->
+			<jt-popup minWidth="294rem" title="跟踪漫游" ref="refTrackRoam">
+				<TrackRoam />
+			</jt-popup>
+
+			<!-- 卷帘对比组件 -->
+			<jt-popup :showfooter="isshowfooter" height="150rem" width="520rem" title="卷帘对比" ref="refImageLayerSplit" :isEmit="true" @closeJTPopup="closeImageLayerSplit">
+				<ImageLayerSplit ref="_refImageLayerSplit" />
+			</jt-popup>
+
+			<!-- 分屏对比组件 -->
+			<jt-popup title="分屏对比" animationClass="fadein-left" ref="refViewerSplitScreen" :isEmit="true" @closeJTPopup="closeViewerSplitScreen">
+				<ViewerSplitScreen ref="_refViewerSplitScreen" />
+			</jt-popup>
+
+			<!-- 图层控jt-popup制组件 -->
+			<jt-popup title="图层控制" ref="refLayerPopup">
+				<layer ref="refLayer" />
+			</jt-popup>
+
+			<!--图上标绘组件-->
+			<jt-popup title="图上标绘" ref="refDialogEdit">
+				<dialogEdit />
+			</jt-popup>
+
+			<!-- 查询结果 -->
+			<jt-popup :showfooter='isshowfooter' animationClass="fadein-left" height="400rem" width="800rem" title="信息展示" ref="refQueryResultPopup" :isEmit="true" @closeJTPopup="closeQueryResult">
+				<queryResult ref="refQueryResult" />
+			</jt-popup>
+
+			<!-- <video id="trailer" style="display: none;"  autoplay loop crossorigin controls>
+				<source src="@/assets/dataFile/jt.mp4" type="video/mp4">
+			</video> -->
+
+		</template>
+	</div>
+</template>
+
+<script>
+	import * as echarts from "echarts";
+	let store = undefined
+	let jt3d = undefined;
+	let tipEntity = undefined;
+
+	export default {
+		name: "Map3DMain",
+
+		/**
+		 *  数据 
+		 */
+		data() {
+			return {
+				isshowfooter: false,
+				mapLoaded: false,
+				showbasicLayer: false, //控制地图组件显示隐藏
+				ChartTestData: {}, //剖面分析结果chart
+			}
+		},
+
+		/**
+		 *  方法 
+		 */
+		methods: {
+
+			/**
+			 * 关闭分屏对比
+			 */
+			closeViewerSplitScreen() {
+				this.$refs._refViewerSplitScreen.removeSplitScreen();
+			},
+
+			/**
+			 * 关闭卷帘对比
+			 */
+			closeImageLayerSplit() {
+				this.$refs._refImageLayerSplit.removeSplitLayer();
+			},
+
+			/**
+			 * 关闭地形分析弹窗
+			 */
+			closeAnalysisTerrain() {
+				//工具初始化
+				this.$refs._refAnalysisTerrain.init();
+				//还原左键单击事件
+				this.$refs.refMap3d.clickEntity(jt3d);
+				window["viewer"].scene.screenSpaceCameraController.enableCollisionDetection = true; //相机与地形的碰撞检测
+			},
+
+			/**
+			 * 关闭地区导航
+			 */
+			closeMapNavigate() {
+				this.$refs._refmapNavigate.remove();
+			},
+
+			/**
+			 * 清除测量结果
+			 */
+			closeMeasure() {
+				this.$refs._refMeasure.clearMeasurementData();
+			},
+
+			/**
+			 * 清除查询结果
+			 */
+			closeQuery() {
+				this.$refs._refQueryGraphics.clearQuery();
+			},
+
+			/**
+			 * 关闭查询结果
+			 */
+			closeQueryResult() {
+				//清除高亮显示
+				let list = jt3d._dataSources.getByName("单击高亮显示")
+				list.forEach(res => {
+					jt3d._dataSources.remove(res)
+				})
+
+				//清除定位样式
+				if (jt3d.LocateUtil._locationEntity) {
+					window["viewer"].entities.remove(jt3d.LocateUtil._locationEntity);
+				}
+			},
+
+			/**
+			 * 关闭剖面分析结果
+			 */
+			closeDrawerSectionAnalysis() {
+				this.$refs.refDrawerSectionAnalysis.drawerVisible = false;
+
+				if (tipEntity) {
+					window.viewer.entities.remove(tipEntity);
+					tipEntity = undefined;
+				}
+				jt3d.SpatialAnalysis.Profile.removeProfileAnalysis();
+				jt3d.DrawTools.Clear();
+
+				//还原左键单击事件
+				this.$refs.refMap3d.clickEntity(jt3d);
+			},
+
+			/**
+			 * 构建剖面分析结果chart
+			 */
+			initEchartsData(sectionAnalysisData) {
+				if (tipEntity) {
+					window.viewer.entities.remove(tipEntity);
+					tipEntity = undefined;
+				}
+				// jt3d.SpatialAnalysis.Profile.removeProfileAnalysis();
+
+				let datas = [],
+					coords = [];
+				let pointsData = sectionAnalysisData;
+
+				let maxDistance = pointsData[pointsData.length - 1].distance;
+				let xAixMax = Math.ceil(maxDistance);
+				for (let index = 0; index < pointsData.length; index++) {
+					let element = pointsData[index];
+					let curData = [
+						parseFloat(element.distance.toFixed(2)),
+						parseFloat(element.position.height.toFixed(2))
+					];
+					datas.push(curData);
+					let curCoords = [element.position.lon, element.position.lat];
+					coords.push(curCoords);
+				}
+
+				let ChartTestData = {
+					tooltip: {
+						show: true,
+						trigger: 'item',
+						formatter(params) {
+							let xy = coords[params.dataIndex];
+							let tipData = params["data"];
+							if (params.name === "Max" || params.name === "Min") {
+								tipData = params["data"].coord;
+							}
+
+							if (!tipEntity) {
+								tipEntity = window.viewer.entities.add({
+									position: Cesium.Cartesian3.fromDegrees(xy[0], xy[1], Number(tipData[1])),
+									billboard: {
+										image: 'jt3dSDK/imgs/point/point.png',
+										horizontalOrigin: Cesium.HorizontalOrigin.center,
+										verticalOrigin: Cesium.VerticalOrigin.bottom,
+										scale: 1,
+										pixelOffset: new Cesium.Cartesian2(0, 0),
+										disableDepthTestDistance: Number.POSITIVE_INFINITY,
+									},
+								});
+							} else {
+								tipEntity.position = Cesium.Cartesian3.fromDegrees(xy[0], xy[1], Number(tipData[1]));
+							}
+
+							//定位到点
+							// jt3d.LocateUtil.flyToPoint({
+							// 	longitude: xy[0],
+							// 	latitude: xy[1],
+							// 	height: Number(tipData[1])
+							// });
+
+							return "距离:" + tipData[0] + "m<br>" + "高度:" + tipData[1] + "m<br>" + "坐标:" + xy[0].toFixed(
+								5) + "," + xy[1].toFixed(5);
+						}
+					},
+					grid: {
+						bottom: '10%',
+						left: '5%',
+						right: '5%',
+					},
+					xAxis: {
+						type: "value",
+						max: xAixMax,
+						axisLabel: { //文字属性
+							textStyle: {
+								color: 'rgb(216 240 255)'
+							},
+							formatter: '{value} m'
+						},
+						axisLine: { //轴线属性
+							lineStyle: {
+								color: 'rgb(216 240 255)',
+								width: 2
+							},
+						},
+						splitLine: { //分割线属性
+							lineStyle: {
+								type: 'dashed'
+							}
+						}
+					},
+					yAxis: {
+						type: "value",
+						axisLabel: { //文字属性
+							textStyle: {
+								color: 'rgb(216 240 255)'
+							},
+							formatter: '{value} m'
+						},
+						axisLine: { //轴线属性
+							lineStyle: {
+								color: 'rgb(216 240 255)',
+								width: 2
+							},
+						},
+						splitLine: { //分割线属性
+							lineStyle: {
+								type: 'dashed'
+							}
+						}
+					},
+					series: [{
+						type: "line",
+						data: datas,
+						markPoint: {
+							symbol: 'path://m 0,0 h 48 v 20 h -30 l -6,10 l -6,-10 h -6 z', // 'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow', path://m 0,0 h 48 v 20 h -30 l -6,10 l -6,-10 h -6 z,  path://m 0,0 h 48 v 20 h -34 l -6,10 l -6,-10 h -2 z
+							symbolSize: [60, 60], // 容器大小
+							symbolOffset: ['34%', '-50%'], //位置偏移
+							symbolKeepAspect: true, // 如果 symbol 是 path:// 的形式,是否在缩放时保持该图形的长宽比。
+							label: {
+								textStyle: {
+									color: 'rgb(216,240,255)'
+								},
+								position: "insideTop",
+								distance: 7,
+							},
+							data: [{
+									type: 'max',
+									name: '最大值',
+									itemStyle: { //背景色
+										color: 'rgb(255, 70, 131)',
+									}
+								},
+								{
+									type: 'min',
+									name: '最小值',
+									itemStyle: { //背景色
+										color: 'rgb(255, 70, 131)',
+									}
+								}
+							]
+						},
+						itemStyle: {
+							color: 'rgba(85,254,139,1)',
+						},
+						areaStyle: {
+							color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+									offset: 0,
+									color: 'rgba(85,254,139,0.8)'
+								},
+								{
+									offset: 1,
+									color: 'rgba(14,245,210,0.2)'
+								}
+							])
+						},
+					}]
+				};
+				this.ChartTestData = ChartTestData;
+			},
+
+			/**
+			 * 地图初始化
+			 * @param {Object} map
+			 */
+			jtMap3DOnload(map) {
+				jt3d = map;
+				this.mapLoaded = true;
+			},
+
+
+
+		},
+		created() {
+			store.queryMapTables = []
+		},
+		mounted() {
+
+		}
+	};
+</script>
+<style lang="scss" scoped>
+
+</style>

+ 372 - 0
src/views/Map3d - 副本 (2)/备份/toolbars - 副本 (2).vue

@@ -0,0 +1,372 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	/**
+	 * element-plus字体
+	 */
+	import {
+		ArrowDown
+	} from '@element-plus/icons-vue';
+
+	import {
+		Store
+	} from '@/store/index';
+	store = Store()
+
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-toolbars fadein-right">
+		<template v-for="(item, i) in toolDatas" :key="i">
+			<div v-if="item.widget && !item.children" class="toolbar-item" @click="showWidget(item.widget)">
+				<i :class="item.icon" />
+				<span class="title">{{ item.name }}</span>
+			</div>
+			<el-dropdown v-if="item.children && !item.widget" class="toolbar-item" :hide-on-click="false" @command="handleCommand">
+				<span class="el-dropdown-link">
+					<i :class="item.icon" />
+					<span class="title">{{ item.name }}</span>
+					<el-icon class="el-icon--right">
+						<ArrowDown />
+					</el-icon>
+				</span>
+				<template #dropdown>
+					<span slot="slot" class="text"></span>
+					<el-dropdown-menu>
+						<el-dropdown-item v-for="child in item.children" :key="child.widget" :title="child.name" @click="showWidget(child.widget)">
+							<i :class="child.icon" />
+							<span>{{ child.name }}</span>
+						</el-dropdown-item>
+					</el-dropdown-menu>
+				</template>
+			</el-dropdown>
+		</template>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+	let store = undefined
+	export default {
+		name: "jt-toolbars",
+		data() {
+			return {
+				toolDatas: [
+					// {
+					// 	name: "绕点自旋",
+					// 	icon: "iconfont icon-chaxunzuobiaozhi",
+					// 	widget: "rotateCamera"
+					// },
+					// {
+					// 	name: "全图",
+					// 	icon: "iconfont icon-chaxunzuobiaozhi",
+					// 	widget: "fullMap"
+					// },
+					{
+						name: "底图",
+						icon: "iconfont icon-dituzuobiao",
+						widget: "basicLayer"
+					},
+					{
+						name: "图层",
+						icon: "iconfont icon-winfo-icon-tucengkongzhi",
+						widget: "layers"
+					},
+					{
+						name: "工具",
+						icon: "iconfont icon-xitong1",
+						children: [{
+								name: "图上标绘",
+								icon: "iconfont icon-dituhuizhi",
+								widget: "DialogEdit"
+							},
+							{
+								name: "地区导航",
+								icon: "iconfont icon-zhijiantou",
+								widget: "navigate"
+							},
+							{
+								name: "视角标签",
+								icon: "iconfont icon-fushi",
+								widget: "viewerlabel"
+							},
+						]
+					},
+					{
+						name: "清除",
+						icon: "iconfont icon-shanchu",
+						widget: "clearAll"
+					},
+				]
+			}
+		},
+		/* 方法 */
+		methods: {
+			showWidget: function(type) {
+				//全图
+				if (type === "fullMap") {
+					this.$parent.$refs.refMap3d.fullMap(jt3d);
+				}
+				//绕点自旋
+				if (type === "rotateCamera") {
+					ElMessage.warning('在地图上单击进行自旋,再次单击停止自旋')
+					jt3d.SketchViewModel.sketchTools('point', {
+						onComplete(cPoint, gPoint) {
+							jt3d.setMapSpinByPoint(cPoint);
+						},
+						onError(message) {}
+					});
+				}
+				//清除所有
+				if (type == "clearAll") {
+					jt3d.DrawToolsEdit.Clear();
+					jt3d.DrawMilitaryPlot.clearAll();
+
+					//清除测量
+					jt3d.CommonTools.clear();
+					this.$parent.$refs._refMeasure.currentIndex = -1;
+					if (this.$parent.$refs._refMeasure.popup) {
+						this.$parent.$refs._refMeasure.popup.close();
+					}
+
+					//移除光照分析
+					if (!jt3d.statusBar.show) {
+						jt3d.statusBar.show = true;
+					}
+					jt3d.SpatialAnalysis.SunshineShadow.remove();
+
+					//移除剖面分析结果
+					this.$parent.closeDrawerSectionAnalysis();
+
+					//清除坐标定位
+					this.$parent.$refs._refCoordsTool.empty();
+
+					//清除空间分析
+					this.$parent.$refs._refAnalysisSpace.init();
+
+					//清除地形分析
+					this.$parent.$refs._refAnalysisTerrain.init();
+
+					//还原左键单击事件
+					this.$parent.$refs.refMap3d.clickEntity(jt3d);
+
+					/* 开启地形检测 必须开启 否则会导致获取地形高度时异常 导致鼠标移动时位置哆嗦 */
+					jt3d._viewer.scene.globe.depthTestAgainstTerrain = true;
+				}
+				
+				//图层控制
+				if (type === "layers") {
+					// this.closePopup()
+					// this.$parent.$refs.refLayerPopup.isshow = true;
+					
+						this.$myPop('layer',{isShow:true})
+				}
+				//底图切换
+				if (type === "basicLayer") {
+					this.closePopup()
+					this.$parent.showbasicLayer = true
+				}
+
+				//视角标签
+				if (type == "viewerlabel") {
+					this.closePopup()
+					this.$parent.$refs.refviewerlabel.isshow = true
+				}
+
+				//图上绘制组件
+				if (type === 'DialogEdit') {
+					this.closePopup()
+					this.$parent.$refs.refDialogEdit.isshow = true
+				}
+				//区域导航
+				if (type === 'navigate') {
+					this.closePopup()
+					this.$parent.$refs.refmapNavigate.isshow = true
+				}
+				//视角标签
+				if (type === 'viewerlabel') {
+					this.closePopup()
+					this.$parent.$refs.refviewerlabel.isshow = true
+				}
+				//打印地图
+				if (type === 'printmap') {
+					this.closePopup()
+					// this.$bus.emit("screenshot")
+					this.$parent.$refs._refprintmap.screenshot();
+					setTimeout(() => {
+						this.$parent.$refs.refprintmap.isshow = true
+					}, 50);
+				}
+				//图上量算
+				if (type === 'measure') {
+					this.closePopup()
+					this.$parent.$refs.refMeasure.isshow = true;
+				}
+				//图形查询
+				if (type === 'query-graphics') {
+					this.closePopup()
+					this.$parent.$refs.refQueryGraphics.isshow = true;
+				}
+				//数据分析
+				if (type === 'analysis-data') {
+					this.closePopup()
+					this.$parent.$refs.refAnalysisData.isshow = true;
+				}
+				//空间分析
+				if (type === 'analysis-space') {
+					this.closePopup()
+					this.$parent.$refs.refAnalysisSpace.isshow = true;
+				}
+				//地形分析
+				if (type === 'analysis-terrain') {
+					this.closePopup()
+					this.$parent.$refs.refAnalysisTerrain.isshow = true;
+				}
+				//特效效果
+				if (type === 'special-effects') {
+					this.closePopup()
+					this.$parent.$refs.refSpecialEffects.isshow = true;
+				}
+				//坐标定位拾取
+				if (type === 'coordsTool') {
+					this.closePopup()
+					this.$parent.$refs.refCoordsTool.isshow = true;
+				}
+				//飞行漫游
+				if (type === 'TrackRoam') {
+					this.closePopup()
+					this.$parent.$refs.refTrackRoam.isshow = true;
+				}
+				//卷帘对比
+				if (type === 'ImageLayerSplit') {
+					this.closePopup();
+					this.$parent.$refs.refImageLayerSplit.isshow = true;
+					this.$parent.$refs._refImageLayerSplit.initSplitLayer(); //开启卷帘
+				}
+				//分屏对比
+				if (type === 'ViewerSplitScreen') {
+					this.closePopup();
+					this.$parent.$refs.refViewerSplitScreen.isshow = true;
+					this.$parent.$refs.refLayerPopup.isshow = true;
+					this.$parent.$refs._refViewerSplitScreen.initSplitScreen(); //开启分屏
+				}
+			},
+
+			//关闭所有弹框
+			closePopup() {
+				this.$parent.$refs.refMeasure.isshow = false;
+				this.$parent.$refs.refQueryGraphics.isshow = false;
+				this.$parent.$refs.refAnalysisData.isshow = false;
+				this.$parent.$refs.refAnalysisSpace.isshow = false;
+				this.$parent.$refs.refAnalysisTerrain.isshow = false;
+				this.$parent.$refs.refSpecialEffects.isshow = false;
+				this.$parent.$refs.refCoordsTool.isshow = false;
+				this.$parent.$refs.refTrackRoam.isshow = false;
+				this.$parent.$refs.refViewerSplitScreen.isshow = false;
+				this.$parent.$refs.refImageLayerSplit.isshow = false;
+				this.$parent.$refs.refmapNavigate.isshow = false;
+				this.$parent.$refs.refviewerlabel.isshow = false;
+				this.$parent.$refs.refprintmap.isshow = false;
+				this.$parent.$refs.refDialogEdit.isshow = false;
+				this.$parent.showbasicLayer = false;
+				this.$parent.$refs.refLayerPopup.isshow = false;
+				if (this.$parent.$refs._refImageLayerSplit) {
+					this.$parent.$refs._refImageLayerSplit.removeSplitLayer(); //关闭卷帘
+				}
+				if (this.$parent.$refs._refViewerSplitScreen) {
+					this.$parent.$refs._refViewerSplitScreen.removeSplitScreen(); //关闭分屏
+				}
+			},
+		},
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.text::before {
+		position: absolute;
+		width: 0rem;
+		height: 0rem;
+		left: calc(50% - 5rem);
+		top: -5rem;
+		content: '';
+		transform: rotate(45deg);
+		z-index: 10;
+		box-sizing: border-box;
+		border-bottom: 5rem solid transparent;
+		border-right: 5rem solid transparent;
+		border-top: 5rem solid rgba(255, 255, 255, 1);
+		border-left: 5rem solid rgba(255, 255, 255, 1);
+		// background: rgba(5, 45, 115, .8) !important;
+	}
+
+	.jt-toolbars {
+		position: absolute;
+		top: 80rem;
+		width: auto;
+		right: 20rem;
+		cursor: pointer !important;
+		padding: 0rem 10rem !important;
+		margin: 0rem !important;
+		background-image: none !important;
+		border: 1rem solid;
+		border: none;
+		border-radius: 2rem !important;
+		background-color: rgb(0 44 126 / 65%);
+		height: 40rem;
+		box-sizing: border-box;
+		line-height: 38rem;
+		text-align: left;
+		user-select: none;
+
+		cursor: default;
+
+		.toolbar-item {
+			display: inline-block;
+			padding: 0rem 10rem;
+
+			margin: 0rem;
+			height: calc(100% - 4rem);
+			color: #fff;
+			font-size: 15rem;
+			vertical-align: middle;
+
+			&:hover {
+				background-color: rgba(255, 255, 255, 0.3);
+			}
+
+			.title {
+				font-size: 16rem;
+			}
+		}
+
+		.toolbar-item:nth-last-child(1) {
+			padding-right: 0rem;
+		}
+
+		.el-icon {
+			margin-right: 5rem;
+			color: #fff;
+		}
+
+		.el-dropdown {
+			// vertical-align: middle;
+			height: 40rem;
+			line-height: 38rem;
+			box-sizing: border-box;
+		}
+	}
+</style>

+ 380 - 0
src/views/Map3d - 副本 (2)/备份/toolbars - 副本 (3).vue

@@ -0,0 +1,380 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	/**
+	 * element-plus字体
+	 */
+	import {
+		ArrowDown
+	} from '@element-plus/icons-vue';
+
+
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+	
+	
+	import { useWidget } from "@/common/store/widget"
+	
+	const { activate } = useWidget()
+	
+	const showWidget = (widget) => {
+	  activate(widget)
+	}
+	
+	const clickMenu = ({ key }) => {
+	  showWidget(key)
+	}
+</script>
+
+<template>
+	<div class="jt-toolbars fadein-right">
+		<template v-for="(item, i) in toolDatas" :key="i">
+			<div v-if="item.widget && !item.children" class="toolbar-item" @click="showWidget(item.widget)">
+				<i :class="item.icon" />
+				<span class="title">{{ item.name }}</span>
+			</div>
+			<el-dropdown v-if="item.children && !item.widget" class="toolbar-item" :hide-on-click="false" @command="handleCommand">
+				<span class="el-dropdown-link">
+					<i :class="item.icon" />
+					<span class="title">{{ item.name }}</span>
+					<el-icon class="el-icon--right">
+						<ArrowDown />
+					</el-icon>
+				</span>
+				<template #dropdown>
+					<span slot="slot" class="text"></span>
+					<el-dropdown-menu>
+						<el-dropdown-item v-for="child in item.children" :key="child.widget" :title="child.name" @click="showWidget(child.widget)">
+							<i :class="child.icon" />
+							<span>{{ child.name }}</span>
+						</el-dropdown-item>
+					</el-dropdown-menu>
+				</template>
+			</el-dropdown>
+		</template>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+
+	export default {
+		name: "jt-toolbars",
+		data() {
+			return {
+				toolDatas: [
+					// {
+					// 	name: "绕点自旋",
+					// 	icon: "iconfont icon-chaxunzuobiaozhi",
+					// 	widget: "rotateCamera"
+					// },
+					// {
+					// 	name: "全图",
+					// 	icon: "iconfont icon-chaxunzuobiaozhi",
+					// 	widget: "fullMap"
+					// },
+					{
+						name: "底图",
+						icon: "iconfont icon-dituzuobiao",
+						widget: "basicLayer"
+					},
+					{
+						name: "图层",
+						icon: "iconfont icon-winfo-icon-tucengkongzhi",
+						widget: "layer"
+					},
+					{
+						name: "工具",
+						icon: "iconfont icon-xitong1",
+						children: [{
+								name: "图上标绘",
+								icon: "iconfont icon-dituhuizhi",
+								widget: "DialogEdit"
+							},
+							{
+								name: "地区导航",
+								icon: "iconfont icon-zhijiantou",
+								widget: "navigate"
+							},
+							{
+								name: "视角标签",
+								icon: "iconfont icon-fushi",
+								widget: "viewerlabel"
+							},
+						]
+					},
+					{
+						name: "清除",
+						icon: "iconfont icon-shanchu",
+						widget: "clearAll"
+					},
+				]
+			}
+		},
+		/* 方法 */
+		methods: {
+			
+			showWidget3333: function(type) {
+				//全图
+				if (type === "fullMap") {
+					this.$parent.$refs.refMap3d.fullMap(jt3d);
+				}
+				//绕点自旋
+				if (type === "rotateCamera") {
+					ElMessage.warning('在地图上单击进行自旋,再次单击停止自旋')
+					jt3d.SketchViewModel.sketchTools('point', {
+						onComplete(cPoint, gPoint) {
+							jt3d.setMapSpinByPoint(cPoint);
+						},
+						onError(message) {}
+					});
+				}
+				//清除所有
+				if (type == "clearAll") {
+					jt3d.DrawToolsEdit.Clear();
+					jt3d.DrawMilitaryPlot.clearAll();
+
+					//清除测量
+					jt3d.CommonTools.clear();
+					this.$parent.$refs._refMeasure.currentIndex = -1;
+					if (this.$parent.$refs._refMeasure.popup) {
+						this.$parent.$refs._refMeasure.popup.close();
+					}
+
+					//移除光照分析
+					if (!jt3d.statusBar.show) {
+						jt3d.statusBar.show = true;
+					}
+					jt3d.SpatialAnalysis.SunshineShadow.remove();
+
+					//移除剖面分析结果
+					this.$parent.closeDrawerSectionAnalysis();
+
+					//清除坐标定位
+					this.$parent.$refs._refCoordsTool.empty();
+
+					//清除空间分析
+					this.$parent.$refs._refAnalysisSpace.init();
+
+					//清除地形分析
+					this.$parent.$refs._refAnalysisTerrain.init();
+
+					//还原左键单击事件
+					this.$parent.$refs.refMap3d.clickEntity(jt3d);
+
+					/* 开启地形检测 必须开启 否则会导致获取地形高度时异常 导致鼠标移动时位置哆嗦 */
+					jt3d._viewer.scene.globe.depthTestAgainstTerrain = true;
+				}
+
+				//图层控制
+				if (type === "layers") {
+					this.closePopup()
+					this.$parent.$refs.refLayerPopup.isshow = true;
+				}
+				//底图切换
+				if (type === "basicLayer") {
+					this.closePopup()
+					this.$parent.showbasicLayer = true
+				}
+
+				//视角标签
+				if (type == "viewerlabel") {
+					this.closePopup()
+					this.$parent.$refs.refviewerlabel.isshow = true
+				}
+
+				//图上绘制组件
+				if (type === 'DialogEdit') {
+					this.closePopup()
+					this.$parent.$refs.refDialogEdit.isshow = true
+				}
+				//区域导航
+				if (type === 'navigate') {
+					this.closePopup()
+					this.$parent.$refs.refmapNavigate.isshow = true
+				}
+				//视角标签
+				if (type === 'viewerlabel') {
+					this.closePopup()
+					this.$parent.$refs.refviewerlabel.isshow = true
+				}
+				//打印地图
+				if (type === 'printmap') {
+					this.closePopup()
+					// this.$bus.emit("screenshot")
+					this.$parent.$refs._refprintmap.screenshot();
+					setTimeout(() => {
+						this.$parent.$refs.refprintmap.isshow = true
+					}, 50);
+				}
+				//图上量算
+				if (type === 'measure') {
+					this.closePopup()
+					this.$parent.$refs.refMeasure.isshow = true;
+				}
+				//图形查询
+				if (type === 'query-graphics') {
+					this.closePopup()
+					this.$parent.$refs.refQueryGraphics.isshow = true;
+				}
+				//数据分析
+				if (type === 'analysis-data') {
+					this.closePopup()
+					this.$parent.$refs.refAnalysisData.isshow = true;
+				}
+				//空间分析
+				if (type === 'analysis-space') {
+					this.closePopup()
+					this.$parent.$refs.refAnalysisSpace.isshow = true;
+				}
+				//地形分析
+				if (type === 'analysis-terrain') {
+					this.closePopup()
+					this.$parent.$refs.refAnalysisTerrain.isshow = true;
+				}
+				//特效效果
+				if (type === 'special-effects') {
+					this.closePopup()
+					this.$parent.$refs.refSpecialEffects.isshow = true;
+				}
+				//坐标定位拾取
+				if (type === 'coordsTool') {
+					this.closePopup()
+					this.$parent.$refs.refCoordsTool.isshow = true;
+				}
+				//飞行漫游
+				if (type === 'TrackRoam') {
+					this.closePopup()
+					this.$parent.$refs.refTrackRoam.isshow = true;
+				}
+				//卷帘对比
+				if (type === 'ImageLayerSplit') {
+					this.closePopup();
+					this.$parent.$refs.refImageLayerSplit.isshow = true;
+					this.$parent.$refs._refImageLayerSplit.initSplitLayer(); //开启卷帘
+				}
+				//分屏对比
+				if (type === 'ViewerSplitScreen') {
+					this.closePopup();
+					this.$parent.$refs.refViewerSplitScreen.isshow = true;
+					this.$parent.$refs.refLayerPopup.isshow = true;
+					this.$parent.$refs._refViewerSplitScreen.initSplitScreen(); //开启分屏
+				}
+			},
+
+			//关闭所有弹框
+			closePopup() {
+				this.$parent.$refs.refMeasure.isshow = false;
+				this.$parent.$refs.refQueryGraphics.isshow = false;
+				this.$parent.$refs.refAnalysisData.isshow = false;
+				this.$parent.$refs.refAnalysisSpace.isshow = false;
+				this.$parent.$refs.refAnalysisTerrain.isshow = false;
+				this.$parent.$refs.refSpecialEffects.isshow = false;
+				this.$parent.$refs.refCoordsTool.isshow = false;
+				this.$parent.$refs.refTrackRoam.isshow = false;
+				this.$parent.$refs.refViewerSplitScreen.isshow = false;
+				this.$parent.$refs.refImageLayerSplit.isshow = false;
+				this.$parent.$refs.refmapNavigate.isshow = false;
+				this.$parent.$refs.refviewerlabel.isshow = false;
+				this.$parent.$refs.refprintmap.isshow = false;
+				this.$parent.$refs.refDialogEdit.isshow = false;
+				this.$parent.showbasicLayer = false;
+				this.$parent.$refs.refLayerPopup.isshow = false;
+				if (this.$parent.$refs._refImageLayerSplit) {
+					this.$parent.$refs._refImageLayerSplit.removeSplitLayer(); //关闭卷帘
+				}
+				if (this.$parent.$refs._refViewerSplitScreen) {
+					this.$parent.$refs._refViewerSplitScreen.removeSplitScreen(); //关闭分屏
+				}
+			},
+		},
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.text::before {
+		position: absolute;
+		width: 0rem;
+		height: 0rem;
+		left: calc(50% - 5rem);
+		top: -5rem;
+		content: '';
+		transform: rotate(45deg);
+		z-index: 10;
+		box-sizing: border-box;
+		border-bottom: 5rem solid transparent;
+		border-right: 5rem solid transparent;
+		border-top: 5rem solid rgba(255, 255, 255, 1);
+		border-left: 5rem solid rgba(255, 255, 255, 1);
+		// background: rgba(5, 45, 115, .8) !important;
+	}
+
+	.jt-toolbars {
+		position: absolute;
+		top: 80rem;
+		width: auto;
+		right: 20rem;
+		cursor: pointer !important;
+		padding: 0rem 10rem !important;
+		margin: 0rem !important;
+		background-image: none !important;
+		border: 1rem solid;
+		border: none;
+		border-radius: 2rem !important;
+		background-color: rgb(0 44 126 / 65%);
+		height: 40rem;
+		box-sizing: border-box;
+		line-height: 38rem;
+		text-align: left;
+		user-select: none;
+
+		cursor: default;
+
+		.toolbar-item {
+			display: inline-block;
+			padding: 0rem 10rem;
+
+			margin: 0rem;
+			height: calc(100% - 4rem);
+			color: #fff;
+			font-size: 15rem;
+			vertical-align: middle;
+
+			&:hover {
+				background-color: rgba(255, 255, 255, 0.3);
+			}
+
+			.title {
+				font-size: 16rem;
+			}
+		}
+
+		.toolbar-item:nth-last-child(1) {
+			padding-right: 0rem;
+		}
+
+		.el-icon {
+			margin-right: 5rem;
+			color: #fff;
+		}
+
+		.el-dropdown {
+			// vertical-align: middle;
+			height: 40rem;
+			line-height: 38rem;
+			box-sizing: border-box;
+		}
+	}
+</style>

+ 431 - 0
src/views/Map3d - 副本 (2)/备份/toolbars - 副本 (4).vue

@@ -0,0 +1,431 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	/**
+	 * element-plus字体
+	 */
+	import {
+		ArrowDown
+	} from '@element-plus/icons-vue';
+
+
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+
+
+	import {
+		useWidget
+	} from "common/store/widget"
+
+	const {
+		activate
+	} = useWidget()
+
+	const showWidget = (widget) => {
+		//全图
+		if (widget === "fullMap") {
+			this.$parent.$refs.refMap3d.fullMap(jt3d);
+		}
+		//绕点自旋
+		else if (widget === "rotateCamera") {
+			ElMessage.warning('在地图上单击进行自旋,再次单击停止自旋')
+			jt3d.SketchViewModel.sketchTools('point', {
+				onComplete(cPoint, gPoint) {
+					jt3d.setMapSpinByPoint(cPoint);
+				},
+				onError(message) {}
+			});
+		}
+		//清除所有
+		else if (widget === "clearAll") {
+			jt3d.DrawToolsEdit.Clear();
+			jt3d.DrawMilitaryPlot.clearAll();
+
+			//清除测量
+			jt3d.CommonTools.clear();
+			this.$parent.$refs._refMeasure.currentIndex = -1;
+			if (this.$parent.$refs._refMeasure.popup) {
+				this.$parent.$refs._refMeasure.popup.close();
+			}
+
+			//移除光照分析
+			if (!jt3d.statusBar.show) {
+				jt3d.statusBar.show = true;
+			}
+			jt3d.SpatialAnalysis.SunshineShadow.remove();
+
+			//移除剖面分析结果
+			this.$parent.closeDrawerSectionAnalysis();
+
+			//清除坐标定位
+			this.$parent.$refs._refCoordsTool.empty();
+
+			//清除空间分析
+			this.$parent.$refs._refAnalysisSpace.init();
+
+			//清除地形分析
+			this.$parent.$refs._refAnalysisTerrain.init();
+
+			//还原左键单击事件
+			this.$parent.$refs.refMap3d.clickEntity(jt3d);
+
+			/* 开启地形检测 必须开启 否则会导致获取地形高度时异常 导致鼠标移动时位置哆嗦 */
+			jt3d._viewer.scene.globe.depthTestAgainstTerrain = true;
+		} else {
+			activate(widget)
+		}
+	}
+</script>
+
+<template>
+	<div class="jt-toolbars fadein-right">
+		<template v-for="(item, i) in toolDatas" :key="i">
+			<div v-if="item.widget && !item.children" class="toolbar-item" @click="showWidget(item.widget)">
+				<i :class="item.icon" />
+				<span class="title">{{ item.name }}</span>
+			</div>
+			<el-dropdown v-if="item.children && !item.widget" class="toolbar-item" >
+				<span class="el-dropdown-link">
+					<i :class="item.icon" />
+					<span class="title">{{ item.name }}</span>
+					<el-icon class="el-icon--right">
+						<ArrowDown />
+					</el-icon>
+				</span>
+				<template #dropdown>
+					<span slot="slot" class="text"></span>
+					<el-dropdown-menu>
+						<el-dropdown-item v-for="child in item.children" :title="child.name" @click="showWidget(child.widget)">
+							<i :class="child.icon" />
+							<span>{{ child.name }}</span>
+						</el-dropdown-item>
+					</el-dropdown-menu>
+				</template>
+			</el-dropdown>
+		</template>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+
+	export default {
+		name: "jt-toolbars",
+		data() {
+			return {
+				toolDatas:store.menuList,
+				toolDatas22: [{
+						name: "绕点自旋",
+						icon: "iconfont icon-chaxunzuobiaozhi",
+						widget: "rotateCamera"
+					},
+					{
+						name: "全图",
+						icon: "iconfont icon-chaxunzuobiaozhi",
+						widget: "fullMap"
+					},
+					{
+						name: "底图",
+						icon: "iconfont icon-dituzuobiao",
+						widget: "basicLayer"
+					},
+					{
+						name: "图层",
+						icon: "iconfont icon-winfo-icon-tucengkongzhi",
+						widget: "layer"
+					},
+					{
+						name: "工具",
+						icon: "iconfont icon-xitong1",
+						children: [{
+								name: "图上标绘",
+								icon: "iconfont icon-dituhuizhi",
+								widget: "DialogEdit"
+							},
+							{
+								name: "地区导航",
+								icon: "iconfont icon-zhijiantou",
+								widget: "navigate"
+							},
+							{
+								name: "视角标签",
+								icon: "iconfont icon-fushi",
+								widget: "viewerlabel"
+							},
+						]
+					},
+					{
+						name: "清除",
+						icon: "iconfont icon-shanchu",
+						widget: "clearAll"
+					},
+				]
+			}
+		},
+		/* 方法 */
+		methods: {
+
+			showWidget3333: function(type) {
+				//全图
+				if (type === "fullMap") {
+					this.$parent.$refs.refMap3d.fullMap(jt3d);
+				}
+				//绕点自旋
+				if (type === "rotateCamera") {
+					ElMessage.warning('在地图上单击进行自旋,再次单击停止自旋')
+					jt3d.SketchViewModel.sketchTools('point', {
+						onComplete(cPoint, gPoint) {
+							jt3d.setMapSpinByPoint(cPoint);
+						},
+						onError(message) {}
+					});
+				}
+				//清除所有
+				if (type == "clearAll") {
+					jt3d.DrawToolsEdit.Clear();
+					jt3d.DrawMilitaryPlot.clearAll();
+
+					//清除测量
+					jt3d.CommonTools.clear();
+					this.$parent.$refs._refMeasure.currentIndex = -1;
+					if (this.$parent.$refs._refMeasure.popup) {
+						this.$parent.$refs._refMeasure.popup.close();
+					}
+
+					//移除光照分析
+					if (!jt3d.statusBar.show) {
+						jt3d.statusBar.show = true;
+					}
+					jt3d.SpatialAnalysis.SunshineShadow.remove();
+
+					//移除剖面分析结果
+					this.$parent.closeDrawerSectionAnalysis();
+
+					//清除坐标定位
+					this.$parent.$refs._refCoordsTool.empty();
+
+					//清除空间分析
+					this.$parent.$refs._refAnalysisSpace.init();
+
+					//清除地形分析
+					this.$parent.$refs._refAnalysisTerrain.init();
+
+					//还原左键单击事件
+					this.$parent.$refs.refMap3d.clickEntity(jt3d);
+
+					/* 开启地形检测 必须开启 否则会导致获取地形高度时异常 导致鼠标移动时位置哆嗦 */
+					jt3d._viewer.scene.globe.depthTestAgainstTerrain = true;
+				}
+
+				//图层控制
+				if (type === "layers") {
+					this.closePopup()
+					this.$parent.$refs.refLayerPopup.isshow = true;
+				}
+				//底图切换
+				if (type === "basicLayer") {
+					this.closePopup()
+					this.$parent.showbasicLayer = true
+				}
+
+				//视角标签
+				if (type == "viewerlabel") {
+					this.closePopup()
+					this.$parent.$refs.refviewerlabel.isshow = true
+				}
+
+				//图上绘制组件
+				if (type === 'DialogEdit') {
+					this.closePopup()
+					this.$parent.$refs.refDialogEdit.isshow = true
+				}
+				//区域导航
+				if (type === 'navigate') {
+					this.closePopup()
+					this.$parent.$refs.refmapNavigate.isshow = true
+				}
+				//视角标签
+				if (type === 'viewerlabel') {
+					this.closePopup()
+					this.$parent.$refs.refviewerlabel.isshow = true
+				}
+				//打印地图
+				if (type === 'printmap') {
+					this.closePopup()
+					// this.$bus.emit("screenshot")
+					this.$parent.$refs._refprintmap.screenshot();
+					setTimeout(() => {
+						this.$parent.$refs.refprintmap.isshow = true
+					}, 50);
+				}
+				//图上量算
+				if (type === 'measure') {
+					this.closePopup()
+					this.$parent.$refs.refMeasure.isshow = true;
+				}
+				//图形查询
+				if (type === 'query-graphics') {
+					this.closePopup()
+					this.$parent.$refs.refQueryGraphics.isshow = true;
+				}
+				//数据分析
+				if (type === 'analysis-data') {
+					this.closePopup()
+					this.$parent.$refs.refAnalysisData.isshow = true;
+				}
+				//空间分析
+				if (type === 'analysis-space') {
+					this.closePopup()
+					this.$parent.$refs.refAnalysisSpace.isshow = true;
+				}
+				//地形分析
+				if (type === 'analysis-terrain') {
+					this.closePopup()
+					this.$parent.$refs.refAnalysisTerrain.isshow = true;
+				}
+				//特效效果
+				if (type === 'special-effects') {
+					this.closePopup()
+					this.$parent.$refs.refSpecialEffects.isshow = true;
+				}
+				//坐标定位拾取
+				if (type === 'coordsTool') {
+					this.closePopup()
+					this.$parent.$refs.refCoordsTool.isshow = true;
+				}
+				//飞行漫游
+				if (type === 'TrackRoam') {
+					this.closePopup()
+					this.$parent.$refs.refTrackRoam.isshow = true;
+				}
+				//卷帘对比
+				if (type === 'ImageLayerSplit') {
+					this.closePopup();
+					this.$parent.$refs.refImageLayerSplit.isshow = true;
+					this.$parent.$refs._refImageLayerSplit.initSplitLayer(); //开启卷帘
+				}
+				//分屏对比
+				if (type === 'ViewerSplitScreen') {
+					this.closePopup();
+					this.$parent.$refs.refViewerSplitScreen.isshow = true;
+					this.$parent.$refs.refLayerPopup.isshow = true;
+					this.$parent.$refs._refViewerSplitScreen.initSplitScreen(); //开启分屏
+				}
+			},
+
+			//关闭所有弹框
+			closePopup() {
+				this.$parent.$refs.refMeasure.isshow = false;
+				this.$parent.$refs.refQueryGraphics.isshow = false;
+				this.$parent.$refs.refAnalysisData.isshow = false;
+				this.$parent.$refs.refAnalysisSpace.isshow = false;
+				this.$parent.$refs.refAnalysisTerrain.isshow = false;
+				this.$parent.$refs.refSpecialEffects.isshow = false;
+				this.$parent.$refs.refCoordsTool.isshow = false;
+				this.$parent.$refs.refTrackRoam.isshow = false;
+				this.$parent.$refs.refViewerSplitScreen.isshow = false;
+				this.$parent.$refs.refImageLayerSplit.isshow = false;
+				this.$parent.$refs.refmapNavigate.isshow = false;
+				this.$parent.$refs.refviewerlabel.isshow = false;
+				this.$parent.$refs.refprintmap.isshow = false;
+				this.$parent.$refs.refDialogEdit.isshow = false;
+				this.$parent.showbasicLayer = false;
+				this.$parent.$refs.refLayerPopup.isshow = false;
+				if (this.$parent.$refs._refImageLayerSplit) {
+					this.$parent.$refs._refImageLayerSplit.removeSplitLayer(); //关闭卷帘
+				}
+				if (this.$parent.$refs._refViewerSplitScreen) {
+					this.$parent.$refs._refViewerSplitScreen.removeSplitScreen(); //关闭分屏
+				}
+			},
+		},
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.text::before {
+		position: absolute;
+		width: 0rem;
+		height: 0rem;
+		left: calc(50% - 5rem);
+		top: -5rem;
+		content: '';
+		transform: rotate(45deg);
+		z-index: 10;
+		box-sizing: border-box;
+		border-bottom: 5rem solid transparent;
+		border-right: 5rem solid transparent;
+		border-top: 5rem solid rgba(255, 255, 255, 1);
+		border-left: 5rem solid rgba(255, 255, 255, 1);
+		// background: rgba(5, 45, 115, .8) !important;
+	}
+
+	.jt-toolbars {
+		position: absolute;
+		top: 80rem;
+		width: auto;
+		right: 20rem;
+		cursor: pointer !important;
+		padding: 0rem 10rem !important;
+		margin: 0rem !important;
+		background-image: none !important;
+		border: 1rem solid;
+		border: none;
+		border-radius: 2rem !important;
+		background-color: rgb(0 44 126 / 65%);
+		height: 40rem;
+		box-sizing: border-box;
+		line-height: 38rem;
+		text-align: left;
+		user-select: none;
+
+		cursor: default;
+
+		.toolbar-item {
+			display: inline-block;
+			padding: 0rem 10rem;
+
+			margin: 0rem;
+			height: calc(100% - 4rem);
+			color: #fff;
+			font-size: 15rem;
+			vertical-align: middle;
+
+			&:hover {
+				background-color: rgba(255, 255, 255, 0.3);
+			}
+
+			.title {
+				font-size: 16rem;
+			}
+		}
+
+		.toolbar-item:nth-last-child(1) {
+			padding-right: 0rem;
+		}
+
+		.el-icon {
+			margin-right: 5rem;
+			color: #fff;
+		}
+
+		.el-dropdown {
+			// vertical-align: middle;
+			height: 40rem;
+			line-height: 38rem;
+			box-sizing: border-box;
+		}
+	}
+</style>

+ 445 - 0
src/views/Map3d - 副本 (2)/备份/toolbars - 副本.vue

@@ -0,0 +1,445 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	/**
+	 * element-plus字体
+	 */
+	import {
+		ArrowDown
+	} from '@element-plus/icons-vue';
+	import {
+		Store
+	} from '@/store/index';
+	store = Store()
+	import {
+		inject
+	} from "vue";
+	import html2canvas from "html2canvas";
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="toolbars fadein-right">
+		<!-- <div class="toolbar-item" @click="PolylineObject()">
+			<i class="iconfont icon-winfo-icon-tucengkongzhi"></i>
+			<span class="title">
+				测试动态线
+			</span>
+		</div> -->
+		<div class="toolbar-item" @click="showWidget('rotateCamera')">
+			<i class="iconfont icon-chaxunzuobiaozhi" />
+			<span class="title">
+				绕点旋转
+			</span>
+		</div>
+		<div class="toolbar-item" @click="showWidget('fullMap')">
+			<i class="iconfont icon-chaxunzuobiaozhi" />
+			<span class="title">
+				全图
+			</span>
+		</div>
+		<div class="toolbar-item" @click="showWidget('basicLayer')">
+			<i class="iconfont icon-dituzuobiao" />
+			<span class="title">
+				底图
+			</span>
+		</div>
+		<div class="toolbar-item" @click="showWidget('layers')">
+			<i class="iconfont icon-winfo-icon-tucengkongzhi"></i>
+			<span class="title">
+				图层
+			</span>
+		</div>
+		<el-dropdown class="toolbar-item" :hide-on-click="false" @command="handleCommand">
+			<span class="el-dropdown-link">
+				<i class="iconfont icon-xitong1" />
+				<span class="title">
+					工具
+				</span>
+				<el-icon class="el-icon--right">
+					<ArrowDown />
+				</el-icon>
+			</span>
+			<template #dropdown>
+				<span slot="slot" class="text"></span>
+				<el-dropdown-menu>
+					<el-dropdown-item command="DialogEdit"><i class="iconfont minsize icon-dituhuizhi"></i>图上标绘</el-dropdown-item>
+					<el-dropdown-item command="navigate"><i class="iconfont icon-zhijiantou"></i>地区导航</el-dropdown-item>
+					<el-dropdown-item command="viewerlabel"><i class="iconfont minsize icon-fushi"></i>视角标签</el-dropdown-item>
+					<el-dropdown-item v-if="store.userport=='PC'" command="printmap"><i class="iconfont maxsize icon-svgdayin"></i>打印地图</el-dropdown-item>
+					<el-dropdown-item command="measure"><i class="iconfont minsize icon-icon_measureTool"></i>图上量算</el-dropdown-item>
+					<el-dropdown-item command="query-graphics"><i class="iconfont icon-search"></i>图形查询</el-dropdown-item>
+					<el-dropdown-item command="analysis-data"><i class="iconfont maxsize icon-svgjiexiwenjian"></i>文件解析</el-dropdown-item>
+					<el-dropdown-item command="analysis-space"><i class="iconfont icon-duodiankeshiyu"></i>空间分析</el-dropdown-item>
+					<el-dropdown-item command="analysis-terrain"><i class="iconfont icon-iconfonttubiao_dixing"></i>地形分析</el-dropdown-item>
+					<el-dropdown-item command="special-effects"><i class="iconfont icon-yu"></i>特效效果</el-dropdown-item>
+					<el-dropdown-item command="coordsTool"><i class="iconfont icon-zuobiao"></i>坐标定位</el-dropdown-item>
+					<el-dropdown-item command="TrackRoam"><i class="iconfont maxsize icon-jurassic_jiankong"></i>路径漫游</el-dropdown-item>
+					<el-dropdown-item command="ImageLayerSplit"><i class="iconfont maxsize icon-juanlian"></i>卷帘对比</el-dropdown-item>
+					<el-dropdown-item command="ViewerSplitScreen"><i class="iconfont minsize icon-fenping"></i>分屏对比</el-dropdown-item>
+				</el-dropdown-menu>
+			</template>
+		</el-dropdown>
+		<div class="toolbar-item" @click="showWidget('clearAll')">
+			<i class="iconfont minsize icon-shanchu"></i>
+			<span class="title">
+				清除
+			</span>
+		</div>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+	let store = undefined
+	export default {
+		name: "toolbars",
+		data() {
+			return {}
+		},
+		/* 方法 */
+		methods: {
+			/**
+			 * 测试动态线
+			 */
+			PolylineObject() {
+				let lines = [
+					[
+						[107.3609526659472, 26.405330345862833],
+						[107.40025603208434, 26.402244579822174]
+					],
+					[
+						[107.3609801462563, 26.40314629662853],
+						[107.3999374877451, 26.400165614674155]
+					],
+					[
+						[107.36081944593964, 26.40080706752495],
+						[107.40012685036773, 26.39813952738571],
+					],
+					[
+						[107.36067906760677, 26.398625963837965],
+						[107.40034550598207, 26.39670894997551],
+					],
+				];
+
+				//定位
+				jt3d._viewer.scene.camera.setView({
+					duration: 1,
+					destination: {
+						x: -1709251.0767395466,
+						y: 5461386.32337908,
+						z: 2820645.238657382
+					},
+					orientation: {
+						heading: 0.13762265446730737,
+						pitch: -1.460307026543739,
+						roll: 0.003401834066556475
+					}
+				});
+
+				lines.forEach((item, index) => {
+
+					if (index === 0) {
+						let a1 = jt3d.PolylineObject.PolylineLinkPulseMaterialProperty(item, {
+							width: 11,
+							color: 'RED',
+							duration: 20000,
+							imgUrl: "jt3dSDK/imgs/polylinematerial/LinkPulse.png",
+							isImageAlpha: false,
+						});
+						a1.then(function() {
+
+						});
+					}
+
+					if (index === 1) {
+						jt3d.PolylineObject.PolylineArrowMaterialProperty(item, {
+							width: 10,
+							color: "YELLOW",
+							duration: 1000,
+							count: 5,
+							direction: "horizontal",
+							order: "+",
+							imgUrl: "jt3dSDK/imgs/polylinematerial/arrowopacity.png",
+							isImageAlpha: false,
+						});
+					}
+
+					if (index === 2) {
+						jt3d.PolylineObject.PolylineArrowMaterialProperty(item, {
+							width: 10,
+							color: 'BLUE',
+							duration: 1000,
+							count: 20,
+							direction: "horizontal",
+							order: "+",
+							imgUrl: "jt3dSDK/imgs/polylinematerial/arrowopacity.png",
+							isImageAlpha: false,
+						});
+					}
+
+					if (index === 3) {
+						jt3d.PolylineObject.PolylineLinkPulseMaterialProperty(item, {
+							width: 10,
+							color: 'GREEN',
+							duration: 10000,
+							imgUrl: "jt3dSDK/imgs/polylinematerial/20201124170520929.png",
+							isImageAlpha: false,
+						});
+					}
+				});
+			},
+
+			showWidget: function(type) {
+				if (type === "layers") {
+					this.closePopup()
+					this.$parent.$refs.refLayerPopup.isshow = true;
+				} else if (type === "fullMap") {
+					this.$parent.$refs.refMap3d.fullMap(jt3d);
+				} else if (type === "rotateCamera") {
+					ElMessage.warning('在地图上单击进行自旋,再次单击停止自旋')
+					jt3d.SketchViewModel.sketchTools('point', {
+						onComplete(cPoint, gPoint) {
+							jt3d.setMapSpinByPoint(cPoint);
+						},
+						onError(message) {}
+					});
+				} else if (type == "viewerlabel") {
+					this.closePopup()
+					this.$parent.$refs.refviewerlabel.isshow = true
+				} else if (type == "clearAll") {//清除所有
+					jt3d.DrawToolsEdit.Clear();
+					jt3d.DrawMilitaryPlot.clearAll();
+					
+					//清除测量
+					jt3d.CommonTools.clear();
+					this.$parent.$refs._refMeasure.currentIndex = -1;
+					if (this.$parent.$refs._refMeasure.popup) {
+						this.$parent.$refs._refMeasure.popup.close();
+					}
+					
+					//移除光照分析
+					if (!jt3d.statusBar.show) {
+						jt3d.statusBar.show = true;
+					}
+					jt3d.SpatialAnalysis.SunshineShadow.remove();
+					
+					//移除剖面分析结果
+					this.$parent.closeDrawerSectionAnalysis();
+					
+					//清除坐标定位
+					this.$parent.$refs._refCoordsTool.empty();
+					
+					//清除空间分析
+					this.$parent.$refs._refAnalysisSpace.init();
+					
+					//清除地形分析
+					this.$parent.$refs._refAnalysisTerrain.init();
+					
+					//还原左键单击事件
+					this.$parent.$refs.refMap3d.clickEntity(jt3d);
+					
+					/* 开启地形检测 必须开启 否则会导致获取地形高度时异常 导致鼠标移动时位置哆嗦 */
+					jt3d._viewer.scene.globe.depthTestAgainstTerrain = true;
+				}else {
+					this.closePopup()
+					this.$parent.showbasicLayer = true
+				}
+
+			},
+
+			//关闭所有弹框
+			closePopup() {
+				this.$parent.$refs.refMeasure.isshow = false;
+				this.$parent.$refs.refQueryGraphics.isshow = false;
+				this.$parent.$refs.refAnalysisData.isshow = false;
+				this.$parent.$refs.refAnalysisSpace.isshow = false;
+				this.$parent.$refs.refAnalysisTerrain.isshow = false;
+				this.$parent.$refs.refSpecialEffects.isshow = false;
+				this.$parent.$refs.refCoordsTool.isshow = false;
+				this.$parent.$refs.refTrackRoam.isshow = false;
+				this.$parent.$refs.refViewerSplitScreen.isshow = false;
+				this.$parent.$refs.refImageLayerSplit.isshow = false;
+				this.$parent.$refs.refmapNavigate.isshow = false;
+				this.$parent.$refs.refviewerlabel.isshow = false;
+				this.$parent.$refs.refprintmap.isshow = false;
+				this.$parent.$refs.refDialogEdit.isshow = false;
+				this.$parent.showbasicLayer = false;
+				this.$parent.$refs.refLayerPopup.isshow = false;
+				if (this.$parent.$refs._refImageLayerSplit) {
+					this.$parent.$refs._refImageLayerSplit.removeSplitLayer(); //关闭卷帘
+				}
+				if (this.$parent.$refs._refViewerSplitScreen) {
+					this.$parent.$refs._refViewerSplitScreen.removeSplitScreen(); //关闭分屏
+				}
+			},
+			/**
+			 * dropdown下拉列表事件
+			 */
+			handleCommand(command) {
+				//图上绘制组件
+				if (command === 'DialogEdit') {
+					this.closePopup()
+					this.$parent.$refs.refDialogEdit.isshow = true
+				}
+				//区域导航
+				if (command === 'navigate') {
+					this.closePopup()
+					this.$parent.$refs.refmapNavigate.isshow = true
+				}
+				//视角标签
+				if (command === 'viewerlabel') {
+					this.closePopup()
+					this.$parent.$refs.refviewerlabel.isshow = true
+				}
+				//打印地图
+				if (command === 'printmap') {
+					this.closePopup()
+					// this.$bus.emit("screenshot")
+					this.$parent.$refs._refprintmap.screenshot();
+					setTimeout(() => {
+						this.$parent.$refs.refprintmap.isshow = true
+					}, 50);
+				}
+				//图上量算
+				if (command === 'measure') {
+					this.closePopup()
+					this.$parent.$refs.refMeasure.isshow = true;
+				}
+				//图形查询
+				if (command === 'query-graphics') {
+					this.closePopup()
+					this.$parent.$refs.refQueryGraphics.isshow = true;
+				}
+				//数据分析
+				if (command === 'analysis-data') {
+					this.closePopup()
+					this.$parent.$refs.refAnalysisData.isshow = true;
+				}
+				//空间分析
+				if (command === 'analysis-space') {
+					this.closePopup()
+					this.$parent.$refs.refAnalysisSpace.isshow = true;
+				}
+				//地形分析
+				if (command === 'analysis-terrain') {
+					this.closePopup()
+					this.$parent.$refs.refAnalysisTerrain.isshow = true;
+				}
+				//特效效果
+				if (command === 'special-effects') {
+					this.closePopup()
+					this.$parent.$refs.refSpecialEffects.isshow = true;
+				}
+				//坐标定位拾取
+				if (command === 'coordsTool') {
+					this.closePopup()
+					this.$parent.$refs.refCoordsTool.isshow = true;
+				}
+				//飞行漫游
+				if (command === 'TrackRoam') {
+					this.closePopup()
+					this.$parent.$refs.refTrackRoam.isshow = true;
+				}
+				//卷帘对比
+				if (command === 'ImageLayerSplit') {
+					this.closePopup();
+					this.$parent.$refs.refImageLayerSplit.isshow = true;
+					this.$parent.$refs._refImageLayerSplit.initSplitLayer(); //开启卷帘
+				}
+				//分屏对比
+				if (command === 'ViewerSplitScreen') {
+					this.closePopup();
+					this.$parent.$refs.refViewerSplitScreen.isshow = true;
+					this.$parent.$refs.refLayerPopup.isshow = true;
+					this.$parent.$refs._refViewerSplitScreen.initSplitScreen(); //开启分屏
+				}
+			},
+		},
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.text::before {
+		position: absolute;
+		width: 0rem;
+		height: 0rem;
+		left: calc(50% - 5rem);
+		top: -5rem;
+		content: '';
+		transform: rotate(45deg);
+		z-index: 10;
+		box-sizing: border-box;
+		border-bottom: 5rem solid transparent;
+		border-right: 5rem solid transparent;
+		border-top: 5rem solid rgba(255, 255, 255, 1);
+		border-left: 5rem solid rgba(255, 255, 255, 1);
+		// background: rgba(5, 45, 115, .8) !important;
+	}
+
+	.toolbars {
+		position: absolute;
+		top: 80rem;
+		width: 540rem;
+		right: 20rem;
+		cursor: pointer !important;
+		padding: 0rem !important;
+		margin: 0rem !important;
+		background-image: none !important;
+		border: 1rem solid;
+		border: none;
+		border-radius: 2rem !important;
+		background-color: rgb(0 44 126 / 65%);
+		height: 40rem;
+		box-sizing: border-box;
+		line-height: 38rem;
+		text-align: left;
+		user-select: none;
+
+		cursor: default;
+
+		.toolbar-item {
+			display: inline-block;
+			padding: 0rem 12rem;
+
+			margin: 0rem;
+			height: calc(100% - 4rem);
+			color: #fff;
+			font-size: 15rem;
+			vertical-align: middle;
+
+			&:hover {
+				background-color: rgba(255, 255, 255, 0.3);
+			}
+
+			.title {
+				font-size: 16rem;
+			}
+		}
+
+		.toolbar-item:nth-last-child(1) {
+			padding-right: 0rem;
+		}
+
+		.el-icon {
+			margin-right: 5rem;
+			color: #fff;
+		}
+
+		.el-dropdown {
+			// vertical-align: middle;
+			height: 40rem;
+			line-height: 38rem;
+			box-sizing: border-box;
+		}
+	}
+</style>

+ 181 - 0
src/views/Map3d - 副本 (3)/Map3DMain.vue

@@ -0,0 +1,181 @@
+<script setup>
+	//组件异步加载
+	import {
+		defineAsyncComponent,
+		markRaw,
+		computed,
+		provide,
+		ref
+	} from 'vue';
+
+	import {
+		Store
+	} from '@/store/index'
+	store = Store()
+
+	import {
+		useWidgetStore,
+		Widget
+	} from "@/common/store/widget"
+
+	import map3d from './components/map.vue';
+	import JtWidget from "./widget.vue"
+
+	const widgetStore = useWidgetStore()
+	// widgetStore.state.widgets = store.aa;
+
+	// widgetStore.state.widgets = [{
+	// 	component: markRaw(defineAsyncComponent(() => import("@/views/map3d/components/layer.vue"))),
+	// 	name: "layer",
+	// 	autoDisable: true,
+	// 	group: "manage",
+	// } ];
+
+	const widgets = computed(() => widgetStore.state.widgets);
+	const openAtStart = computed(() => widgetStore.state.openAtStart);
+
+	let jtMap3dInstance = null;
+	let isJTMap3DOnload = ref(false);
+	const jtMap3DOnload = (map) => {
+		console.log("map构造完成", map)
+		jtMap3dInstance = map;
+		isJTMap3DOnload.value = true
+	}
+	provide("getMapInstance", () => {
+		return jtMap3dInstance;
+	});
+</script>
+
+<template>
+	<div class="jt-map3dMain">
+
+		<!-- 地图组件 -->
+		<map3d @onload="jtMap3DOnload" ref="refMap3d" />
+
+		<!-- 地图加载完成后,在加载其他组件 -->
+		<template v-if="isJTMap3DOnload">
+
+			<template v-for="comp in widgets" :key="comp.key">
+				<jt-widget v-if="openAtStart.includes(comp.name) && comp.visible" v-model:visible="comp.visible" :widget="comp" />
+			</template>
+
+		</template>
+	</div>
+</template>
+
+<script>
+	import useLifecycle from "@/common/uses/use-lifecycle"
+	import * as mapWork from "./map"
+	let store = undefined
+
+	// 启用map.ts生命周期
+	useLifecycle(mapWork)
+
+	export default {
+		name: "JtMap3DMain",
+
+		/**
+		 *  数据 
+		 */
+		data() {
+			return {
+
+			}
+		},
+
+		/**
+		 *  方法 
+		 */
+		methods: {
+			init() {
+
+				//默认加载图层控制
+				mapWork.getLayers().then(layers => {
+					layers.map((item) => {
+						if (item.isinit === '1') {
+
+							//图层ID
+							let serviceId = "service_" + item.layercode + item.layerorder;
+							item.serviceId = serviceId;
+
+							//透明度
+							let opacity = 1;
+							if (item.opacity == null) {
+								opacity = 1;
+							} else {
+								opacity = Number(item.opacity);
+							}
+							item.opacity = opacity;
+
+							//默认加载
+							mapWork.setLayersControl(window.viewer, item, true);
+						}
+						
+						//默认展开
+						if (item.isexpand === '1') {
+							store.expandedKeys.push(item.id);
+						}
+						
+						// 复选框默认选中
+						if (item.isinit === '1') {
+							store.checkedkeys.push(item.id);
+						}
+					})
+				});
+
+				// 默认加载底图切换
+				mapWork.getBaseMaps().then(baseMaps => {
+					baseMaps.map((item) => {
+						//图层ID
+						let serviceId = "service_" + item.layercode + item.layerorder;
+						item.serviceId = serviceId;
+
+						//透明度
+						let opacity = 1;
+						if (item.opacity == null) {
+							opacity = 1;
+						} else {
+							opacity = Number(item.opacity);
+						}
+						item.opacity = opacity;
+
+						if (item.layertype === '地形') {
+							store.terrain.terrainData = item;
+							
+							if (item.isinit === '1') {
+								store.terrain.isTerrain = true;
+								
+								//默认加载的地形
+								mapWork.setLayersControl(window.viewer, item, true);
+							}
+						} else if (item.layertype === '标注') {
+							store.mark.markData = item;
+							
+							if (item.isinit === '1') {
+								store.mark.isMark = true;
+								
+								//默认加载的标注
+								mapWork.setLayersControl(window.viewer, item, true);
+							}
+						} else {
+							if (item.isinit === '1') {
+								store.basemap.selectBaseMap = item;
+								store.basemap.selectImg = item.layerorder;
+								
+								//默认加载的底图
+								mapWork.setLayersControl(window.viewer, item, true);
+							}
+						}
+					})
+				});
+			}
+		},
+
+		mounted() {
+			this.init();
+		}
+	};
+</script>
+<style lang="scss" scoped>
+
+</style>

+ 237 - 0
src/views/Map3d - 副本 (3)/components/TrackRoam.vue

@@ -0,0 +1,237 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-TrackRoam">
+
+		<el-row style="margin-bottom: 5px;">
+			<el-button type="danger" v-if="isNew" @click="drawLine()">
+				<el-icon>
+					<Plus />
+				</el-icon>新增漫游
+			</el-button>
+			<el-button type="danger" v-if="!isNew" @click="flightRoaming('remove')">
+				<el-icon>
+					<Delete />
+				</el-icon>
+				退出漫游
+			</el-button>
+		</el-row>
+
+		<el-row style="margin-bottom: 5px;" v-if="!isNew">
+
+			<el-button type="danger" v-if="isBackward" @click="flightRoaming('playReverse')">
+				<el-icon>
+					<Back />
+				</el-icon>向后飞行
+			</el-button>
+			<el-button type="danger" v-if="!isBackward" @click="flightRoaming('playForward')">
+				<el-icon>
+					<Right />
+				</el-icon>向前飞行
+			</el-button>
+
+			<el-button type="danger" v-if="isPause" @click="flightRoaming('pause')">
+				<el-icon>
+					<VideoPause />
+				</el-icon>暂停漫游
+			</el-button>
+			<el-button type="danger" v-if="!isPause" @click="flightRoaming('pause')">
+				<el-icon>
+					<VideoPlay />
+				</el-icon>继续漫游
+			</el-button>
+		</el-row>
+
+		<el-row style="margin-bottom: 5px;" v-if="!isNew">
+			<el-button type="danger" @click="flightRoaming(0)">
+				自由漫游
+			</el-button>
+			<el-button type="danger" @click="flightRoaming(1)">
+				相机跟随
+			</el-button>
+		</el-row>
+		<el-row style="margin-bottom: 5px;" v-if="!isNew">
+			<el-button type="danger" @click="flightRoaming(2)">
+				第一视角
+			</el-button>
+			<el-button type="danger" @click="flightRoaming(3)">
+				上帝视角
+			</el-button>
+		</el-row>
+
+		<el-form label-width="130rem">
+			<el-form-item label="飞行速度:" v-if="!isNew">
+				<el-slider v-model="roam.speed" @input="handleSpeedChange" :max="100" :min="1" :step="1" />
+			</el-form-item>
+			<el-form-item label="距离运动点的距离(后方):" v-if="roam.role===2">
+				<el-slider v-model="roam.followedX" @input="handleFollowedXChange" :max="10000" :min="1" :step="1" />
+			</el-form-item>
+			<el-form-item label="距离运动点的距离(上方):" v-if="roam.role===2">
+				<el-slider v-model="roam.followedZ" @input="handleFollowedZChange" :max="10000" :min="1" :step="1" />
+			</el-form-item>
+		</el-form>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+
+	export default {
+		data() {
+			return {
+				isNew: true,
+				isPause: true,
+				isBackward: true,
+				Roaming: undefined,
+
+				roam: {
+					role: 0,
+					speed: 10,
+					followedX: 50,
+					followedZ: 10
+				}
+			}
+		},
+
+		/* 方法 */
+		methods: {
+
+			handleFollowedXChange(followedX) {
+				this.Roaming.followedX = followedX;
+			},
+			handleFollowedZChange(followedZ) {
+				this.Roaming.followedZ = followedZ;
+			},
+
+			handleSpeedChange(speed) {
+				this.Roaming.ChangeRoamingSpeed(speed);
+			},
+
+			/**
+			 * 绘制飞行路线
+			 */
+			drawLine() {
+				let _self = this;
+
+				jt3d.DrawTools.draw('polyline', {
+					isEdit: false,
+					onComplete(cartesian3d, points) {
+						//清除绘制
+						jt3d.DrawTools.Clear();
+
+						_self.Roaming = new jt3dSDK.Roaming(jt3d._viewer, cartesian3d, {
+							time: 360,
+							role: 2,
+							label: {
+								text: "lineName",
+							}
+						});
+						_self.isPause = true;
+						_self.isNew = false;
+						_self.roam.role = 2;
+						_self.Roaming.PauseOrContinue(_self.isPause);
+					}
+				});
+
+			},
+
+			/**
+			 * 飞行漫游
+			 * @param {Object} type
+			 */
+			flightRoaming(type) {
+
+				let _self = this;
+
+				switch (type) {
+					case "pause": //暂停飞行
+						this.isPause = !this.isPause;
+						this.Roaming.PauseOrContinue(this.isPause);
+						break;
+					case "playForward": //向前飞行
+						this.isPause = true;
+						this.isBackward = !this.isBackward;
+						this.Roaming.forwardFly();
+						break;
+					case "playReverse": //向后飞行
+						this.isPause = true;
+						this.isBackward = !this.isBackward;
+						this.Roaming.backwardsFly();
+						break;
+					case "remove": //向后飞行
+						this.isNew = true;
+						this.roam.role = Number(type);
+						this.Roaming.EndRoaming();
+						// //获取被clock监听的全部事件数量
+						// let len = jt3d._viewer.clock.onTick.numberOfListeners;
+						// for (let i = 0; i < len; i++) {
+						// 	//将被监听的方法移除来停止方法
+						// 	jt3d._viewer.clock.onTick.removeEventListener(jt3d._viewer.clock.onTick._listeners[i]);
+						// }
+						break;
+					case 0:
+						this.roam.role = Number(type);
+						this.Roaming.initRole(0);
+						break;
+					case 1:
+						this.roam.role = Number(type);
+						this.Roaming.initRole(1);
+						break;
+					case 2:
+						this.roam.role = Number(type);
+						this.Roaming.initRole(2);
+						break;
+					case 3:
+						this.roam.role = Number(type);
+						this.Roaming.initRole(3);
+						break;
+				}
+			},
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	::v-deep .el-table .cell {
+		line-height: 23rem !important;
+		padding: 0 12rem !important;
+		font-size: 14rem;
+	}
+
+	//整体样式
+	.jt-TrackRoam {
+		width: 90%;
+		margin-top: 16rem;
+		margin-left: 5%;
+		text-align: left;
+
+		--el-bg-color: rgb(0 44 126 / 60%);
+		--el-fill-color-blank: rgb(0 44 126 / 60%);
+		--el-text-color-secondary: rgb(216 240 255); //title
+		--el-text-color-regular: rgb(216 240 255); //内容
+		--el-fill-color-light: rgb(30 130 255);
+
+		.el-icon {
+			margin-right: 5rem;
+			color: #fff;
+		}
+	}
+</style>

+ 220 - 0
src/views/Map3d - 副本 (3)/components/analysis-data.vue

@@ -0,0 +1,220 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-analysisData">
+		<el-collapse v-model="activeName" accordion>
+			<el-upload drag :auto-upload=false action="" accept="shp" :on-preview="handlePreview" :on-remove="handleRemove" :on-change="bind">
+				<i class="el-icon-upload"></i>
+				<div class="el-upload__text">将shp文件拖到此处,或<em>点击上传</em></div>
+
+				<!-- <div class="el-upload__tip" slot="tip">必须是shp文件</div> -->
+				<span>
+					<el-icon>
+						<WarnTriangleFilled />
+					</el-icon>必须是shp文件
+				</span>
+			</el-upload>
+			<!-- <el-button style="margin-left: 10rem;" size="small" type="success" @click="config">生成GeoJson数据</el-button> -->
+		</el-collapse>
+	</div>
+</template>
+
+<script>
+	import {
+		open
+	} from 'shapefile'
+
+	let jt3d = undefined;
+
+	export default {
+		props: {},
+		watch: {
+
+		},
+		name: "Config",
+		data() {
+			return {
+				file: {},
+				filelist: [],
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			/* shp文件解析生成图形 */
+			config() {
+				let _this = this
+				const name = this.file.name
+				const extension = name.split('.')[1]
+				console.log(extension)
+				if ('shp' !== extension) {
+					this.$alert('文件不是shp文件!请重新选择文件', {
+						confirmButtonText: '确定'
+					})
+				} else {
+					const reader = new FileReader()
+					const fileData = this.file.raw
+					reader.readAsArrayBuffer(fileData)
+					reader.onload = function(e) {
+						open(this.result).then(source => source.read().then(function log(result) {
+							if (result.done) return;
+							console.log(result)
+							console.log(result.value);
+
+							let promise = Cesium.GeoJsonDataSource.load(result.value, {
+								clampToGround: true
+							});
+							promise.then((dataSource) => {
+
+								window["viewer"].dataSources.add(dataSource); // 加载这个geojson资源
+								dataSource.name = name.split('.')[0];
+								console.log(dataSource)
+								const entities = dataSource.entities.values;
+								for (let index = 0; index < entities.length; index++) {
+									const entity = entities[index];
+									entity.polygon.material = Cesium.Color.fromBytes(50, 160, 255, 77)
+									entity.polygon.outlineWidth = 3;
+									entity.polygon.outline = false;
+									entity.polygon.outlineColor = Cesium.Color.RED;
+									entity.polyline = {
+										positions: entity.polygon.hierarchy._value.positions,
+										width: entity.polygon.outlineWidth,
+										material: Cesium.Color.fromBytes(0, 255, 180, 255),
+										clampToGround: true
+									}
+								}
+
+								let options = {};
+								// 初始化参数默认值
+								options.duration = Cesium.defaultValue(options.duration, 2);
+								options.heading = Cesium.defaultValue(options.heading, 0);
+								options.pitch = Cesium.defaultValue(options.pitch, -60);
+								options.range = Cesium.defaultValue(options.range, 0.0);
+								let flyPromise = window["viewer"].flyTo(entities, {
+									duration: options.duration,
+									offset: {
+										heading: Cesium.Math.toRadians(options.heading),
+										pitch: Cesium.Math.toRadians(options.pitch),
+										range: options.range
+									}
+								});
+
+							});
+
+							return source.read().then(log);
+
+						})).catch(error => console.error(error.stack));
+					}
+				}
+
+			},
+			remove() {
+
+			},
+
+			//移除
+			handleRemove(file, fileList) {
+
+				/* 清除图形 */
+				console.log(file, fileList);
+				let list = window["viewer"].dataSources.getByName(file.name.split('.')[0])
+				// for(let i=0;i<list.length;i++){
+				// 	console.log(list.length)
+				// 	window["viewer"].dataSources.remove(list[i])
+				// }
+				list.forEach(res => {
+					console.log(res)
+					window["viewer"].dataSources.remove(res)
+				})
+
+				// window["viewer"].dataSources.remove(window["viewer"].dataSources.getByName(file.name.split('.')[0]))
+
+			},
+
+			//定位
+			handlePreview(file) {
+				console.log(file)
+				this.file = file;
+				// this.config();
+
+				let list = window["viewer"].dataSources.getByName(file.name.split('.')[0])
+				list.forEach(res => {
+					const entities = res.entities.values;
+					
+					let options = {};
+					// 初始化参数默认值
+					options.duration = Cesium.defaultValue(options.duration, 2);
+					options.heading = Cesium.defaultValue(options.heading, 0);
+					options.pitch = Cesium.defaultValue(options.pitch, -60);
+					options.range = Cesium.defaultValue(options.range, 0.0);
+					let flyPromise = window["viewer"].flyTo(entities, {
+						duration: options.duration,
+						offset: {
+							heading: Cesium.Math.toRadians(options.heading),
+							pitch: Cesium.Math.toRadians(options.pitch),
+							range: options.range
+						}
+					});
+				})
+
+			},
+			bind(files, fileList) {
+				//绑定文件
+				this.file = fileList[fileList.length - 1]
+				//console.log(this.file)
+				this.config();
+			}
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.el-upload-dragger .el-upload__text{
+		font-size: 16rem;
+	}
+	
+	.upload_demo {
+		text-align: center;
+		margin-top: 50rem;
+	}
+
+	.el-button {
+		margin-top: 10rem;
+	}
+
+	::v-deep .el-upload-dragger {
+		padding: 0rem;
+		margin-top: 10rem;
+		color: #606266;
+		font-size: 12rem;
+
+	}
+
+	::v-deep .el-upload-list__item-name {
+		color: #fff;
+		margin-left: -21rem;
+	}
+
+	::v-deep .el-icon svg {
+		color: #409eff;
+		font-size: smaller;
+	}
+</style>

+ 517 - 0
src/views/Map3d - 副本 (3)/components/analysis-space.vue

@@ -0,0 +1,517 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-analysisSpace">
+		<el-collapse v-model="activeName" accordion>
+			<el-collapse-item name="光照分析">
+				<template #title>
+					<i class='iconfont icon-svgguangzhaofenxi' />光照分析
+				</template>
+				<div class="el-collapse-item__content">
+					<el-button color="rgb(20 136 255)" @click="SunShine('start')">开启光照分析</el-button>
+					<el-button color="rgb(255 100 100)" @click="SunShine('remove')"><span style="color: #fff;">移除光照分析</span></el-button>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="方量分析">
+				<template #title>
+					<i class='iconfont icon-svgfangliangfenxi' />方量分析
+				</template>
+				<div class="el-collapse-item__content">
+					<el-form label-width="100rem">
+						<el-form-item label="挖方填方高度:">
+							<el-input v-model="cutFill.height" />
+						</el-form-item>
+						<el-form-item label="挖方填方精度:">
+							<el-input v-model="cutFill.precision" />
+						</el-form-item>
+					</el-form>
+					<div class="jt-btn" style="margin: 10rem;">
+						<el-button color="rgb(255 100 100)" @click="CutFill('draw')"><span style="color: #fff;">绘制挖方填方区域</span></el-button>
+						<el-button color="rgb(255 100 100)" @click="CutFill('remove')"><span style="color: #fff;">清除分析结果</span></el-button>
+					</div>
+					<el-form label-width="120rem">
+						<el-form-item label="总分析面积(㎡):">
+							<el-input v-model="cutFill.result.allArea" />
+						</el-form-item>
+						<el-form-item label="填方面积(㎡):">
+							<el-input v-model="cutFill.result.fillArea" />
+						</el-form-item>
+						<el-form-item label="填方体积(m³):">
+							<el-input v-model="cutFill.result.fillVolume" />
+						</el-form-item>
+						<el-form-item label="挖方面积(㎡):">
+							<el-input v-model="cutFill.result.cutArea" />
+						</el-form-item>
+						<el-form-item label="挖方体积(m³):">
+							<el-input v-model="cutFill.result.cutVolume" />
+						</el-form-item>
+					</el-form>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="剖面分析">
+				<template #title>
+					<i class='iconfont icon-svgpoumianfenxi' />剖面分析
+				</template>
+				<div class="el-collapse-item__content">
+					<div style="line-height: 2em; table-layout: fixed; word-wrap: break-word; word-break: normal; text-align:justify; text-justify: inter-ideograph;color: #ffffff99;">
+						提示:单击【剖面分析】按钮触发,然后在实景三维或地形上左键单击开始,左键双击结束
+					</div>
+					<el-button color="rgb(20 136 255)" @click="SectionAnalysis">剖面分析</el-button>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="通视分析">
+				<template #title>
+					<i class='iconfont icon-svgtongshifenxi' />通视分析
+				</template>
+				<div class="el-collapse-item__content">
+					<div style="line-height: 2em; table-layout: fixed; word-wrap: break-word; word-break: normal; text-align:justify; text-justify: inter-ideograph;color: #ffffff99;">
+						提示:红色代表不可视,绿色代表可视;
+					</div>
+					<el-button color="rgb(20 136 255)" @click="SightLine('activate')">添加通视分析</el-button>
+					<el-button color="rgb(255 100 100)" @click="SightLine('deactivate')"><span style="color: #fff;">清除通视分析</span></el-button>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="视域分析">
+				<template #title>
+					<i class='iconfont icon-svgshiyufenxi' />视域分析
+				</template>
+				<div class="el-collapse-item__content">
+					<div style="line-height: 2em; table-layout: fixed; word-wrap: break-word; word-break: normal; text-align:justify; text-justify: inter-ideograph;color: #ffffff99;">
+						提示:点击“添加视域”按钮后在场景中点击两个点添加视域,红色代表不可视,绿色代表可视;
+					</div>
+					<el-button color="rgb(20 136 255)" @click="ViewShed('activate')">添加视域</el-button>
+					<el-button color="rgb(255 100 100)" @click="ViewShed('deactivate')"><span style="color: #fff;">清除视域</span></el-button>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="限高分析">
+				<template #title>
+					<i class='iconfont icon-svgxiangaofenxi' />限高分析
+				</template>
+				<div class="el-collapse-item__content">
+					<el-form ref="form" label-width="100rem" label-position="right" size="mini">
+						<el-form-item label="地表海拔:">
+							<span>{{heightLimit.baseHeight}}</span>米&nbsp;&nbsp;<el-button color="rgb(20 136 255)" @click="HeightLimit('pickUp')">图上选点</el-button>
+						</el-form-item>
+						<el-form-item label="限制高度:">
+							<el-slider v-model="heightLimit.height" :min="0" :max="300" :step="1" @input="changeHeight"></el-slider>
+						</el-form-item>
+						<el-form-item label="当前高度:">
+							{{heightLimit.height}}米
+						</el-form-item>
+					</el-form>
+					<div class="jt-btn" style="margin-bottom: 10rem;">
+						<el-button color="rgb(20 136 255)" @click="HeightLimit('activate')">绘制限高区域</el-button>
+						<el-button color="rgb(255 100 100)" @click="HeightLimit('deactivate')"><span style="color: #fff;">清除限高分析</span></el-button>
+					</div>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="剖切展示">
+				<template #title>
+					<i class='iconfont icon-svgpouqiezhanshi' />剖切展示
+				</template>
+				<div class="el-collapse-item__content">
+					<div style="line-height: 2em; table-layout: fixed; word-wrap: break-word; word-break: normal; text-align:justify; text-justify: inter-ideograph;color: #ffffff60;">
+						目前仅支持凸多边形,如果绘制的是凹多边形,可能裁剪结果不正确
+					</div>
+					<el-button color="rgb(20 136 255)" @click="Cutting('activate')">添加剖切多边形</el-button>
+				</div>
+			</el-collapse-item>
+			<!-- <el-collapse-item name="视频融合">
+				<template #title>
+					<i class='iconfont icon-svgshipinronghe' />视频融合
+				</template>
+				<div class="el-collapse-item__content">
+					<div style="line-height: 2em; table-layout: fixed; word-wrap: break-word; word-break: normal; text-align:justify; text-justify: inter-ideograph;color: #ffffff60;">
+						请先打开【牟平中心城实景三维】
+					</div>
+					<el-button color="rgb(20 136 255)" @click="PolygonHierarchy">视频融合</el-button>
+				</div>
+			</el-collapse-item> -->
+		</el-collapse>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+
+	export default {
+		props: {},
+		watch: {},
+
+		/* 数据 */
+		data() {
+			return {
+				activeName: "光照分析",
+
+				// 限高分析
+				heightLimit: {
+					height: 20,
+					baseHeight: 0,
+				},
+
+				//方量分析	
+				cutFill: {
+					height: 10, //挖方填方高度
+					precision: 1256, //挖方填方精度
+					result: { //挖方填方结果
+						allArea: "",
+						cutArea: "",
+						cutVolume: "",
+						fillArea: "",
+						fillVolume: "",
+					},
+				},
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			/**
+			 * 光照分析
+			 */
+			SunShine(type) {
+				let _self = this;
+				switch (type) {
+					case "start":
+						jt3d.statusBar.show = false;
+						jt3d.SpatialAnalysis.SunshineShadow.start();
+
+						break;
+					case "remove":
+						jt3d.statusBar.show = true;
+						jt3d.SpatialAnalysis.SunshineShadow.remove();
+						break;
+				}
+			},
+
+			/**
+			 * 方量分析
+			 */
+			CutFill(type) {
+				let _self = this;
+
+				//功能初始化
+				_self.init();
+
+				switch (type) {
+					case "draw":
+						jt3d.DrawTools.draw('polygon', {
+							isEdit: false,
+							onComplete(cartesian3d, points) {
+								//清除绘制
+								jt3d.DrawTools.Clear();
+
+								let pointsArray = [];
+								points.forEach((coordinate, index) => {
+									pointsArray.push([
+										coordinate.lng,
+										coordinate.lat,
+										coordinate.height
+									]);
+								});
+
+								jt3d.SpatialAnalysis.CutFill.createPolygonGeo(pointsArray, {
+									height: _self.height,
+									precision: _self.precision,
+								}).then(res => {
+									_self.cutFill.result = res;
+								});
+
+							}
+						});
+
+						break;
+					case "remove":
+						jt3d.SpatialAnalysis.CutFill.remove();
+						this.cutFill.result = {
+							allArea: "",
+							cutArea: "",
+							cutVolume: "",
+							fillArea: "",
+							fillVolume: "",
+						}
+
+						//还原左键单击事件
+						this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+						break;
+				}
+			},
+
+			/**
+			 * 视频融合
+			 */
+			PolygonHierarchy() {
+				let videoElement = document.getElementById('trailer');
+				var videopolygon = jt3d._viewer.entities.add({
+					polygon: {
+						height: 0.1,
+						hierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights([121.600444, 37.398272, 37.95, 121.600443, 37.398272, 33, 121.600443, 37.398341, 33, 121.600444, 37.398341, 37.95])),
+						material: videoElement,
+						perPositionHeight: true,
+					}
+				});
+
+				let flyToEntity = jt3d.LocateUtil.flyToEntity(videopolygon, {
+					heading: 90, //方向
+					pitch: -32, //倾斜角度
+					range: 72
+				});
+				flyToEntity.then(function(vehicleEntity) {
+					jt3d._viewer.trackedEntity = vehicleEntity; //获取或设置摄像机当前正在跟踪的Entity实例。
+					vehicleEntity.viewFrom = new Cesium.Cartesian3(0, 1, 0.3);
+				});
+			},
+
+			/**
+			 * 剖切分析
+			 */
+			Cutting(type) {
+				let _self = this;
+				//功能初始化
+				_self.init();
+
+				switch (type) {
+					case "activate":
+						if (window["my3dtiles"]) {
+							jt3d.DrawTools.draw('polygon', {
+								isEdit: false,
+								onComplete(cartesian3d, points) {
+									//清除绘制
+									jt3d.DrawTools.Clear();
+							
+									let pointsArray = [];
+									points.forEach((coordinate, index) => {
+										pointsArray.push([
+											coordinate.lng,
+											coordinate.lat,
+											coordinate.height
+										]);
+									});
+							
+									jt3d.SpatialAnalysis.Cutting.addTiles(window["my3dtiles"], pointsArray);
+							
+								}
+							});
+						} else {
+							ElMessage.error("请先勾选3D模型");
+						}
+						break;
+					case "deactivate":
+						//还原左键单击事件
+						this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+						break;
+				}
+			},
+
+			/**
+			 * 限高分析
+			 */
+			HeightLimit(type) {
+				let _self = this;
+				//功能初始化
+				_self.init();
+
+				switch (type) {
+					case "pickUp": //图上选点,获取地表高度
+						jt3d.CommonTools._sketchViewModel.sketchTools('point', {
+							onComplete(cPoint, gPoint) {
+								_self.heightLimit.baseHeight = Number(gPoint.height.toFixed(2));
+							},
+							onError(message) {
+								
+							}
+						});
+						break;
+					case "activate":
+						jt3d.DrawTools.draw('polygon', {
+							isEdit: false,
+							onComplete(cartesian3d, points) {
+								//清除绘制
+								// jt3d.DrawTools._entities.remove(jt3d.DrawTools._drawEntity.polygon);
+								jt3d.DrawTools.Clear();
+
+								let pointsArray = [];
+								points.forEach((coordinate, index) => {
+									pointsArray.push([
+										coordinate.lng,
+										coordinate.lat,
+										coordinate.height
+									]);
+								});
+
+								jt3d.SpatialAnalysis.HeightLimit.addPrimitive(pointsArray, {
+									height: _self.heightLimit.height,
+									baseHeight: _self.heightLimit.baseHeight,
+								});
+							}
+						});
+						break;
+					case "deactivate":
+						jt3d.SpatialAnalysis.HeightLimit.removePrimitive();
+						jt3d.CommonTools._sketchViewModel.sketchClear();
+						//还原左键单击事件
+						this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+						break;
+				}
+			},
+			changeHeight(val) {
+				jt3d.SpatialAnalysis.HeightLimit.changeHeight(val);
+			},
+
+			/**
+			 * 通视分析
+			 * @param {Object} type
+			 */
+			SightLine(type) {
+				let _self = this;
+				//功能初始化
+				_self.init();
+
+				switch (type) {
+					case "activate":
+						jt3d.SpatialAnalysis.SightLine.startSightLine();
+						break;
+					case "deactivate":
+						jt3d.SpatialAnalysis.SightLine.clearAll();
+						//还原左键单击事件
+						this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+						break;
+				}
+			},
+
+			/**
+			 * 视域分析
+			 */
+			ViewShed(type) {
+				let _self = this;
+				//功能初始化
+				_self.init();
+
+				switch (type) {
+					case "activate":
+						jt3d.SpatialAnalysis.ViewShed.createViewshed(10);
+						break;
+					case "deactivate":
+						jt3d.SpatialAnalysis.ViewShed.clearAll();
+						//还原左键单击事件
+						this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+						break;
+				}
+			},
+
+			/**
+			 * 剖面分析
+			 */
+			SectionAnalysis() {
+				let _self = this;
+				//功能初始化
+				_self.init();
+
+				jt3d.DrawTools.draw('polyline', {
+					isEdit: false,
+					onComplete(cartesian3d, points) {
+						let pointsArray = [];
+						points.forEach((coordinate, index) => {
+							pointsArray.push([
+								coordinate.lng,
+								coordinate.lat,
+								coordinate.height
+							]);
+						});
+
+						let ProfileAnalysis = jt3d.SpatialAnalysis.Profile.startProfileAnalysis(pointsArray, jt3d.DrawTools._drawEntity.polyline);
+						ProfileAnalysis.then(function(result) {
+							_self.$parent.$parent.$refs.refDrawerSectionAnalysis.drawerVisible = true;
+							_self.$parent.$parent.initEchartsData(result);
+						});
+
+					}
+				});
+			},
+
+			/**
+			 * 功能初始化
+			 */
+			init() {
+				//移除左键单击事件
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); //移除事件
+				}
+
+				jt3d.DrawTools.Clear();
+				jt3d.CommonTools._sketchViewModel.sketchClear();
+
+				jt3d.SpatialAnalysis.CutFill.remove(); //清除方量分析
+				jt3d.SpatialAnalysis.Profile.removeProfileAnalysis(); //移除剖面分析
+				jt3d.SpatialAnalysis.SightLine.clearAll(); //清除通视分析
+				jt3d.SpatialAnalysis.ViewShed.clearAll(); //清除视域分析
+				jt3d.SpatialAnalysis.HeightLimit.removePrimitive(); //清除限高分析		
+			}
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.jt-analysisSpace {
+		position: relative;
+
+		.iconfont {
+			padding: 0 10rem;
+		}
+
+		.el-collapse {
+			--el-collapse-border-color: rgb(0 44 126 / 0%);
+
+			--el-collapse-header-text-color: #ffffff;
+			--el-collapse-header-font-size: 13rem;
+			--el-collapse-content-bg-color: rgb(0 44 126 / 0%);
+			--el-collapse-content-font-size: 13rem;
+			--el-collapse-content-text-color: rgb(216 240 255);
+
+			--el-collapse-header-height: 40rem;
+			--el-collapse-header-bg-color: rgb(30 130 255);
+
+			--el-fill-color-blank: rgb(0 44 126 / 68%);
+			--el-text-color-regular: rgb(216 240 255);
+			--el-border-color: rgb(35 135 255);
+
+			.el-collapse-item__content {
+				padding: 10rem;
+				// padding-bottom: 0rem;
+			}
+		}
+	}
+
+	::v-deep .el-collapse-item__content {
+		padding: 10rem;
+		// padding-bottom: 0rem;
+		overflow-y: hidden;
+	}
+
+	::v-deep .el-collapse-item__header {
+		background: url(@/assets/images/bg_collapse_title.png) no-repeat;
+		background-size: 350rem 40rem;
+		// background-color: rgb(22 90 190);
+		// background-color: rgb(5 45 100 /60%);
+		background-color: rgb(30 130 255);
+		border-bottom: 0;
+	}
+</style>

+ 342 - 0
src/views/Map3d - 副本 (3)/components/analysis-terrain.vue

@@ -0,0 +1,342 @@
+<script setup>
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-analysisTerrain">
+		<el-collapse v-model="activeName" accordion>
+			<el-collapse-item name="地下模式">
+				<template #title>
+					<i class='iconfont icon-svgdixiamoshi' />地下模式
+				</template>
+				<div class="el-collapse-item__content">
+					<div style="line-height: 2em; table-layout: fixed; word-wrap: break-word; word-break: normal; text-align:justify; text-justify: inter-ideograph;color: #ffffff60;">
+						提示:可以透明地表,进入地下模式,可以看地下管网数据。
+					</div>
+					<el-form label-width="130rem">
+						<el-form-item label="地下模式开启状态:">
+							<el-switch v-model="underground.boolUnderground" active-text="已开启" inactive-text="已关闭" @change="handleUndergroundChange">
+							</el-switch>
+						</el-form-item>
+						<el-form-item label="地表透明度:">
+							<el-slider v-model="underground.alpha" :min="0" :max="1" :step="0.1" :disabled="!underground.boolUnderground" @input="handleAlphaChange">
+							</el-slider>
+						</el-form-item>
+					</el-form>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="地形开挖">
+				<template #title>
+					<i class='iconfont icon-svgdixingkaiwa' />地形开挖
+				</template>
+				<div class="el-collapse-item__content">
+					<el-form ref="form" label-width="100rem" label-position="right" size="mini">
+						<el-form-item label="开挖深度:">
+							<el-input v-model="terrainExcavation.excavateDepth" />
+						</el-form-item>
+					</el-form>
+					<div class="jt-btn" style="margin-bottom: 10rem;">
+						<el-button color="rgb(20 136 255)" @click="terrainExcavate('add')">绘制开挖区域</el-button>
+						<el-button color="rgb(255 100 100)" @click="terrainExcavate('remove')"><span style="color: #fff;">清除开挖分析</span></el-button>
+					</div>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="坡度分析">
+				<template #title>
+					<i class='iconfont icon-svgpodufenxi' />坡度分析
+				</template>
+				<div class="el-collapse-item__content">
+					<div class="jt-btn" style="margin-top: 10rem;">
+						<el-button color="rgb(20 136 255)" @click="SlopeAspect('Num')">坡度等分</el-button>
+						<el-button color="rgb(20 136 255)" @click="SlopeAspect('Distance')">坡度等距</el-button>
+						<el-button color="rgb(255 100 100)" @click="removeSlopeAspect"><span style="color: #fff;">移除</span></el-button>
+					</div>
+				</div>
+			</el-collapse-item>
+			<!-- <el-collapse-item name="深度检测">
+					<template #title>
+						<i class='iconfont icon-tianqizitiku43' />深度检测
+					</template>
+					<div class="el-collapse-item__content">
+						深度检测
+					</div>
+				</el-collapse-item>
+				<el-collapse-item name="等高线">
+					<template #title>
+						<i class='iconfont icon-tianqizitiku43' />等高线
+					</template>
+					<div class="el-collapse-item__content">
+						等高线
+					</div>
+				</el-collapse-item> -->
+		</el-collapse>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+
+	export default {
+		props: {
+
+		},
+		watch: {
+		},
+
+		/* 数据 */
+		data() {
+			return {
+				activeName: "地下模式",
+				
+				//地下模式
+				underground: {
+					alpha: 0.5,
+					boolUnderground: false,
+				},
+				
+				//地形开挖
+				terrainExcavation:{
+					excavateDepth: 10, //开挖深度
+				}
+				
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			/**
+			 * 是否开启地下模式
+			 * @param {Object} bool
+			 */
+			handleUndergroundChange(bool) {
+				window["viewer"].scene.screenSpaceCameraController.enableCollisionDetection = !bool; //相机与地形的碰撞检测
+				window["viewer"].scene.globe.translucency.frontFaceAlphaByDistance = new Cesium.NearFarScalar(1.5e2, 0.5, 8.0e6, 1.0);
+				window["viewer"].scene.globe.translucency.enabled = bool; //是否开启透明
+				this.handleAlphaChange(this.underground.alpha);
+			},
+			/**
+			 * el-slider 值改变时触发
+			 * 设置地表透明度
+			 * @param {Object} alpha
+			 */
+			handleAlphaChange(alpha) {
+				const frontFaceAlphaByDistance = window["viewer"].scene.globe.translucency.frontFaceAlphaByDistance;
+				frontFaceAlphaByDistance.nearValue = alpha;
+				frontFaceAlphaByDistance.farValue = alpha;
+			},
+
+			/**
+			 * 移除坡度分析
+			 */
+			removeSlopeAspect() {
+				jt3d.TerrainAnalysis.SlopeAspect.clearAll();
+				//还原左键单击事件
+				this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+			},
+			/**
+			 * 坡度坡向分析
+			 * @param {Object} type
+			 */
+			SlopeAspect(type) {
+				let _self = this;
+				//功能初始化
+				_self.init();
+
+				switch (type) {
+					case "Num":
+						jt3d.DrawTools.draw('polygon', {
+							isEdit: false,
+							onComplete(cartesian3d, points) {
+
+								let pointsArray = [];
+								points.forEach((coordinate, index) => {
+									pointsArray.push([
+										coordinate.lng,
+										coordinate.lat,
+										coordinate.height
+									]);
+								});
+
+								jt3d.TerrainAnalysis.SlopeAspect.createNew4Num(pointsArray, jt3d.DrawTools._drawEntity.polygon, {
+									num: 10
+								});
+
+								//清除绘制
+								// jt3d.DrawTools._entities.remove(jt3d.DrawTools._drawEntity.polygon);
+								jt3d.DrawTools.Clear();
+							}
+						});
+
+						break;
+					case "Distance":
+						jt3d.DrawTools.draw('polygon', {
+							isEdit: false,
+							onComplete(cartesian3d, points) {
+
+								let pointsArray = [];
+								points.forEach((coordinate, index) => {
+									pointsArray.push([
+										coordinate.lng,
+										coordinate.lat,
+										coordinate.height
+									]);
+								});
+
+								jt3d.TerrainAnalysis.SlopeAspect.createNew4Distance(pointsArray, jt3d.DrawTools._drawEntity.polygon, {
+									distance: 0.05
+								});
+
+								//清除绘制
+								// jt3d.DrawTools._entities.remove(jt3d.DrawTools._drawEntity.polygon);
+								jt3d.DrawTools.Clear();
+							}
+						});
+						break;
+				}
+			},
+
+			/**
+			 * 移除地形开挖
+			 */
+			removeTerrainExcavate() {
+				jt3d.TerrainAnalysis.TerrainExcavation.clear();
+				//还原左键单击事件
+				this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+			},
+			/**
+			 * 地形开挖
+			 */
+			terrainExcavate(type) {
+				let _self = this;
+				//功能初始化
+				_self.init();
+				
+				if (type === "add") {
+					jt3d.DrawTools.draw('polygon', {
+						onComplete(aa, points) {
+							jt3d.DrawTools.Clear();
+							let pointsArray = [];
+							points.forEach((coordinate, index) => {
+								pointsArray.push([
+									coordinate.lng,
+									coordinate.lat,
+									coordinate.height
+								]);
+							});
+							jt3d.TerrainAnalysis.TerrainExcavation.add(pointsArray, {
+								excavateDepth: _self.terrainExcavation.excavateDepth
+							});
+
+						}
+					});
+				} else if (type === "remove") {
+					_self.removeTerrainExcavate();
+				}
+			},
+
+			/**
+			 * 功能初始化
+			 */
+			init() {
+				//移除左键单击事件
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); //移除事件
+				}
+
+				jt3d.DrawTools.Clear();
+
+				jt3d.TerrainAnalysis.TerrainExcavation.clear();; //清除地形开挖
+				jt3d.TerrainAnalysis.SlopeAspect.clearAll(); //移除坡度坡向分析	
+			}
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.el-switch{
+		font-size: 14rem !important;
+		line-height: 20rem !important;
+		align-items: self-start !important;
+	}
+	::v-deep .is-checked .el-switch__core .el-switch__action{
+		margin-left: calc(-1rem - 14rem);
+	}
+	
+	::v-deep .el-switch__core .el-switch__action{
+		top:1rem;
+	}
+	
+	::v-deep .el-switch__core .el-switch__action{
+		width: 14rem;
+		height: 14rem;
+	}
+	
+	::v-deep .el-switch__core{
+		width: 40rem !important;
+		height: 20rem !important;
+	}
+	::v-deep .el-switch__label{
+		height: 20rem !important;
+		font-size: 14rem !important;
+	}
+	::v-deep .el-switch__label *{
+		font-size: 14rem !important;
+	}
+	
+	::v-deep .el-switch__label--left{
+		margin-right: 10rem;
+	}
+	
+	.jt-analysisTerrain {
+		position: relative;
+		.iconfont {
+			padding: 0 10rem;
+		}
+
+		.el-collapse {
+			--el-collapse-border-color: rgb(0 44 126 / 0%);
+
+			--el-collapse-header-text-color: #ffffff;
+			--el-collapse-header-font-size: 13rem;
+			--el-collapse-content-bg-color: rgb(0 44 126 / 0%);
+			--el-collapse-content-font-size: 13rem;
+			--el-collapse-content-text-color: rgb(216 240 255);
+
+			--el-collapse-header-height: 40rem;
+			--el-collapse-header-bg-color: rgb(30 130 255);
+
+			--el-fill-color-blank: rgb(0 44 126 / 68%);
+			--el-text-color-regular: rgb(216 240 255);
+			--el-border-color: rgb(35 135 255);
+
+			.el-collapse-item__content {
+				padding: 10rem;
+				// padding-bottom: 0rem;
+			}
+		}
+	}
+
+	::v-deep .el-collapse-item__content {
+		padding: 10rem;
+		// padding-bottom: 0rem;
+		overflow-y: hidden;
+	}
+
+	::v-deep .el-collapse-item__header {
+		background: url(@/assets/images/bg_collapse_title.png) no-repeat;
+		background-size: 350rem 40rem;
+		// background-color: rgb(22 90 190);
+		// background-color: rgb(5 45 100 /60%);
+		background-color: rgb(30 130 255);
+		border-bottom: 0;
+	}
+</style>

+ 386 - 0
src/views/Map3d - 副本 (3)/components/coordsTool.vue

@@ -0,0 +1,386 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+<template>
+	<div class="jt-coordsTool">
+		<el-collapse v-model="activeName" accordion>
+			<el-collapse-item name="坐标定位">
+				<template #title>
+					<i class='iconfont icon-dituzuobiao' />坐标定位
+				</template>
+				<div class="el-collapse-item__content">
+					<div style="line-height: 2em; table-layout: fixed; word-wrap: break-word; word-break: normal; text-align:justify; text-justify: inter-ideograph;color: #ffffff60;">
+						提示: 填写格式:x1,y1,z1;x2,y2,z2;x3,y3,z3;......;标点符号必须采用英文半角。
+					</div>
+					<el-form label-width="80rem">
+						<el-form-item label="定位类型:">
+							<el-radio-group v-model="position.locationType">
+								<el-radio label="point">点</el-radio>
+								<el-radio label="polyline">线</el-radio>
+								<el-radio label="polygon">多边形</el-radio>
+							</el-radio-group>
+						</el-form-item>
+					</el-form>
+					<el-input v-model="position.locationCoords" type="textarea" :autosize="{ minRows: 6, maxRows: 6 }" />
+					<div class="jt-btn" style="margin-top: 10rem;">
+						<el-button color="rgb(20 136 255)" @click="Position">坐标定位</el-button>
+						<el-button color="rgb(255 100 100)" @click="emptyLoc"><span style="color: #fff;">清除定位</span></el-button>
+					</div>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="坐标拾取">
+				<template #title>
+					<i class='iconfont icon-chaxunzuobiaozhi' />坐标拾取
+				</template>
+				<div class="el-collapse-item__content">
+					<div style="line-height: 2em; table-layout: fixed; word-wrap: break-word; word-break: normal; text-align:justify; text-justify: inter-ideograph;color: #ffffff60;">
+						提示:点击【坐标拾取】按钮,在地图上点击获取坐标。
+					</div>
+					<el-input v-model="pickCoords" type="textarea" :autosize="{ minRows: 6, maxRows: 6 }" />
+					<div class="jt-btn" style="margin-top: 10rem;">
+						<el-button color="rgb(20 136 255)" @click="pickUp">坐标拾取</el-button>
+						<el-button color="rgb(20 136 255)" @click="undo">撤销</el-button>
+						<el-button color="rgb(255 100 100)" @click="emptyPic"><span style="color: #fff;">清空</span></el-button>
+					</div>
+				</div>
+			</el-collapse-item>
+		</el-collapse>
+	</div>
+</template>
+<script>
+	let jt3d = undefined;
+
+	export default {
+		props: {
+
+		},
+		watch: {
+			pickCoordsLable: function(val) {
+				this.setPickCoordsLable(val);
+			},
+
+		},
+
+		/* 数据 */
+		data() {
+			return {
+				activeName: "坐标定位",
+
+				position: {
+					locationType: "point", //定位类型
+					locationCoords: "", //定位坐标
+				},
+
+				pickCoords: "", //坐标拾取
+				pickCoordsArray: [],
+				pickCoordsLable: 1,
+
+				pointEntities: []
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			/**
+			 * 设置点的lable
+			 */
+			setPickCoordsLable(val) {
+				jt3d.CommonTools._sketchViewModel._lineLabel = val.toString();
+			},
+
+			/**
+			 * 坐标拾取
+			 */
+			pickUp() {
+				let _self = this;
+
+				//移除左键单击事件
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
+				}
+
+				jt3d.CommonTools._sketchViewModel._lineLabel = _self.pickCoordsLable.toString();
+				jt3d.CommonTools._sketchViewModel.sketchTools('point', {
+					onComplete(cPoint, gPoint) {
+						_self.pickCoordsArray.push(gPoint.lng.toFixed(6) + ',' + gPoint.lat.toFixed(6) + ',' + gPoint.height.toFixed(2)) + ";";
+						_self.pickCoords = _self.pickCoordsArray.join(";\n");
+						_self.pickCoordsLable++;
+
+						//还原左键单击事件
+						_self.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+					},
+					onError(message) {
+						
+					}
+				});
+			},
+
+			/**
+			 * 坐标拾取 - 撤销
+			 */
+			undo() {
+				this.pickCoordsArray.pop();
+				this.pickCoords = this.pickCoordsArray.join(";\n");
+				this.pickCoordsLable--;
+
+				//移除最后一个元素
+				let lastPointEntity = jt3d.CommonTools._sketchViewModel._pointEntitys[jt3d.CommonTools._sketchViewModel._pointEntitys.length - 1];
+				jt3d._entities.remove(lastPointEntity);
+				jt3d.CommonTools._sketchViewModel._pointEntitys.pop();
+			},
+
+			/**
+			 * 坐标拾取 - 清空
+			 */
+			empty() {
+				this.pickCoords = "";
+				this.pickCoordsArray = [];
+				this.pickCoordsLable = 1;
+				jt3d.CommonTools._sketchViewModel.sketchClear();
+				jt3d.CommonTools._sketchViewModel._clearEvent();
+				jt3d.CommonTools._sketchViewModel._clearEvent(jt3d.CommonTools._sketchViewModel._sketchEventHandler);
+
+				this.position.locationCoords = "";
+				jt3d._viewer.entities.remove(jt3d.LocateUtil._locationEntity);
+
+				for (let i = 0; i < this.pointEntities.length; i++) {
+					jt3d._viewer.entities.remove(this.pointEntities[i]);
+				}
+				this.pointEntities = []; //脏数据,存储entities
+			},
+			
+			/**
+			 * 坐标拾取 - 清空
+			 */
+			emptyPic() {
+				this.pickCoords = "";
+				this.pickCoordsArray = [];
+				this.pickCoordsLable = 1;
+				jt3d.CommonTools._sketchViewModel.sketchClear();
+				jt3d.CommonTools._sketchViewModel._clearEvent();
+				jt3d.CommonTools._sketchViewModel._clearEvent(jt3d.CommonTools._sketchViewModel._sketchEventHandler);
+			
+				jt3d._viewer.entities.remove(jt3d.LocateUtil._locationEntity);
+			
+				for (let i = 0; i < this.pointEntities.length; i++) {
+					jt3d._viewer.entities.remove(this.pointEntities[i]);
+				}
+				this.pointEntities = []; //脏数据,存储entities
+			},
+			
+			/**
+			 * 坐标定位 - 清空
+			 */
+			emptyLoc() {
+				this.pickCoordsArray = [];
+				this.pickCoordsLable = 1;
+				jt3d.CommonTools._sketchViewModel.sketchClear();
+				jt3d.CommonTools._sketchViewModel._clearEvent();
+				jt3d.CommonTools._sketchViewModel._clearEvent(jt3d.CommonTools._sketchViewModel._sketchEventHandler);
+			
+				this.position.locationCoords = "";
+				jt3d._viewer.entities.remove(jt3d.LocateUtil._locationEntity);
+			
+				for (let i = 0; i < this.pointEntities.length; i++) {
+					jt3d._viewer.entities.remove(this.pointEntities[i]);
+				}
+				this.pointEntities = []; //脏数据,存储entities
+			},
+
+			/**
+			 * 坐标定位
+			 */
+			Position() {
+				let _self = this;
+
+				let endstring = _self.position.locationCoords.substring(_self.position.locationCoords.length - 1);
+				if (endstring != ";") {
+					ElMessage("最后一位请用;结束!");
+					return false;
+				}
+
+				let coords = _self.position.locationCoords.substr(0, _self.position.locationCoords.length - 1);
+				let coordArray = coords.split(';');
+				let pointArray = [];
+				coordArray.forEach((coordinate, index) => {
+					let xyArray = coordinate.split(',');
+					if (xyArray.length != 2 && xyArray.length != 3) {
+						ElMessage("坐标不是成对出现,请检查!");
+						throw Error(); //forEach()本身无法跳出循环,所以,这里使用了抛异常的方法来终止它。
+					} else {
+						let longitude = xyArray[0];
+						let latitude = xyArray[1];
+
+						if (xyArray[2]) {
+							let height = xyArray[2];
+							let point = [Number(longitude), Number(latitude), Number(height)];
+
+							pointArray.push(point);
+							//点标记
+							jt3d.CommonTools._sketchViewModel._lineLabel = (index + 1).toString();
+							jt3d.CommonTools._sketchViewModel.sketchDrawFeacture(point, 'drawPoint');
+
+							if (index === (coordArray.length - 1)) {
+								loc();
+							}
+						} else {
+
+							let terrainAltitude = jt3dSDK.common.getHeigthByPointsMostDetailed(jt3d._viewer, [
+								[Number(longitude), Number(latitude)]
+							]);
+							terrainAltitude.then(function(updatedPositions) {
+								let point = [Number(longitude), Number(latitude), Number(updatedPositions[0].height)];
+								pointArray.push(point);
+								//点标记
+								jt3d.CommonTools._sketchViewModel._lineLabel = (index + 1).toString();
+								jt3d.CommonTools._sketchViewModel.sketchDrawFeacture(point, 'drawPoint');
+
+								if (index === (coordArray.length - 1)) {
+									loc();
+								}
+							});
+						}
+					}
+				});
+
+				function loc() {
+					switch (_self.position.locationType) {
+						case "point":
+							if (coordArray.length === 1) {
+
+								let point = jt3d.PointObject.generatePoint(
+									pointArray[0]
+								);
+								point.then(function(entity) {
+									_self.flyToEntity(entity);
+								});
+							} else {
+								let line = jt3d.PolylineObject.drawSpecifyColorLine(pointArray, {
+									color: [255, 0, 0, 0]
+								});
+								line.then(function(entity) {
+									_self.flyToEntity(entity);
+								});
+							}
+							break;
+						case "polyline":
+							let line = jt3d.PolylineObject.drawSpecifyColorLine(pointArray, {
+								color: [255, 255, 0, 0.8]
+							});
+							line.then(function(entity) {
+								_self.flyToEntity(entity);
+							});
+
+							break;
+						case "polygon":
+							let polygon = jt3d.PolygonObject.generatePolygonByPoints(pointArray, {
+								color: [255, 255, 0, 0.8]
+							});
+							polygon.then(function(entity) {
+								_self.flyToEntity(entity);
+							});
+							break;
+					}
+
+				}
+
+			},
+
+			flyToEntity(entity) {
+				let flyToEntity = jt3d.LocateUtil.flyToEntity(entity, {
+					duration: 3,
+					heading: -45,
+					pitch: -20,
+					range: 6000
+				});
+				flyToEntity.then(function(entity) {
+					if (entity.point) {
+						jt3d._viewer.entities.remove(entity);
+					}
+				});
+			},
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.el-radio-group {
+		height: 32rem;
+		line-height: 32rem;
+		flex-wrap: nowrap;
+	}
+
+	::v-deep .el-radio__label {
+		font-size: 14rem !important;
+		padding-left: 8rem !important;
+	}
+
+	.jt-coordsTool {
+		position: relative;
+
+		.iconfont {
+			padding: 0 10rem;
+		}
+
+		.el-collapse {
+			--el-collapse-border-color: rgb(0 44 126 / 0%);
+
+			--el-collapse-header-text-color: #ffffff;
+			--el-collapse-header-font-size: 13rem;
+			--el-collapse-content-bg-color: rgb(0 44 126 / 0%);
+			--el-collapse-content-font-size: 13rem;
+			--el-collapse-content-text-color: rgb(216 240 255);
+
+			--el-collapse-header-height: 40rem;
+			--el-collapse-header-bg-color: rgb(30 130 255);
+
+			--el-fill-color-blank: rgb(0 44 126 / 68%);
+			--el-text-color-regular: rgb(216 240 255);
+			--el-border-color: rgb(35 135 255);
+
+			.el-collapse-item__content {
+				padding: 10rem;
+				// padding-bottom: 0rem;
+			}
+		}
+	}
+
+	::v-deep .el-collapse-item__content {
+		padding: 10rem;
+		// padding-bottom: 0rem;
+		overflow-y: hidden;
+	}
+
+	::v-deep .el-collapse-item__header {
+		background: url(@/assets/images/bg_collapse_title.png) no-repeat;
+		background-size: 350rem 40rem;
+		// background-color: rgb(22 90 190);
+		// background-color: rgb(5 45 100 /60%);
+		background-color: rgb(30 130 255);
+		border-bottom: 0;
+	}
+
+	::v-deep .el-form-item {
+		margin-bottom: 10rem;
+	}
+
+	::v-deep .el-radio {
+		margin-right: 10rem;
+	}
+</style>

+ 462 - 0
src/views/Map3d - 副本 (3)/components/drawEdit.vue

@@ -0,0 +1,462 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+	import {
+		inject
+	} from "vue";
+	import {
+		ArrowLeft,
+		ArrowRight,
+		Delete,
+		Edit,
+		Share
+	} from '@element-plus/icons-vue';
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-drawTool">
+		<div style="margin-bottom: 0rem;">
+			<el-select class="selectInfo" v-model="value" @change="handleClick" placeholder="请选择" style="width: 65%; margin-bottom: 10rem;margin-right: 10rem;">
+				<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
+			</el-select>
+			<el-button type="danger" :icon="Delete" style="margin-top: 8rem;width: 30%;" @click="removeAll()">清除</el-button>
+		</div>
+		<div v-show="value=='二维平面类'">
+			<el-row :gutter="20" style="margin-left: 0rem; margin-right: 0rem">
+				<el-col v-for="(item,index) in towDimension" :span="8" @click="createGraphics(item.drawType,index)">
+					<el-avatar shape="circle" :size="70" :class="currentIndex===index?'selectStyle':'defaultStyle'">
+						<i :class="[item.icon,currentIndex===index?'selectFontStyle':'']" />
+					</el-avatar>
+					<div style="margin-top: 5rem; font-size: 14rem;" :class="currentIndex===index?'selectFontStyle':''">{{item.label}}</div>
+				</el-col>
+			</el-row>
+		</div>
+		<div v-show="value=='三维立体类'">
+			<el-row :gutter="20" style="margin-left: 0rem; margin-right: 0rem">
+				<el-col v-for="(item,index) in threeDimension" :span="8" @click="createGraphics(item.drawType,index)">
+					<el-avatar shape="circle" :size="70" :class="currentIndex===index?'selectStyle':'defaultStyle'">
+						<i :class="[item.icon,currentIndex===index?'selectFontStyle':'']" />
+					</el-avatar>
+					<div style="margin-top: 5rem; font-size: 14rem;" :class="currentIndex===index?'selectFontStyle':''">{{item.label}}</div>
+				</el-col>
+			</el-row>
+		</div>
+		<div v-show="value=='军事标绘类'">
+			<el-row :gutter="20" style="margin-left: 0rem; margin-right: 0rem">
+				<el-col v-for="(item,index) in militaryPlotting" :span="8" @click="createMilitaryPlot(item.drawType,index)">
+					<el-avatar shape="circle" :size="70" :class="currentIndex===index?'selectStyle':'defaultStyle'">
+						<i :class="[item.icon,currentIndex===index?'selectFontStyle':'']" />
+					</el-avatar>
+					<div style="margin-top: 5rem; font-size: 14rem;" :class="currentIndex===index?'selectFontStyle':''">{{item.label}}</div>
+				</el-col>
+			</el-row>
+		</div>
+		<div v-show="value=='点标绘类'">
+			<el-row :gutter="20" style="margin-left: 0rem; margin-right: 0rem">
+				<el-col v-for="(item,index) in point" :span="8" @click="createDrawPoint(item.drawType,index)">
+					<el-avatar shape="circle" :size="70" :class="currentIndex===index?'selectStyle':'defaultStyle'">
+						<i :class="[item.icon,currentIndex===index?'selectFontStyle':'']" />
+					</el-avatar>
+					<div style="margin-top: 5rem; font-size: 14rem;" :class="currentIndex===index?'selectFontStyle':''">{{item.label}}</div>
+				</el-col>
+			</el-row>
+		</div>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+	let tipEntity = undefined;
+	export default {
+		props: {},
+		watch: {},
+		/* 数据 */
+		data() {
+			return {
+				currentIndex: -1,
+				value: "二维平面类",
+				options: [{
+						value: '点标绘类',
+						label: '点标绘类',
+					}, {
+						value: '二维平面类',
+						label: '二维平面类',
+					},
+					{
+						value: '三维立体类',
+						label: '三维立体类',
+					},
+					{
+						value: '军事标绘类',
+						label: '军事标绘类',
+					},
+				],
+				towDimension: [{
+						label: '贴地线',
+						drawType: 'polyline',
+						number: 0,
+						icon: 'iconfont icon-svgtiedixian'
+					},
+					{
+						label: '箭头线',
+						drawType: 'arrowPolyline',
+						number: 1,
+						icon: 'iconfont icon-svgjiantouxian'
+					},
+					{
+						label: '贴地面',
+						drawType: 'polygon', //polygon
+						number: 2,
+						icon: 'iconfont icon-svgtiedimian'
+					},
+					{
+						label: '动态线',
+						drawType: 'dynamicPolyline',
+						number: 3,
+						icon: 'iconfont icon-svgliudongxian'
+					},
+					{
+						label: '发光线',
+						drawType: '发光线',
+						number: 4,
+						icon: 'iconfont icon-svgfaguangxian'
+					},
+					{
+						label: '描边线',
+						drawType: 'outlinePolyline',
+						number: 5,
+						icon: 'iconfont icon-svgmiaobianxian'
+					},
+					{
+						label: '动态圆',
+						drawType: 'dynamicCircle',
+						number: 6,
+						icon: 'iconfont icon-svgdongtaiyuan'
+					},
+					{
+						label: '普通圆',
+						drawType: 'circle',
+						number: 7,
+						icon: 'iconfont icon-svgputongyuan'
+					},
+					{
+						label: '矩形',
+						drawType: 'rectangle',
+						number: 8,
+						icon: 'iconfont icon-svgjuxing'
+					},
+
+				],
+				threeDimension: [{
+						label: '空间线',
+						drawType: 'spatialLine',
+						number: 0,
+						icon: 'iconfont icon-svgkongjianxian'
+					},
+					{
+						label: '动态墙',
+						drawType: 'dynamicWall',
+						number: 1,
+						icon: 'iconfont icon-svgdongtaiqiang'
+					},
+					{
+						label: '房屋',
+						drawType: 'house',
+						number: 2,
+						icon: 'iconfont icon-svgfangwu'
+					},
+					{
+						label: '文字',
+						drawType: 'text',
+						number: 3,
+						icon: 'iconfont icon-svgzi'
+					},
+					{
+						label: '视频墙',
+						drawType: 'videoWall',
+						number: 4,
+						icon: 'iconfont icon-svgshipinqiang'
+					},
+					{
+						label: '普通墙',
+						drawType: 'normalWall',
+						number: 5,
+						icon: 'iconfont icon-svgputongqiang'
+					},
+				],
+				militaryPlotting: [{
+						label: '直线箭头',
+						drawType: 'straightArrow',
+						number: 1,
+						icon: 'iconfont icon-zhijiantou'
+					},
+					{
+						label: '攻击箭头',
+						drawType: 'attackArrow',
+						number: 2,
+						icon: 'iconfont icon-tujifangxiang'
+					},
+					{
+						label: '钳击箭头',
+						drawType: 'pincerArrow',
+						number: 3,
+						icon: 'iconfont icon-qianji'
+					}
+				],
+				point: [{
+						label: '小模型',
+						drawType: 'model',
+						number: 1,
+						icon: 'iconfont icon-jihedi'
+					}, {
+						label: '文字',
+						drawType: 'label',
+						number: 2,
+						icon: 'iconfont icon-jihedi'
+					},
+					{
+						label: '点',
+						drawType: 'point',
+						number: 3,
+						icon: 'iconfont icon-jihedi'
+					},
+					{
+						label: '点及文字',
+						drawType: 'point2Label',
+						number: 4,
+						icon: 'iconfont icon-jihedi'
+					},
+					{
+						label: '广告牌',
+						drawType: 'billboard',
+						number: 5,
+						icon: 'iconfont icon-jihedi'
+					},
+					{
+						label: '广告牌及文字',
+						drawType: 'billboard2Label',
+						number: 6,
+						icon: 'iconfont icon-jihedi'
+					}
+				],
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			//清除全部
+			removeAll() {
+				jt3d.DrawToolsEdit.Clear();
+				jt3d.DrawMilitaryPlot.clearAll();
+				jt3d.DrawPointEdit.clearAll();
+
+				this.currentIndex = -1;
+
+				//还原左键单击事件
+				this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+			},
+
+			//选择绘制类型
+			//头部标题点击事件
+			handleClick(val) {
+				console.log(val)
+				this.currentIndex = -1;
+				this.value = val
+			},
+
+			//创建军事标会
+			createMilitaryPlot(type, index) {
+				let _self = this;
+				this.currentIndex = index;
+
+				//移除左键单击事件
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
+				}
+
+				/* 创建监听 */
+				jt3d.DrawMilitaryPlot.onEditProperty = {};
+				// 开始绘制
+				jt3d.DrawMilitaryPlot.draw(type, {
+					onComplete(cPoint, gPoint) {
+						// _self.$parent.$parent.param = param;
+						// _self.$parent.$parent.showDialog = true;
+					}
+				});
+			},
+
+			//创建二维标会和三维标会
+			createGraphics(type, index) {
+				let _self = this;
+				this.currentIndex = index;
+
+				//移除左键单击事件
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
+				}
+
+				/* 创建监听 */
+				jt3d.DrawToolsEdit.onEditProperty = {};
+				// 开始绘制
+				jt3d.DrawToolsEdit.draw(type, {
+					isEdit: true,
+					onComplete(cPoint, gPoint) {
+
+					},
+					onError(message) {
+						console.log('错误原因', message)
+					}
+				});
+			},
+
+			//创建点类标绘
+			createDrawPoint(type, index) {
+				let _self = this;
+				this.currentIndex = index;
+
+				//移除左键单击事件
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
+				}
+
+				/* 创建监听 */
+				jt3d.DrawPointEdit.onEditProperty = {};
+				// 开始绘制
+				jt3d.DrawPointEdit.draw(type, {
+					isEdit: true,
+					onComplete(cPoint, gPoint) {
+
+					},
+					onError(message) {
+						console.log('错误原因', message)
+					}
+				});
+			}
+
+		},
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.el-avatar {
+		width: 70rem !important;
+		height: 70rem !important;
+		font-size: 14px !important;
+		cursor: pointer;
+	}
+
+	// .el-popper{
+	// 	padding: 5rem 11rem;
+	// 	font-size: 12rem;
+	// 	line-height: 20rem;
+	// 	min-height: 10rem;
+	// 	width: 322rem;
+	// 	height: 311rem;
+	// 	left: 15rem !important;
+	// 	top: 175rem !important;
+	// }
+
+	::v-deep .el-scrollbar {
+		background-color: gainsboro !important;
+	}
+
+	.el-select-dropdown__item {
+		color: #409eff !important;
+		padding: 0 32rem 0 20rem;
+		height: 34rem;
+		line-height: 34rem;
+		font-size: 14rem;
+	}
+
+	.jt-drawTool {
+		--el-avatar-size: 70rem !important;
+
+
+		.el-col {
+			padding: 10rem;
+			// color: rgba(90, 172, 255, 1.0);
+			color: #fff;
+		}
+
+		i {
+			display: inline-block;
+			width: 100%;
+			height: 36rem;
+			line-height: 36rem;
+			text-align: center;
+			border-radius: 5rem;
+			font-size: 40rem;
+			// color: rgba(90, 172, 255, 1.0);
+			color: #fff;
+			transition: all .3s;
+			-webkit-transition: all .3s
+		}
+
+		.selectStyle {
+			// background: rgba(135, 182, 254, 0.5);
+			background: rgb(0 44 126);
+			--el-avatar-size: 70rem !important;
+		}
+
+		.defaultStyle {
+			background: #ffffff00;
+			--el-avatar-size: 70rem !important;
+		}
+
+		.selectFontStyle {
+			color: #fff;
+		}
+
+		.el-button.is-text {
+			background-color: rgba(255, 255, 255, 0.5);
+		}
+
+		el-option {
+			margin-top: -15rem !important;
+		}
+
+		.iconactive {
+			box-shadow: 0 0 3rem 3rem rgba(12, 123, 200, .6);
+		}
+
+		.active {
+			color: #409eff
+		}
+
+		::v-deep .el-input__wrapper {
+			background-color: rgba(255, 255, 255, 0);
+			color: #fff;
+		}
+
+		::v-deep .el-input__inner {
+			color: #fff;
+		}
+
+		.selectInfo {
+			top: 10rem !important;
+		}
+
+		.el-select-dropdown__wrap {
+			margin-top: 10rem;
+		}
+
+		.el-select-dropdown__item {
+			background-color: rgba(255, 255, 255, 1) !important;
+
+		}
+
+		.el-select-dropdown__item:hover {
+			background-color: rgba(255, 255, 235, 1) !important;
+		}
+
+	}
+</style>

+ 387 - 0
src/views/Map3d - 副本 (3)/components/location-region.vue

@@ -0,0 +1,387 @@
+<script setup>
+	import {
+		ref
+	} from 'vue';
+	import {
+		inject
+	} from "vue";
+	import selshi from '@/assets/images/selshi.png';
+	import selcun from '@/assets/images/selcun.png';
+	import cun from '@/assets/images/cun.png';
+	import shi from '@/assets/images/shi.png';
+	import xian from '@/assets/images/xian.png';
+	import selxian from '@/assets/images/selxian.png';
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<jt-popup title="空间分析" ref="refAnalysisSpace" >
+		<div class="tabs">
+			<el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
+				<i v-for="(item,index) in cityList">
+					<el-tab-pane :name="item.number">
+						<template #label>
+							<span class="custom-tabs-label">
+								<img v-if="index==0" :src="isindex==0?selshi:shi">
+								<img v-if="index==1" :src="isindex==1?selxian:xian">
+								<img v-if="index==2" :src="isindex==2?selcun:cun">
+								<span>{{item.label}}</span>
+							</span>
+						</template>
+						<template #default>
+							<div class="content">
+								<div :class="dj == 1?'item':'item2'" v-for="(res,num) in ALLlist" @click="selectCity(res.label,index+1,res.regioncode,res.dj)">
+									<div :class="addcolor(num)" @click="currentidx(num)">
+										<span>{{res.label}}</span>
+									</div>
+								</div>
+							</div>
+						</template>
+					</el-tab-pane>
+				</i>
+			</el-tabs>
+		</div>
+		<div class="Ficons">
+			<!-- <span>遮罩</span> -->
+			<!-- <el-icon color="#ffffff" class="icons" @click="hide" :size="20">
+			<View v-show="!hideicon" />
+			<Hide v-show="hideicon" />
+		</el-icon> -->
+		</div>
+	</jt-popup>
+</template>
+
+<script>
+	let jt3d = undefined;
+	let entities = undefined;
+	export default {
+		data() {
+			return {
+				currentIndex: -1,
+				isindex: 0, //判断选中第几个标题
+				cityList: [{ //tab数组展示列表
+					label: '牟平',
+					number: 0,
+					dj: 1
+				}],
+				activeName: 0, //选中的下标牵引
+				ALLlist: [], //所有子集城市
+				downlist: [], //村集
+				dj: 1, //控制列表样式
+				entities: undefined,
+				hideicon: false, //控制遮罩层显示
+				acolor: true, //是否展示颜色
+			}
+		},
+		watch: {
+			//改变高度值
+			activeName() {
+				this.acolor = false
+			}
+		},
+		methods: {
+			currentidx(index) {
+				this.currentIndex = index
+				this.acolor = true
+			},
+
+			//添加颜色样式
+			addcolor(index) {
+				if (this.currentIndex == index) {
+					return {
+						active: this.acolor
+					}
+				}
+			},
+
+			/**
+			 *控制遮罩层
+			 */
+			hide() {
+				this.hideicon = !this.hideicon
+				if (this.hideicon) {
+					entities[0].polygon.material = Cesium.Color.fromBytes(50, 160, 255, 1)
+				} else {
+					entities[0].polygon.material = Cesium.Color.fromBytes(50, 160, 255, 77)
+				}
+			},
+			/**
+			 * 移除定位样式
+			 */
+			remove() {
+				if (window["viewer"].dataSources.getByName('标绘区')) {
+					window["viewer"].dataSources.remove(window["viewer"].dataSources.getByName('标绘区')[0])
+				}
+			},
+
+			//头部标题点击事件
+			handleClick(data) {
+				let index = Number(data.index)
+				//判断点击的是否是第一个标题
+				if (index == 0) {
+					this.getcityList()
+					this.cityList = this.cityList.slice(0, index + 1)
+					this.isindex = index
+					this.activeName = index
+
+					this.remove();
+					//全图事件
+					this.$parent.$parent.$refs.refMap3d.fullMap(jt3d);
+				}
+			},
+
+			/* 
+			 *** label  城镇村庄名字
+			 * * index  选中下标
+			 * * regioncode  编号
+			 * * dj  村镇等级
+			 */
+			selectCity(label, index, regioncode, dj) {
+
+				let _this = this
+
+				if (!regioncode) {
+					return
+				}
+
+				//如果等级为1,代表点击的乡镇,需要重新设置ALLlist为村庄列表,并在头部添加乡镇名称
+				if (dj == 1) {
+					this.cityList.push({
+						label: label,
+						number: index,
+						dj: 2
+					})
+
+					var id = regioncode.slice(0, 9)
+
+					this.isindex = index
+					this.activeName = index
+					this.$http.get('/getTableList', {
+						tableName: 'map_region', //
+						sqlWhere: "dj = 2 and regioncode like '" + id + "%'",
+						orderByField: ''
+					}).then(res => {
+						if (res.data.length == 0) return
+						this.dj = 2
+						this.ALLlist = []
+						res.data.forEach(
+							item => {
+								this.ALLlist.push({
+									label: item.regionname,
+									regioncode: item.regioncode,
+									dj: 2
+								})
+							}
+						)
+					})
+				}
+
+				//根据等级与id获取乡镇或者村庄的面坐标
+				this.$http.get('/getGeoJson', {
+					tableName: 'map_region', //
+					sqlWhere: "dj = " + dj + " and regioncode like '" + regioncode + "%'",
+					orderByField: ''
+				}).then(res => {
+
+					if (window["viewer"].dataSources.getByName('标绘区')) {
+						window["viewer"].dataSources.remove(window["viewer"].dataSources.getByName('标绘区')[0])
+					}
+					let promise = Cesium.GeoJsonDataSource.load(res.data, {
+						clampToGround: true
+					});
+					promise.then((dataSource) => {
+						window["viewer"].dataSources.add(dataSource); // 加载这个geojson资源 
+						dataSource.name = '标绘区'
+						entities = dataSource.entities.values;
+						const entity = entities[0];
+						entity.polygon.material = Cesium.Color.fromBytes(50, 160, 255, 77)
+						entity.polygon.outlineWidth = 3;
+						entity.polygon.outline = false;
+						entity.polygon.outlineColor = Cesium.Color.RED;
+						entity.polyline = {
+							positions: entity.polygon.hierarchy._value.positions,
+							width: entity.polygon.outlineWidth,
+							material: Cesium.Color.fromBytes(0, 255, 180, 255),
+							clampToGround: true
+						}
+
+						_this.hideicon = false;
+
+						let options = {};
+						// 初始化参数默认值
+						options.duration = Cesium.defaultValue(options.duration, 2);
+						options.heading = Cesium.defaultValue(options.heading, 0);
+						options.pitch = Cesium.defaultValue(options.pitch, -60);
+						options.range = Cesium.defaultValue(options.range, 0.0);
+
+						let colorList = [
+							[90, 120, 255, 153],
+							[150, 255, 90, 153],
+							[255, 150, 50, 153],
+							[50, 160, 255, 77]
+						]
+
+						let flyPromise = window["viewer"].flyTo(entity, {
+							duration: options.duration,
+							offset: {
+								heading: Cesium.Math.toRadians(options.heading),
+								pitch: Cesium.Math.toRadians(options.pitch),
+								range: options.range
+							}
+						});
+						flyPromise.then(res => {
+							//面首次加载颜色
+							const entity = entities[0];
+							entity.polygon.material = Cesium.Color.fromBytes(colorList[0][0],
+								colorList[0][1], colorList[0][2], colorList[0][3])
+
+							let idx = 1
+							let timer = setInterval(res => {
+								const entity = entities[0];
+								entity.polygon.material = Cesium.Color.fromBytes(colorList[idx][0], colorList[idx][1], colorList[idx][2], colorList[idx][3]);
+								idx++
+							}, 500)
+							setTimeout(res => {
+								clearInterval(timer)
+
+								_this.hide();
+							}, 2100)
+						})
+					});
+				})
+			},
+
+			//获取一级街道
+			getcityList() {
+
+				this.dj = 1
+				this.ALLlist = []
+				this.$http.get("/getTableList", {
+					tableName: "map_region",
+					sqlWhere: "dj = 1",
+					orderByField: ''
+				}).then(res => {
+					if (res.data.length > 0) {
+						res.data.forEach(
+							item => {
+								console.log('街道信息', item)
+								this.ALLlist.push({
+									label: item.regionname,
+									regioncode: item.regioncode,
+									dj: 1
+								})
+							}
+						)
+					}
+				})
+
+			}
+		},
+		mounted() {
+			this.getcityList()
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.Ficons {
+		position: absolute;
+		top: 10rem;
+		left: 20rem;
+	}
+
+	.active {
+		color: #409eff;
+	}
+
+	//整体样式
+	.tabs {
+		width: 90%;
+		margin-left: 5%;
+		text-align: left;
+
+		--el-font-size-base: 16rem;
+
+		.item {
+			// width: 135rem;
+			width: 80rem;
+			display: inline-block;
+			height: 42rem;
+			margin-right: 15rem;
+			color: #ffffff;
+			font-size: 16rem;
+			cursor: pointer;
+			white-space: nowrap;
+			/*显示的行数;如果要设置2行加...则设置为2*/
+			overflow: hidden;
+			/*超出的文本隐藏*/
+			text-overflow: ellipsis;
+			/* 溢出用省略号*/
+
+			font-style: normal;
+		}
+
+		.item2 {
+			width: 65rem;
+			display: inline-block;
+			height: 35rem;
+			margin-right: 10rem;
+			color: #ffffff;
+			font-size: 16rem;
+			cursor: pointer;
+			white-space: nowrap;
+			/*显示的行数;如果要设置2行加...则设置为2*/
+			overflow: hidden;
+			/*超出的文本隐藏*/
+			text-overflow: ellipsis;
+			/* 溢出用省略号*/
+
+			font-style: normal;
+		}
+
+		.content {
+			width: 100%;
+			margin: 10rem 0;
+			overflow-y: auto;
+		}
+
+		img {
+			width: 18rem;
+			height: 18rem;
+			vertical-align: -10%;
+			margin-right: 2rem;
+		}
+	}
+
+
+
+	.demo-tabs>.el-tabs__content {
+		padding: 32rem;
+		color: #6b778c;
+		font-size: 32rem;
+		font-weight: 600;
+	}
+
+	//未选择tabs标题样式
+	::v-deep .el-tabs__item {
+		color: #ffffff !important;
+	}
+
+	//选中tabs标签样式
+	::v-deep .el-tabs__item.is-active {
+		color: var(--el-color-primary) !important;
+	}
+
+	//选中下划线样式
+	::v-deep .el-tabs__active-bar {
+		bottom: -1rem !important;
+		height: 4rem !important;
+	}
+
+	//下横线样式
+	::v-deep .el-tabs__nav-wrap::after {
+		height: 1rem !important;
+		background-color: darkgrey;
+	}
+</style>

+ 266 - 0
src/views/Map3d - 副本 (3)/components/manage-basemap.vue

@@ -0,0 +1,266 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	import {
+		Store
+	} from '@/store/index'
+	store = Store();
+
+	import no_img from '@/assets/images/no_img.png';
+</script>
+
+<template>
+	<jt-popup title="底图切换">
+		<div class="jt-basemap">
+			<div class="top">
+				<div class="onceLayer" v-for="(item,index) in baseMaps" :key="index" @click="changeBasicLayer(item)">
+					<img v-if="item.imageurl" :src="item.imageurl" :class="item.layerorder===selectImg?'selectImg':''" />
+				</div>
+			</div>
+			<div class="bottom">
+				<el-switch v-model="terrain.isTerrain" @change="changeTerrain" />
+				<span>显示地形</span>
+				<span> </span>
+				<el-switch v-model="mark.isMark" @change="changeMark" />
+				<span>显示标注</span>
+			</div>
+		</div>
+	</jt-popup>
+
+</template>
+
+<script>
+	let store = undefined
+
+	import * as mapWork from "../map"
+
+	export default {
+		data() {
+			return {
+				//底图数据
+				baseMaps: [], //底图
+				selectImg: store.basemap.selectImg, //选中的底图图片
+				selectBaseMap: store.basemap.selectBaseMap, //选中的底图数据
+
+				//地形数据
+				terrain: {
+					isTerrain: store.terrain.isTerrain, //是否切换地形
+					terrainData: store.terrain.terrainData, //地形数据
+				},
+
+				//标注数据
+				mark: {
+					isMark: store.mark.isMark, //是否显示标注
+					markData: store.mark.markData, //地形数据
+				}
+
+			}
+		},
+		methods: {
+
+			/**
+			 * 切换地形事件
+			 */
+			changeTerrain() {
+				mapWork.setLayersControl(window.viewer, this.terrain.terrainData, this.terrain.isTerrain);
+			},
+
+			/**
+			 * 切换标注
+			 */
+			changeMark() {
+				//图层ID
+				let serviceId = "service_" + this.mark.markData.layercode + this.mark.markData.layerorder;
+				this.mark.markData.serviceId = serviceId;
+
+				//透明度
+				let opacity = 1;
+				if (this.mark.markData.opacity == null) {
+					opacity = 1;
+				} else {
+					opacity = Number(this.mark.markData.opacity);
+				}
+				this.mark.markData.opacity = opacity;
+
+				mapWork.setLayersControl(window.viewer, this.mark.markData, this.mark.isMark);
+			},
+
+			/**
+			 * 切换底图事件
+			 * @param {Object} item
+			 */
+			changeBasicLayer(item) {
+
+				this.selectImg = item.layerorder;
+				store.basemap.selectImg = item.layerorder;
+
+
+				//删除底图后再添加
+				mapWork.setLayersControl(window.viewer, this.selectBaseMap, false).then(res => {
+
+					//图层ID
+					let serviceId = "service_" + item.layercode + item.layerorder;
+					item.serviceId = serviceId;
+
+					//透明度
+					let opacity = 1;
+					if (item.opacity == null) {
+						opacity = 1;
+					} else {
+						opacity = Number(item.opacity);
+					}
+					item.opacity = opacity;
+					
+					store.basemap.selectBaseMap = item;
+
+					mapWork.setLayersControl(window.viewer, item, true);
+					this.selectBaseMap = item;
+				});
+			},
+
+			/**
+			 * 添加底图图集
+			 */
+			initBaseMap() {
+				let _self = this;
+
+				mapWork.getBaseMaps().then(basemaps => {
+					basemaps.forEach(item => {
+						let parameterset = item.parameterset;
+						if (item.parameterset instanceof Object) {
+							parameterset = item.parameterset;
+						} else if (item.parameterset != "" && item.parameterset != null && item.parameterset != undefined) {
+							parameterset = JSON.parse(item.parameterset);
+						}
+
+						if (item.datasource && item.datasource != '#' && item.layertype != '地形' && item.layertype != '标注') {
+							if (parameterset) {
+								if (parameterset.imgurl) {
+									item.imageurl = parameterset.imgurl;
+								} else {
+									item.imageurl = no_img;
+									ElMessage("请检查底图图层表parameterset字段是否设置imgurl");
+								}
+								_self.baseMaps.push(item);
+							}
+						}
+					});
+
+					//底图组件高度不变
+					if (_self.baseMaps.length % 3 == 1) {
+						_self.baseMaps.push({}, {})
+					} else if (_self.baseMaps.length % 3 == 2) {
+						_self.baseMaps.push({})
+					} else if (_self.baseMaps.length % 3 == 0) {
+						_self.baseMaps.push({}, {}, {})
+					}
+				});
+			}
+		},
+		mounted() {
+			this.initBaseMap();
+		}
+	}
+</script>
+
+<style scoped lang="scss">
+	@charset "UTF-8";
+
+	@font-face {
+		font-family: "TTTGB-Medium";
+		src: url("@/assets/fonts/fonts/TTTGB-Medium.ttf") format("truetype"),
+			url("@/assets/fonts/fonts/TTTGB-Medium.eot") format("embedded-opentype"),
+			url("@/assets/fonts/fonts/TTTGB-Medium.svg") format("svg");
+		font-weight: normal;
+		font-style: normal;
+	}
+
+	::v-deep .is-checked .el-switch__core .el-switch__action {
+		margin-left: calc(-1rem - 14rem);
+	}
+
+	::v-deep .el-switch__core .el-switch__action {
+		top: 1rem;
+	}
+
+	::v-deep .el-switch__core .el-switch__action {
+		width: 14rem;
+		height: 14rem;
+	}
+
+	::v-deep .el-switch__core {
+		width: 40rem !important;
+		height: 20rem !important;
+	}
+
+	.jt-basemap {
+		position: absolute;
+		width: 350rem;
+		height: calc(100% - 105rem);
+
+		.top {
+			height: calc(100% - 50rem);
+			padding: 10rem;
+			flex-wrap: wrap;
+			justify-content: space-around;
+			overflow-y: scroll; // 设置y轴方向的滚动条
+			overflow: hidden; // 超出部分隐藏
+
+			.onceLayer {
+				display: inline-block;
+				padding: 5rem;
+				width: 100rem;
+				height: 120rem;
+
+				img {
+					height: 100%;
+					width: 100%;
+					border-radius: 5rem;
+				}
+
+				img:hover {
+					cursor: pointer;
+					height: calc(100% - 0rem);
+					width: calc(100% - 0rem);
+					border: 0rem solid rgba(255, 255, 255, .8);
+					box-shadow: 0 0 2rem 2rem rgba(255, 255, 255, .5);
+					transition: all .2s;
+				}
+
+				//选中图片样式
+				.selectImg {
+					border: 0rem solid rgba(255, 255, 255, .8);
+					box-shadow: 0 0 3rem 3rem rgba(255, 255, 255, .5);
+				}
+
+				span {
+					font-size: 14rem;
+					display: inline-block;
+				}
+			}
+		}
+
+		.bottom {
+			width: 100%;
+			height: 40rem;
+			line-height: 40rem;
+			text-align: left;
+			padding-left: 10rem;
+			border: 0px solid red;
+
+			el-switch {
+				margin: 3rem 0rem;
+				width: 36rem !important;
+			}
+
+			span {
+				margin: 4rem 4rem;
+			}
+		}
+	}
+</style>

+ 334 - 0
src/views/Map3d - 副本 (3)/components/manage-layer.vue

@@ -0,0 +1,334 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+
+	import {
+		Store
+	} from '@/store/index'
+	store = Store();
+
+	import {
+		deepTree
+	} from "@/utils/deepTree.js";
+
+	import {
+		useWidget
+	} from "@/common/store/widget"
+
+	// const {
+	// 	activate,
+	// 	disable,
+	// 	currentWidget
+	// } = useWidget()
+	// currentWidget.onUpdate(() => {
+	// 	treeData = []
+	// 	expandedKeys = []
+	// 	checkedKey = []
+	// 	initTree()
+	// })
+</script>
+
+<template>
+	<jt-popup title="图层控制">
+		<div class="jt-layer">
+			<!-- :default-checked-keys="checkedkeys"  默认勾选的节点的 key 的数组-->
+			<!-- :default-expanded-keys="expandedKeys" 默认展开的节点的 key 的数组-->
+			<!-- @node-click 节点单击事件 -->
+			<el-tree :data="treeData" :default-expanded-keys="expandedKeys" :default-checked-keys="checkedkeys" node-key="id" class="tree-line" ref="treeRef">
+				<template #default="{ node, data }">
+					<!-- 复选框 -->
+					<el-checkbox v-if="data.ischeck == '1' && store.userport == 'PC'" v-model="node.checked" :indeterminate="node.indeterminate" :disabled="!!node.disabled" @change="handleCheckBoxChange($event, data, node)">
+					</el-checkbox>
+					<el-switch v-else-if="data.ischeck == 1 && store.userport == 'APP'" width="30rem" size="small" v-model="node.checked" @change="handleCheckBoxChange($event, data, node)" />
+					<span class="custom-tree-node" @click="handleClick(data)" style="width: 150rem;text-align: left;">
+						<!-- 字体、图标 -->
+						<!-- <span>
+						<img src="@/assets/images/logo16x16.ico" />
+					</span> -->
+						<span class="overflowtext">
+							{{ data.layername }}
+						</span>
+
+					</span>
+
+					<!-- 透明度 -->
+					<template v-if="node.checked && data.opacity >0">
+						<div style="width: 80rem; padding: 0 20rem; position: absolute; right: 0">
+							<el-slider v-model="data.opacity" @input="handleSliderChange($event, data)" :max="1" :min="0.1" :step="0.1" />
+						</div>
+					</template>
+				</template>
+			</el-tree>
+		</div>
+	</jt-popup>
+</template>
+
+<script>
+	let store = undefined
+
+	import * as mapWork from "../map"
+
+	export default {
+
+		/* 数据 */
+		data() {
+			return {
+				treeData: [], //树结构
+				// expandedKeys: [], //对应要展开的节点id
+				// checkedkeys: [], //默认打开节点的id
+				
+				expandedKeys: store.expandedKeys, //对应要展开的节点id
+				checkedkeys: store.checkedkeys, //默认打开节点的id
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			/**
+			 * 单击图层名称触发服务定位
+			 * @param {Object} data 传递给 data 属性的数组中该节点所对应的对象
+			 */
+			handleClick(data) {
+				store.serviceMark = 'service';
+				let serviceId = store.serviceMark + "_" + data.layercode + data.layerorder;
+				mapWork.setLayersLocation(window.viewer, {
+					serviceId:_serviceId,
+					parameterset:data.parameterset,
+					isinit:'1',
+					loadtype:data.loadtype
+				});
+			},
+
+			/**
+			 * el-slider 值改变时触发
+			 * 地图服务的透明度调整
+			 */
+			handleSliderChange($event, data) {
+				store.serviceMark = 'service';
+				let serviceId = store.serviceMark + "_" + data.layercode + data.layerorder;
+				mapWork.setLayersAlpha(window.viewer, {
+					loadtype:data.loadtype,
+					serviceId:serviceId,
+					alpha:$event
+				});
+			},
+
+			/**
+			 * el-checkbox 当绑定值变化时触发的事件
+			 * @param {Object} checked 复选框状态
+			 * @param {Object} data 对应于节点点击的节点对象
+			 * @param {Object} node TreeNode 的 node 属性
+			 */
+			handleCheckBoxChange(checked, data, node) {
+
+				store.serviceMark = 'service';
+				let _node = this.$refs.treeRef.getNode(data);
+				if (_node.isLeaf) {
+					
+					//图层ID
+					let serviceId = "service_" + data.layercode + data.layerorder;
+					data.serviceId = serviceId;
+					
+					//透明度
+					let opacity = 1;
+					if (data.opacity == null) {
+						opacity = 1;
+					} else {
+						opacity = Number(data.opacity);
+					}
+					data.opacity = opacity;
+					
+					mapWork.setLayersControl(window.viewer, data, checked);
+					
+					this.$refs.treeRef.setChecked(_node, checked); //是否设置子节点,默认为false,利用tree组件渲染后带有的isLeaf(是否为叶子节点)属性,如果为叶子节点就选中。利用tree的API就实现了正确的回显效果	
+
+				} else {
+					//控制子节点
+					this.childNodesChange(node, checked);
+				}
+			},
+
+			/**
+			 * 控制子节点
+			 * @param {Object} node
+			 * @param {Object} checked
+			 */
+			childNodesChange(node, checked) {
+				let _self = this;
+				node.childNodes.forEach(item => {
+					
+					//图层ID
+					let serviceId = "service_" + item.data.layercode + item.data.layerorder;
+					item.data.serviceId = serviceId;
+					
+					//透明度
+					let opacity = 1;
+					if (item.data.opacity == null) {
+						opacity = 1;
+					} else {
+						opacity = Number(item.data.opacity);
+					}
+					item.data.opacity = opacity;
+					
+					mapWork.setLayersControl(window.viewer, item.data, checked);
+					
+					_self.$refs.treeRef.setChecked(item, checked);
+					_self.childNodesChange(item, checked);
+				});
+			},
+
+
+			/**
+			 * 初始化图层控制树
+			 */
+			initLayerTree() {
+				let _self = this;
+
+				mapWork.getLayers().then(layers => {
+
+					layers.map((item) => {
+						let num = Number(item.layerorder)
+						if (num < 10) {
+							item.layerorder = '0' + item.layerorder
+						}
+
+						//透明度
+						item.opacity = Number(item.opacity);
+
+						// //默认展开
+						// if (item.isexpand === '1') {
+						// 	_self.expandedKeys.push(item.id);
+						// }
+
+						// // 复选框默认选中
+						// if (item.isinit === '1') {
+						// 	_self.checkedkeys.push(item.id);
+						// }
+					})
+
+					_self.treeData = deepTree(layers)
+				});
+			}
+		},
+
+		mounted() {
+			this.initLayerTree();
+		},
+	};
+</script>
+
+<style lang="scss">
+	.el-switch--small .el-switch__core .el-switch__action {
+		width: 12rem;
+		height: 12rem;
+	}
+
+	.el-switch--small.is-checked .el-switch__core .el-switch__action {
+		margin-left: calc(-1rem - 12rem);
+	}
+
+	.el-switch__core .el-switch__action {
+		top: 0;
+	}
+
+	.el-slider__button {
+		width: 20rem;
+		height: 20rem;
+	}
+
+	.el-tree-node__content {
+		height: 26rem;
+	}
+
+	.el-switch--small .el-switch__core {
+		height: 16rem;
+	}
+
+	.el-switch--small {
+		padding: 0 5rem;
+	}
+
+	.jt-layer {
+		padding-left: 10rem;
+
+		.el-tree {
+			background: none;
+			color: #fff;
+			--el-tree-node-hover-bg-color: #2a67c3;
+
+			.overflowtext {
+				width: auto !important;
+				padding: 0;
+			}
+		}
+
+		.tree-line {
+			.el-tree-node {
+				position: relative;
+				// padding-left: 16rem; // 缩进量
+			}
+
+			.el-tree-node__children {
+				padding-left: 16rem !important; // 缩进量
+
+				.el-tree-node__content {
+					padding-left: 18rem !important;
+				}
+			}
+
+			// 竖线
+			.el-tree-node::before {
+				content: "";
+				height: 100%;
+				width: 1rem;
+				position: absolute;
+				left: -3rem;
+				top: -26rem;
+				border-width: 1rem;
+				border-left: 1rem dashed rgba(255, 255, 255, .8);
+			}
+
+			// 当前层最后一个节点的竖线高度固定
+			.el-tree-node:last-child::before {
+				height: 38rem; // 可以自己调节到合适数值
+			}
+
+			// 横线
+			.el-tree-node::after {
+				content: "";
+				width: 24rem;
+				height: 20rem;
+				position: absolute;
+				left: -3rem;
+				top: 12rem;
+				border-width: 1rem;
+				border-top: 1rem dashed rgba(255, 255, 255, .8);
+			}
+
+			// 去掉最顶层的虚线,放最下面样式才不会被上面的覆盖了
+			&>.el-tree-node::after {
+				border-top: none;
+			}
+
+			&>.el-tree-node::before {
+				border-left: none;
+			}
+
+			// 展开关闭的icon
+			.el-tree-node__expand-icon {
+				font-size: 16rem;
+
+				// 叶子节点(无子节点)
+				&.is-leaf {
+					color: transparent;
+					display: none; // 也可以去掉
+				}
+			}
+		}
+	}
+</style>

+ 432 - 0
src/views/Map3d - 副本 (3)/components/map-compare.vue

@@ -0,0 +1,432 @@
+<script setup>
+	import {
+		inject
+	} from "vue";
+	const getMapInstance = inject("getMapInstance");
+	jt3dRight = getMapInstance();
+
+	import {
+		Store
+	} from '@/store/index'
+	store = Store();
+
+	import {
+		deepTree
+	} from "@/utils/deepTree.js";
+</script>
+
+<template>
+	<jt-popup title="分屏对比" animationClass="fadein-left" :isEmit="true" @closeJTPopup="closeJTPopup">
+		<div class="jt-map-compare">
+			<el-tree :data="treeData" :default-expanded-keys="expandedKeys" :default-checked-keys="checkedkeys" node-key="id" class="tree-line" ref="treeRef">
+				<template #default="{ node, data }">
+					<!-- 复选框 -->
+					<el-checkbox v-if="data.ischeck === '1' && store.userport == 'PC'" v-model="node.checked" :indeterminate="node.indeterminate" :disabled="!!node.disabled" @change="handleCheckBoxChange($event, data, node)">
+					</el-checkbox>
+					<el-switch v-else-if="data.ischeck == 1 && store.userport == 'APP'" width="30rem" size="small" v-model="node.checked" @change="handleCheckBoxChange($event, data, node)" />
+					<span class="custom-tree-node" @click="handleClick(data)" style="width: 150rem;text-align: left;">
+						<!-- 字体、图标 -->
+						<!-- <span>
+						<img src="@/assets/images/logo16x16.ico" />
+					</span> -->
+						<span class="overflowtext">
+							{{ data.layername }}
+						</span>
+					</span>
+
+					<!-- 透明度 -->
+					<template v-if="node.checked && data.opacity >0">
+						<div style="width: 80rem; padding: 0 20rem; position: absolute; right: 0">
+							<el-slider v-model="data.opacity" @input="handleSliderChange($event, data)" :max="1" :min="0.1" :step="0.1" />
+						</div>
+					</template>
+				</template>
+			</el-tree>
+		</div>
+	</jt-popup>
+</template>
+
+<script>
+	let store = undefined;
+	let jt3dRight = undefined;
+	let jt3dLeft = undefined;
+
+	import * as mapWork from "../map"
+
+	export default {
+
+		/* 数据 */
+		data() {
+			return {
+				treeData: [],
+				expandedKeys: [], //对应要展开的节点id
+				checkedkeys: [] //默认打开节点的id
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			/**
+			 * 单击图层名称触发服务定位
+			 * @param {Object} data 传递给 data 属性的数组中该节点所对应的对象
+			 */
+			handleClick(data) {
+				store.serviceMark = 'serviceLeft';
+				letserviceId = store.serviceMark + "_" + data.layercode + data.layerorder;
+				mapWork.setLayersLocation(window.viewerLeft, {
+					serviceId:serviceId,
+					parameterset:data.parameterset,
+					isinit:'1',
+					loadtype:data.loadtype
+				});
+				
+			},
+
+			/**
+			 * el-slider 值改变时触发
+			 * 地图服务的透明度调整
+			 */
+			handleSliderChange($event, data) {
+				store.serviceMark = 'serviceLeft';
+				let serviceId = store.serviceMark + "_" + data.layercode + data.layerorder;
+				mapWork.setLayersAlpha(window.viewerLeft, {
+					loadtype:data.loadtype,
+					serviceId:serviceId,
+					alpha:$event
+				})
+			},
+			
+			/**
+			 * el-checkbox 当绑定值变化时触发的事件
+			 * @param {Object} checked 复选框状态
+			 * @param {Object} data 对应于节点点击的节点对象
+			 * @param {Object} node TreeNode 的 node 属性
+			 */
+			handleCheckBoxChange(checked, data, node) {
+				store.serviceMark = 'serviceLeft';
+
+				let _node = this.$refs.treeRef.getNode(data);
+				if (_node.isLeaf) {
+					
+					//图层ID
+					let serviceId = "serviceLeft_" + data.layercode + data.layerorder;
+					data.serviceId = serviceId;
+					
+					//透明度
+					let opacity = 1;
+					if (data.opacity == null) {
+						opacity = 1;
+					} else {
+						opacity = Number(data.opacity);
+					}
+					data.opacity = opacity;
+					
+					mapWork.setLayersControl(window.viewerLeft, data, checked);
+					//是否设置子节点,默认为false,利用tree组件渲染后带有的isLeaf(是否为叶子节点)属性,如果为叶子节点就选中。利用tree的API就实现了正确的回显效果	
+					this.$refs.treeRef.setChecked(_node, checked);
+				}
+
+				//控制子节点
+				this.childNodesChange(node, checked);
+			},
+			/**
+			 * 控制子节点
+			 * @param {Object} node
+			 * @param {Object} checked
+			 */
+			childNodesChange(node, checked) {
+				let _self = this;
+				node.childNodes.forEach(item => {
+					//图层ID
+					let serviceId = "serviceLeft_" + item.data.layercode + item.data.layerorder;
+					item.data.serviceId = serviceId;
+					
+					//透明度
+					let opacity = 1;
+					if (item.data.opacity == null) {
+						opacity = 1;
+					} else {
+						opacity = Number(item.data.opacity);
+					}
+					item.data.opacity = opacity;
+					
+					mapWork.setLayersControl(window.viewerLeft, item.data, checked);
+					
+					_self.$refs.treeRef.setChecked(item, checked);
+					_self.childNodesChange(item, checked);
+				});
+			},
+
+			/**
+			 * 分屏对比初始化
+			 */
+			initSplitScreen() {
+				let mapView1 = document.getElementById("cesiumContainer");
+				let mapView2 = document.getElementById("cesiumContainer2");
+				mapView1.className = "ViewerSplitScreen";
+				mapView2.style.display = "block";
+
+				//加载分屏左侧大球
+				this.initMap3d();
+				//同步相机状态
+				this.syncViewer();
+				//绑定图层控制
+				this.initLayerTree();
+			},
+
+			/**
+			 * 加载分屏左侧大球
+			 */
+			initMap3d() {
+				jt3dLeft = new jt3dSDK.jtMap3d({
+					container: "cesiumContainer2",
+				});
+
+				//底部工具
+				jt3dLeft.statusBar.show = true;
+				//图层
+				jt3dLeft.layer = new jt3dSDK.layer(jt3dLeft._viewer);
+
+				window["viewerLeft"] = jt3dLeft._viewer;
+				window["viewerLeft"].scene.terrainExaggeration = 100;
+
+				//显示帧率
+				window["viewerLeft"].scene.debugShowFramesPerSecond = true;
+
+			},
+
+			/**
+			 * 同步相机状态
+			 */
+			syncViewer() {
+				let _self = this;
+
+				let viewerL = jt3dLeft._viewer;
+				let viewerR = jt3dRight._viewer;
+
+				var sceneL = viewerL.scene;
+				var sceneR = viewerR.scene;
+
+				var handlerL = new Cesium.ScreenSpaceEventHandler(sceneL.canvas);
+				var ellipsoidL = sceneL.globe.ellipsoid;
+				var handlerR = new Cesium.ScreenSpaceEventHandler(sceneR.canvas);
+				var ellipsoidR = sceneR.globe.ellipsoid;
+
+				handlerL.setInputAction((movement) => {
+					this.isLeftTrigger = true;
+					this.isRightTrigger = false;
+				}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+				handlerR.setInputAction((movement) => {
+					this.isLeftTrigger = false;
+					this.isRightTrigger = true;
+				}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+				var syncViewerL = function() {
+					if (_self.isLeftTrigger) {
+						viewerR.camera.flyTo({
+							destination: viewerL.camera.position,
+							orientation: {
+								heading: viewerL.camera.heading,
+								pitch: viewerL.camera.pitch,
+								roll: viewerL.camera.roll
+							},
+							duration: 0.0
+						});
+					}
+				}
+				viewerR.camera.changed.addEventListener(syncViewerL);
+				viewerR.scene.preRender.addEventListener(syncViewerL);
+
+				var syncViewerR = function() {
+					if (_self.isRightTrigger) {
+						viewerL.camera.flyTo({
+							destination: viewerR.camera.position,
+							orientation: {
+								heading: viewerR.camera.heading,
+								pitch: viewerR.camera.pitch,
+								roll: viewerR.camera.roll
+							},
+							duration: 0.0
+						});
+					}
+				}
+				viewerR.camera.changed.addEventListener(syncViewerR);
+				viewerR.scene.preRender.addEventListener(syncViewerR);
+			},
+
+			/**
+			 * 初始化图层控制树
+			 */
+			initLayerTree() {
+
+				let _self = this;
+
+				mapWork.getAllLayers().then(layers => {
+					layers.map((item) => {
+
+						let num = Number(item.layerorder)
+						if (num < 10) {
+							item.layerorder = '0' + item.layerorder
+						}
+
+						//透明度
+						item.opacity = Number(item.opacity);
+
+						//默认展开
+						if (item.isexpand === '1') {
+							_self.expandedKeys.push(item.id);
+						}
+
+						// 复选框默认选中
+						if (item.isinit === '1') {
+							_self.checkedkeys.push(item.id);
+							
+							//图层ID
+							let serviceId = "serviceLeft_" + item.layercode + item.layerorder;
+							item.serviceId = serviceId;
+							
+							//透明度
+							let opacity = 1;
+							if (item.opacity == null) {
+								opacity = 1;
+							} else {
+								opacity = Number(item.opacity);
+							}
+							item.opacity = opacity;
+							
+							mapWork.setLayersControl(window.viewerLeft, item, true);
+						}
+					})
+
+					_self.treeData = deepTree(layers)
+				});
+
+			},
+
+			closeJTPopup() {
+				mapWork.removeSplitScreen(window.viewerLeft);
+			}
+		},
+
+		mounted() {
+			this.initSplitScreen();
+		},
+
+		beforeDestroy() {
+			alert(111)
+			this.closeJTPopup();
+		}
+	};
+</script>
+
+<style lang="scss">
+	.el-switch--small .el-switch__core .el-switch__action {
+		width: 12rem;
+		height: 12rem;
+	}
+
+	.el-switch--small.is-checked .el-switch__core .el-switch__action {
+		margin-left: calc(-1rem - 12rem);
+	}
+
+	.el-switch__core .el-switch__action {
+		top: 0;
+	}
+
+	.el-slider__button {
+		width: 20rem;
+		height: 20rem;
+	}
+
+	.el-tree-node__content {
+		height: 26rem;
+	}
+
+	.el-switch--small .el-switch__core {
+		height: 16rem;
+	}
+
+	.el-switch--small {
+		padding: 0 5rem;
+	}
+
+	.jt-map-compare {
+		padding-left: 10rem;
+
+		.el-tree {
+			background: none;
+			color: #fff;
+			--el-tree-node-hover-bg-color: #2a67c3;
+
+			.overflowtext {
+				width: auto !important;
+				padding: 0;
+			}
+		}
+
+		.tree-line {
+			.el-tree-node {
+				position: relative;
+				// padding-left: 16rem; // 缩进量
+			}
+
+			.el-tree-node__children {
+				padding-left: 16rem !important; // 缩进量
+
+				.el-tree-node__content {
+					padding-left: 18rem !important;
+				}
+			}
+
+			// 竖线
+			.el-tree-node::before {
+				content: "";
+				height: 100%;
+				width: 1rem;
+				position: absolute;
+				left: -3rem;
+				top: -26rem;
+				border-width: 1rem;
+				border-left: 1rem dashed rgba(255, 255, 255, .8);
+			}
+
+			// 当前层最后一个节点的竖线高度固定
+			.el-tree-node:last-child::before {
+				height: 38rem; // 可以自己调节到合适数值
+			}
+
+			// 横线
+			.el-tree-node::after {
+				content: "";
+				width: 24rem;
+				height: 20rem;
+				position: absolute;
+				left: -3rem;
+				top: 12rem;
+				border-width: 1rem;
+				border-top: 1rem dashed rgba(255, 255, 255, .8);
+			}
+
+			// 去掉最顶层的虚线,放最下面样式才不会被上面的覆盖了
+			&>.el-tree-node::after {
+				border-top: none;
+			}
+
+			&>.el-tree-node::before {
+				border-left: none;
+			}
+
+			// 展开关闭的icon
+			.el-tree-node__expand-icon {
+				font-size: 16rem;
+
+				// 叶子节点(无子节点)
+				&.is-leaf {
+					color: transparent;
+					display: none; // 也可以去掉
+				}
+			}
+		}
+	}
+</style>

+ 304 - 0
src/views/Map3d - 副本 (3)/components/map-split.vue

@@ -0,0 +1,304 @@
+<script setup>
+	import {
+		Store
+	} from '@/store/index'
+	store = Store();
+
+	import {
+		deepTree
+	} from "@/utils/deepTree.js";
+</script>
+
+<template>
+	<jt-popup title="卷帘对比" :showfooter="isshowfooter" height="120rem" width="620rem" :isEmit="true" @closeJTPopup="closeJTPopup">
+		<div class="jt-map-split">
+			<div class="_left">
+				<div style="line-height: 30rem;float: left;">左侧图层:</div>
+				<el-tree-select v-model="leftModel" :data="leftData" :render-after-expand="true" @change="handleClickLeft" style="width: 200rem; float: left;" />
+			</div>
+			<div class="_right">
+				<div style="line-height: 30rem;float: left;">右侧图层:</div>
+				<el-tree-select v-model="rightModel" :data="rightData" :render-after-expand="true" @change="handleClickRight" style="width: 200rem; float: left;" />
+			</div>
+		</div>
+	</jt-popup>
+</template>
+
+<script>
+	let store = undefined;
+
+	let earthAtLeft = undefined;
+	let earthAtRight = undefined;
+
+	import * as mapWork from "../map"
+
+	//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
+	//例如:import 《组件名称》 from '《组件路径》';
+
+	export default {
+		//import引入的组件需要注入到对象中才能使用
+		components: {},
+
+		//这里存放数据
+		data() {
+
+			return {
+				leftModel: {},
+				leftData: [],
+				leftValue: [],
+				rightModel: {},
+				rightData: [],
+				rightValue: [],
+			};
+		},
+
+		//监听属性 类似于data概念
+		computed: {},
+
+		//监控data中的数据变化
+		watch: {},
+
+		//方法集合
+		methods: {
+			/**
+			 * 左侧图层控制
+			 * @param {Object} item
+			 */
+			handleClickLeft(item) {
+				let _self = this;
+				store.serviceMark = 'service';
+				let _serviceId = store.serviceMark + "_" + item.layercode + item.layerorder;
+
+				//移除
+				if (earthAtLeft) {
+					mapWork.setLayersControl(window.viewer, _self.leftValue, false);
+				}
+
+				//添加
+				mapWork.setLayersControl(window.viewer, item, true).then(res => {
+					//定位
+					mapWork.setLayersLocation(window.viewer, {
+						serviceId:_serviceId,
+						parameterset:item.parameterset,
+						isinit:'1',
+						loadtype:item.loadtype
+					});
+
+					_self.leftValue = item;
+
+					earthAtLeft = window[_serviceId];
+					earthAtLeft.splitDirection = Cesium.SplitDirection.LEFT;
+				});
+			},
+			/**
+			 * 
+			 * 
+			 * 右侧图层控制
+			 * @param {Object} item
+			 */
+			handleClickRight(item) {
+				let _self = this;
+				store.serviceMark = "service";
+				let _serviceId = store.serviceMark + "_" + item.layercode + item.layerorder;
+
+				//移除
+				if (earthAtRight) {
+					mapWork.setLayersControl(window.viewer, _self.rightValue, false);
+				}
+
+				//添加
+				mapWork.setLayersControl(window.viewer, item, true).then(res => {
+
+					//定位
+					mapWork.setLayersLocation(window.viewer, {
+						serviceId:_serviceId,
+						parameterset:item.parameterset,
+						isinit:'1',
+						loadtype:item.loadtype
+					});
+					
+
+					_self.rightValue = item;
+
+					earthAtRight = window[_serviceId];
+					earthAtRight.splitDirection = Cesium.SplitDirection.RIGHT;
+				});
+
+			},
+
+			/**
+			 * 卷帘对比初始化
+			 */
+			initSplitLayer() {
+				let _self = this;
+				this.viewer = window.viewer;
+
+				let sliderDiv = document.getElementById("image_slider");
+				if (sliderDiv == null) {
+					//创建画布
+					sliderDiv = document.createElement('div');
+					sliderDiv.id = "image_slider";
+					sliderDiv.style.position = "absolute";
+					sliderDiv.style.left = "50%";
+					sliderDiv.style.top = "70rem";
+					sliderDiv.style.backgroundColor = "#d3d3d3";
+					sliderDiv.style.width = "5rem";
+					sliderDiv.style.height = "calc(100% - 70rem)";
+					sliderDiv.style.zIndex = "9999";
+
+					sliderDiv.onmouseover = function() {
+						//设置其背景颜色为黄色
+						this.style.cursor = "ew-resize";
+					};
+
+					/* 加入到页面 */
+					document.body.appendChild(sliderDiv);
+				}
+
+				// 设置图像拆分位置
+				this.viewer.scene.splitPosition = sliderDiv.offsetLeft / sliderDiv.parentElement.offsetWidth; //确定分割点位置,占据父级容器的比例
+
+				if (this.handler) {
+					this.handler.destroy();
+					this.handler = null;
+				}
+				//处理用户输入事件。可以添加自定义功能以在用户输入时执行;参数为任意
+				this.handler = new Cesium.ScreenSpaceEventHandler(sliderDiv);
+				var moveActive = false;
+
+				// 计算拆分
+				function move(movement) {
+					if (!moveActive) {
+						return;
+					}
+
+					//捕获滑动停止的位置
+					var relativeOffset = movement.endPosition.x;
+					var splitPosition = (sliderDiv.offsetLeft + relativeOffset) / sliderDiv.parentElement.offsetWidth;
+					sliderDiv.style.left = `${100.0 * splitPosition}%`;
+					viewer.scene.splitPosition = splitPosition;
+				}
+
+				//对分割条的操作
+				this.handler.setInputAction(function() {
+					moveActive = true;
+				}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
+				this.handler.setInputAction(function() {
+					moveActive = true;
+				}, Cesium.ScreenSpaceEventType.PINCH_START);
+
+				this.handler.setInputAction(move, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+				this.handler.setInputAction(move, Cesium.ScreenSpaceEventType.PINCH_MOVE);
+
+				this.handler.setInputAction(function() {
+					moveActive = false;
+				}, Cesium.ScreenSpaceEventType.LEFT_UP);
+				this.handler.setInputAction(function() {
+					moveActive = false;
+				}, Cesium.ScreenSpaceEventType.PINCH_END);
+
+				_self.handleClickLeft(_self.leftModel);
+				_self.handleClickRight(_self.rightModel);
+			},
+
+			/**
+			 * 初始化图层控制树
+			 */
+			initLayerTree() {
+				let _self = this;
+
+				mapWork.getLayers().then(layers => {
+					layers.map((item) => {
+						let num = Number(item.layerorder)
+						if (num < 10) {
+							item.layerorder = '0' + item.layerorder
+						}
+
+						item.value = item;
+						item.label = item.layername;
+
+						if (item.layername === "牟平中心城") {
+							_self.leftModel = item;
+						}
+						if (item.layername === "牟平区") {
+							_self.rightModel = item;
+						}
+					})
+
+					_self.leftData = _self.rightData = deepTree(layers)
+
+				});
+
+			},
+
+			/**
+			 * 移除卷帘
+			 */
+			removeSplitLayer() {
+				let sliderDiv = document.getElementById("image_slider");
+				if (sliderDiv) {
+					document.body.removeChild(sliderDiv);
+				}
+
+				if (earthAtLeft) {
+					mapWork.setLayersControl(window.viewer, this.leftValue, false);
+					earthAtLeft.splitDirection = Cesium.SplitDirection.NONE;
+				}
+
+				if (earthAtRight) {
+					mapWork.setLayersControl(window.viewer, this.rightValue, false);
+					earthAtRight.splitDirection = Cesium.SplitDirection.NONE;
+				}
+			},
+
+			closeJTPopup() {
+				if (window.viewerLeft) {
+					mapWork.removeSplitScreen(window.viewerLeft);
+				}
+				// mapWork.removeSplitLayer(window.viewer, earthAtLeft, earthAtRight,_self.leftValue,_self.rightValue);
+				this.removeSplitLayer();
+			}
+		},
+
+		//生命周期 - 创建完成(可以访问当前this实例)
+		created() {},
+
+		//生命周期 - 挂载完成(可以访问DOM元素)
+		mounted() {
+			this.initLayerTree();
+			this.initSplitLayer();
+		},
+
+		beforeCreate() {}, //生命周期 - 创建之前
+		beforeMount() {}, //生命周期 - 挂载之前
+		beforeUpdate() {}, //生命周期 - 更新之前
+		updated() {}, //生命周期 - 更新之后
+		beforeDestroy() {}, //生命周期 - 销毁之前
+		destroyed() {}, //生命周期 - 销毁完成
+		activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+	};
+</script>
+
+<style lang="scss" scoped>
+	//整体样式
+	.jt-map-split {
+		// padding: 10rem;
+
+		//左侧
+		._left {
+			width: 300rem;
+			float: left;
+		}
+
+		//右侧
+		._right {
+			width: 300rem;
+			float: left;
+			margin-left: 10rem;
+		}
+
+		.el-tree {
+			width: 300rem !important;
+		}
+	}
+</style>

+ 101 - 0
src/views/Map3d - 副本 (3)/components/map.vue

@@ -0,0 +1,101 @@
+<template>
+	<div id="cesiumContainer2" class="ViewerSplitScreen" style="display: none; border-right: 5rem solid #fff"></div>
+	<div id="cesiumContainer" class="jt-map" ref="cesiumContainer"></div>
+</template>
+
+<script>
+	import * as mapWork from "../map"
+
+	let jt3d = undefined;
+	export default {
+
+		/* 数据 */
+		data() {
+			return {
+
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			/**
+			 * 初始化
+			 */
+			init(el) {
+				//初始化大球
+				this.initMap3d(el);
+				//调用父组件的方法,onload是在父组件的的动态组件component上面的方法,并将jt3d传过去
+				this.$emit("onload", jt3d);
+
+				//设置默认视图
+				mapWork.setView(jt3d);
+
+				// 初始化项目区域范围视角
+				mapWork.fullMap(jt3d);
+
+				//加载天空盒子
+				mapWork.addSkybox(jt3d);	
+
+				//单击事件
+				// mapWork.clickEntity(jt3d);
+
+				//添加镇街边界线——精灵线
+				mapWork.addBoundaryLine(jt3d);
+
+			},
+
+			/**
+			 * 创建大球
+			 */
+			initMap3d(el) {
+
+				jt3d = new jt3dSDK.jtMap3d({
+					container: el,
+				});
+
+				jt3d.statusBar.show = true;
+
+				window["viewer"] = jt3d._viewer;
+				window["viewer"].scene.terrainExaggeration = 100;
+
+				//显示帧率
+				window["viewer"].scene.debugShowFramesPerSecond = true;
+			},
+
+		},
+
+		mounted() {
+			this.init("cesiumContainer");
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.lk-status-bar {
+		font-size: 16rem !important;
+	}
+
+	.jt-map {
+		// width: calc(100% - 0rem);
+		// height: calc(100vh - 70rem);
+		height: 100vh;
+		margin: 0;
+		padding: 0;
+		overflow: hidden;
+		background-color: blue;
+		border: 0rem solid red;
+	}
+
+	//分屏样式
+	.ViewerSplitScreen {
+		float: left;
+		width: calc(50% - 2.5rem);
+		// height: calc(100vh - 70rem);
+		height: 100vh;
+		margin: 0;
+
+		.lk-status-bar {
+			width: calc(50% - 0rem) !important;
+		}
+	}
+</style>

+ 242 - 0
src/views/Map3d - 副本 (3)/components/measure.vue

@@ -0,0 +1,242 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-measure">
+		<el-row :gutter="20" style="margin-left: 0rem; margin-right: 0rem; ">
+			<el-col :span="8" v-for="(item,index) in measure" @click="handleMeasure(item.type,index)">
+				<el-avatar shape="circle" :size="70" :class="currentIndex===index?'selectStyle':'defaultStyle'">
+					<i :class="[item.icon,currentIndex===index?'selectFontStyle':'']" />
+				</el-avatar>
+				<div style="margin-top: 5rem; font-size: 14rem;" :class="currentIndex===index?'selectFontStyle':''">{{item.label}}</div>
+			</el-col>
+		</el-row>
+		<div class="jt-btn" style="margin: 8rem;">
+			<el-button color="rgb(255 100 100)" @click="clearMeasurementData"><span style="color: #fff;width: 300rem;">清空测量数据</span></el-button>
+		</div>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+	let popup = undefined;
+
+	export default {
+		props: {
+
+		},
+		watch: {
+
+		},
+
+		/* 数据 */
+		data() {
+			return {
+				currentIndex: -1,
+				measure: [{
+						label: '长度测量(贴地)',
+						type: 'measureLength',
+						number: 0,
+						icon: 'iconfont icon-thin-_pencil_rul'
+					},
+					{
+						label: '面积测量(贴地)',
+						type: 'measureArea',
+						number: 1,
+						icon: 'iconfont icon-svgmianjiceliang'
+					},
+					{
+						label: '高度测量',
+						type: 'measureHeight',
+						number: 2,
+						icon: 'iconfont icon-svggaoduceliang'
+					},
+					{
+						label: '空间距离',
+						type: 'measureSpatialLength',
+						number: 3,
+						icon: 'iconfont icon-svgkongjianceliang'
+					},
+					{
+						label: '三角测量',
+						type: 'measureTriangle',
+						number: 4,
+						icon: 'iconfont icon-svgsanjiaoceliang'
+					},
+					{
+						label: '坐标测量',
+						type: 'pickUp',
+						number: 5,
+						icon: 'iconfont icon-svgzuobiaoceliang'
+					},
+				],
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			/**
+			 * 测量事件
+			 * @param {Object} type 测量类型
+			 * @param {Object} index 第几个被选中
+			 */
+			handleMeasure(type, index) {
+				this.currentIndex = index;
+
+				//移除左键单击事件
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
+				}
+
+				jt3d.CommonTools.clear();
+
+				switch (type) {
+					case "measureLength": //长度测量(贴地)
+						jt3d.CommonTools.measureLength(function(error) {
+							ElMessage.error(error)
+						});
+						break;
+					case "measureArea": //面积测量(贴地)
+						jt3d.CommonTools.measureArea(function(error) {
+							ElMessage.error(error)
+						});
+						break;
+					case "measureHeight": //高度测量
+						jt3d.CommonTools.measureHeight()
+						break;
+					case "measureSpatialLength": //空间距离
+						jt3d.CommonTools.measureSpatialLength(function(error) {
+							ElMessage.error(error)
+						});
+						break;
+					case "measureTriangle": //三角测量
+						jt3d.CommonTools.measureTriangle()
+						break;
+					case "pickUp": //坐标测量
+						ElMessage("点击位置开始测量");
+						this.pickUp();
+						break;
+				}
+			},
+
+			/**
+			 * 坐标测量
+			 */
+			pickUp() {
+				let _self = this;
+
+				if (popup) {
+					popup.close();
+				}
+
+				jt3d.SketchViewModel.sketchTools('point', {
+					onComplete(cPoint, gPoint) {
+						if (gPoint.lng) {
+							let html = "";
+							html += "<div style='text-align: left;'>";
+							html += "<p>经度:" + gPoint.lng.toFixed(6) + "</p>";
+							html += "<p>纬度:" + gPoint.lat.toFixed(6) + "</p>";
+							html += "<p>高度:" + gPoint.height.toFixed(2) + "米</p>";
+							html += "</div>";
+
+							let position = {
+								x: Number(gPoint.lng),
+								y: Number(gPoint.lat),
+								z: Number(gPoint.height)
+							}
+
+							// popup = new jt3dSDK.PopupWindow.HtmlWindow(window["viewer"], position, "位置信息", html,40);
+							popup = new jt3dSDK.PopupWindow.HtmlWindow(window["viewer"], cPoint, "位置信息", html, -30);
+						}
+					},
+					onError(message) {
+						
+					}
+				});
+			},
+
+			/**
+			 * 清空测量数据
+			 */
+			clearMeasurementData() {
+				this.currentIndex = -1;
+				jt3d.CommonTools.clear();
+				if (popup) {
+					popup.close();
+				}
+
+				//还原左键单击事件
+				this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+			},
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.el-avatar{
+		width: 70rem !important;
+		height: 70rem !important;
+		font-size: 14px !important;
+		cursor: pointer;
+	}
+	
+	.el-button{
+		height: 32rem;
+		font-size: 16rem;
+		padding: 8rem 15rem;
+	}
+	
+	.jt-measure {
+		.el-col {
+			padding: 10rem;
+			// color: rgba(90, 172, 255, 1.0);
+			color: #fff;
+		}
+
+		i {
+			display: inline-block;
+			width: 100%;
+			height: 36rem;
+			line-height: 36rem;
+			text-align: center;
+			border-radius: 5rem;
+			font-size: 40rem;
+			// color: rgba(90, 172, 255, 1.0);
+			color: #fff;
+			transition: all .3s;
+			-webkit-transition: all .3s
+		}
+
+		.selectStyle {
+			// background: rgba(135, 182, 254, 0.5);
+			background: rgb(0 44 126);
+			--el-avatar-size: 70rem !important;
+		}
+
+		.defaultStyle {
+			background: #ffffff00;
+			--el-avatar-size: 70rem !important;
+		}
+
+		.selectFontStyle {
+			color: #fff;
+		}
+	}
+</style>

+ 278 - 0
src/views/Map3d - 副本 (3)/components/navigation.vue

@@ -0,0 +1,278 @@
+<script setup>
+
+	import jt3dNavigation from 'cesium-navigation-es6';
+
+	import {
+		inject
+	} from "vue";
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	
+</template>
+
+<script>
+	let jt3d = undefined;
+	export default {
+		props: {
+
+		},
+
+		/**
+		 * 数据
+		 */
+		data() {
+			return {
+		
+			}
+		},
+
+		/**
+		 * 方法
+		 */
+		methods: {
+			/**
+			 * 比例尺、指南针
+			 */
+			initNavigation(jt3d) {
+				let options = {};
+				// 用于在使用重置导航重置地图视图时设置默认视图控制。接受的值是Cesium.Cartographic 和 Cesium.Rectangle.
+				options.defaultResetView = Cesium.Rectangle.fromDegrees(121.13766, 36.99670, 121.94984, 37.55286);
+				// options.defaultResetView = Cesium.Cartographic.fromDegrees(103.84,31.15,24000);
+				// options.defaultResetView = Cesium.Cartographic.fromDegrees(Cesium.Math.toRadians(103.84),Cesium.Math.toRadians(31.15),Cesium.Math.toRadians(24000));
+				options.orientation = {
+					heading: Cesium.Math.toRadians(0),
+					pitch: Cesium.Math.toRadians(-90),
+					roll: 0
+				};
+			
+				//相机延时
+				options.duration = 4; //默认为3s
+			
+				// 用于启用或禁用罗盘。
+				options.enableCompass = true;
+				// 用于启用或禁用指南针外环。
+				options.enableCompassOuterRing = true;
+				// 用于启用或禁用缩放控件。
+				options.enableZoomControls = true;
+				// 用于启用或禁用距离图例。
+				options.enableDistanceLegend = false;
+			
+				//修改重置视图的tooltip
+				options.resetTooltip = "重置视图";
+				//修改放大按钮的tooltip
+				options.zoomInTooltip = "放大";
+				//修改缩小按钮的tooltip
+				options.zoomOutTooltip = "缩小";
+			
+				//如需自定义罗盘控件,请看下面的自定义罗盘控件
+				new jt3dNavigation(jt3d._viewer, options);
+			},
+
+		},
+
+		mounted() {
+			//比例尺、指南针
+			this.initNavigation(jt3d);
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	$jt3d-text-color:#fff;
+	$jt3d-content-color:#fff;
+
+	$jt3d-select-bg:red;
+
+	.query-keyword {
+		position: absolute;
+		top: 80rem;
+		width: 200rem;
+		left: 10rem;
+		border: 1rem solid rgb(0 44 126 / 100%);
+
+		.el-input {
+			--el-input-bg-color: rgb(0 44 126 / 50%);
+			--el-input-border-color: rgb(0 44 126 / 50%);
+			--el-input-placeholder-color: #fff;
+
+			--el-fill-color-blank: rgb(0 44 126 / 80%);
+			--el-text-color-regular: #fff;
+			--el-color-primary: #fff --el-border-radius-base:0rem;
+			--el-border-radius-base: 0rem;
+
+			.el-button {
+				background-color: rgb(0 44 126 / 100%);
+				color: #fff;
+			}
+		}
+
+		.autocomplete {
+			--el-fill-color-blank: rgb(0 44 126 / 0%);
+		}
+	}
+
+	.autocomplete ul {
+		font-family: sans-serif;
+		position: absolute;
+		list-style: none;
+		background: rgb(0 44 126 / 30%);
+		margin: 0;
+		width: 80%;
+		margin-top: 1rem;
+		margin-left: -1rem;
+		border: 1rem solid rgb(0 44 126 / 100%);
+	}
+
+	.autocomplete ul li {
+		text-decoration: none;
+		display: block;
+		background: rgb(0 44 126 / 30%);
+		color: #fff;
+		padding: 5rem;
+		margin-left: -40rem;
+		text-align: left;
+	}
+
+	.autocomplete ul li:hover,
+	.autocomplete ul li.focus-list {
+		color: white;
+		background: #2F9AF7;
+	}
+
+	.query-result {
+		position: absolute;
+		border-top: none;
+		padding-bottom: 0rem;
+		width: 100%;
+		z-index: 100;
+		border: 1rem solid rgb(0 44 126 / 100%);
+		background: rgb(0 44 126 / 30%);
+		margin-left: -1rem;
+
+		--el-fill-color-blank: rgb(0 44 126 / 0%);
+		--color: #fff;
+		--el-color-primary: #fff;
+
+		.query-result__item {
+			height: 80rem;
+			padding: 0 10rem;
+			display: flex;
+			justify-content: flex-start;
+			align-items: center;
+			margin-left: -40rem;
+			text-align: left;
+
+			&:hover {
+				// background-color: var(--mars-select-bg);
+			}
+
+			.query-result__context {
+				flex-grow: 1;
+				width: 90%;
+
+				.query-result-text {
+					font-size: 16rem;
+					width: 200rem;
+					font-family: Source Han Sans CN;
+					font-weight: 400;
+					// color: var($jt3d-text-color);
+					color: $jt3d-text-color;
+
+					.query-result-text_num {
+						width: 20rem;
+						height: 20rem;
+						margin-right: 5rem;
+						display: inline-block;
+						text-align: center;
+						background: rgb(0 44 126 / 100%);
+					}
+				}
+
+				.query-result-sub {
+					font-size: 14rem;
+					width: 200rem;
+					margin-left: 19rem;
+					font-family: Source Han Sans CN;
+					font-weight: 400;
+					// color: var($jt3d-content-color);
+					color: $jt3d-content-color;
+				}
+			}
+
+			.query-result__more {
+				font-size: 14rem;
+				font-family: Source Han Sans CN;
+				font-weight: 400;
+				// color: var($jt3d-content-color);
+				color: $jt3d-content-color;
+			}
+		}
+
+		.query-result__page {
+			display: flex;
+			justify-content: space-between;
+			padding: 5rem;
+
+			.query-result-allcount {
+				font-size: 14rem;
+				// color: var($jt3d-text-color);
+				color: $jt3d-text-color;
+			}
+		}
+	}
+	
+	/* 四个边角样式 */
+	// .borderstyle {
+	// 	position: relative;
+	// 	width: 100%;
+	// 	height: 490rem;
+	// 	padding: 10rem;
+	// 	border: 1rem solid #008aff70 !important;
+	// 	background-color: rgba(5, 45, 115, 0.7) !important;
+	// 	box-shadow: 0 4rem 15rem 1rem #02213bb3;
+	
+
+		.angle-border {
+			position: absolute;
+			width: 12rem;
+			height: 12rem;
+		}
+	
+		.angle-border-blue {
+			position: absolute;
+			width: 70rem;
+			height: 30rem;
+		}
+	
+		.left-top-border {
+			top: -2rem;
+			left: -2rem;
+			border-left: 2rem solid #008affdd;
+			border-top: 2rem solid #008affdd;
+		}
+	
+		.right-top-border {
+			top: -2rem;
+			right: -2rem;
+			border-right: 2rem solid #008affdd;
+			border-top: 2rem solid #008affdd;
+		}
+	
+		.left-bottom-border {
+			bottom: -2rem;
+			left: -2rem;
+			border-bottom: 2rem solid #FFFFFF;
+			border-left: 2rem solid #FFFFFF;
+		}
+	
+		.right-bottom-border {
+			bottom: -2rem;
+			right: -2rem;
+			border-right: 2rem solid #FFFFFF;
+			border-bottom: 2rem solid #FFFFFF;
+		}
+	// }
+</style>

+ 318 - 0
src/views/Map3d - 副本 (3)/components/printmap.vue

@@ -0,0 +1,318 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	import {
+		ref
+	} from "vue";
+	import {
+		inject
+	} from "vue";
+	import html2canvas from "html2canvas";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-MapPrinting">
+		<div class="middleviewer">
+			<el-input v-model="inputValue.mapname" placeholder="请输入地图名称" @focus="getfous" @blur="onblur" />
+			<div class="viewer">
+				<div id="printbox" ref="print"></div>
+				<div class="viewertop" display='block' ref="thumbnailmap"></div>
+				<div style="display:none" ref="originalmap"></div>
+			</div>
+		</div>
+		<div class="viewerbottom">
+			<!-- <el-button color="rgb(20 136 255)" v-print="printObj"><span style="color: #fff;font-size: 16rem;">打 印</span></el-button> -->
+			<el-button color="rgb(255 100 100)" @click="download"><span style="color: #fff;font-size: 16rem;">下 载</span></el-button>
+		</div>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+	export default {
+		data() {
+			return {
+				inputValue: {
+					mapname: "默认地图",
+				},
+
+				printObj: {
+					id: "printbox",
+					popTitle: "", // 打印配置页上方的标题
+					extraCss: "background-color:red",
+					preview: false, // 是否启动预览模式,默认是false
+					previewTitle: " 关闭预览", // 打印预览的标题
+					previewPrintBtnLabel: "点击打印", // 打印预览的标题下方的按钮文本,点击可进入打印
+					zIndex: 20002, // 预览窗口的z-index,默认是20002,最好比默认值更高
+					previewBeforeOpenCallback() {
+						console.log("正在加载预览窗口!")
+					}, // 预览窗口打开之前的callback
+					previewOpenCallback() {
+						console.log("已经加载完预览窗口,预览打开了!");
+					}, // 预览窗口打开时的callback
+					beforeOpenCallback() {
+						console.log("开始打印之前!");
+					}, // 开始打印之前的callback
+					openCallback() {
+						console.log("执行打印了!");
+					}, // 调用打印时的callback
+					closeCallback() {
+						console.log("关闭了打印工具!");
+					},
+					clickMounted() {
+						console.log("点击v-print绑定的按钮了!");
+					},
+					standard: "",
+					extarCss: "",
+				},
+			};
+		},
+		methods: {
+			//当选择器的输入框获得焦点时触发,标题获取焦点清空输入框
+			getfous() {
+				this.inputValue.mapname = ""
+			},
+
+			//当选择器的输入框失去焦点时触发
+			onblur() {
+				//删除print组件的内容
+				this.$refs.print.innerHTML = "";
+				// 获取标题
+				let value = this.inputValue.mapname;
+
+				//获取输入框的缺省内容
+				let text = value.length > 0 ? value : '默认地图标题';
+				let canvas = this.changcanvastitile(this.$refs.originalmap.lastChild, text);
+				let url = canvas.toDataURL('image/png', 5.0)
+				let img = document.createElement('img');
+				img.style.display = "block"
+				img.style.width = canvas.style.width;
+				img.style.height = canvas.style.height;
+				img.src = url
+				this.$refs.print.appendChild(img);
+			},
+
+			//下载按钮
+			download() {
+				if (this.$refs.originalmap.children.length <= 0) {
+					ElMessage.error("截图未成功");
+					return
+				}
+				let value = this.inputValue.mapname;
+				//获取输入框的缺省内容
+				let text = value.length > 0 ? value : '默认地图标题';
+
+				let img = this.$refs.print.lastChild;
+				let a = document.createElement('a');
+				a.style.display = 'none';
+				a.download = text + '.png';
+				a.href = img.src;
+				document.body.appendChild(a);
+				a.click();
+				document.body.removeChild(a);
+			},
+
+			//更新打印标题
+			changcanvastitile(canvas, text) {
+
+				//清理标题位置区域
+				let width = parseInt(canvas.style.width.slice(0, -2));
+				let height = parseInt(canvas.style.height.slice(0, -2));
+				//获取上下文
+				const ctx = canvas.getContext('2d');
+				//清理标题问题
+				ctx.clearRect(0, 0, width, 160)
+				//设置字体
+				ctx.font = "bold 50rem arial";
+				document.fonts.load(ctx.font);
+				//设置填充颜色
+				ctx.fillStyle = "black";
+				//循环输入标题,字间距50rem
+				for (let i = 0; i < text.length; i++) {
+					//第I个字的水平位置=((canvs.leght)/2-(text.legth)*letterspace/2+i*letterspace)
+					let x = Math.ceil(width / 2) - (text.length - 1) * 50 + i * 100
+					//水平绘制填充文本
+					ctx.fillText(text[i], x, 100);
+				}
+				return canvas;
+			},
+
+			//打印地图截屏
+			screenshot() {
+				this.$refs.print.innerHTML = "";
+				this.$refs.thumbnailmap.innerHTML = ""
+				this.$refs.originalmap.innerHTML = '';
+				this.inputValue.mapname = "默认地图"
+				html2canvas(this.$parent.$parent.$refs.refMap3d.$refs.cesiumContainer, {
+
+					// backgroundColor: null, //画出来的图片有白色的边框,不要可设置背景为透明色(null)
+					useCORS: true, //支持图片跨域
+					scale: 1, //设置放大的倍数
+					// tainTest:false,
+					// foreignObjectRendering: true,//// 是否在浏览器支持的情况下使用ForeignObject渲染
+					dpi: 300,
+					// width:1920,
+					// height:1080
+
+				}).then(
+					(canvas) => {
+						let url = canvas.toDataURL('image/png', 5.0)
+						let img = document.createElement('img');
+						img.style.display = "block"
+						img.style.width = "calc(100% - 0rem)"
+						img.style.height = "calc(100% - 0rem)";
+						img.src = url
+						//缩略图
+						this.$refs.thumbnailmap.appendChild(img);
+						//创建新的canvas
+						let canvasnew = this.createmap(canvas)
+						let urla = canvasnew.toDataURL('image/png', 5.0)
+						let imga = document.createElement('img');
+						imga.style.display = "block"
+						imga.style.width = canvas.style.width / 2;
+						imga.style.height = canvas.style.height / 2;
+						imga.src = urla
+						//原图
+						this.$refs.originalmap.appendChild(canvasnew);
+						//打印图
+						this.$refs.print.appendChild(imga)
+					}
+				)
+			},
+
+			createmap(img) {
+				//渲染之前先清理掉所有所有指定canvas
+				if (document.getElementById('canvasid')) {
+					document.getElementById('canvasid').remove();
+				}
+				let width = parseInt(img.style.width.slice(0, -2));
+				let height = parseInt(img.style.height.slice(0, -2));
+
+				let canvas = this.createHDCanvas(width + 60, height + 160, 'block')
+
+				//获取上下文
+				const ctx = canvas.getContext('2d');
+				//获取图片对象
+				ctx.drawImage(img, 30, 120, width, height)
+				// let value = this.$refs.refinput.value;
+				let value = this.inputValue.mapname;
+				let text = value.length > 0 ? value : '默认地图标题';
+				console.log("text")
+				console.log(text)
+				ctx.clearRect(0, 0, width, 120)
+				//设置字体
+				ctx.font = "bold 50rem arial";
+				//设置填充颜色
+				ctx.fillStyle = "black";
+				//循环输入标题,字间距50rem
+				for (let i = 0; i < text.length; i++) {
+					//第I个字的水平位置=((canvs.leght)/2-(text.legth)*letterspace/2+i*letterspace)
+					let x = Math.ceil(width / 2) - (text.length - 1) * 50 + i * 100
+					//水平绘制填充文本
+					ctx.fillText(text[i], x, 100);
+				}
+				return canvas;
+			},
+			createHDCanvas(w = 300, h = 150, display = 'block') {
+				let ratio = window.devicePixelRatio * 1 || 1;
+				let canvas = document.createElement('canvas');
+				canvas.id = "canvasid";
+				canvas.width = w * ratio; // 实际渲染像素
+				canvas.height = h * ratio; // 实际渲染像素
+				canvas.style.display = display;
+				canvas.style.width = `${w}rem`; // 控制显示大小
+				canvas.style.height = `${h}rem`; // 控制显示大小
+				canvas.style.backgroundColor = "red";
+				// setTransform() 允许您缩放、旋转、移动并倾斜当前的环境
+				canvas.getContext('2d').setTransform(ratio, 0, 0, ratio, 0, 0);
+				return canvas;
+			},
+		},
+
+		mounted() {
+			// //获取角色
+			// this.info = JSON.parse(localStorage.getItem("person"));
+			// //获取角色id
+			// this.id = this.info.id;
+			// this.$bus.on("screenshot", (e) => {
+			// 	console.log("aaaaa")
+			// 	this.screenshot()
+			// })
+		},
+	};
+</script>
+
+<style lang="scss" scoped>
+	.jt-MapPrinting {
+		width: 100%;
+		height: 100%;
+		overflow: hidden;
+
+		--el-fill-color-blank: rgb(0 44 126 / 68%);
+		--el-text-color-regular: rgb(216 240 255);
+		--el-border-color: rgb(35 135 255);
+
+		.middleviewer {
+			height: 92%;
+
+			.viewer {
+				position: relative;
+				width: 100% !important;
+				height: calc(100% - 29rem) !important;
+				overflow: hidden;
+
+				.viewertop {
+					width: calc(100% - 2rem);
+					height: calc(100% - 2rem);
+					border: 1rem solid rgb(35 135 255);
+					position: absolute;
+					top: 0;
+					left: 0;
+				}
+			}
+		}
+
+		.viewerbottom {
+			margin: 10rem;
+		}
+	}
+
+	::v-deep .el-input {
+		flex-grow: 0 !important;
+		width: calc(100%);
+		height: 30rem !important;
+		letter-spacing: 100rem;
+	}
+
+	//输入框文字颜色
+	::v-deep .el-input__inner {
+		color: rgb(255, 255, 255);
+		text-align: center;
+	}
+
+	//输入框背景色
+	::v-deep .el-input__wrapper {
+		background-color: rgba(255, 255, 255, 0) !important;
+	}
+
+	::v-deep .el-button {
+		border-radius: 3rem !important;
+		height: 32rem;
+	}
+
+	::v-deep .el-button--primary {
+		background-color: rgba(64, 158, 255, 0.6) !important;
+	}
+
+	::-webkit-scrollbar {
+		width: 0rem;
+	}
+</style>

+ 465 - 0
src/views/Map3d - 副本 (3)/components/query-graphics.vue

@@ -0,0 +1,465 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage,
+		ElLoading
+	} from 'element-plus';
+
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-query-graphics">
+		<el-row :gutter="20" style="margin-left: 0rem; margin-right: 0rem">
+			<el-col :span="8" v-for="(item,index) in queryGraphics" @click="handleQueryGraphics(item.type,index)">
+				<el-avatar shape="circle" :size="70" :class="currentIndex===index?'selectStyle':'defaultStyle'">
+					<i :class="[item.icon,currentIndex===index?'selectFontStyle':'']" />
+				</el-avatar>
+				<div style="margin-top: 5rem; font-size: 14rem;" :class="currentIndex===index?'selectFontStyle':''">{{item.label}}</div>
+			</el-col>
+		</el-row>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+	let loading = undefined;
+
+	import {
+		Store
+	} from '@/store/index'
+	let store = Store();
+
+	import {
+		deepTree
+	} from "@/utils/deepTree.js";
+
+	export default {
+		props: {
+
+		},
+		watch: {
+
+		},
+
+		/* 数据 */
+		data() {
+			return {
+				currentIndex: -1,
+				queryGraphics: [{
+						label: '点查询',
+						type: 'Point',
+						number: 0,
+						icon: 'iconfont icon-svgdianchaxun'
+					},
+					{
+						label: '线查询',
+						type: 'Line',
+						number: 1,
+						icon: 'iconfont icon-svgxianchaxun'
+					},
+					{
+						label: '圆形查询',
+						type: 'Circle',
+						number: 2,
+						icon: 'iconfont icon-svgyuanxingchaxun'
+					},
+					{
+						label: '矩形查询',
+						type: 'Rectangle',
+						number: 3,
+						icon: 'iconfont icon-svgjuxingchaxun'
+					},
+					{
+						label: '多边形',
+						type: 'Polygon',
+						number: 4,
+						icon: 'iconfont icon-svgduobianxingchaxun'
+					},
+					{
+						label: '清除',
+						type: 'clear',
+						number: 5,
+						icon: 'iconfont icon-shanchu'
+					},
+				],
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			/**
+			 * 查询事件
+			 * @param {Object} type 查询类型
+			 * @param {Object} index 第几个被选中
+			 */
+			handleQueryGraphics(type, index) {
+				let _self = this;
+				this.currentIndex = index;
+
+				//移除左键单击事件
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); //移除事件
+				}
+
+				jt3d.CommonTools.clear();
+				switch (type) {
+					case "Point": //点查询
+						jt3d.CommonTools.queryByPoint(function(coordinates) {
+							console.log(coordinates)
+
+							//还原左键单击事件
+							_self.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+
+							/* 转换坐标 */
+							let points = coordinates.split(',');
+
+							_self.initQuery({
+								spatialType: '点',
+								coordinate: Number(points[0]) + " " + Number(points[1]),
+								buffer: ''
+							});
+
+						});
+						break;
+					case "Line": //线查询
+						jt3d.CommonTools.queryByLine(function(coordinates) {
+							console.log(coordinates)
+
+							//还原左键单击事件
+							_self.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+
+							/* 转换坐标 */
+							let points = coordinates.split(',');
+							let pointsArray = [];
+							for (let i = 0; i < points.length;) {
+								pointsArray.push(Number(points[i]) + " " + Number(points[i + 1]));
+								i = i + 2;
+							}
+
+							_self.initQuery({
+								spatialType: '线',
+								coordinate: pointsArray.join(','),
+								buffer: ''
+							});
+						});
+						break;
+					case "Circle": //圆形查询
+						jt3d.CommonTools.queryByCircle(function(coordinates, radius) {
+							console.log("圆点:" + coordinates + ",半径:" + radius)
+
+							//还原左键单击事件
+							_self.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+
+							/* 转换坐标 */
+							let points = coordinates.split(',');
+
+							_self.initQuery({
+								spatialType: '点',
+								coordinate: Number(points[0]) + " " + Number(points[1]),
+								buffer: radius
+							});
+
+						});
+						break;
+					case "Rectangle": //矩形查询
+						jt3d.CommonTools.queryByRectangle(function(coordinates) {
+							console.log(coordinates)
+
+							//还原左键单击事件
+							_self.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+
+							/* 转换坐标 */
+							let points = coordinates.split(',');
+							let pointsArray = [];
+							for (let i = 0; i < points.length;) {
+								pointsArray.push(Number(points[i]) + " " + Number(points[i + 1]));
+								i = i + 2;
+							}
+
+							_self.initQuery({
+								spatialType: '面',
+								coordinate: pointsArray.join(','),
+								buffer: ''
+							});
+
+						});
+						break;
+					case "Polygon": //多边形查询
+						jt3d.CommonTools.queryByPolygon(function(coordinates) {
+							console.log(coordinates)
+
+							//还原左键单击事件
+							_self.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+
+							/* 转换坐标 */
+							let points = coordinates.split(',');
+							let pointsArray = [];
+							for (let i = 0; i < points.length;) {
+								pointsArray.push(Number(points[i]) + " " + Number(points[i + 1]));
+								i = i + 2;
+							}
+
+							_self.initQuery({
+								spatialType: '面',
+								coordinate: pointsArray.join(','),
+								buffer: ''
+							});
+
+						});
+						break;
+					case "clear": //清除查询效果
+						this.currentIndex = -1;
+
+						//清除绘制
+						jt3d.CommonTools.clear();
+
+						//还原左键单击事件
+						this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+
+						//清除高亮显示
+						let list = jt3d._dataSources.getByName("单击高亮显示")
+						list.forEach(res => {
+							jt3d._dataSources.remove(res)
+						})
+
+						//清除定位样式
+						if (jt3d.LocateUtil._locationEntity) {
+							window["viewer"].entities.remove(jt3d.LocateUtil._locationEntity);
+						}
+						break;
+				}
+			},
+
+			/**
+			 * @param {Object} options
+			 */
+			initQuery(options) {
+				let _self = this;
+				let treeNodes = [];
+
+				//清除高亮显示
+				let list = jt3d._dataSources.getByName("单击高亮显示")
+				list.forEach(res => {
+					jt3d._dataSources.remove(res)
+				})
+
+				//清除定位样式
+				if (jt3d.LocateUtil._locationEntity) {
+					window["viewer"].entities.remove(jt3d.LocateUtil._locationEntity);
+				}
+
+				const getData = () => {
+
+					if (store.queryMapTables.length > 0) {
+						//查询等待框
+						loading = ElLoading.service({
+							lock: true,
+							text: 'Loading',
+							background: 'rgba(0, 0, 0, 0.7)',
+						});
+
+						let data = [];
+						store.queryMapTables.forEach((itemTable, index) => {
+							let result = getAxios(itemTable, options);
+							data.push(result);
+						})
+
+						Promise.all(data).then(itemList => {
+
+							console.log("itemList", itemList) //itemList返回的数据是按顺序的
+							//执行自己接下来的操作
+							//doSomething
+
+							itemList.forEach((item, index) => {
+								let field = item.table;
+								let tableName = item.table[0].tableName;
+								let tableDescription = item.table[0].tableDescription;
+
+								if (item.data.features.length > 0) {
+									//添加父节点
+									let parentNode = {
+										id: tableName,
+										parentid: "CIM",
+										label: tableDescription + "(" + item.data.features.length + ")",
+									};
+									treeNodes.push(parentNode);
+
+									item.data.features.forEach((itemData, index) => {
+
+										//**************高亮显示****************
+
+										// /* 转换坐标 */
+										// let positions = itemData.geometry.coordinates[0][0].map(point => {
+										// 	return Cesium.Cartesian3.fromDegrees(point[0], point[1], point[2] || 0);
+										// });
+
+										// //先创建一个CustomDataSource源,然后把entity存入这里面
+										// let Polygon = new Cesium.CustomDataSource("单击高亮显示");
+										// jt3d._dataSources.add(Polygon);
+										// //添加数据的方式
+										// Polygon.entities.add({
+										// 	polygon: {
+										// 		hierarchy: new Cesium.PolygonHierarchy(positions),
+										// 		material: Cesium.Color.fromCssColorString("rgba(255,0,255,.7)"),
+										// 		classificationType: Cesium.ClassificationType.BOTH,
+										// 	},
+										// });
+
+										//**************高亮显示****************
+
+										let childNode = {
+											id: itemData.properties["id"],
+											parentid: tableName,
+											field: field,
+											data: itemData,
+										};
+
+										switch (tableName) {
+											//==============规划管理数据-重要控制线=========================
+											case "yjjbnt": //永久基本农田
+												childNode.label = itemData.properties["cfzr"] + "(" + itemData.properties["zzsxmc"] + ")"
+												break;
+											case "yjtz": //永久基本农田调整
+												childNode.label = itemData.properties["zldwmc"] + "(" + itemData.properties["dlmc"] + ")"
+												break;
+											case "bnrgdbh": //不纳入耕地保护目标
+												childNode.label = itemData.properties["zldwmc"] + "(" + itemData.properties["dlmc"] + ")"
+												break;
+											case "gdbhrw": //耕地保护任务
+												childNode.label = itemData.properties["zldwmc"] + "(" + itemData.properties["dlmc"] + ")"
+												break;
+
+												//==============规划管理数据-历史规划==============
+											case "tdzgh": //土地利用总体规划
+												childNode.label = itemData.properties["ghdlmc"]
+												break;
+											case "jsyd": //建设用地管制区
+												childNode.label = itemData.properties["id"]
+												break;
+
+												//==============现状类数据-森林资源-森林资源调查==============
+											case "slyzt": //2019年森林资源管理一张图
+												childNode.label = itemData.properties["id"]
+												break;
+
+												//==============现状类数据-国土调查==============
+											case "ed2009": //二调
+												childNode.label = itemData.properties["zldwmc"] + "(" + itemData.properties["dlmc"] + ")"
+												break;
+											case "ed2020": //二调2020
+												childNode.label = itemData.properties["zldwmc"] + "(" + itemData.properties["dlmc"] + ")"
+												break;
+											case "ed2021": //二调2021
+												childNode.label = itemData.properties["zldwmc"] + "(" + itemData.properties["dlmc"] + ")"
+												break;
+											case "sddltb": //三调   
+												childNode.label = itemData.properties["zldwmc"] + "(" + itemData.properties["dlmc"] + ")"
+												break;
+										}
+
+										treeNodes.push(childNode);
+									});
+								}
+							});
+
+							//处理查询结果树
+							if (treeNodes.length > 0) {
+
+								_self.$parent.$parent.$refs.refQueryResult.expandedKeys = []
+								_self.$parent.$parent.$refs.refQueryResultPopup.isshow = true;
+								_self.$parent.$parent.$refs.refQueryResult.treeData = deepTree(treeNodes);
+
+								//默认选中第一个节点并赋予选中样式
+								_self.$nextTick(function() {
+									let currentNode = _self.$parent.$parent.$refs.refQueryResult.treeData[0].children[0];
+									let currentKey = currentNode.id;
+									_self.$parent.$parent.$refs.refQueryResult.currentKey = currentKey;
+									_self.$parent.$parent.$refs.refQueryResult.$refs.tree.setCurrentKey(currentKey);
+									_self.$parent.$parent.$refs.refQueryResult.handleNodeClick(currentNode);
+								});
+
+								//expandedKeys默认展开treedata第一层,加载第一层数据
+								_self.$parent.$parent.$refs.refQueryResult.expandedKeys.push(_self.$parent.$parent.$refs.refQueryResult.treeData[0].id)
+							}
+
+							//清除绘制
+							jt3d.CommonTools.clear();
+
+							//关闭等待框
+							loading.close()
+
+						})
+					}
+				}
+
+				const getAxios = (itemTable, options) => {
+					return new Promise(function(resolve, reject) {
+						_self.$http.get('/getSpatialQuery', {
+							tableName: itemTable,
+							spatialType: options.spatialType,
+							coordinate: options.coordinate,
+							buffer: options.buffer
+						}).then(res => {
+							resolve(res)
+						});
+					}).catch(err => {
+
+					})
+				}
+
+				getData();
+			},
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.jt-query-graphics {
+		.el-col {
+			padding: 10rem;
+			// color: rgba(90, 172, 255, 1.0);
+			//color: #55ffff;
+			color: #fff;
+		}
+
+		i {
+			display: inline-block;
+			width: 100%;
+			height: 36rem;
+			line-height: 36rem;
+			text-align: center;
+			border-radius: 5rem;
+			font-size: 40rem;
+			// color: rgba(90, 172, 255, 1.0);
+			// color: #55ffff;
+			color: #fff;
+			transition: all .3s;
+			-webkit-transition: all .3s
+		}
+
+		.selectStyle {
+			// background: rgba(135, 182, 254, 0.5);
+			background: rgb(0 44 126);
+		}
+
+		.defaultStyle {
+			background: #ffffff00;
+		}
+
+		.selectFontStyle {
+			color: #fff;
+		}
+	}
+</style>

+ 365 - 0
src/views/Map3d - 副本 (3)/components/query-keyword.vue

@@ -0,0 +1,365 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	/**
+	 * element-plus字体
+	 */
+	import {
+		Search,
+		DArrowRight
+	} from '@element-plus/icons-vue';
+	import {
+		inject
+	} from "vue";
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="query-keyword fadein-left">
+		<el-input v-model="search.searchKey" placeholder="请输入查询关键字" @change="searchKeyChange" @input="searchKeyChange" clearable>
+			<template #append>
+				<el-button :icon="Search" @click="btnSearchClick" />
+			</template>
+		</el-input>
+		<div class="autocomplete " v-if="search.searchListShow">
+			<ul>
+				<li v-for="(item,index) in search.searchCompleteData" :key="index" @click="SearchSelect(index)">
+					{{ item }}
+				</li>
+			</ul>
+		</div>
+		<div class="query-result" v-if="resultListShow">
+			<template v-if="resultCompleteData && resultCompleteData.length">
+				<ul>
+					<li v-for="(item, i) in resultCompleteData" :key="i" class="query-result__item" @click.stop="flyTo(item)">
+						<div class="query-result__context">
+							<p class="query-result-text" :title="item.name">
+								<span class="query-result-text_num">{{ i + 1 }}</span>
+								{{ item.name }}
+							</p>
+							<p class="query-result-sub">{{ item.label }}</p>
+						</div>
+						<p class="query-result__more">
+							<el-icon>
+								<DArrowRight />
+							</el-icon>
+						</p>
+					</li>
+				</ul>
+				<div class="query-result__page">
+					<p class="query-result-allcount">共{{ resultCompleteData.length }}条结果</p>
+					<el-pagination layout="prev, pager, next" size="small" :total="resultCompleteData.length" pageSize="1" :simple="true" />
+				</div>
+			</template>
+		</div>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+	export default {
+		props: {
+
+		},
+
+		/**
+		 * 数据
+		 */
+		data() {
+			return {
+				search: {
+					searchKey: "", // input框输入的值,用v-model双向绑定
+					searchDataList: [], // autocomplete查询数据,一般由后端返回
+					searchCompleteData: [], // autocomplete查询到的数据
+					searchListShow: false,
+				},
+				resultCompleteData: [], // 查询结果
+				resultListShow: false,
+				pagination: {
+					size: "small",
+					total: 0,
+					pageSize: 6,
+					simple: true
+				}
+			}
+		},
+
+		/**
+		 * 方法
+		 */
+		methods: {
+			
+			/**
+			 * 在 Input 值改变时触发
+			 * 当 modelValue 改变时,当输入框失去焦点或用户按Enter时触发
+			 */
+			searchKeyChange() {
+				let _self = this;
+				this.search.searchListShow = true;
+				this.resultListShow = false;
+				let searchRegex = new RegExp(this.search.searchKey, 'i');
+				this.search.searchCompleteData = []; // 先把原有的数据清空,重新查询
+				if (this.search.searchKey === '') return; //如果什么都没有输入,则不用查找
+				this.search.searchDataList.forEach((item) => {
+					if (searchRegex.test(item.label)) {
+						_self.search.searchCompleteData.push(item.label)
+					}
+				});
+			},
+
+			/**
+			 * 选中联想查询数据
+			 * @param {Object} index
+			 */
+			SearchSelect(index) {
+				this.search.searchListShow = false;
+				console.log(this.search.searchCompleteData[index]);
+				this.getSearchData(this.search.searchCompleteData[index]);
+			},
+
+			/**
+			 * 查询按钮
+			 */
+			btnSearchClick() {
+				if (this.search.searchKey === "") {
+					ElMessage("请输入查询关键字");
+					return;
+				}
+				this.getSearchData(this.search.searchKey);
+			},
+
+			/**
+			 * 数据查询
+			 * @param {Object} queryString
+			 */
+			getSearchData(queryString) {
+				let _self = this;
+				_self.$http.get('/getTableList', {
+					tableName: 'base_sys_role',
+					sqlWhere: " label like '%" + queryString + "%'",
+					orderByField: ''
+				}).then(res => {
+					console.log('从服务端搜索数据', res.data)
+					_self.resultCompleteData = res.data;
+					_self.resultListShow = true;
+					_self.search.searchListShow = false;
+				});
+			}
+		},
+
+		mounted() {
+			let _self = this;
+			_self.$http.get('/getTableList', {
+				tableName: 'base_sys_role',
+				sqlWhere: '',
+				orderByField: ''
+			}).then(res => {
+				console.log('从服务端搜索数据', res.data)
+				_self.search.searchDataList = res.data;
+			});
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	$jt3d-text-color:#fff;
+	$jt3d-content-color:#fff;
+
+	$jt3d-select-bg:red;
+
+	.query-keyword {
+		position: absolute;
+		top: 80rem;
+		width: 200rem;
+		left: 10rem;
+		border: 1rem solid rgb(0 44 126 / 100%);
+
+		.el-input {
+			--el-input-bg-color: rgb(0 44 126 / 50%);
+			--el-input-border-color: rgb(0 44 126 / 50%);
+			--el-input-placeholder-color: #fff;
+
+			--el-fill-color-blank: rgb(0 44 126 / 80%);
+			--el-text-color-regular: #fff;
+			--el-color-primary: #fff --el-border-radius-base:0rem;
+			--el-border-radius-base: 0rem;
+
+			.el-button {
+				background-color: rgb(0 44 126 / 100%);
+				color: #fff;
+			}
+		}
+
+		.autocomplete {
+			--el-fill-color-blank: rgb(0 44 126 / 0%);
+		}
+	}
+
+	.autocomplete ul {
+		font-family: sans-serif;
+		position: absolute;
+		list-style: none;
+		background: rgb(0 44 126 / 30%);
+		margin: 0;
+		width: 80%;
+		margin-top: 1rem;
+		margin-left: -1rem;
+		border: 1rem solid rgb(0 44 126 / 100%);
+	}
+
+	.autocomplete ul li {
+		text-decoration: none;
+		display: block;
+		background: rgb(0 44 126 / 30%);
+		color: #fff;
+		padding: 5rem;
+		margin-left: -40rem;
+		text-align: left;
+	}
+
+	.autocomplete ul li:hover,
+	.autocomplete ul li.focus-list {
+		color: white;
+		background: #2F9AF7;
+	}
+
+	.query-result {
+		position: absolute;
+		border-top: none;
+		padding-bottom: 0rem;
+		width: 100%;
+		z-index: 100;
+		border: 1rem solid rgb(0 44 126 / 100%);
+		background: rgb(0 44 126 / 30%);
+		margin-left: -1rem;
+
+		--el-fill-color-blank: rgb(0 44 126 / 0%);
+		--color: #fff;
+		--el-color-primary: #fff;
+
+		.query-result__item {
+			height: 80rem;
+			padding: 0 10rem;
+			display: flex;
+			justify-content: flex-start;
+			align-items: center;
+			margin-left: -40rem;
+			text-align: left;
+
+			&:hover {
+				// background-color: var(--mars-select-bg);
+			}
+
+			.query-result__context {
+				flex-grow: 1;
+				width: 90%;
+
+				.query-result-text {
+					font-size: 16rem;
+					width: 200rem;
+					font-family: Source Han Sans CN;
+					font-weight: 400;
+					// color: var($jt3d-text-color);
+					color: $jt3d-text-color;
+
+					.query-result-text_num {
+						width: 20rem;
+						height: 20rem;
+						margin-right: 5rem;
+						display: inline-block;
+						text-align: center;
+						background: rgb(0 44 126 / 100%);
+					}
+				}
+
+				.query-result-sub {
+					font-size: 14rem;
+					width: 200rem;
+					margin-left: 19rem;
+					font-family: Source Han Sans CN;
+					font-weight: 400;
+					// color: var($jt3d-content-color);
+					color: $jt3d-content-color;
+				}
+			}
+
+			.query-result__more {
+				font-size: 14rem;
+				font-family: Source Han Sans CN;
+				font-weight: 400;
+				// color: var($jt3d-content-color);
+				color: $jt3d-content-color;
+			}
+		}
+
+		.query-result__page {
+			display: flex;
+			justify-content: space-between;
+			padding: 5rem;
+
+			.query-result-allcount {
+				font-size: 14rem;
+				// color: var($jt3d-text-color);
+				color: $jt3d-text-color;
+			}
+		}
+	}
+	
+	/* 四个边角样式 */
+	// .borderstyle {
+	// 	position: relative;
+	// 	width: 100%;
+	// 	height: 490rem;
+	// 	padding: 10rem;
+	// 	border: 1rem solid #008aff70 !important;
+	// 	background-color: rgba(5, 45, 115, 0.7) !important;
+	// 	box-shadow: 0 4rem 15rem 1rem #02213bb3;
+	
+
+		.angle-border {
+			position: absolute;
+			width: 12rem;
+			height: 12rem;
+		}
+	
+		.angle-border-blue {
+			position: absolute;
+			width: 70rem;
+			height: 30rem;
+		}
+	
+		.left-top-border {
+			top: -2rem;
+			left: -2rem;
+			border-left: 2rem solid #008affdd;
+			border-top: 2rem solid #008affdd;
+		}
+	
+		.right-top-border {
+			top: -2rem;
+			right: -2rem;
+			border-right: 2rem solid #008affdd;
+			border-top: 2rem solid #008affdd;
+		}
+	
+		.left-bottom-border {
+			bottom: -2rem;
+			left: -2rem;
+			border-bottom: 2rem solid #FFFFFF;
+			border-left: 2rem solid #FFFFFF;
+		}
+	
+		.right-bottom-border {
+			bottom: -2rem;
+			right: -2rem;
+			border-right: 2rem solid #FFFFFF;
+			border-bottom: 2rem solid #FFFFFF;
+		}
+	// }
+</style>

+ 300 - 0
src/views/Map3d - 副本 (3)/components/queryResult.vue

@@ -0,0 +1,300 @@
+<script setup>
+	import {
+		formattingTime
+	} from '@/assets/js/localtime.js';
+
+	import {
+		inject
+	} from "vue";
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+<template>
+	<div class="jt-queryResult">
+		<div class="_left">
+			<el-tree class="tree-line queryResultTree" ref="tree" node-key="id" :data="treeData" :default-expanded-keys="expandedKeys" :current-node-key="currentKey" @node-click="handleNodeClick" highlight-current />
+		</div>
+		<div class="_right">
+			<div id="detailDiv"></div>
+		</div>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+
+	export default {
+		props: {
+			tree: {
+				type: Object,
+				default () {
+					return []
+				}
+			}
+		},
+		data() {
+			return {
+				treeData: this.tree,
+				currentKey: "",
+				expandedKeys: [], //对应要展开的节点id
+			}
+		},
+		methods: {
+			/**
+			 * 树单击事件
+			 */
+			handleNodeClick(treeNode) {
+
+				let _self = this;
+
+				return new Promise((resolve, reject) => {
+
+					if (treeNode.parentid != 'CIM') {
+
+						//清除高亮显示
+						let list = jt3d._dataSources.getByName("单击高亮显示")
+						list.forEach(res => {
+							jt3d._dataSources.remove(res)
+						})
+
+						//高亮显示并定位显示详细信息
+						jt3d.PolygonObject.generatePolygonByPoints(treeNode.data.geometry.coordinates[0][0], {
+							color: [255, 0, 255, 0],
+							outline: true,
+							outlineWidth: 5,
+							outlineColor: [0, 255, 180, 1]
+						}).then((locationEntity) => {
+							// 初始化定位参数
+							let options = {};
+							options.duration = Cesium.defaultValue(options.duration, 2);
+							options.heading = Cesium.defaultValue(options.heading, 0);
+							options.pitch = Cesium.defaultValue(options.pitch, -60);
+							options.range = Cesium.defaultValue(options.range, 800.0);
+
+							let flyToEntity = jt3d.LocateUtil.flyToEntity(locationEntity, options);
+							flyToEntity.then(function(flag) {
+								//详细信息
+								let strHtml = "";
+								strHtml += "<table>";
+								strHtml += "<thead>";
+								strHtml += "<tr>";
+								strHtml += "<th>属性名</th>";
+								strHtml += "<th>属性值</th>";
+								strHtml += "</tr> ";
+								strHtml += " </thead>";
+								strHtml += "<tbody>";
+
+								var field = treeNode.field;
+								var properties = treeNode.data.properties
+								field.forEach(itemField => {
+									if (itemField.isDisplay === 1) {
+										var fieldDesc = itemField.fieldDescription || itemField
+											.fieldName;
+										var fieldVals = properties[itemField.fieldName];
+
+										//日期格式
+										if (itemField.fieldType === 1) {
+											let time = new Date(fieldVals).getTime();
+											fieldVals = formattingTime(time);
+										}
+
+										if (fieldVals != null && fieldVals != "" && fieldVals !=
+											undefined) {
+											strHtml += "<tr>";
+											strHtml += "<td>" + fieldDesc + "</td>";
+											strHtml += "<td>" + fieldVals + "</td>";
+											strHtml += "</tr>";
+										}
+									}
+								});
+
+								strHtml += "</tbody>";
+								strHtml += "</table>";
+
+								let divb = document.getElementById('detailDiv')
+								divb.innerHTML = strHtml; //设置显示的数据,可以是标签.
+
+							});
+
+						});
+					}
+
+					resolve(1)
+				})
+			},
+
+		},
+		mounted() {}
+	}
+</script>
+
+<style lang="scss">
+	.jt-queryResult {
+		overflow: hidden;
+
+		//左侧树
+		&>div:nth-child(1) {
+			width: 220rem;
+			height: 380rem;
+			float: left;
+			overflow: auto;
+			border-right: 5rem solid #ddd;
+
+			.el-tree {
+				background: rgb(28 59 112 / 0%);
+				height: calc(100% - 2rem);
+				color: #fff;
+				--el-tree-node-hover-bg-color: #2a67c3;
+				--el-font-size-base: 14rem;
+
+				.overflowtext {
+					width: auto !important;
+					padding: 0;
+				}
+			}
+
+
+
+			.tree-line {
+				.el-tree-node {
+					position: relative;
+				}
+
+				.el-tree-node__children {
+					padding-left: 16rem !important; // 缩进量
+
+					.el-tree-node__content {
+						padding-left: 18rem !important;
+					}
+				}
+
+				//高亮显示选中样式
+				.el-tree-node.is-current>.el-tree-node__content {
+					background: #2a67c3;
+				}
+
+				// 竖线
+				.el-tree-node::before {
+					content: "";
+					height: 100%;
+					width: 1rem;
+					position: absolute;
+					left: -3rem;
+					top: -26rem;
+					border-width: 1rem;
+					border-left: 1rem dashed rgba(255, 255, 255, .8);
+				}
+
+				// 当前层最后一个节点的竖线高度固定
+				.el-tree-node:last-child::before {
+					height: 38rem; // 可以自己调节到合适数值
+				}
+
+				// 横线
+				.el-tree-node::after {
+					content: "";
+					width: 24rem;
+					height: 20rem;
+					position: absolute;
+					left: -3rem;
+					top: 12rem;
+					border-width: 1rem;
+					border-top: 1rem dashed rgba(255, 255, 255, .8);
+				}
+
+				// 去掉最顶层的虚线,放最下面样式才不会被上面的覆盖了
+				&>.el-tree-node::after {
+					border-top: none;
+				}
+
+				&>.el-tree-node::before {
+					border-left: none;
+				}
+
+				// 展开关闭的icon
+				.el-tree-node__expand-icon {
+					font-size: 16rem;
+
+					// 叶子节点(无子节点)
+					&.is-leaf {
+						color: transparent;
+						display: none; // 也可以去掉
+					}
+				}
+			}
+
+		}
+
+		//右侧基本信息
+		&>div:nth-child(2) {
+			width: calc(100% - 240rem);
+			height: calc(100% - 0rem);
+			float: left;
+			margin-left: 10rem;
+			font-size: 14rem;
+			padding-top: 5rem;
+
+			table {
+				border-collapse: collapse;
+				margin: 0 auto;
+				text-align: center;
+				width: 100%;
+			}
+
+			table td,
+			table th {
+				// border: 1rem solid #ddd;
+				color: #fff;
+				height: 30rem;
+			}
+
+			table thead th {
+				background-color: rgb(28 59 112 / 100%);
+				border: 2rem solid #ddd;
+			}
+
+			table tr:nth-child(odd) {
+				background: rgb(40 89 172 / 60%);
+				border-left: 2rem solid #ddd;
+				border-right: 2rem solid #ddd;
+				border-bottom: 1rem solid #ddd;
+			}
+
+			table tr:nth-child(even) {
+				background: rgb(28 59 112 / 60%);
+				border-left: 2rem solid #ddd;
+				border-right: 2rem solid #ddd;
+				border-bottom: 1rem solid #ddd;
+			}
+
+			// thead 表头固定,tbody 滚动
+			table>thead>tr {
+				display: table;
+				width: 100%;
+				table-layout: fixed;
+			}
+
+			table>tbody {
+				display: block;
+				height: 340rem;
+				/* 隐藏水平溢出内容 */
+				overflow-x: hidden;
+				/* 当垂直内容超出显示高度时以滚动条形式展示 */
+				overflow-y: auto;
+			}
+
+			table>tbody>tr {
+				/* 将tr设置为table元素,以此达到内容沾满table的效果 */
+				display: table;
+				/* 将tr宽度设置为100%,以此达到内容沾满table的效果 */
+				width: 100%;
+				/* 设置table-layout为fixed以达到首行和内容行对其的效果 */
+				table-layout: fixed;
+			}
+
+			table>tbody>tr>td {
+				border-right: 2rem solid #ddd;
+			}
+		}
+	}
+</style>

+ 401 - 0
src/views/Map3d - 副本 (3)/components/special-effects.vue

@@ -0,0 +1,401 @@
+<script setup>
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-weather-effects">
+		<el-collapse v-model="activeName" accordion>
+			<el-collapse-item name="特效效果">
+				<template #title>
+					<span class='iconfont icon-tianqizitiku43' />天气特效
+				</template>
+				<el-row :gutter="20">
+					<el-col :span="8" v-for="(item,index) in weather" @click="handleWeatherEffects(item.type,index)">
+						<el-avatar shape="circle" style="width:70rem;height: 70rem;" :class="currentIndex===index?'selectStyle':'defaultStyle'">
+							<i :class="[item.icon,currentIndex===index?'selectFontStyle':'']" />
+						</el-avatar>
+						<div style="margin-top: 5rem; font-size: 14rem;" :class="currentIndex===index?'selectFontStyle':''">{{item.label}}</div>
+					</el-col>
+				</el-row>
+			</el-collapse-item>
+			<el-collapse-item name="天空样式">
+				<template #title>
+					<span class='iconfont icon-tianqizitiku43' />天空样式
+				</template>
+				<el-row :gutter="20">
+					<el-col :span="8" v-for="(item,index) in skybox" @click="handleSkybox(item.type,index)">
+						<!-- <el-avatar :src="item.url" /> -->
+						<el-avatar shape="circle" src="https://empty" style="width:70rem;height: 70rem;">
+							<img :src="item.url" />
+						</el-avatar>
+						<div style="margin-top: 5rem; font-size: 14rem;" :class="currentIndex===index?'selectFontStyle':''">{{item.label}}</div>
+					</el-col>
+				</el-row>
+			</el-collapse-item>
+			<!-- <el-collapse-item name="粒子效果">
+				<template #title>
+					<span class='iconfont icon-tianqizitiku43' />粒子效果
+				</template>
+				<div class="el-collapse-item__content">
+					<el-button color="rgb(20 136 255)" @click="ParticleSystem('add')">加载粒子效果</el-button>
+					<el-button color="rgb(255 100 100)" @click="ParticleSystem('remove')"><span style="color: #fff;">清除粒子效果</span></el-button>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="热力图">
+				<template #title>
+					<span class='iconfont icon-tianqizitiku43' />热力图
+				</template>
+				<div class="el-collapse-item__content">
+					<el-button color="rgb(20 136 255)" @click="HeatMap('add')">添加热力图</el-button>
+					<el-button color="rgb(255 100 100)" @click="HeatMap('remove')"><span style="color: #fff;">清除热力图</span></el-button>
+				</div>
+			</el-collapse-item> -->
+		</el-collapse>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+
+	export default {
+		data() {
+			return {
+				activeName: "特效效果",
+				currentIndex: -1,
+				weather: [{
+						label: '雨天',
+						type: 'rain',
+						number: 0,
+						icon: 'iconfont icon-yu'
+					},
+					{
+						label: '雪天',
+						type: 'snow',
+						number: 1,
+						icon: 'iconfont icon-huaban'
+					},
+					{
+						label: '雾天',
+						type: 'fog',
+						number: 2,
+						icon: 'iconfont icon-tianqizitiku43'
+					},
+					{
+						label: '关闭天气',
+						type: 'remove',
+						number: 3,
+						icon: 'iconfont icon-cloudofftianqiguanbi'
+					},
+				],
+				skybox: [{
+						label: '晚霞',
+						type: '晚霞',
+						number: 0,
+						url: 'jt3dSDK/imgs/skybox/01/py.png'
+					},
+					{
+						label: '蓝天',
+						type: '蓝天',
+						number: 1,
+						url: 'jt3dSDK/imgs/skybox/03/py.jpg'
+					},
+					{
+						label: '阴天',
+						type: '阴天',
+						number: 2,
+						url: 'jt3dSDK/imgs/skybox/02/py.jpg'
+					},
+					{
+						label: '蓝色星空',
+						type: '蓝色星空',
+						number: 3,
+						url: 'jt3dSDK/imgs/skybox/05/pz.jpg'
+					},
+					{
+						label: '紫色星空',
+						type: '紫色星空',
+						number: 4,
+						url: 'jt3dSDK/imgs/skybox/04/ny.jpg'
+					},
+				],
+			}
+		},
+		props: {},
+		watch: {},
+
+		/* 方法 */
+		methods: {
+			/**
+			 * 天空盒子事件
+			 * @param {Object} type 天空盒子类型
+			 * @param {Object} index 第几个被选中
+			 */
+			handleSkybox(type, index) {
+				this.currentIndex = index;
+
+				jt3d.SceneEffects.SkyBox.setGroundSkyBox({
+					type: type
+				});
+			},
+
+			/**
+			 * 天气特效事件
+			 * @param {Object} type 天气类型
+			 * @param {Object} index 第几个被选中
+			 */
+			handleWeatherEffects(type, index) {
+				this.currentIndex = index;
+				switch (type) {
+					case "rain": //雨天
+						jt3d.SceneEffects.Weather.removeEffect();
+						jt3d.SceneEffects.Weather.addRainEffect({
+							tiltAngle: 0.3,
+							rainSize: 0.5,
+							rainSpeed: 70
+						});
+						break;
+					case "snow": //雪天
+						jt3d.SceneEffects.Weather.removeEffect();
+						jt3d.SceneEffects.Weather.addSnowEffect();
+						break;
+					case "fog": //雾天
+						jt3d.SceneEffects.Weather.removeEffect();
+						jt3d.SceneEffects.Weather.addFogEffect();
+						break;
+					case "remove": //移除天气特效
+						this.currentIndex = -1;
+						jt3d.SceneEffects.Weather.removeEffect()
+						break;
+
+				}
+			},
+
+			/**
+			 * 粒子效果
+			 */
+			ParticleSystem(type) {
+				let options = {};
+				// 初始化参数默认值
+				options.duration = Cesium.defaultValue(options.duration, 2);
+				options.heading = Cesium.defaultValue(options.heading, 0.5); //指向,默认值0.0(北)
+				options.pitch = Cesium.defaultValue(options.pitch, -40); //俯仰角, 垂直向下。默认值-90(向下看)。
+				options.range = Cesium.defaultValue(options.range, 150); //距目标点距离
+
+				const position = {
+					x: 121.554042,
+					y: 37.395186,
+					z: 25.60
+				};
+
+				// 定位到点
+				let flyToPoint = jt3d.LocateUtil.flyToPoint({
+					longitude: position.x,
+					latitude: position.y,
+					height: position.z,
+					duration: options.duration,
+					heading: options.heading,
+					pitch: options.pitch,
+					range: options.range,
+				});
+				flyToPoint.then(function() {
+					// alert(1111)
+				});
+
+				if (type === "add") {
+
+					const positionF = {
+						x: 121.554042,
+						y: 37.395186,
+						z: 25.60
+					};
+
+					this.fireArr = [];
+					this.waterArr = [];
+
+					let fireEntity = jt3d.SceneEffects.ParticleSystem.createParticleFire([positionF.x, positionF.y, positionF.z])
+					this.fireArr.push(fireEntity)
+
+					const positionW = {
+						x: 121.553975,
+						y: 37.395075,
+						z: 18.10
+					};
+
+					let waterEntity = jt3d.SceneEffects.ParticleSystem.createParticleWater([positionW.x, positionW.y, positionW.z])
+					this.waterArr.push(waterEntity)
+
+				}
+				if (type === "remove") {
+					for (var i = 0; i < this.fireArr.length; i++) {
+						this.fireArr[i].remove()
+					}
+					for (var i = 0; i < this.waterArr.length; i++) {
+						this.waterArr[i].remove()
+					}
+				}
+			},
+
+			/**
+			 * 热力图
+			 */
+			HeatMap(type) {
+
+				if (type === "add") {
+					let viewer = this.viewer = window["viewer"];
+
+					// 矩形坐标
+					var bounds = {
+						west: 121.563298,
+						south: 37.284514,
+						east: 121.565298,
+						north: 37.286514,
+					};
+
+					// 初始化CesiumHeatmap
+					var heatMap = this.heatMap = CesiumHeatmap.create(
+						viewer, // 视图层
+						bounds, // 矩形坐标
+						// heatmap相应参数
+						{
+							backgroundColor: "rgba(0, 0, 0, 0)",
+							radius: 50,
+							maxOpacity: .5,
+							minOpacity: 0,
+							blur: .75
+						}
+					);
+
+					//加载数据,生成热力图
+					// 添加数据 最小值,最大值,数据集
+					heatMap.setWGS84Data(0, 100, getData(300));
+					viewer.zoomTo(viewer.entities);
+
+					if (this._layer) {
+						//移除热力图
+						this.viewer.entities.remove(this.heatMap._layer);
+					} else {
+						this._layer = this.heatMap._layer;
+					}
+
+					// 数据格式:动态数据 [{x: -97.6433525165054, y: 45.61443064377248, value: 11.409122369106317}]
+					function getData(length) {
+						var data = [];
+						for (var i = 0; i < length; i++) {
+							var x = 121.563298 + Math.random() * (121.565298 - 121.563298);
+							var y = 37.284514 + Math.random() * (37.286514 - 37.284514);
+							var value = Math.random() * 100;
+							data.push({
+								x: x,
+								y: y,
+								value: value
+							});
+						}
+						return data;
+					}
+				}
+				if (type === "remove") {
+
+					//移除热力图
+					this.viewer.entities.remove(this.heatMap._layer);
+				}
+			}
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.el-avatar{
+		width: 70rem !important;
+		height: 70rem !important;
+		font-size: 14px !important;
+		cursor: pointer;
+	}
+	
+	::v-deep .el-collapse-item__content {
+		padding: 10rem;
+		// padding-bottom: 0rem;
+		overflow-y: hidden;
+	}
+
+	::v-deep .el-collapse-item__header {
+		background: url(@/assets/images/bg_collapse_title.png) no-repeat;
+		background-size: 350rem 40rem;
+		// background-color: rgb(22 90 190);
+		// background-color: rgb(5 45 100 /60%);
+		background-color: rgb(30 130 255);
+		border-bottom: 0;
+	}
+
+	.el-col {
+		padding: 10rem;
+		// color: rgba(90, 172, 255, 1.0);
+		color: #fff;
+	}
+
+	.jt-weather-effects {
+		position: relative;
+
+		.iconfont {
+			padding: 0 10rem;
+		}
+
+		.el-collapse {
+			--el-collapse-border-color: rgb(0 44 126 / 0%);
+
+			--el-collapse-header-text-color: #ffffff;
+			--el-collapse-header-font-size: 13rem;
+			--el-collapse-content-bg-color: rgb(0 44 126 / 0%);
+			--el-collapse-content-font-size: 13rem;
+			--el-collapse-content-text-color: rgb(216 240 255);
+
+			--el-collapse-header-height: 40rem;
+			--el-collapse-header-bg-color: rgb(30 130 255);
+
+			--el-fill-color-blank: rgb(0 44 126 / 68%);
+			--el-text-color-regular: rgb(216 240 255);
+			--el-border-color: rgb(35 135 255);
+
+			.el-collapse-item__content {
+				padding: 10rem;
+				// padding-bottom: 0rem;
+			}
+		}
+
+		i {
+			display: inline-block;
+			width: 100%;
+			height: 36rem;
+			line-height: 36rem;
+			text-align: center;
+			border-radius: 5rem;
+			font-size: 40rem;
+			// color: rgba(90, 172, 255, 1.0);
+			color: #fff;
+			transition: all .3s;
+			-webkit-transition: all .3s
+		}
+
+		.selectStyle {
+			// background: rgba(135, 182, 254, 0.5);
+			background: rgb(0 44 126);
+		}
+
+		.defaultStyle {
+			background: #ffffff00;
+		}
+
+		.selectFontStyle {
+			// color: #fff;
+			color: #55ffff;
+		}
+	}
+</style>

+ 234 - 0
src/views/Map3d - 副本 (3)/components/toolbars.vue

@@ -0,0 +1,234 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	/**
+	 * element-plus字体
+	 */
+	import {
+		ArrowDown
+	} from '@element-plus/icons-vue';
+
+	import {
+		inject
+	} from "vue";
+
+	import {
+		Store
+	} from '@/store/index'
+	store = Store()
+	
+	const getMapInstance = inject("getMapInstance");
+	let jt3d = getMapInstance();
+	
+	import * as mapWork from "../map"
+
+	import {
+		useWidget
+	} from "@/common/store/widget"
+
+
+	const {
+		activate
+	} = useWidget()
+
+	const showWidget = (widget) => {
+		//全图
+		if (widget === "fullMap") {
+			mapWork.fullMap(jt3d);
+		}
+		//绕点自旋
+		else if (widget === "rotateCamera") {
+			ElMessage.warning('在地图上单击进行自旋,再次单击停止自旋')
+			mapWork.setMapSpin(jt3d);
+		}
+		//清除所有
+		else if (widget === "clearAll") {
+
+		} else {
+			activate(widget)
+		}
+	}
+</script>
+
+<template>
+	<div class="jt-toolbars fadein-right">
+		<template v-for="(item, i) in toolDatas" :key="i">
+			<div v-if="item.router && !item.children" class="toolbar-item" @click="showWidget(item.router)">
+				<i :class="item.icon" />
+				<span class="title">{{ item.name }}</span>
+			</div>
+			<el-dropdown v-if="item.children && !item.router" class="toolbar-item">
+				<span class="el-dropdown-link">
+					<i :class="item.icon" />
+					<span class="title">{{ item.name }}</span>
+					<el-icon class="el-icon--right">
+						<ArrowDown />
+					</el-icon>
+				</span>
+				<template #dropdown>
+					<span slot="slot" class="text"></span>
+					<el-dropdown-menu>
+						<el-dropdown-item v-for="child in item.children" :title="child.name" @click="showWidget(child.router)">
+							<i :class="child.icon" />
+							<span>{{ child.name }}</span>
+						</el-dropdown-item>
+					</el-dropdown-menu>
+				</template>
+			</el-dropdown>
+		</template>
+	</div>
+</template>
+
+<script>
+	let store = undefined;
+	export default {
+		name: "jt-toolbars",
+		data() {
+			return {
+				// toolDatas:store.menuList,
+				toolDatas: [{
+						name: "绕点自旋",
+						icon: "iconfont icon-chaxunzuobiaozhi",
+						router: "rotateCamera"
+					},
+					{
+						name: "全图",
+						icon: "iconfont icon-chaxunzuobiaozhi",
+						router: "fullMap"
+					},
+					{
+						name: "底图",
+						icon: "iconfont icon-dituzuobiao",
+						router: "manage-basemap"
+					},
+					{
+						name: "图层",
+						icon: "iconfont icon-winfo-icon-tucengkongzhi",
+						router: "manage-layer"
+					},
+					{
+						name: "工具",
+						icon: "iconfont icon-xitong1",
+						children: [{
+								name: "卷帘对比",
+								icon: "iconfont maxsize icon-juanlian",
+								router: "map-split"
+							},
+							{
+								name: "分屏对比",
+								icon: "iconfont minsize icon-fenping",
+								router: "map-compare"
+							},
+							{
+								name: "地区导航",
+								icon: "iconfont icon-zhijiantou",
+								router: "location-region"
+							},
+							{
+								name: "视角标签",
+								icon: "iconfont icon-fushi",
+								router: "viewerlabel"
+							},
+						]
+					},
+					{
+						name: "清除",
+						icon: "iconfont icon-shanchu",
+						router: "clearAll"
+					},
+				]
+			}
+		},
+		/* 方法 */
+		methods: {},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.text::before {
+		position: absolute;
+		width: 0rem;
+		height: 0rem;
+		left: calc(50% - 5rem);
+		top: -5rem;
+		content: '';
+		transform: rotate(45deg);
+		z-index: 10;
+		box-sizing: border-box;
+		border-bottom: 5rem solid transparent;
+		border-right: 5rem solid transparent;
+		border-top: 5rem solid rgba(255, 255, 255, 1);
+		border-left: 5rem solid rgba(255, 255, 255, 1);
+		// background: rgba(5, 45, 115, .8) !important;
+	}
+
+	.jt-toolbars {
+		position: absolute;
+		top: 80rem;
+		width: auto;
+		right: 20rem;
+		cursor: pointer !important;
+		padding: 0rem 10rem !important;
+		margin: 0rem !important;
+		background-image: none !important;
+		border: 1rem solid;
+		border: none;
+		border-radius: 2rem !important;
+		background-color: rgb(0 44 126 / 65%);
+		height: 40rem;
+		box-sizing: border-box;
+		line-height: 38rem;
+		text-align: left;
+		user-select: none;
+
+		cursor: default;
+
+		.toolbar-item {
+			display: inline-block;
+			padding: 0rem 10rem;
+
+			margin: 0rem;
+			height: calc(100% - 4rem);
+			color: #fff;
+			font-size: 15rem;
+			vertical-align: middle;
+
+			&:hover {
+				background-color: rgba(255, 255, 255, 0.3);
+			}
+
+			.title {
+				font-size: 16rem;
+			}
+		}
+
+		.toolbar-item:nth-last-child(1) {
+			padding-right: 0rem;
+		}
+		
+		.iconfont{
+			margin-right: 5rem;
+		}
+
+		.el-icon {
+			margin-right: 5rem;
+			color: #fff;
+		}
+
+		.el-dropdown {
+			// vertical-align: middle;
+			height: 40rem;
+			line-height: 38rem;
+			box-sizing: border-box;
+		}
+	}
+</style>

+ 316 - 0
src/views/Map3d - 副本 (3)/components/viewerlabel.vue

@@ -0,0 +1,316 @@
+<script setup>
+	import {
+		inject
+	} from "vue";
+	import html2canvas from 'html2canvas';
+	import {Store} from '@/store/index';
+	store = Store()
+	import {
+		blobToBase64,
+		base64ToBlob
+	} from '@/assets/js/blobtobase64';
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="mainview">
+		<div class="header">
+			<input @input="getName()" id="inputValue" type="text" placeholder="创建视角标签" />
+			<el-button v-if="store.userport=='PC'" type="primary" @click="addviewer" size="small">添加</el-button>
+			<el-button type="primary" @click="searchviewer" size="small">查询</el-button>
+		</div>
+		<div class="middleviewer">
+			<div class="viewer" v-for="(res,index) in ImgurlList" :key="index">
+				<div class="viewertop">
+					<img :src="res.url" @click="flyto(res.info)">
+				</div>
+				<div class="viewerbottom">
+					{{res.name}}
+					<img src="@/assets/images/delete.png" class="deleteImg" @click="deleteviewer(res,index)" />
+				</div>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script>
+	let store = undefined;
+	let jt3d = undefined;
+	export default {
+		data() {
+			return {
+				viewersName: '', //视角标签名称
+				ImgurlList: [], //截图地址列表
+			}
+		},
+		methods: {
+			//获取输入框值
+			getName() {
+				this.viewersName = document.getElementById("inputValue").value;
+			},
+
+			//跳转方法
+			flyto(options) {
+				jt3d.LocateUtil.flyToPoint(options)
+			},
+
+			//删除方法,传keyvalue以及需要修改属性
+			deleteviewer(item, index) {
+				//删除对应数组内的对象
+				this.ImgurlList.splice(index, 1)
+				if (item.id) {
+					this.$http.get('/delete', {
+						tableName: 'map_angle',
+						keyValue: item.id,
+					}).then(res => {
+						console.log(res.data)
+					})
+				}
+			},
+
+			//添加视角标签,当前页存数组,向数据库传入相机参数
+			addviewer() {
+				//获取当前界面截图方法
+				html2canvas(
+					this.$parent.$parent.$refs.refMap3d.$refs.cesiumContainer, {
+						// backgroundColor: null, //画出来的图片有白色的边框,不要可设置背景为透明色(null)
+						useCORS: true, //支持图片跨域
+						scale: 1 / 8, //设置放大的倍数
+					}
+				).then(canvas => {
+					//截图用img元素承装,显示在页面的上
+					let url = canvas.toDataURL('image/png')
+					//经纬度、高度
+					// 获取 相机姿态信息
+					let heading = window["viewer"].scene.camera.heading
+					let pitch = window["viewer"].scene.camera.pitch
+					let roll = window["viewer"].scene.camera.roll
+					let position = window["viewer"].scene.camera.positionCartographic
+					let longitude = Cesium.Math.toDegrees(position.longitude) //y
+					let latitude = Cesium.Math.toDegrees(position.latitude) //x
+					let height = position.height
+					let info = {
+						latitude: latitude,
+						longitude: longitude,
+						height: height,
+						pitch: Cesium.Math.toDegrees(pitch),
+						roll: Cesium.Math.toDegrees(roll),
+						heading: Cesium.Math.toDegrees(heading)
+					}
+					//dom for循环渲染列表
+					this.ImgurlList.unshift({
+						url: url,
+						name: this.viewersName,
+						info: info
+					})
+
+					//base64转换为二进制文件
+					// let blob = base64ToBlob(url)
+					// //文件转为文件流
+					// let formData = new FormData();
+					// formData.append('file',blob)
+
+					let data = {
+						name: this.viewersName,
+						x: latitude,
+						y: longitude,
+						z: height,
+						pitch: Cesium.Math.toDegrees(pitch),
+						roll: Cesium.Math.toDegrees(roll),
+						heading: Cesium.Math.toDegrees(heading),
+						screenshot: url,
+						// screenshot: '',
+						userId: this.id,
+						// id:0
+					}
+
+					//添加数据接口
+					this.$http.post('/postSubmit', {
+						tableName: 'map_angle',
+						keyValue: '',
+						formData: data,
+					}).then(res => {
+						console.log(res)
+						if (res.success == true) {
+							console.log('添加成功')
+							document.getElementById("inputValue").value = ''
+						}
+					})
+				}).catch(err => {
+					console.log(err)
+				})
+			},
+			searchviewer() {
+				this.info = JSON.parse(localStorage.getItem('person'))
+				this.id = this.info.id
+				//获取所有图片数据
+				this.$http.get('/getTableList', {
+					tableName: 'map_angle', //
+					sqlWhere: "name like '%" + this.viewersName + "%'",
+					orderByField: ''
+				}).then(res => {
+					console.log('获取图片', res.data)
+					this.ImgurlList = [];
+					res.data.forEach(item => {
+						let info = {
+							latitude: item.x,
+							longitude: item.y,
+							height: item.z,
+							pitch: item.pitch,
+							roll: item.roll,
+							heading: item.heading
+						}
+						// let url = blobToBase64(item.screenshot)
+						//dom for循环渲染列表
+						this.ImgurlList.push({
+							url: item.screenshot,
+							name: item.name,
+							info: info,
+							id: item.id
+						})
+					})
+
+					// console.log('img列表',this.ImgurlList)
+				})
+			}
+		},
+
+		mounted() {
+			this.info = JSON.parse(localStorage.getItem('person'))
+			this.id = this.info.id
+			//获取所有图片数据
+			this.$http.get('/getTableList', {
+				tableName: 'map_angle', //
+				sqlWhere: '', //+ this.loginForm.id
+				orderByField: ''
+			}).then(res => {
+				console.log('获取图片', res.data)
+				if(res.data.length == 0) return
+				res.data.forEach(item => {
+					let info = {
+						latitude: item.x,
+						longitude: item.y,
+						height: item.z,
+						pitch: item.pitch,
+						roll: item.roll,
+						heading: item.heading
+					}
+					// let url = blobToBase64(item.screenshot)
+					//dom for循环渲染列表
+					this.ImgurlList.push({
+						url: item.screenshot,
+						name: item.name,
+						info: info,
+						id: item.id
+					})
+				})
+
+				// console.log('img列表',this.ImgurlList)
+			})
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.el-button--small{
+		--el-button-size:24rem;
+		font-size:12rem;
+		padding: 5rem 12rem;
+	}
+	
+	.mainview {
+		width: 100%;
+		height: 100%;
+
+		.header {
+			width: 100%;
+			display: flex;
+
+			input,
+			input:focus {
+				outline: none;
+				width: 185rem !important;
+				border: 1rem solid rgba(255, 255, 255, 0.8);
+				margin-right: 10rem;
+				height: 26rem !important;
+				color: rgba(255, 255, 255, 1);
+				background-color: rgba(255, 255, 255, 0) !important;
+				border-radius: 3rem;
+			}
+		}
+
+		.middleviewer {
+			width: 322rem;
+			height: 100%;
+			margin-left: 7rem;
+
+			.viewer {
+				width: 322rem !important;
+				height: 240rem !important;
+				margin-top: 15rem;
+				border: 1rem solid #ffffff !important;
+				border-radius: 1rem !important;
+
+				.viewertop {
+					width: 322rem !important;
+					height: 210rem !important;
+
+					img {
+						width: 100% !important;
+						height: 100% !important;
+					}
+				}
+
+				.viewerbottom {
+					line-height: 30rem !important;
+					text-align: center !important;
+					width: 322rem !important;
+					height: 30rem !important;
+					position: relative;
+					background-color: rgba(15, 145, 185, 0.7);
+
+					.deleteImg {
+						width: 24rem;
+						height: 24rem;
+						right: 5rem;
+						top: 3rem;
+						position: absolute;
+					}
+				}
+			}
+		}
+	}
+
+	::v-deep .el-input {
+		flex-grow: 0 !important;
+		width: 200rem !important;
+		// display: inline !important;
+		// margin-left: 5rem;
+		margin-right: 10rem;
+		height: 30rem !important;
+	}
+
+	//输入框文字颜色
+	::v-deep .el-input__inner {
+		color: rgba(255, 255, 255, 1)
+	}
+
+	//输入框背景色
+	::v-deep .el-input__wrapper {
+		background-color: rgba(255, 255, 255, 0) !important;
+	}
+
+	::v-deep .el-button {
+		border-radius: 3rem !important;
+
+	}
+
+	::v-deep .el-button--primary {
+		background-color: rgba(64, 158, 255, 0.6) !important;
+	}
+
+	::-webkit-scrollbar {
+		width: 0rem;
+	}
+</style>

+ 1137 - 0
src/views/Map3d - 副本 (3)/map.js

@@ -0,0 +1,1137 @@
+import {
+	Store
+} from '@/store/index'
+let store = Store();
+
+import http from '@/utils/http.js'
+
+// import * as jt3dSDK from '/public/jt3dSDK/jt3d.es.js';
+
+import map_xzqh_zj from '@/assets/dataFile/map_xzqh_zj.json';
+
+let jtMap3d = undefined; // 地图对象
+
+/**
+ * 初始化地图业务,生命周期钩子函数(必须)
+ * 框架在地图初始化完成后自动调用该函数
+ * @param  mapInstance 地图对象
+ */
+export function onMounted(mapInstance) {
+	jtMap3d = mapInstance // 记录首次创建的map
+
+	debugger
+}
+
+//所有图层
+export function getAllLayers() {
+
+	return new Promise((resolve, reject) => {
+
+		//获取地图图集id
+		let roleId = store.roleId
+		let atlasLayersSqlWhere = '"roleId"' + " = " + roleId + " "
+
+		//获取图集
+		http.get('/getTableList', {
+			tableName: 'sys_map_atlas_layers', //表名
+			sqlWhere: atlasLayersSqlWhere, //查询条件
+			orderByField: '' //排序字段
+		}).then(res => {
+			resolve(res.data)
+		});
+	});
+}
+export function getLayers() {
+
+	return new Promise((resolve, reject) => {
+
+		//获取地图图集id
+		let roleId = store.roleId
+		let atlasLayersSqlWhere = '"roleId"' + " = " + roleId + " and " + '"atlasType"' + "='图层'"
+
+		//获取图集
+		http.get('/getTableList', {
+			tableName: 'sys_map_atlas_layers', //表名
+			sqlWhere: atlasLayersSqlWhere, //查询条件
+			orderByField: '' //排序字段
+		}).then(res => {
+			resolve(res.data)
+		});
+	});
+}
+
+export function getBaseMaps() {
+
+	return new Promise((resolve, reject) => {
+
+		//获取地图图集id
+		let roleId = store.roleId
+		let atlasLayersSqlWhere = '"roleId"' + " = " + roleId + " and " + '"atlasType"' + "='底图'"
+
+		//获取图集
+		http.get('/getTableList', {
+			tableName: 'sys_map_atlas_layers', //表名
+			sqlWhere: atlasLayersSqlWhere, //查询条件
+			orderByField: '' //排序字段
+		}).then(res => {
+			resolve(res.data)
+		});
+	});
+}
+
+/**
+ * 单击事件
+ */
+export function clickEntity(jt3d) {
+
+	if (jt3d.handlerLeftClick) {
+		jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); //移除事件
+	}
+
+	jt3d.handlerLeftClick = new Cesium.ScreenSpaceEventHandler(
+		jt3d._viewer.scene.canvas
+	);
+	//注册大球单机事件
+	jt3d.handlerLeftClick.setInputAction(function(e) {
+		var pick = jt3d._viewer.scene.pick(e.position); //拾取当前的entity对象
+		var cartesian = jt3d._viewer.scene.pickPosition(e.position); //获取当前点坐标
+		if (Cesium.defined(cartesian)) {
+			//将笛卡尔坐标转换为地理坐标
+			let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
+			//将弧度转为度的十进制度表示
+			let lng = Cesium.Math.toDegrees(cartographic.longitude);
+			let lat = Cesium.Math.toDegrees(cartographic.latitude);
+			let alt = cartographic.height; //高度
+
+			initQuery({
+				spatialType: '点',
+				coordinate: lng + " " + lat,
+				buffer: ''
+			});
+		}
+	}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+}
+
+
+/**
+ * 设置默认视图-初始化中国区域范围视角
+ */
+export function setView(jt3d) {
+	// jt3d.flytoChina();
+
+	//初始化中国区域范围视角
+	jt3d.setViewChina();
+
+	// jt3d.setView({
+	// 	longitude: 103.84, //经度
+	// 	latitude: 31.15, // 维度
+	// 	height: 24000000, // 高度
+	// 	heading: 0, // 偏航
+	// 	pitch: -90, // 俯仰,人如果在赤道上空,俯仰角为0可见地球。如果在北纬,俯仰角为负才能见地球
+	// 	roll: 0.0 // 翻滚
+	// });
+}
+
+/**
+ * 全图-飞行到项目区域范围视角
+ */
+export function fullMap(jt3d) {
+	// 初始化项目区域范围视角
+	let optionsS = {
+		west: 121.563298,
+		south: 37.284514,
+		east: 121.565298,
+		north: 37.286514,
+		isRemove: false, //定位完成后是否删除
+		duration: 3, //飞行时间
+		heading: 0,
+		pitch: -90,
+		range: 115000
+	};
+
+	let optionsE = {
+		west: 121.563298,
+		south: 37.284514,
+		east: 121.565298,
+		north: 37.286514,
+		isRemove: true, //定位完成后是否删除
+		duration: 3, //飞行时间
+		heading: 0,
+		pitch: -60,
+		range: 115000
+	};
+
+	var fullMapPromise = jt3d.fullMap(optionsS);
+	fullMapPromise.then(function(flyPromise) {
+		jt3d.fullMap(optionsE);
+	});
+}
+
+/**
+ * 设置天空盒子
+ */
+export function addSkybox(jt3d) {
+	//设置天空盒子,默认蓝天
+	let SceneEffects = new jt3dSDK.SceneEffects.SkyBox(window.viewer);
+	SceneEffects.setGroundSkyBox();
+}
+
+/**
+ * 添加镇街边界线——精灵线
+ */
+export function addBoundaryLine(jt3d) {
+	let PolylineObject = new jt3dSDK.PolylineObject(jt3d._viewer);
+	PolylineObject.drawPolylineByGeoJson(map_xzqh_zj, {
+		width: 5,
+		color: '#04FFFF',
+		isImageAlpha: true, //用图片自带颜色
+		duration: 3000,
+		imgUrl: "jt3dSDK/imgs/polylinematerial/spriteline1.png"
+	});
+}
+
+/**
+ * 控制地图服务的显示及隐藏
+ * @param {Object} viewer
+ * @param {Object} options 
+ */
+export function setLayersControl(viewer, options, checked) {
+
+	let layer = new jt3dSDK.layer(viewer);
+	var imageryLayers = viewer.imageryLayers;
+
+	//参数集
+	let parameterset = options.parameterset;
+	if (options.parameterset instanceof Object) {
+		parameterset = options.parameterset;
+	} else if (options.parameterset != "" && options.parameterset != null && options.parameterset != undefined) {
+		parameterset = JSON.parse(options.parameterset);
+	}
+
+	return new Promise((resolve, reject) => {
+		switch (options.loadtype) {
+			case "DEM": //地形服务(DEM)
+				if (checked) {
+
+					//设置参数
+					let _options = {
+						url: options.datasource,
+					}
+					if (parameterset) {
+						if (parameterset.terrainExaggeration) { //地形夸张系数
+							_options.terrainExaggeration = parameterset.terrainExaggeration;
+						}
+					}
+					layer.addTerrain(_options);
+					resolve(true);
+				} else {
+					layer.removeTerrain().then(res => {
+						resolve(true);
+					});
+				}
+				break;
+
+			case "Cesium3DTileset": //加载3DTileset地图服务--实景
+
+				if (checked) {
+
+					if (window[options.serviceId]) {
+						window[options.serviceId].show = true;
+					} else {
+						//设置参数
+						let _options = {
+							id: options.serviceId,
+							url: options.datasource,
+						}
+						if (parameterset) {
+							if (parameterset.height) {
+								_options.height = parameterset.height;
+							}
+							if (parameterset.alpha) {
+								_options.alpha = parameterset.alpha;
+							}
+						}
+						//加载实景
+						layer.addCesium3DTileset(_options, function(serviceId) {
+							window[serviceId].show = true;
+							resolve(true);
+						});
+					}
+				} else {
+					if (window[options.serviceId]) {
+						//3DTileset数据量比较大,会报很多cesium错误
+						// layer.removeScenePrimitives({
+						// 	serviceId: options.serviceId
+						// }).then(res => {
+
+						// });
+
+						window[options.serviceId].show = false;
+
+						resolve(true);
+					}
+				}
+
+				break;
+			case "Cesium3DTileset_BM": //加载3DTileset地图服务--白膜
+				if (checked) {
+
+					if (window[options.serviceId]) {
+						window[options.serviceId].show = true;
+					} else {
+						//设置参数
+						let _options = {
+							id: options.serviceId,
+							url: options.datasource,
+						}
+						if (parameterset) {
+							if (parameterset.color) {
+								_options.color = parameterset.color;
+							}
+						}
+
+						//加载白膜
+						layer.addCesium3DTilesetBm(_options, function(serviceId) {
+							window[serviceId].show = true;
+							resolve(true);
+						});
+					}
+				} else {
+					if (window[options.serviceId]) {
+						// layer.removeScenePrimitives({
+						// 	serviceId: options.serviceId
+						// }).then(res => {
+						// });
+
+						window[options.serviceId].show = false;
+						resolve(true);
+					}
+				}
+				break;
+
+
+			case "GeoJsonPoint": //GeoJsonPoint
+				if (checked) {
+
+					//设置参数
+					let _options = {
+						id: options.serviceId,
+						url: options.datasource,
+					}
+
+					if (parameterset) {
+						if (parameterset.billboard instanceof Object) {
+							let billboard = parameterset.billboard;
+							_options.billboard = billboard;
+						}
+
+						if (parameterset.label instanceof Object) {
+							let label = parameterset.label;
+							_options.label = label;
+						}
+					}
+
+					layer.addBillboardByJson(_options, function(serviceId) {
+						resolve(true);
+					});
+
+				} else {
+					layer.removeDataSources({
+						serviceId: options.serviceId,
+					}).then(res => {
+						resolve(true);
+					});
+				}
+				break;
+			case "GeoJsonPolyline": //GeoJsonPolyline
+				if (checked) {
+
+
+					//设置参数
+					let _options = {
+						id: options.serviceId,
+						url: options.datasource,
+					}
+
+					if (parameterset) {
+
+						if (parameterset.clampToGround) { //是否贴地
+							_options.clampToGround = parameterset.clampToGround;
+						}
+						if (parameterset.isImageAlpha) { //是否采用图片颜色
+							_options.isImageAlpha = parameterset.isImageAlpha;
+						}
+						if (parameterset.imgUrl) { //精灵线图片
+							_options.imgUrl = parameterset.imgUrl;
+						}
+						if (parameterset.color) { //指定线的颜色
+							_options.color = parameterset.color;
+						}
+						if (parameterset.width) { //线宽
+							_options.width = parameterset.width;
+						}
+						if (parameterset.duration) { //持续时间 毫秒,越小越快
+							_options.duration = parameterset.duration;
+						}
+						if (parameterset.count) { //重复次数
+							_options.count = parameterset.count;
+						}
+						if (parameterset
+							.direction) { //direction=vertical 纵,order='-'(由下到上) , '+"(由上到下)
+							_options.direction = parameterset.direction;
+						}
+						if (parameterset
+							.order) { //direction=horizontal 横,order='-'(顺时针) , '+'(逆时针)
+							_options.order = parameterset.order;
+						}
+					}
+
+					layer.addPolylineByGeoJson(_options, function(serviceId) {
+						resolve(true);
+					});
+				} else {
+					layer.removeDataSources({
+						serviceId: options.serviceId,
+					}).then(res => {
+						resolve(true);
+					});
+				}
+				break;
+			case "GeoJsonWall": //GeoJson Wall
+				if (checked) {
+
+					//设置参数
+					let _options = {
+						id: options.serviceId,
+						url: options.datasource,
+					}
+
+					if (parameterset) {
+
+						if (parameterset.clampToGround) { //是否贴地
+							_options.clampToGround = parameterset.clampToGround;
+						}
+						if (parameterset.minimunHeights) { //最低高度
+							_options.minimunHeights = parameterset.minimunHeights;
+						}
+						if (parameterset.maximumHeights) { //最高高度
+							_options.maximumHeights = parameterset.maximumHeights;
+						}
+						if (parameterset.color) { //指定墙体的颜色
+							_options.color = parameterset.color;
+						}
+						if (parameterset.trailImage) { //墙体图片
+							_options.trailImage = parameterset.trailImage;
+						}
+						if (parameterset.duration) { //持续时间 毫秒,越小越快
+							_options.duration = parameterset.duration;
+						}
+						if (parameterset.count) { //重复次数
+							_options.count = parameterset.count;
+						}
+						if (parameterset.direction) { //direction=vertical 纵,order='-'(由下到上) , '+"(由上到下)
+							_options.direction = parameterset.direction;
+						}
+						if (parameterset.order) { //direction=horizontal 横,order='-'(顺时针) , '+'(逆时针)
+							_options.order = parameterset.order;
+						}
+					}
+
+					// .json文件需要放到public文件夹下,直接调用,
+					layer.addWallByJson(_options, function(serviceId) {
+						resolve(true);
+					});
+				} else {
+					layer.removeDataSources({
+						serviceId: options.serviceId,
+					}).then(res => {
+						resolve(true);
+					});
+				}
+				break;
+			case "entitiesGltf": //gltf/glb
+				if (checked) {
+
+					//设置参数
+					let _options = {
+						id: options.serviceId,
+						url: options.datasource,
+						points: [],
+					}
+
+					if (parameterset) {
+						if (parameterset.points) { //模型位置
+							_options.points = parameterset.points;
+
+							if (parameterset.minimumPixelSize) { //模型最小刻度
+								_options.minimumPixelSize = parameterset.minimumPixelSize;
+							}
+							if (parameterset.maximumScale) { //模型的最大比例尺大小,设置模型最大放大大小
+								_options.maximumScale = parameterset.maximumScale;
+							}
+							if (parameterset.silhouetteColor) { //模型轮廓颜色
+								_options.silhouetteColor = parameterset.silhouetteColor;
+							}
+							if (parameterset.alpha) { //模型透明度
+								_options.alpha = parameterset.alpha;
+							}
+							if (parameterset.heading) { //以弧度为单位的航向分量
+								_options.heading = parameterset.heading;
+							}
+							if (parameterset.pitch) { //以弧度为单位的航向分量
+								_options.pitch = parameterset.pitch;
+							}
+							if (parameterset.roll) { //以弧度为单位的滚动分量
+								_options.roll = parameterset.roll;
+							}
+
+							layer.addEntitiesGltf(_options, function(serviceId) {
+
+								resolve(true);
+							});
+
+						} else {
+							ElMessage("请检测图层表parameterset字段是否设置points");
+						}
+					} else {
+						ElMessage("请检测图层表parameterset字段是否设置points");
+					}
+				} else {
+					layer.removeEntity({
+						serviceId: options.serviceId,
+					}).then(res => {
+						resolve(true);
+					});
+				}
+				break;
+			case "scenePrimitivesGltf": //加载gltf/glb
+				if (checked) {
+
+					//设置参数
+					let _options = {
+						id: options.serviceId,
+						url: options.datasource,
+						points: [],
+					}
+
+					if (parameterset) {
+						if (parameterset.points) { //模型位置
+							_options.points = parameterset.points;
+
+							if (parameterset.scale) { //放大倍数
+								_options.scale = parameterset.scale;
+							}
+
+							layer.addScenePrimitivesGltf(_options, function(serviceId) {
+
+								resolve(true);
+							});
+
+						} else {
+							ElMessage("请检测图层表parameterset字段是否设置points");
+						}
+					} else {
+						ElMessage("请检测图层表parameterset字段是否设置points");
+					}
+				} else {
+					layer.removeScenePrimitives({
+						serviceId: options.serviceId,
+					}).then(res => {
+						resolve(true);
+					});
+				}
+				break;
+			case "PolygonImageMaterial": //图片材质
+				if (checked) {
+
+					if (parameterset) {
+						if (parameterset.points) {
+							layer.addPolygonImageMaterial({
+								id: options.serviceId,
+								points: parameterset.points,
+								url: options.datasource,
+								alpha: options.opacity
+							}, function(serviceId) {
+								resolve(true);
+							});
+						} else {
+							ElMessage("请检测图层表parameterset字段是否设置points");
+						}
+					} else {
+						ElMessage("请检测图层表parameterset字段是否设置points");
+					}
+				} else {
+					layer.removeEntity({
+						serviceId: options.serviceId,
+					}).then(res => {
+						resolve(true);
+					});
+				}
+				break;
+			case "CrImageServerLayer": //贴地所有地形、模型的规划图、网格地图
+
+				if (checked) {
+
+					let floatLayer = new jt3dSDK.CrImageServerLayer({
+						viewer: viewer,
+						url: options.datasource,
+						opacity: options.opacity,
+						show: true
+					});
+					window[options.serviceId] = floatLayer;
+					//添加网格地图
+					// window[options.serviceId].show();
+					resolve(true);
+				} else {
+					window[options.serviceId].hide();
+					resolve(true);
+				}
+				break;
+
+
+			case "UrlTemplateImageryProvider": //加载URL模板服务
+				if (checked) {
+
+					//设置参数
+					let _options = {
+						id: options.serviceId,
+						url: options.datasource,
+						alpha: options.opacity
+					}
+					if (parameterset) {
+						if (parameterset.CRS) { //坐标系
+							_options.CRS = parameterset.CRS;
+						}
+						if (parameterset.minimumLevel) { //最小层级
+							_options.minimumLevel = parameterset.minimumLevel;
+						}
+						if (parameterset.maximumLevel) { //最大层级
+							_options.maximumLevel = parameterset.maximumLevel;
+						}
+					}
+
+					//加载服务
+					layer.addUrlTemplateImagery(_options, function(serviceId) {
+
+						//重置图层顺序
+						setLayerNumber(imageryLayers, {
+							serviceId: serviceId,
+							layertype: options.layertype
+						})
+						resolve(true);
+					});
+				} else {
+					layer.removeImageryProvider({
+						serviceId: options.serviceId
+					}).then(res => {
+						resolve(true);
+					});
+				}
+
+				break;
+			case "WebMapTileServiceImageryProvider": // WMTS地图服务
+				if (checked) {
+
+					//设置参数
+					let _options = {
+						id: options.serviceId,
+						url: options.datasource,
+						layers: 'cia',
+						style: 'default',
+						tileMatrixSetID: 'w',
+						alpha: options.opacity
+					}
+					if (parameterset) {
+						if (parameterset.layers) { //WMTS请求的层名
+							_options.layers = parameterset.layers;
+
+							if (parameterset.style) { //WMTS请求的样式名
+								_options.style = parameterset.style;
+
+								if (parameterset.tileMatrixSetID) { //用于WMTS请求的TileMatrixSet的标识符
+									_options.tileMatrixSetID = parameterset.tileMatrixSetID;
+
+									if (parameterset.minimumLevel) { //最小层级
+										_options.minimumLevel = parameterset.minimumLevel;
+									}
+									if (parameterset.maximumLevel) { //最大层级
+										_options.maximumLevel = parameterset.maximumLevel;
+									}
+
+									layer.addWebMapTileService(_options, function(serviceId) {
+
+										//重置图层顺序
+										setLayerNumber(imageryLayers, {
+											serviceId: serviceId,
+											layertype: options.layertype
+										})
+
+										resolve(true);
+									});
+
+								} else {
+									ElMessage("请检测图层表parameterset字段是否设置tileMatrixSetID");
+								}
+
+							} else {
+								ElMessage("请检测图层表parameterset字段是否设置style");
+							}
+
+						} else {
+							ElMessage("请检测图层表parameterset字段是否设置layers");
+						}
+					} else {
+						ElMessage("请检测图层表parameterset字段是否设置layers,style,tileMatrixSetID");
+					}
+
+				} else {
+					layer.removeImageryProvider({
+						serviceId: options.serviceId
+					}).then(res => {
+
+						resolve(true);
+					});
+				}
+				break;
+			case "WebMapServiceImageryProvider": //WMS地图服务
+				if (checked) {
+
+					//设置参数
+					let _options = {
+						id: options.serviceId,
+						url: options.datasource,
+						alpha: options.opacity
+					}
+					if (parameterset) {
+						if (parameterset.layers) { //WMTS请求的层名
+							_options.layers = parameterset.layers;
+
+							if (parameterset.minimumLevel) { //最小层级
+								_options.minimumLevel = parameterset.minimumLevel;
+							}
+							if (parameterset.maximumLevel) { //最大层级
+								_options.maximumLevel = parameterset.maximumLevel;
+							}
+
+							layer.addWebMapService(_options, function(serviceId) {
+
+								//重置图层顺序
+								setLayerNumber(imageryLayers, {
+									serviceId: serviceId,
+									layertype: options.layertype
+								})
+
+								resolve(true);
+							});
+						} else {
+							ElMessage("请检测图层表parameterset字段是否设置layers");
+						}
+					} else {
+						ElMessage("请检测图层表parameterset字段是否设置layers");
+					}
+				} else {
+					layer.removeImageryProvider({
+						serviceId: options.serviceId
+					}).then(res => {
+
+						resolve(true);
+					});
+				}
+				break;
+			case "ArcGisMapServerImageryProvider": // ArcGIS Online和Server的相关服务
+				if (checked) {
+
+					//设置参数
+					let _options = {
+						id: options.serviceId,
+						url: options.datasource,
+						alpha: options.opacity
+					}
+					if (parameterset) {
+						if (parameterset.layers) {
+							_options.layers = parameterset.layers;
+						}
+					}
+
+					//加载服务
+					layer.addArcGisMapServer(_options, function(serviceId) {
+
+						//重置图层顺序
+						setLayerNumber(imageryLayers, {
+							serviceId: serviceId,
+							layertype: options.layertype
+						})
+
+						resolve(true);
+					})
+				} else {
+					layer.removeImageryProvider({
+						serviceId: options.serviceId
+					}).then(res => {
+
+						resolve(true);
+					});
+				}
+				break;
+			case "TileMapServiceImageryProvider": // 2.5维度地图
+				if (checked) {
+
+					//设置参数
+					let _options = {
+						id: options.serviceId,
+						url: options.datasource,
+						alpha: options.opacity
+					}
+					if (parameterset) {
+						if (parameterset.minimumLevel) { //最小层级
+							_options.minimumLevel = parameterset.minimumLevel;
+						}
+						if (parameterset.maximumLevel) { //最大层级
+							_options.maximumLevel = parameterset.maximumLevel;
+						}
+					}
+
+					layer.addTileMapServiceImagery(_options, function(serviceId) {
+
+						//重置图层顺序
+						setLayerNumber(imageryLayers, {
+							serviceId: serviceId,
+							layertype: options.layertype
+						})
+
+						resolve(true);
+					});
+				} else {
+					layer.removeImageryProvider({
+						serviceId: options.serviceId
+					}).then(res => {
+
+						resolve(true);
+					});
+				}
+				break;
+
+			default:
+				break;
+		}
+	})
+}
+
+/**
+ * 服务定位
+ * @param {Object} viewer
+ * @param {Object} options
+ */
+export function setLayersLocation(viewer, options) {
+
+	//参数集
+	let parameterset = options.parameterset;
+	if (options.parameterset instanceof Object) {
+		parameterset = options.parameterset;
+	} else if (options.parameterset != "" && options.parameterset != null && options.parameterset != undefined) {
+		parameterset = JSON.parse(options.parameterset);
+	}
+
+	if (options.isinit === '1') {
+		return new Promise((resolve, reject) => {
+			switch (options.loadtype) {
+				case "GeoJsonPolyline": //GeoJsonPolyline
+
+					break;
+				case "GeoJsonWall": //GeoJsonWall
+
+					break;
+				case "entitiesGltf": //gltf/glb
+
+					if (parameterset) {
+						if (parameterset.points) { //模型位置
+
+							// let LocateUtil = new jt3dSDK.LocateUtil(viewer);
+							// let flyToEntity = LocateUtil.flyToEntityByPoints([
+							// 	parameterset.points,
+							// ], 'point', {
+							// 	heading: '0',
+							// 	pitch: -90,
+							// 	range: 8880
+							// });
+							viewer.scene.camera.flyTo({
+								//定位坐标点
+								destination: Cesium.Cartesian3.fromDegrees(parameterset.points[0], parameterset.points[1], parameterset.points[2] || 0),
+								duration: 2, //定位的时间间隔
+								orientation: {
+									heading: Cesium.Math.toRadians(56), //方向
+									pitch: Cesium.Math.toRadians(-11), //倾斜角度
+									roll: 0
+								}
+							});
+
+							resolve(true);
+						} else {
+							ElMessage("请检测图层表parameterset字段是否设置points");
+						}
+					} else {
+						ElMessage("请检测图层表parameterset字段是否设置points");
+					}
+
+					break;
+				case "scenePrimitivesGltf": //gltf/glb
+
+					if (parameterset) {
+						if (parameterset.points) { //模型位置
+
+							viewer.scene.camera.flyTo({
+								//定位坐标点
+								destination: Cesium.Cartesian3.fromDegrees(parameterset.points[0], parameterset.points[1], parameterset.points[2] || 0),
+								duration: 2, //定位的时间间隔
+								orientation: {
+									// heading: Cesium.Math.toRadians(56), //方向
+									// pitch: Cesium.Math.toRadians(-11), //倾斜角度
+									// roll: 0
+								}
+							});
+
+							resolve(true);
+						} else {
+							ElMessage("请检测图层表parameterset字段是否设置points");
+						}
+					} else {
+						ElMessage("请检测图层表parameterset字段是否设置points");
+					}
+
+					break;
+				case "PolygonImageMaterial": //图片材质
+
+					break;
+				case "CrImageServerLayer": //地形服务(DEM)
+
+					break;
+				case "DEM": //地形服务(DEM)
+
+					break;
+				case "UrlTemplateImageryProvider": //加载URL模板服务
+
+					break;
+				case "WebMapTileServiceImageryProvider": // WMTS地图服务
+
+					break;
+				case "WebMapServiceImageryProvider": //WMS地图服务
+
+					break;
+				case "ArcGisMapServerImageryProvider": // ArcGIS Online和Server的相关服务
+
+					break;
+				case "TileMapServiceImageryProvider": // 2.5维度地图
+
+					break;
+				case "Cesium3DTileset": //加载3DTileset地图服务--实景
+
+					if (window[options.serviceId]) {
+						viewer.flyTo(window[options.serviceId]);
+						resolve(true);
+					}
+					break;
+				case "Cesium3DTileset_BM": //加载3DTileset地图服务--白膜
+
+					break;
+				default:
+					break;
+			}
+		})
+	}
+}
+
+/**
+ * 设置服务透明度
+ * @param {Object} viewer
+ * @param {Object} options
+ */
+export function setLayersAlpha(viewer, options) {
+	let layer = new jt3dSDK.layer(viewer);
+
+	if (options.loadtype === "Cesium3DTileset") {
+		//设置实景透明度
+		layer.set3DTileStyle({
+			serviceId: options.serviceId,
+			alpha: options.alpha,
+		});
+	} else if (options.loadtype === "CrImageServerLayer") {
+		let floatLayer = window[options.serviceId];
+		floatLayer.setOpacity(options.alpha)
+	} else if (options.loadtype === "PolygonImageMaterial") {
+		//设置透明度
+		layer.setPolygonImageMaterial({
+			serviceId: options.serviceId,
+			alpha: options.alpha,
+		});
+	} else if (options.loadtype === "entitiesGltf") {
+		//设置透明度
+		layer.setModelStyle({
+			serviceId: options.serviceId,
+			alpha: options.alpha,
+		});
+	} else {
+		layer.setLayersStyle({
+			serviceId: options.serviceId,
+			alpha: options.alpha,
+		});
+	}
+}
+
+/**
+ * 设置图层顺序
+ * @param {Object} imageryLayers
+ * @param {Object} options
+ */
+export function setLayerNumber(imageryLayers, options) {
+
+	// var imageryLayers = viewer.imageryLayers;
+
+	//设置图层初始顺序
+	imageryLayers.lowerToBottom(window[options.serviceId]);
+	imageryLayers.raise(window[options.serviceId]);
+	imageryLayers.raise(window[options.serviceId]);
+
+	getAllLayers().then(layers => {
+		layers.map((item) => {
+			if (item.layercode && item.layerorder) {
+				let id = store.serviceMark + "_" + item.layercode + item.layerorder
+				let startid = Number(item.layercode + item.layerorder)
+				let strid = Number(options.serviceId.replace(store.serviceMark + "_", ""))
+
+				if (imageryLayers.contains(window[id])) {
+					if (startid <= strid) {
+						imageryLayers.raise(window[options.serviceId])
+					}
+				}
+			}
+		})
+
+		//底图置底
+		if (options.layertype === "底图影像") {
+			imageryLayers.lowerToBottom(window[options.serviceId]);
+			imageryLayers.raise(window[options.serviceId]);
+		}
+
+		//标注置顶
+		if (options.layertype === '标注') {
+			imageryLayers.raiseToTop(window[options.serviceId]);
+		}
+	});
+}
+
+/**
+ * 移除分屏对比
+ */
+export function removeSplitScreen(viewer) {
+	let mapView1 = document.getElementById("cesiumContainer");
+	let mapView2 = document.getElementById("cesiumContainer2");
+
+	mapView1.className = "jt-map";
+	mapView2.style.display = "none";
+	mapView2.innerHTML = "";
+
+	if (viewer) {
+		viewer.entities.removeAll(); // 删除全部
+		viewer.imageryLayers.removeAll();
+		viewer.scene.primitives.removeAll(); //谨慎使用,可能删除不必要的primitive
+		viewer.destroy();
+	}
+}
+
+/**
+ * 地图绕点自旋
+ */
+export function setMapSpin(jt3d) {
+	//移除左键单击事件
+	if (jt3d.handlerLeftClick) {
+		jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
+	}
+
+	let SketchViewModel = new jt3dSDK.SketchViewModel(window.viewer, {
+		isClear: true,
+		isDrawPoint: false, //是否标记参考点
+		isRetainDrawPoint: false, //绘制完成是否保留绘制点
+		iconType: 'blue',
+	}, );
+
+	SketchViewModel.sketchTools('point', {
+		onComplete(cPoint, gPoint) {
+			jt3d.setMapSpinByPoint(cPoint, {
+				// height: 100000
+			});
+		},
+		onError(message) {}
+	});
+}
+
+/**
+ * 地图指北
+ */
+export function setMapNorth(jt3d) {
+	jt3d.setMapNorth();
+	jt3d.isSpan = false;
+}
+
+
+/**
+ * 移除卷帘
+ */
+export function removeSplitLayer(viewer, earthAtLeft, earthAtRight) {
+	let sliderDiv = document.getElementById("image_slider");
+	if (sliderDiv) {
+		document.body.removeChild(sliderDiv);
+	}
+	removeSplitLayerLeft(viewer, earthAtLeft);
+	removeSplitLayerRight(viewer, earthAtRight);
+
+	if (earthAtLeft) {
+		earthAtLeft.splitDirection = Cesium.SplitDirection.NONE;
+	}
+
+	if (earthAtRight) {
+		earthAtRight.splitDirection = Cesium.SplitDirection.NONE;
+	}
+}
+/**
+ * 移除左侧图层
+ */
+export function removeSplitLayerLeft(viewer, leftValue) {
+	setLayersControl(viewer, leftValue, false);
+
+	// if (earthAtLeft) {
+	// 	if (earthAtLeft instanceof Cesium.ImageryLayer) {
+	// 		viewer.imageryLayers.remove(earthAtLeft);
+	// 	}
+
+	// 	if (earthAtLeft instanceof Cesium.Cesium3DTileset) {
+	// 		viewer.scene.primitives.remove(earthAtLeft);
+	// 	}
+
+	// 	if (earthAtLeft instanceof Array) {
+	// 		earthAtLeft.forEach((res, index) => {
+	// 			viewer.scene.primitives.remove(res);
+	// 		})
+	// 	}
+	// }
+}
+/**
+ * 移除右侧图层
+ */
+export function removeSplitLayerRight(viewer, rightValue) {
+	setLayersControl(viewer, rightValue, false);
+	// if (earthAtRight) {
+	// 	if (earthAtRight instanceof Cesium.ImageryLayer) {
+	// 		viewer.imageryLayers.remove(earthAtRight);
+	// 	}
+
+	// 	if (earthAtRight instanceof Cesium.Cesium3DTileset) {
+	// 		viewer.scene.primitives.remove(earthAtRight);
+	// 	}
+
+	// 	if (earthAtRight instanceof Array) {
+	// 		earthAtRight.forEach((res, index) => {
+	// 			viewer.scene.primitives.remove(res);
+	// 		});
+	// 	}
+	// }
+}

+ 42 - 0
src/views/Map3d - 副本 (3)/widget.vue

@@ -0,0 +1,42 @@
+<template>
+  <component :is="widget.component" v-bind="getWidgetAttr(widget)" />
+</template>
+<script lang="ts">
+import { useAttrs, defineComponent, provide } from "vue"
+import type { Widget } from "@/common/store/widget"
+
+export default defineComponent({
+  name: "jt-widget",
+  props: ["widget"],
+  setup(props) {
+    const attrs = useAttrs()
+
+    provide("getCurrentWidget", () => {
+      return props.widget.name
+    })
+
+    const getWidgetAttr = (widget: Widget) => {
+      let attr = {}
+      if (widget.meta && widget.meta.props) {
+        attr = {
+          ...attr,
+          ...widget.meta.props
+        }
+      }
+      if (widget.data && widget.data.props) {
+        attr = {
+          ...attr,
+          ...widget.data.props
+        }
+      }
+      return attr
+    }
+
+    return {
+      attrs,
+      getWidgetAttr
+    }
+  }
+})
+</script>
+

+ 474 - 0
src/views/Map3d - 副本/Map3DMain - 副本.vue

@@ -0,0 +1,474 @@
+<script setup>
+	/**
+	 * 业务组件,在components中进行注册
+	 */
+	//组件异步加载
+	import {
+		defineAsyncComponent
+	} from 'vue';
+	// const TrackRoam = defineAsyncComponent(() => import('./components/TrackRoam.vue'));
+	// const ImageLayerSplit = defineAsyncComponent(() => import('./components/ImageLayerSplit.vue'));
+	// const ViewerSplitScreen = defineAsyncComponent(() => import('./components/ViewerSplitScreen.vue'));
+	// const viewerlabel = defineAsyncComponent(() => import('./components/viewerlabel.vue'));
+	// const printmap = defineAsyncComponent(() => import('./components/printmap.vue'));
+	// const dialogEdit = defineAsyncComponent(() => import('./components/drawEdit.vue'));
+	// const queryResult = defineAsyncComponent(() => import('./components/queryResult.vue'));
+	// const analysisSpace = defineAsyncComponent(() => import('./components/analysis-space.vue'));
+	// const analysisTerrain = defineAsyncComponent(() => import('./components/analysis-terrain.vue'));
+	// const analysisData = defineAsyncComponent(() => import('./components/analysis-data.vue'));
+	// const layer = defineAsyncComponent(() => import('./components/layer.vue'));
+	// const measure = defineAsyncComponent(() => import('./components/measure.vue'));
+	// const queryGraphics = defineAsyncComponent(() => import('./components/query-graphics.vue'));
+	// const SpecialEffects = defineAsyncComponent(() => import('./components/special-effects.vue'));
+	// const coordsTool = defineAsyncComponent(() => import('./components/coordsTool.vue'));
+	// const basicLayer = defineAsyncComponent(() => import('./components/basicLayer.vue'));
+	// const queryKeyword = defineAsyncComponent(() => import('./components/query-keyword.vue'));
+	// const toolbars = defineAsyncComponent(() => import('./components/toolbars.vue'));
+	// const map3d = defineAsyncComponent(() => import('./components/map.vue'));
+
+	// const navigation = defineAsyncComponent(() => import('./components/navigation.vue'));
+	// import map3d from './components/map.vue';
+	// import queryKeyword from './components/query-keyword.vue';
+	// import toolbars from './components/toolbars.vue';
+	// import layer from './components/layer.vue';
+	// import measure from './components/measure.vue';
+	// import queryGraphics from './components/query-graphics.vue';
+	// import SpecialEffects from './components/special-effects.vue';
+	// import coordsTool from './components/coordsTool.vue';
+	// import basicLayer from './components/basicLayer.vue'
+	// import analysisSpace from './components/analysis-space.vue';
+	// import analysisTerrain from './components/analysis-terrain.vue';
+	// import analysisData from './components/analysis-data.vue';
+	// import mapNavigate from './components/mapNavigate.vue';
+	// import TrackRoam from './components/TrackRoam.vue';
+	// import ImageLayerSplit from './components/ImageLayerSplit.vue';
+	// import ViewerSplitScreen from './components/ViewerSplitScreen.vue';
+	// import viewerlabel from './components/viewerlabel.vue';
+	// import printmap from './components/printmap.vue';
+	// import dialogEdit from "./components/drawEdit.vue";
+	// import queryResult from "./components/queryResult.vue";
+
+
+	import {
+		Store
+	} from '@/store/index'
+	store = Store()
+
+	/**
+	 * 通过provide/inject可以轻松实现跨级访问父组件的数据
+	 * provide和inject是成对出现的
+	 * 必须放在setup内
+	 * 简单的来说就是在父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量
+	 * provide 和 inject 绑定并不是可响应的。这是刻意为之的。
+	 * 代码执行顺序data->provide->created->mounted
+	 */
+	import {
+		provide
+	} from "vue";
+	provide("getMapInstance", () => {
+		return jt3d;
+	});
+</script>
+
+<template>
+	<div class="jt-mapMain">
+
+		<!-- 地图组件 -->
+		<map3d @onload="jtMap3DOnload" ref="refMap3d" />
+
+		<!-- 地图加载完成后,在加载其他组件 -->
+		<template v-if="mapLoaded">
+			<!-- 底图组件 -->
+			<basicLayer v-show="showbasicLayer" ref="basicLayers"></basicLayer>
+
+			<!-- 弹出框组件,tabs组件测试 -->
+			<jt-popup title="地区导航" ref="refmapNavigate" :isEmit="true" @closeJTPopup="closeMapNavigate">
+				<mapNavigate ref="_refmapNavigate"></mapNavigate>
+			</jt-popup>
+
+			<!-- 关键字查询组件 -->
+			<queryKeyword ref="queryword" />
+
+			<!-- 比例尺、指南针 -->
+			<navigation ref="refNavigation" />
+
+			<!-- 视角标签 -->
+			<jt-popup title="视角标签" ref="refviewerlabel">
+				<viewerlabel ref="_refviewerlabel"></viewerlabel>
+			</jt-popup>
+
+			<!-- 打印地图 -->
+			<jt-popup :showfooter="isshowfooter" longheader="1" right="calc(50% - 480rem)" width="960rem" top="calc(50% - 270rem)" height="600rem" title="打印地图" ref="refprintmap">
+				<printmap ref="_refprintmap"></printmap>
+			</jt-popup>
+
+			<!-- 工具栏组件 -->
+			<toolbars />
+
+			<!-- 图上量算组件 -->
+			<jt-popup title="图上量算" ref="refMeasure" :isEmit="true" @closeJTPopup="closeMeasure">
+				<measure ref="_refMeasure" />
+			</jt-popup>
+
+			<!-- 数据分析组件 -->
+			<jt-popup title="数据分析" ref="refAnalysisData">
+				<analysisData />
+			</jt-popup>
+
+			<!-- 空间分析组件 -->
+			<jt-popup title="空间分析" ref="refAnalysisSpace">
+				<analysisSpace />
+			</jt-popup>
+
+			<!-- 剖面分析结果组件 -->
+			<jt-drawer ref="refDrawerSectionAnalysis" title="剖面分析结果" direction="btt" size="30vh" @closeJTDrawer="closeDrawerSectionAnalysis">
+				<jt-charts id="sectionAnalysisChart" width='98vw' height="20vh" :option='ChartTestData' />
+			</jt-drawer>
+
+			<!-- 图形查询组件 -->
+			<jt-popup title="图形查询" ref="refQueryGraphics" :isEmit="true" @closeJTPopup="closeQuery">
+				<queryGraphics ref="_refQueryGraphics" />
+			</jt-popup>
+
+			<!-- 特效组件 -->
+			<jt-popup title="特效效果" ref="refSpecialEffects">
+				<SpecialEffects />
+			</jt-popup>
+
+			<!-- 坐标定位拾取组件 -->
+			<jt-popup title="坐标定位拾取" ref="refCoordsTool">
+				<coordsTool />
+			</jt-popup>
+
+			<!-- 地形分析组件 -->
+			<jt-popup title="地形分析" ref="refAnalysisTerrain" :isEmit="true" @closeJTPopup="closeAnalysisTerrain">
+				<analysisTerrain ref="_refAnalysisTerrain" />
+			</jt-popup>
+
+			<!-- 跟踪漫游组件 -->
+			<jt-popup minWidth="294rem" title="跟踪漫游" ref="refTrackRoam">
+				<TrackRoam />
+			</jt-popup>
+
+			<!-- 卷帘对比组件 -->
+			<jt-popup :showfooter="isshowfooter" height="150rem" width="520rem" title="卷帘对比" ref="refImageLayerSplit" :isEmit="true" @closeJTPopup="closeImageLayerSplit">
+				<ImageLayerSplit ref="_refImageLayerSplit" />
+			</jt-popup>
+
+			<!-- 分屏对比组件 -->
+			<jt-popup title="分屏对比" animationClass="fadein-left" ref="refViewerSplitScreen" :isEmit="true" @closeJTPopup="closeViewerSplitScreen">
+				<ViewerSplitScreen ref="_refViewerSplitScreen" />
+			</jt-popup>
+
+			<!-- 图层控jt-popup制组件 -->
+			<jt-popup title="图层控制" ref="refLayerPopup">
+				<layer ref="refLayer" />
+			</jt-popup>
+
+			<!--图上标绘组件-->
+			<jt-popup title="图上标绘" ref="refDialogEdit">
+				<dialogEdit />
+			</jt-popup>
+
+			<!-- 查询结果 -->
+			<jt-popup :showfooter='isshowfooter' animationClass="fadein-left" height="400rem" width="800rem" title="信息展示" ref="refQueryResultPopup" :isEmit="true" @closeJTPopup="closeQueryResult">
+				<queryResult ref="refQueryResult" />
+			</jt-popup>
+
+			<!-- <video id="trailer" style="display: none;"  autoplay loop crossorigin controls>
+				<source src="@/assets/dataFile/jt.mp4" type="video/mp4">
+			</video> -->
+
+		</template>
+	</div>
+</template>
+
+<script>
+	import * as echarts from "echarts";
+	let store = undefined
+	let jt3d = undefined;
+	let tipEntity = undefined;
+
+	export default {
+		name: "Map3DMain",
+
+		/**
+		 *  数据 
+		 */
+		data() {
+			return {
+				isshowfooter: false,
+				mapLoaded: false,
+				showbasicLayer: false, //控制地图组件显示隐藏
+				ChartTestData: {}, //剖面分析结果chart
+			}
+		},
+
+		/**
+		 *  方法 
+		 */
+		methods: {
+
+			/**
+			 * 关闭分屏对比
+			 */
+			closeViewerSplitScreen() {
+				this.$refs._refViewerSplitScreen.removeSplitScreen();
+			},
+
+			/**
+			 * 关闭卷帘对比
+			 */
+			closeImageLayerSplit() {
+				this.$refs._refImageLayerSplit.removeSplitLayer();
+			},
+
+			/**
+			 * 关闭地形分析弹窗
+			 */
+			closeAnalysisTerrain() {
+				//工具初始化
+				this.$refs._refAnalysisTerrain.init();
+				//还原左键单击事件
+				this.$refs.refMap3d.clickEntity(jt3d);
+				window["viewer"].scene.screenSpaceCameraController.enableCollisionDetection = true; //相机与地形的碰撞检测
+			},
+
+			/**
+			 * 关闭地区导航
+			 */
+			closeMapNavigate() {
+				this.$refs._refmapNavigate.remove();
+			},
+
+			/**
+			 * 清除测量结果
+			 */
+			closeMeasure() {
+				this.$refs._refMeasure.clearMeasurementData();
+			},
+
+			/**
+			 * 清除查询结果
+			 */
+			closeQuery() {
+				this.$refs._refQueryGraphics.clearQuery();
+			},
+
+			/**
+			 * 关闭查询结果
+			 */
+			closeQueryResult() {
+				//清除高亮显示
+				let list = jt3d._dataSources.getByName("单击高亮显示")
+				list.forEach(res => {
+					jt3d._dataSources.remove(res)
+				})
+
+				//清除定位样式
+				if (jt3d.LocateUtil._locationEntity) {
+					window["viewer"].entities.remove(jt3d.LocateUtil._locationEntity);
+				}
+			},
+
+			/**
+			 * 关闭剖面分析结果
+			 */
+			closeDrawerSectionAnalysis() {
+				this.$refs.refDrawerSectionAnalysis.drawerVisible = false;
+
+				if (tipEntity) {
+					window.viewer.entities.remove(tipEntity);
+					tipEntity = undefined;
+				}
+				jt3d.SpatialAnalysis.Profile.removeProfileAnalysis();
+				jt3d.DrawTools.Clear();
+
+				//还原左键单击事件
+				this.$refs.refMap3d.clickEntity(jt3d);
+			},
+
+			/**
+			 * 构建剖面分析结果chart
+			 */
+			initEchartsData(sectionAnalysisData) {
+				if (tipEntity) {
+					window.viewer.entities.remove(tipEntity);
+					tipEntity = undefined;
+				}
+				// jt3d.SpatialAnalysis.Profile.removeProfileAnalysis();
+
+				let datas = [],
+					coords = [];
+				let pointsData = sectionAnalysisData;
+
+				let maxDistance = pointsData[pointsData.length - 1].distance;
+				let xAixMax = Math.ceil(maxDistance);
+				for (let index = 0; index < pointsData.length; index++) {
+					let element = pointsData[index];
+					let curData = [
+						parseFloat(element.distance.toFixed(2)),
+						parseFloat(element.position.height.toFixed(2))
+					];
+					datas.push(curData);
+					let curCoords = [element.position.lon, element.position.lat];
+					coords.push(curCoords);
+				}
+
+				let ChartTestData = {
+					tooltip: {
+						show: true,
+						trigger: 'item',
+						formatter(params) {
+							let xy = coords[params.dataIndex];
+							let tipData = params["data"];
+							if (params.name === "Max" || params.name === "Min") {
+								tipData = params["data"].coord;
+							}
+
+							if (!tipEntity) {
+								tipEntity = window.viewer.entities.add({
+									position: Cesium.Cartesian3.fromDegrees(xy[0], xy[1], Number(tipData[1])),
+									billboard: {
+										image: 'jt3dSDK/imgs/point/point.png',
+										horizontalOrigin: Cesium.HorizontalOrigin.center,
+										verticalOrigin: Cesium.VerticalOrigin.bottom,
+										scale: 1,
+										pixelOffset: new Cesium.Cartesian2(0, 0),
+										disableDepthTestDistance: Number.POSITIVE_INFINITY,
+									},
+								});
+							} else {
+								tipEntity.position = Cesium.Cartesian3.fromDegrees(xy[0], xy[1], Number(tipData[1]));
+							}
+
+							//定位到点
+							// jt3d.LocateUtil.flyToPoint({
+							// 	longitude: xy[0],
+							// 	latitude: xy[1],
+							// 	height: Number(tipData[1])
+							// });
+
+							return "距离:" + tipData[0] + "m<br>" + "高度:" + tipData[1] + "m<br>" + "坐标:" + xy[0].toFixed(
+								5) + "," + xy[1].toFixed(5);
+						}
+					},
+					grid: {
+						bottom: '10%',
+						left: '5%',
+						right: '5%',
+					},
+					xAxis: {
+						type: "value",
+						max: xAixMax,
+						axisLabel: { //文字属性
+							textStyle: {
+								color: 'rgb(216 240 255)'
+							},
+							formatter: '{value} m'
+						},
+						axisLine: { //轴线属性
+							lineStyle: {
+								color: 'rgb(216 240 255)',
+								width: 2
+							},
+						},
+						splitLine: { //分割线属性
+							lineStyle: {
+								type: 'dashed'
+							}
+						}
+					},
+					yAxis: {
+						type: "value",
+						axisLabel: { //文字属性
+							textStyle: {
+								color: 'rgb(216 240 255)'
+							},
+							formatter: '{value} m'
+						},
+						axisLine: { //轴线属性
+							lineStyle: {
+								color: 'rgb(216 240 255)',
+								width: 2
+							},
+						},
+						splitLine: { //分割线属性
+							lineStyle: {
+								type: 'dashed'
+							}
+						}
+					},
+					series: [{
+						type: "line",
+						data: datas,
+						markPoint: {
+							symbol: 'path://m 0,0 h 48 v 20 h -30 l -6,10 l -6,-10 h -6 z', // 'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow', path://m 0,0 h 48 v 20 h -30 l -6,10 l -6,-10 h -6 z,  path://m 0,0 h 48 v 20 h -34 l -6,10 l -6,-10 h -2 z
+							symbolSize: [60, 60], // 容器大小
+							symbolOffset: ['34%', '-50%'], //位置偏移
+							symbolKeepAspect: true, // 如果 symbol 是 path:// 的形式,是否在缩放时保持该图形的长宽比。
+							label: {
+								textStyle: {
+									color: 'rgb(216,240,255)'
+								},
+								position: "insideTop",
+								distance: 7,
+							},
+							data: [{
+									type: 'max',
+									name: '最大值',
+									itemStyle: { //背景色
+										color: 'rgb(255, 70, 131)',
+									}
+								},
+								{
+									type: 'min',
+									name: '最小值',
+									itemStyle: { //背景色
+										color: 'rgb(255, 70, 131)',
+									}
+								}
+							]
+						},
+						itemStyle: {
+							color: 'rgba(85,254,139,1)',
+						},
+						areaStyle: {
+							color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+									offset: 0,
+									color: 'rgba(85,254,139,0.8)'
+								},
+								{
+									offset: 1,
+									color: 'rgba(14,245,210,0.2)'
+								}
+							])
+						},
+					}]
+				};
+				this.ChartTestData = ChartTestData;
+			},
+
+			/**
+			 * 地图初始化
+			 * @param {Object} map
+			 */
+			jtMap3DOnload(map) {
+				jt3d = map;
+				this.mapLoaded = true;
+			},
+
+
+
+		},
+		created() {
+			store.queryMapTables = []
+		},
+		mounted() {
+
+		}
+	};
+</script>
+<style lang="scss" scoped>
+
+</style>

+ 433 - 0
src/views/Map3d - 副本/Map3DMain.vue

@@ -0,0 +1,433 @@
+<script setup>
+	/**
+	 * 业务组件,在components中进行注册
+	 */
+	//组件异步加载
+	import {
+		defineAsyncComponent
+	} from 'vue';
+	// const TrackRoam = defineAsyncComponent(() => import('./components/TrackRoam.vue'));
+	// const ImageLayerSplit = defineAsyncComponent(() => import('./components/ImageLayerSplit.vue'));
+	// const ViewerSplitScreen = defineAsyncComponent(() => import('./components/ViewerSplitScreen.vue'));
+	// const viewerlabel = defineAsyncComponent(() => import('./components/viewerlabel.vue'));
+	// const printmap = defineAsyncComponent(() => import('./components/printmap.vue'));
+	// const dialogEdit = defineAsyncComponent(() => import('./components/drawEdit.vue'));
+	// const queryResult = defineAsyncComponent(() => import('./components/queryResult.vue'));
+	// const analysisSpace = defineAsyncComponent(() => import('./components/analysis-space.vue'));
+	// const analysisTerrain = defineAsyncComponent(() => import('./components/analysis-terrain.vue'));
+	// const analysisData = defineAsyncComponent(() => import('./components/analysis-data.vue'));
+	// const layer = defineAsyncComponent(() => import('./components/layer.vue'));
+	// const measure = defineAsyncComponent(() => import('./components/measure.vue'));
+	// const queryGraphics = defineAsyncComponent(() => import('./components/query-graphics.vue'));
+	// const SpecialEffects = defineAsyncComponent(() => import('./components/special-effects.vue'));
+	// const coordsTool = defineAsyncComponent(() => import('./components/coordsTool.vue'));
+	// const basicLayer = defineAsyncComponent(() => import('./components/basicLayer.vue'));
+	// const queryKeyword = defineAsyncComponent(() => import('./components/query-keyword.vue'));
+	// const toolbars = defineAsyncComponent(() => import('./components/toolbars.vue'));
+	// const map3d = defineAsyncComponent(() => import('./components/map.vue'));
+
+
+	import map3d from './components/map.vue';
+	const navigation = defineAsyncComponent(() => import('./components/navigation.vue'));
+	import queryKeyword from './components/query-keyword.vue';
+	import toolbars from './components/toolbars.vue';
+
+	// import layer from './components/layer.vue';
+	// import measure from './components/measure.vue';
+	// import queryGraphics from './components/query-graphics.vue';
+	// import SpecialEffects from './components/special-effects.vue';
+	// import coordsTool from './components/coordsTool.vue';
+	// import basicLayer from './components/basicLayer.vue'
+	// import analysisSpace from './components/analysis-space.vue';
+	// import analysisTerrain from './components/analysis-terrain.vue';
+	// import analysisData from './components/analysis-data.vue';
+	// import mapNavigate from './components/mapNavigate.vue';
+	// import TrackRoam from './components/TrackRoam.vue';
+	// import ImageLayerSplit from './components/ImageLayerSplit.vue';
+	// import ViewerSplitScreen from './components/ViewerSplitScreen.vue';
+	// import viewerlabel from './components/viewerlabel.vue';
+	// import printmap from './components/printmap.vue';
+	// import dialogEdit from "./components/drawEdit.vue";
+	// import queryResult from "./components/queryResult.vue";
+
+
+	import {
+		Store
+	} from '@/store/index'
+	store = Store()
+
+	/**
+	 * 通过provide/inject可以轻松实现跨级访问父组件的数据
+	 * provide和inject是成对出现的
+	 * 必须放在setup内
+	 * 简单的来说就是在父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量
+	 * provide 和 inject 绑定并不是可响应的。这是刻意为之的。
+	 * 代码执行顺序data->provide->created->mounted
+	 */
+	import {
+		provide
+	} from "vue";
+	provide("getMapInstance", () => {
+		return jt3d;
+	});
+</script>
+
+<template>
+	<div class="jt-mapMain">
+
+		<!-- 地图组件 -->
+		<map3d @onload="jtMap3DOnload" ref="refMap3d" />
+
+		<!-- 地图加载完成后,在加载其他组件 -->
+		<template v-if="mapLoaded">
+			<!-- 比例尺、指南针 -->
+			<navigation ref="refNavigation" />
+
+			<!-- 关键字查询组件 -->
+			<queryKeyword ref="queryword" />
+
+			<!-- 工具栏组件 -->
+			<toolbars />
+
+		</template>
+	</div>
+</template>
+
+<script>
+	import * as echarts from "echarts";
+	let store = undefined
+	let jt3d = undefined;
+	let tipEntity = undefined;
+
+	export default {
+		name: "Map3DMain",
+
+		/**
+		 *  数据 
+		 */
+		data() {
+			return {
+				isshowfooter: false,
+				mapLoaded: false,
+				showbasicLayer: false, //控制地图组件显示隐藏
+				ChartTestData: {}, //剖面分析结果chart
+				toolDatas: [{
+						name: "底图",
+						icon: "iconfont icon-dituzuobiao",
+						widget: "basicLayer",
+						component: "./components/basicLayer.vue"
+					},
+					{
+						name: "图层",
+						icon: "iconfont icon-winfo-icon-tucengkongzhi",
+						widget: "layers",
+						component: "./components/layer.vue"
+					},
+				]
+			}
+		},
+
+		/**
+		 *  方法 
+		 */
+		methods: {
+
+			/**
+			 * 关闭分屏对比
+			 */
+			closeViewerSplitScreen() {
+				this.$refs._refViewerSplitScreen.removeSplitScreen();
+			},
+
+			/**
+			 * 关闭卷帘对比
+			 */
+			closeImageLayerSplit() {
+				this.$refs._refImageLayerSplit.removeSplitLayer();
+			},
+
+			/**
+			 * 关闭地形分析弹窗
+			 */
+			closeAnalysisTerrain() {
+				//工具初始化
+				this.$refs._refAnalysisTerrain.init();
+				//还原左键单击事件
+				this.$refs.refMap3d.clickEntity(jt3d);
+				window["viewer"].scene.screenSpaceCameraController.enableCollisionDetection = true; //相机与地形的碰撞检测
+			},
+
+			/**
+			 * 关闭地区导航
+			 */
+			closeMapNavigate() {
+				this.$refs._refmapNavigate.remove();
+			},
+
+			/**
+			 * 清除测量结果
+			 */
+			closeMeasure() {
+				this.$refs._refMeasure.clearMeasurementData();
+			},
+
+			/**
+			 * 清除查询结果
+			 */
+			closeQuery() {
+				this.$refs._refQueryGraphics.clearQuery();
+			},
+
+			/**
+			 * 关闭查询结果
+			 */
+			closeQueryResult() {
+				//清除高亮显示
+				let list = jt3d._dataSources.getByName("单击高亮显示")
+				list.forEach(res => {
+					jt3d._dataSources.remove(res)
+				})
+
+				//清除定位样式
+				if (jt3d.LocateUtil._locationEntity) {
+					window["viewer"].entities.remove(jt3d.LocateUtil._locationEntity);
+				}
+			},
+
+			/**
+			 * 关闭剖面分析结果
+			 */
+			closeDrawerSectionAnalysis() {
+				this.$refs.refDrawerSectionAnalysis.drawerVisible = false;
+
+				if (tipEntity) {
+					window.viewer.entities.remove(tipEntity);
+					tipEntity = undefined;
+				}
+				jt3d.SpatialAnalysis.Profile.removeProfileAnalysis();
+				jt3d.DrawTools.Clear();
+
+				//还原左键单击事件
+				this.$refs.refMap3d.clickEntity(jt3d);
+			},
+
+			/**
+			 * 构建剖面分析结果chart
+			 */
+			initEchartsData(sectionAnalysisData) {
+				if (tipEntity) {
+					window.viewer.entities.remove(tipEntity);
+					tipEntity = undefined;
+				}
+				// jt3d.SpatialAnalysis.Profile.removeProfileAnalysis();
+
+				let datas = [],
+					coords = [];
+				let pointsData = sectionAnalysisData;
+
+				let maxDistance = pointsData[pointsData.length - 1].distance;
+				let xAixMax = Math.ceil(maxDistance);
+				for (let index = 0; index < pointsData.length; index++) {
+					let element = pointsData[index];
+					let curData = [
+						parseFloat(element.distance.toFixed(2)),
+						parseFloat(element.position.height.toFixed(2))
+					];
+					datas.push(curData);
+					let curCoords = [element.position.lon, element.position.lat];
+					coords.push(curCoords);
+				}
+
+				let ChartTestData = {
+					tooltip: {
+						show: true,
+						trigger: 'item',
+						formatter(params) {
+							let xy = coords[params.dataIndex];
+							let tipData = params["data"];
+							if (params.name === "Max" || params.name === "Min") {
+								tipData = params["data"].coord;
+							}
+
+							if (!tipEntity) {
+								tipEntity = window.viewer.entities.add({
+									position: Cesium.Cartesian3.fromDegrees(xy[0], xy[1], Number(tipData[1])),
+									billboard: {
+										image: 'jt3dSDK/imgs/point/point.png',
+										horizontalOrigin: Cesium.HorizontalOrigin.center,
+										verticalOrigin: Cesium.VerticalOrigin.bottom,
+										scale: 1,
+										pixelOffset: new Cesium.Cartesian2(0, 0),
+										disableDepthTestDistance: Number.POSITIVE_INFINITY,
+									},
+								});
+							} else {
+								tipEntity.position = Cesium.Cartesian3.fromDegrees(xy[0], xy[1], Number(tipData[1]));
+							}
+
+							//定位到点
+							// jt3d.LocateUtil.flyToPoint({
+							// 	longitude: xy[0],
+							// 	latitude: xy[1],
+							// 	height: Number(tipData[1])
+							// });
+
+							return "距离:" + tipData[0] + "m<br>" + "高度:" + tipData[1] + "m<br>" + "坐标:" + xy[0].toFixed(
+								5) + "," + xy[1].toFixed(5);
+						}
+					},
+					grid: {
+						bottom: '10%',
+						left: '5%',
+						right: '5%',
+					},
+					xAxis: {
+						type: "value",
+						max: xAixMax,
+						axisLabel: { //文字属性
+							textStyle: {
+								color: 'rgb(216 240 255)'
+							},
+							formatter: '{value} m'
+						},
+						axisLine: { //轴线属性
+							lineStyle: {
+								color: 'rgb(216 240 255)',
+								width: 2
+							},
+						},
+						splitLine: { //分割线属性
+							lineStyle: {
+								type: 'dashed'
+							}
+						}
+					},
+					yAxis: {
+						type: "value",
+						axisLabel: { //文字属性
+							textStyle: {
+								color: 'rgb(216 240 255)'
+							},
+							formatter: '{value} m'
+						},
+						axisLine: { //轴线属性
+							lineStyle: {
+								color: 'rgb(216 240 255)',
+								width: 2
+							},
+						},
+						splitLine: { //分割线属性
+							lineStyle: {
+								type: 'dashed'
+							}
+						}
+					},
+					series: [{
+						type: "line",
+						data: datas,
+						markPoint: {
+							symbol: 'path://m 0,0 h 48 v 20 h -30 l -6,10 l -6,-10 h -6 z', // 'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow', path://m 0,0 h 48 v 20 h -30 l -6,10 l -6,-10 h -6 z,  path://m 0,0 h 48 v 20 h -34 l -6,10 l -6,-10 h -2 z
+							symbolSize: [60, 60], // 容器大小
+							symbolOffset: ['34%', '-50%'], //位置偏移
+							symbolKeepAspect: true, // 如果 symbol 是 path:// 的形式,是否在缩放时保持该图形的长宽比。
+							label: {
+								textStyle: {
+									color: 'rgb(216,240,255)'
+								},
+								position: "insideTop",
+								distance: 7,
+							},
+							data: [{
+									type: 'max',
+									name: '最大值',
+									itemStyle: { //背景色
+										color: 'rgb(255, 70, 131)',
+									}
+								},
+								{
+									type: 'min',
+									name: '最小值',
+									itemStyle: { //背景色
+										color: 'rgb(255, 70, 131)',
+									}
+								}
+							]
+						},
+						itemStyle: {
+							color: 'rgba(85,254,139,1)',
+						},
+						areaStyle: {
+							color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+									offset: 0,
+									color: 'rgba(85,254,139,0.8)'
+								},
+								{
+									offset: 1,
+									color: 'rgba(14,245,210,0.2)'
+								}
+							])
+						},
+					}]
+				};
+				this.ChartTestData = ChartTestData;
+			},
+
+			/**
+			 * 地图初始化
+			 * @param {Object} map
+			 */
+			jtMap3DOnload(map) {
+				jt3d = map;
+				this.mapLoaded = true;
+			},
+
+
+
+		},
+		created() {
+			store.queryMapTables = []
+		},
+		mounted() {
+			// 使用闭包实现单例模式
+			var OldCase; 
+			// 接收name和opts,name是组件名,opts是传过去的值
+			Vue.prototype.$myPop = (name, opts) => {
+				// 从json表中获取所有配置参数
+				// let myComponents = this.toolDatas.components;
+				// 遍历json表,寻找相应的组件
+				this.toolDatas.forEach((item) => {
+					if (item.widget === name) {
+						// 导入组件
+						// let myCom = import('./components/' + item.componentsName + '.vue');
+						let myCom = import(item.components);
+						myCom.then(res => {
+							// 生成一个Vue的子类
+							let MyTpl = Vue.extend(res.default);
+							// 生成一个该子类的实例
+							let NewCase = new MyTpl().$mount()
+							// 如果还没有任何实例就使用新实例
+							if (OldCase === undefined) {
+								OldCase = NewCase;
+							// 如果已经有实例,就清除旧的实例,再使用新的实例
+							} else if (OldCase.$options.name !== NewCase.$options.name) {
+								document.body.removeChild(OldCase.$el);
+								OldCase = NewCase;
+							}
+							// 将此div加入全局挂载点内部
+							document.body.appendChild(OldCase.$el);
+							// 把传进来的参数传过去组件中
+							Object.keys(opts).forEach(key => {
+								OldCase[key] = opts[key];
+							})
+						})
+			
+					}
+				})
+			
+			}
+		}
+	};
+</script>
+<style lang="scss" scoped>
+
+</style>

+ 0 - 0
src/views/Map3d/components/ImageLayerSplit.vue → src/views/Map3d - 副本/components/ImageLayerSplit.vue


+ 237 - 0
src/views/Map3d - 副本/components/TrackRoam.vue

@@ -0,0 +1,237 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-TrackRoam">
+
+		<el-row style="margin-bottom: 5px;">
+			<el-button type="danger" v-if="isNew" @click="drawLine()">
+				<el-icon>
+					<Plus />
+				</el-icon>新增漫游
+			</el-button>
+			<el-button type="danger" v-if="!isNew" @click="flightRoaming('remove')">
+				<el-icon>
+					<Delete />
+				</el-icon>
+				退出漫游
+			</el-button>
+		</el-row>
+
+		<el-row style="margin-bottom: 5px;" v-if="!isNew">
+
+			<el-button type="danger" v-if="isBackward" @click="flightRoaming('playReverse')">
+				<el-icon>
+					<Back />
+				</el-icon>向后飞行
+			</el-button>
+			<el-button type="danger" v-if="!isBackward" @click="flightRoaming('playForward')">
+				<el-icon>
+					<Right />
+				</el-icon>向前飞行
+			</el-button>
+
+			<el-button type="danger" v-if="isPause" @click="flightRoaming('pause')">
+				<el-icon>
+					<VideoPause />
+				</el-icon>暂停漫游
+			</el-button>
+			<el-button type="danger" v-if="!isPause" @click="flightRoaming('pause')">
+				<el-icon>
+					<VideoPlay />
+				</el-icon>继续漫游
+			</el-button>
+		</el-row>
+
+		<el-row style="margin-bottom: 5px;" v-if="!isNew">
+			<el-button type="danger" @click="flightRoaming(0)">
+				自由漫游
+			</el-button>
+			<el-button type="danger" @click="flightRoaming(1)">
+				相机跟随
+			</el-button>
+		</el-row>
+		<el-row style="margin-bottom: 5px;" v-if="!isNew">
+			<el-button type="danger" @click="flightRoaming(2)">
+				第一视角
+			</el-button>
+			<el-button type="danger" @click="flightRoaming(3)">
+				上帝视角
+			</el-button>
+		</el-row>
+
+		<el-form label-width="130rem">
+			<el-form-item label="飞行速度:" v-if="!isNew">
+				<el-slider v-model="roam.speed" @input="handleSpeedChange" :max="100" :min="1" :step="1" />
+			</el-form-item>
+			<el-form-item label="距离运动点的距离(后方):" v-if="roam.role===2">
+				<el-slider v-model="roam.followedX" @input="handleFollowedXChange" :max="10000" :min="1" :step="1" />
+			</el-form-item>
+			<el-form-item label="距离运动点的距离(上方):" v-if="roam.role===2">
+				<el-slider v-model="roam.followedZ" @input="handleFollowedZChange" :max="10000" :min="1" :step="1" />
+			</el-form-item>
+		</el-form>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+
+	export default {
+		data() {
+			return {
+				isNew: true,
+				isPause: true,
+				isBackward: true,
+				Roaming: undefined,
+
+				roam: {
+					role: 0,
+					speed: 10,
+					followedX: 50,
+					followedZ: 10
+				}
+			}
+		},
+
+		/* 方法 */
+		methods: {
+
+			handleFollowedXChange(followedX) {
+				this.Roaming.followedX = followedX;
+			},
+			handleFollowedZChange(followedZ) {
+				this.Roaming.followedZ = followedZ;
+			},
+
+			handleSpeedChange(speed) {
+				this.Roaming.ChangeRoamingSpeed(speed);
+			},
+
+			/**
+			 * 绘制飞行路线
+			 */
+			drawLine() {
+				let _self = this;
+
+				jt3d.DrawTools.draw('polyline', {
+					isEdit: false,
+					onComplete(cartesian3d, points) {
+						//清除绘制
+						jt3d.DrawTools.Clear();
+
+						_self.Roaming = new _self.jt3dSDK.Roaming(jt3d._viewer, cartesian3d, {
+							time: 360,
+							role: 2,
+							label: {
+								text: "lineName",
+							}
+						});
+						_self.isPause = true;
+						_self.isNew = false;
+						_self.roam.role = 2;
+						_self.Roaming.PauseOrContinue(_self.isPause);
+					}
+				});
+
+			},
+
+			/**
+			 * 飞行漫游
+			 * @param {Object} type
+			 */
+			flightRoaming(type) {
+
+				let _self = this;
+
+				switch (type) {
+					case "pause": //暂停飞行
+						this.isPause = !this.isPause;
+						this.Roaming.PauseOrContinue(this.isPause);
+						break;
+					case "playForward": //向前飞行
+						this.isPause = true;
+						this.isBackward = !this.isBackward;
+						this.Roaming.forwardFly();
+						break;
+					case "playReverse": //向后飞行
+						this.isPause = true;
+						this.isBackward = !this.isBackward;
+						this.Roaming.backwardsFly();
+						break;
+					case "remove": //向后飞行
+						this.isNew = true;
+						this.roam.role = Number(type);
+						this.Roaming.EndRoaming();
+						// //获取被clock监听的全部事件数量
+						// let len = jt3d._viewer.clock.onTick.numberOfListeners;
+						// for (let i = 0; i < len; i++) {
+						// 	//将被监听的方法移除来停止方法
+						// 	jt3d._viewer.clock.onTick.removeEventListener(jt3d._viewer.clock.onTick._listeners[i]);
+						// }
+						break;
+					case 0:
+						this.roam.role = Number(type);
+						this.Roaming.initRole(0);
+						break;
+					case 1:
+						this.roam.role = Number(type);
+						this.Roaming.initRole(1);
+						break;
+					case 2:
+						this.roam.role = Number(type);
+						this.Roaming.initRole(2);
+						break;
+					case 3:
+						this.roam.role = Number(type);
+						this.Roaming.initRole(3);
+						break;
+				}
+			},
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	::v-deep .el-table .cell {
+		line-height: 23rem !important;
+		padding: 0 12rem !important;
+		font-size: 14rem;
+	}
+
+	//整体样式
+	.jt-TrackRoam {
+		width: 90%;
+		margin-top: 16rem;
+		margin-left: 5%;
+		text-align: left;
+
+		--el-bg-color: rgb(0 44 126 / 60%);
+		--el-fill-color-blank: rgb(0 44 126 / 60%);
+		--el-text-color-secondary: rgb(216 240 255); //title
+		--el-text-color-regular: rgb(216 240 255); //内容
+		--el-fill-color-light: rgb(30 130 255);
+
+		.el-icon {
+			margin-right: 5rem;
+			color: #fff;
+		}
+	}
+</style>

+ 0 - 0
src/views/Map3d/components/ViewerSplitScreen.vue → src/views/Map3d - 副本/components/ViewerSplitScreen.vue


+ 220 - 0
src/views/Map3d - 副本/components/analysis-data.vue

@@ -0,0 +1,220 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-analysisData">
+		<el-collapse v-model="activeName" accordion>
+			<el-upload drag :auto-upload=false action="" accept="shp" :on-preview="handlePreview" :on-remove="handleRemove" :on-change="bind">
+				<i class="el-icon-upload"></i>
+				<div class="el-upload__text">将shp文件拖到此处,或<em>点击上传</em></div>
+
+				<!-- <div class="el-upload__tip" slot="tip">必须是shp文件</div> -->
+				<span>
+					<el-icon>
+						<WarnTriangleFilled />
+					</el-icon>必须是shp文件
+				</span>
+			</el-upload>
+			<!-- <el-button style="margin-left: 10rem;" size="small" type="success" @click="config">生成GeoJson数据</el-button> -->
+		</el-collapse>
+	</div>
+</template>
+
+<script>
+	import {
+		open
+	} from 'shapefile'
+
+	let jt3d = undefined;
+
+	export default {
+		props: {},
+		watch: {
+
+		},
+		name: "Config",
+		data() {
+			return {
+				file: {},
+				filelist: [],
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			/* shp文件解析生成图形 */
+			config() {
+				let _this = this
+				const name = this.file.name
+				const extension = name.split('.')[1]
+				console.log(extension)
+				if ('shp' !== extension) {
+					this.$alert('文件不是shp文件!请重新选择文件', {
+						confirmButtonText: '确定'
+					})
+				} else {
+					const reader = new FileReader()
+					const fileData = this.file.raw
+					reader.readAsArrayBuffer(fileData)
+					reader.onload = function(e) {
+						open(this.result).then(source => source.read().then(function log(result) {
+							if (result.done) return;
+							console.log(result)
+							console.log(result.value);
+
+							let promise = Cesium.GeoJsonDataSource.load(result.value, {
+								clampToGround: true
+							});
+							promise.then((dataSource) => {
+
+								window["viewer"].dataSources.add(dataSource); // 加载这个geojson资源
+								dataSource.name = name.split('.')[0];
+								console.log(dataSource)
+								const entities = dataSource.entities.values;
+								for (let index = 0; index < entities.length; index++) {
+									const entity = entities[index];
+									entity.polygon.material = Cesium.Color.fromBytes(50, 160, 255, 77)
+									entity.polygon.outlineWidth = 3;
+									entity.polygon.outline = false;
+									entity.polygon.outlineColor = Cesium.Color.RED;
+									entity.polyline = {
+										positions: entity.polygon.hierarchy._value.positions,
+										width: entity.polygon.outlineWidth,
+										material: Cesium.Color.fromBytes(0, 255, 180, 255),
+										clampToGround: true
+									}
+								}
+
+								let options = {};
+								// 初始化参数默认值
+								options.duration = Cesium.defaultValue(options.duration, 2);
+								options.heading = Cesium.defaultValue(options.heading, 0);
+								options.pitch = Cesium.defaultValue(options.pitch, -60);
+								options.range = Cesium.defaultValue(options.range, 0.0);
+								let flyPromise = window["viewer"].flyTo(entities, {
+									duration: options.duration,
+									offset: {
+										heading: Cesium.Math.toRadians(options.heading),
+										pitch: Cesium.Math.toRadians(options.pitch),
+										range: options.range
+									}
+								});
+
+							});
+
+							return source.read().then(log);
+
+						})).catch(error => console.error(error.stack));
+					}
+				}
+
+			},
+			remove() {
+
+			},
+
+			//移除
+			handleRemove(file, fileList) {
+
+				/* 清除图形 */
+				console.log(file, fileList);
+				let list = window["viewer"].dataSources.getByName(file.name.split('.')[0])
+				// for(let i=0;i<list.length;i++){
+				// 	console.log(list.length)
+				// 	window["viewer"].dataSources.remove(list[i])
+				// }
+				list.forEach(res => {
+					console.log(res)
+					window["viewer"].dataSources.remove(res)
+				})
+
+				// window["viewer"].dataSources.remove(window["viewer"].dataSources.getByName(file.name.split('.')[0]))
+
+			},
+
+			//定位
+			handlePreview(file) {
+				console.log(file)
+				this.file = file;
+				// this.config();
+
+				let list = window["viewer"].dataSources.getByName(file.name.split('.')[0])
+				list.forEach(res => {
+					const entities = res.entities.values;
+					
+					let options = {};
+					// 初始化参数默认值
+					options.duration = Cesium.defaultValue(options.duration, 2);
+					options.heading = Cesium.defaultValue(options.heading, 0);
+					options.pitch = Cesium.defaultValue(options.pitch, -60);
+					options.range = Cesium.defaultValue(options.range, 0.0);
+					let flyPromise = window["viewer"].flyTo(entities, {
+						duration: options.duration,
+						offset: {
+							heading: Cesium.Math.toRadians(options.heading),
+							pitch: Cesium.Math.toRadians(options.pitch),
+							range: options.range
+						}
+					});
+				})
+
+			},
+			bind(files, fileList) {
+				//绑定文件
+				this.file = fileList[fileList.length - 1]
+				//console.log(this.file)
+				this.config();
+			}
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.el-upload-dragger .el-upload__text{
+		font-size: 16rem;
+	}
+	
+	.upload_demo {
+		text-align: center;
+		margin-top: 50rem;
+	}
+
+	.el-button {
+		margin-top: 10rem;
+	}
+
+	::v-deep .el-upload-dragger {
+		padding: 0rem;
+		margin-top: 10rem;
+		color: #606266;
+		font-size: 12rem;
+
+	}
+
+	::v-deep .el-upload-list__item-name {
+		color: #fff;
+		margin-left: -21rem;
+	}
+
+	::v-deep .el-icon svg {
+		color: #409eff;
+		font-size: smaller;
+	}
+</style>

+ 517 - 0
src/views/Map3d - 副本/components/analysis-space.vue

@@ -0,0 +1,517 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-analysisSpace">
+		<el-collapse v-model="activeName" accordion>
+			<el-collapse-item name="光照分析">
+				<template #title>
+					<i class='iconfont icon-svgguangzhaofenxi' />光照分析
+				</template>
+				<div class="el-collapse-item__content">
+					<el-button color="rgb(20 136 255)" @click="SunShine('start')">开启光照分析</el-button>
+					<el-button color="rgb(255 100 100)" @click="SunShine('remove')"><span style="color: #fff;">移除光照分析</span></el-button>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="方量分析">
+				<template #title>
+					<i class='iconfont icon-svgfangliangfenxi' />方量分析
+				</template>
+				<div class="el-collapse-item__content">
+					<el-form label-width="100rem">
+						<el-form-item label="挖方填方高度:">
+							<el-input v-model="cutFill.height" />
+						</el-form-item>
+						<el-form-item label="挖方填方精度:">
+							<el-input v-model="cutFill.precision" />
+						</el-form-item>
+					</el-form>
+					<div class="jt-btn" style="margin: 10rem;">
+						<el-button color="rgb(255 100 100)" @click="CutFill('draw')"><span style="color: #fff;">绘制挖方填方区域</span></el-button>
+						<el-button color="rgb(255 100 100)" @click="CutFill('remove')"><span style="color: #fff;">清除分析结果</span></el-button>
+					</div>
+					<el-form label-width="120rem">
+						<el-form-item label="总分析面积(㎡):">
+							<el-input v-model="cutFill.result.allArea" />
+						</el-form-item>
+						<el-form-item label="填方面积(㎡):">
+							<el-input v-model="cutFill.result.fillArea" />
+						</el-form-item>
+						<el-form-item label="填方体积(m³):">
+							<el-input v-model="cutFill.result.fillVolume" />
+						</el-form-item>
+						<el-form-item label="挖方面积(㎡):">
+							<el-input v-model="cutFill.result.cutArea" />
+						</el-form-item>
+						<el-form-item label="挖方体积(m³):">
+							<el-input v-model="cutFill.result.cutVolume" />
+						</el-form-item>
+					</el-form>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="剖面分析">
+				<template #title>
+					<i class='iconfont icon-svgpoumianfenxi' />剖面分析
+				</template>
+				<div class="el-collapse-item__content">
+					<div style="line-height: 2em; table-layout: fixed; word-wrap: break-word; word-break: normal; text-align:justify; text-justify: inter-ideograph;color: #ffffff99;">
+						提示:单击【剖面分析】按钮触发,然后在实景三维或地形上左键单击开始,左键双击结束
+					</div>
+					<el-button color="rgb(20 136 255)" @click="SectionAnalysis">剖面分析</el-button>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="通视分析">
+				<template #title>
+					<i class='iconfont icon-svgtongshifenxi' />通视分析
+				</template>
+				<div class="el-collapse-item__content">
+					<div style="line-height: 2em; table-layout: fixed; word-wrap: break-word; word-break: normal; text-align:justify; text-justify: inter-ideograph;color: #ffffff99;">
+						提示:红色代表不可视,绿色代表可视;
+					</div>
+					<el-button color="rgb(20 136 255)" @click="SightLine('activate')">添加通视分析</el-button>
+					<el-button color="rgb(255 100 100)" @click="SightLine('deactivate')"><span style="color: #fff;">清除通视分析</span></el-button>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="视域分析">
+				<template #title>
+					<i class='iconfont icon-svgshiyufenxi' />视域分析
+				</template>
+				<div class="el-collapse-item__content">
+					<div style="line-height: 2em; table-layout: fixed; word-wrap: break-word; word-break: normal; text-align:justify; text-justify: inter-ideograph;color: #ffffff99;">
+						提示:点击“添加视域”按钮后在场景中点击两个点添加视域,红色代表不可视,绿色代表可视;
+					</div>
+					<el-button color="rgb(20 136 255)" @click="ViewShed('activate')">添加视域</el-button>
+					<el-button color="rgb(255 100 100)" @click="ViewShed('deactivate')"><span style="color: #fff;">清除视域</span></el-button>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="限高分析">
+				<template #title>
+					<i class='iconfont icon-svgxiangaofenxi' />限高分析
+				</template>
+				<div class="el-collapse-item__content">
+					<el-form ref="form" label-width="100rem" label-position="right" size="mini">
+						<el-form-item label="地表海拔:">
+							<span>{{heightLimit.baseHeight}}</span>米&nbsp;&nbsp;<el-button color="rgb(20 136 255)" @click="HeightLimit('pickUp')">图上选点</el-button>
+						</el-form-item>
+						<el-form-item label="限制高度:">
+							<el-slider v-model="heightLimit.height" :min="0" :max="300" :step="1" @input="changeHeight"></el-slider>
+						</el-form-item>
+						<el-form-item label="当前高度:">
+							{{heightLimit.height}}米
+						</el-form-item>
+					</el-form>
+					<div class="jt-btn" style="margin-bottom: 10rem;">
+						<el-button color="rgb(20 136 255)" @click="HeightLimit('activate')">绘制限高区域</el-button>
+						<el-button color="rgb(255 100 100)" @click="HeightLimit('deactivate')"><span style="color: #fff;">清除限高分析</span></el-button>
+					</div>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="剖切展示">
+				<template #title>
+					<i class='iconfont icon-svgpouqiezhanshi' />剖切展示
+				</template>
+				<div class="el-collapse-item__content">
+					<div style="line-height: 2em; table-layout: fixed; word-wrap: break-word; word-break: normal; text-align:justify; text-justify: inter-ideograph;color: #ffffff60;">
+						目前仅支持凸多边形,如果绘制的是凹多边形,可能裁剪结果不正确
+					</div>
+					<el-button color="rgb(20 136 255)" @click="Cutting('activate')">添加剖切多边形</el-button>
+				</div>
+			</el-collapse-item>
+			<!-- <el-collapse-item name="视频融合">
+				<template #title>
+					<i class='iconfont icon-svgshipinronghe' />视频融合
+				</template>
+				<div class="el-collapse-item__content">
+					<div style="line-height: 2em; table-layout: fixed; word-wrap: break-word; word-break: normal; text-align:justify; text-justify: inter-ideograph;color: #ffffff60;">
+						请先打开【牟平中心城实景三维】
+					</div>
+					<el-button color="rgb(20 136 255)" @click="PolygonHierarchy">视频融合</el-button>
+				</div>
+			</el-collapse-item> -->
+		</el-collapse>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+
+	export default {
+		props: {},
+		watch: {},
+
+		/* 数据 */
+		data() {
+			return {
+				activeName: "光照分析",
+
+				// 限高分析
+				heightLimit: {
+					height: 20,
+					baseHeight: 0,
+				},
+
+				//方量分析	
+				cutFill: {
+					height: 10, //挖方填方高度
+					precision: 1256, //挖方填方精度
+					result: { //挖方填方结果
+						allArea: "",
+						cutArea: "",
+						cutVolume: "",
+						fillArea: "",
+						fillVolume: "",
+					},
+				},
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			/**
+			 * 光照分析
+			 */
+			SunShine(type) {
+				let _self = this;
+				switch (type) {
+					case "start":
+						jt3d.statusBar.show = false;
+						jt3d.SpatialAnalysis.SunshineShadow.start();
+
+						break;
+					case "remove":
+						jt3d.statusBar.show = true;
+						jt3d.SpatialAnalysis.SunshineShadow.remove();
+						break;
+				}
+			},
+
+			/**
+			 * 方量分析
+			 */
+			CutFill(type) {
+				let _self = this;
+
+				//功能初始化
+				_self.init();
+
+				switch (type) {
+					case "draw":
+						jt3d.DrawTools.draw('polygon', {
+							isEdit: false,
+							onComplete(cartesian3d, points) {
+								//清除绘制
+								jt3d.DrawTools.Clear();
+
+								let pointsArray = [];
+								points.forEach((coordinate, index) => {
+									pointsArray.push([
+										coordinate.lng,
+										coordinate.lat,
+										coordinate.height
+									]);
+								});
+
+								jt3d.SpatialAnalysis.CutFill.createPolygonGeo(pointsArray, {
+									height: _self.height,
+									precision: _self.precision,
+								}).then(res => {
+									_self.cutFill.result = res;
+								});
+
+							}
+						});
+
+						break;
+					case "remove":
+						jt3d.SpatialAnalysis.CutFill.remove();
+						this.cutFill.result = {
+							allArea: "",
+							cutArea: "",
+							cutVolume: "",
+							fillArea: "",
+							fillVolume: "",
+						}
+
+						//还原左键单击事件
+						this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+						break;
+				}
+			},
+
+			/**
+			 * 视频融合
+			 */
+			PolygonHierarchy() {
+				let videoElement = document.getElementById('trailer');
+				var videopolygon = jt3d._viewer.entities.add({
+					polygon: {
+						height: 0.1,
+						hierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights([121.600444, 37.398272, 37.95, 121.600443, 37.398272, 33, 121.600443, 37.398341, 33, 121.600444, 37.398341, 37.95])),
+						material: videoElement,
+						perPositionHeight: true,
+					}
+				});
+
+				let flyToEntity = jt3d.LocateUtil.flyToEntity(videopolygon, {
+					heading: 90, //方向
+					pitch: -32, //倾斜角度
+					range: 72
+				});
+				flyToEntity.then(function(vehicleEntity) {
+					jt3d._viewer.trackedEntity = vehicleEntity; //获取或设置摄像机当前正在跟踪的Entity实例。
+					vehicleEntity.viewFrom = new Cesium.Cartesian3(0, 1, 0.3);
+				});
+			},
+
+			/**
+			 * 剖切分析
+			 */
+			Cutting(type) {
+				let _self = this;
+				//功能初始化
+				_self.init();
+
+				switch (type) {
+					case "activate":
+						if (window["my3dtiles"]) {
+							jt3d.DrawTools.draw('polygon', {
+								isEdit: false,
+								onComplete(cartesian3d, points) {
+									//清除绘制
+									jt3d.DrawTools.Clear();
+							
+									let pointsArray = [];
+									points.forEach((coordinate, index) => {
+										pointsArray.push([
+											coordinate.lng,
+											coordinate.lat,
+											coordinate.height
+										]);
+									});
+							
+									jt3d.SpatialAnalysis.Cutting.addTiles(window["my3dtiles"], pointsArray);
+							
+								}
+							});
+						} else {
+							ElMessage.error("请先勾选3D模型");
+						}
+						break;
+					case "deactivate":
+						//还原左键单击事件
+						this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+						break;
+				}
+			},
+
+			/**
+			 * 限高分析
+			 */
+			HeightLimit(type) {
+				let _self = this;
+				//功能初始化
+				_self.init();
+
+				switch (type) {
+					case "pickUp": //图上选点,获取地表高度
+						jt3d.CommonTools._sketchViewModel.sketchTools('point', {
+							onComplete(cPoint, gPoint) {
+								_self.heightLimit.baseHeight = Number(gPoint.height.toFixed(2));
+							},
+							onError(message) {
+								
+							}
+						});
+						break;
+					case "activate":
+						jt3d.DrawTools.draw('polygon', {
+							isEdit: false,
+							onComplete(cartesian3d, points) {
+								//清除绘制
+								// jt3d.DrawTools._entities.remove(jt3d.DrawTools._drawEntity.polygon);
+								jt3d.DrawTools.Clear();
+
+								let pointsArray = [];
+								points.forEach((coordinate, index) => {
+									pointsArray.push([
+										coordinate.lng,
+										coordinate.lat,
+										coordinate.height
+									]);
+								});
+
+								jt3d.SpatialAnalysis.HeightLimit.addPrimitive(pointsArray, {
+									height: _self.heightLimit.height,
+									baseHeight: _self.heightLimit.baseHeight,
+								});
+							}
+						});
+						break;
+					case "deactivate":
+						jt3d.SpatialAnalysis.HeightLimit.removePrimitive();
+						jt3d.CommonTools._sketchViewModel.sketchClear();
+						//还原左键单击事件
+						this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+						break;
+				}
+			},
+			changeHeight(val) {
+				jt3d.SpatialAnalysis.HeightLimit.changeHeight(val);
+			},
+
+			/**
+			 * 通视分析
+			 * @param {Object} type
+			 */
+			SightLine(type) {
+				let _self = this;
+				//功能初始化
+				_self.init();
+
+				switch (type) {
+					case "activate":
+						jt3d.SpatialAnalysis.SightLine.startSightLine();
+						break;
+					case "deactivate":
+						jt3d.SpatialAnalysis.SightLine.clearAll();
+						//还原左键单击事件
+						this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+						break;
+				}
+			},
+
+			/**
+			 * 视域分析
+			 */
+			ViewShed(type) {
+				let _self = this;
+				//功能初始化
+				_self.init();
+
+				switch (type) {
+					case "activate":
+						jt3d.SpatialAnalysis.ViewShed.createViewshed(10);
+						break;
+					case "deactivate":
+						jt3d.SpatialAnalysis.ViewShed.clearAll();
+						//还原左键单击事件
+						this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+						break;
+				}
+			},
+
+			/**
+			 * 剖面分析
+			 */
+			SectionAnalysis() {
+				let _self = this;
+				//功能初始化
+				_self.init();
+
+				jt3d.DrawTools.draw('polyline', {
+					isEdit: false,
+					onComplete(cartesian3d, points) {
+						let pointsArray = [];
+						points.forEach((coordinate, index) => {
+							pointsArray.push([
+								coordinate.lng,
+								coordinate.lat,
+								coordinate.height
+							]);
+						});
+
+						let ProfileAnalysis = jt3d.SpatialAnalysis.Profile.startProfileAnalysis(pointsArray, jt3d.DrawTools._drawEntity.polyline);
+						ProfileAnalysis.then(function(result) {
+							_self.$parent.$parent.$refs.refDrawerSectionAnalysis.drawerVisible = true;
+							_self.$parent.$parent.initEchartsData(result);
+						});
+
+					}
+				});
+			},
+
+			/**
+			 * 功能初始化
+			 */
+			init() {
+				//移除左键单击事件
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); //移除事件
+				}
+
+				jt3d.DrawTools.Clear();
+				jt3d.CommonTools._sketchViewModel.sketchClear();
+
+				jt3d.SpatialAnalysis.CutFill.remove(); //清除方量分析
+				jt3d.SpatialAnalysis.Profile.removeProfileAnalysis(); //移除剖面分析
+				jt3d.SpatialAnalysis.SightLine.clearAll(); //清除通视分析
+				jt3d.SpatialAnalysis.ViewShed.clearAll(); //清除视域分析
+				jt3d.SpatialAnalysis.HeightLimit.removePrimitive(); //清除限高分析		
+			}
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.jt-analysisSpace {
+		position: relative;
+
+		.iconfont {
+			padding: 0 10rem;
+		}
+
+		.el-collapse {
+			--el-collapse-border-color: rgb(0 44 126 / 0%);
+
+			--el-collapse-header-text-color: #ffffff;
+			--el-collapse-header-font-size: 13rem;
+			--el-collapse-content-bg-color: rgb(0 44 126 / 0%);
+			--el-collapse-content-font-size: 13rem;
+			--el-collapse-content-text-color: rgb(216 240 255);
+
+			--el-collapse-header-height: 40rem;
+			--el-collapse-header-bg-color: rgb(30 130 255);
+
+			--el-fill-color-blank: rgb(0 44 126 / 68%);
+			--el-text-color-regular: rgb(216 240 255);
+			--el-border-color: rgb(35 135 255);
+
+			.el-collapse-item__content {
+				padding: 10rem;
+				// padding-bottom: 0rem;
+			}
+		}
+	}
+
+	::v-deep .el-collapse-item__content {
+		padding: 10rem;
+		// padding-bottom: 0rem;
+		overflow-y: hidden;
+	}
+
+	::v-deep .el-collapse-item__header {
+		background: url(@/assets/images/bg_collapse_title.png) no-repeat;
+		background-size: 350rem 40rem;
+		// background-color: rgb(22 90 190);
+		// background-color: rgb(5 45 100 /60%);
+		background-color: rgb(30 130 255);
+		border-bottom: 0;
+	}
+</style>

+ 342 - 0
src/views/Map3d - 副本/components/analysis-terrain.vue

@@ -0,0 +1,342 @@
+<script setup>
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-analysisTerrain">
+		<el-collapse v-model="activeName" accordion>
+			<el-collapse-item name="地下模式">
+				<template #title>
+					<i class='iconfont icon-svgdixiamoshi' />地下模式
+				</template>
+				<div class="el-collapse-item__content">
+					<div style="line-height: 2em; table-layout: fixed; word-wrap: break-word; word-break: normal; text-align:justify; text-justify: inter-ideograph;color: #ffffff60;">
+						提示:可以透明地表,进入地下模式,可以看地下管网数据。
+					</div>
+					<el-form label-width="130rem">
+						<el-form-item label="地下模式开启状态:">
+							<el-switch v-model="underground.boolUnderground" active-text="已开启" inactive-text="已关闭" @change="handleUndergroundChange">
+							</el-switch>
+						</el-form-item>
+						<el-form-item label="地表透明度:">
+							<el-slider v-model="underground.alpha" :min="0" :max="1" :step="0.1" :disabled="!underground.boolUnderground" @input="handleAlphaChange">
+							</el-slider>
+						</el-form-item>
+					</el-form>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="地形开挖">
+				<template #title>
+					<i class='iconfont icon-svgdixingkaiwa' />地形开挖
+				</template>
+				<div class="el-collapse-item__content">
+					<el-form ref="form" label-width="100rem" label-position="right" size="mini">
+						<el-form-item label="开挖深度:">
+							<el-input v-model="terrainExcavation.excavateDepth" />
+						</el-form-item>
+					</el-form>
+					<div class="jt-btn" style="margin-bottom: 10rem;">
+						<el-button color="rgb(20 136 255)" @click="terrainExcavate('add')">绘制开挖区域</el-button>
+						<el-button color="rgb(255 100 100)" @click="terrainExcavate('remove')"><span style="color: #fff;">清除开挖分析</span></el-button>
+					</div>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="坡度分析">
+				<template #title>
+					<i class='iconfont icon-svgpodufenxi' />坡度分析
+				</template>
+				<div class="el-collapse-item__content">
+					<div class="jt-btn" style="margin-top: 10rem;">
+						<el-button color="rgb(20 136 255)" @click="SlopeAspect('Num')">坡度等分</el-button>
+						<el-button color="rgb(20 136 255)" @click="SlopeAspect('Distance')">坡度等距</el-button>
+						<el-button color="rgb(255 100 100)" @click="removeSlopeAspect"><span style="color: #fff;">移除</span></el-button>
+					</div>
+				</div>
+			</el-collapse-item>
+			<!-- <el-collapse-item name="深度检测">
+					<template #title>
+						<i class='iconfont icon-tianqizitiku43' />深度检测
+					</template>
+					<div class="el-collapse-item__content">
+						深度检测
+					</div>
+				</el-collapse-item>
+				<el-collapse-item name="等高线">
+					<template #title>
+						<i class='iconfont icon-tianqizitiku43' />等高线
+					</template>
+					<div class="el-collapse-item__content">
+						等高线
+					</div>
+				</el-collapse-item> -->
+		</el-collapse>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+
+	export default {
+		props: {
+
+		},
+		watch: {
+		},
+
+		/* 数据 */
+		data() {
+			return {
+				activeName: "地下模式",
+				
+				//地下模式
+				underground: {
+					alpha: 0.5,
+					boolUnderground: false,
+				},
+				
+				//地形开挖
+				terrainExcavation:{
+					excavateDepth: 10, //开挖深度
+				}
+				
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			/**
+			 * 是否开启地下模式
+			 * @param {Object} bool
+			 */
+			handleUndergroundChange(bool) {
+				window["viewer"].scene.screenSpaceCameraController.enableCollisionDetection = !bool; //相机与地形的碰撞检测
+				window["viewer"].scene.globe.translucency.frontFaceAlphaByDistance = new Cesium.NearFarScalar(1.5e2, 0.5, 8.0e6, 1.0);
+				window["viewer"].scene.globe.translucency.enabled = bool; //是否开启透明
+				this.handleAlphaChange(this.underground.alpha);
+			},
+			/**
+			 * el-slider 值改变时触发
+			 * 设置地表透明度
+			 * @param {Object} alpha
+			 */
+			handleAlphaChange(alpha) {
+				const frontFaceAlphaByDistance = window["viewer"].scene.globe.translucency.frontFaceAlphaByDistance;
+				frontFaceAlphaByDistance.nearValue = alpha;
+				frontFaceAlphaByDistance.farValue = alpha;
+			},
+
+			/**
+			 * 移除坡度分析
+			 */
+			removeSlopeAspect() {
+				jt3d.TerrainAnalysis.SlopeAspect.clearAll();
+				//还原左键单击事件
+				this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+			},
+			/**
+			 * 坡度坡向分析
+			 * @param {Object} type
+			 */
+			SlopeAspect(type) {
+				let _self = this;
+				//功能初始化
+				_self.init();
+
+				switch (type) {
+					case "Num":
+						jt3d.DrawTools.draw('polygon', {
+							isEdit: false,
+							onComplete(cartesian3d, points) {
+
+								let pointsArray = [];
+								points.forEach((coordinate, index) => {
+									pointsArray.push([
+										coordinate.lng,
+										coordinate.lat,
+										coordinate.height
+									]);
+								});
+
+								jt3d.TerrainAnalysis.SlopeAspect.createNew4Num(pointsArray, jt3d.DrawTools._drawEntity.polygon, {
+									num: 10
+								});
+
+								//清除绘制
+								// jt3d.DrawTools._entities.remove(jt3d.DrawTools._drawEntity.polygon);
+								jt3d.DrawTools.Clear();
+							}
+						});
+
+						break;
+					case "Distance":
+						jt3d.DrawTools.draw('polygon', {
+							isEdit: false,
+							onComplete(cartesian3d, points) {
+
+								let pointsArray = [];
+								points.forEach((coordinate, index) => {
+									pointsArray.push([
+										coordinate.lng,
+										coordinate.lat,
+										coordinate.height
+									]);
+								});
+
+								jt3d.TerrainAnalysis.SlopeAspect.createNew4Distance(pointsArray, jt3d.DrawTools._drawEntity.polygon, {
+									distance: 0.05
+								});
+
+								//清除绘制
+								// jt3d.DrawTools._entities.remove(jt3d.DrawTools._drawEntity.polygon);
+								jt3d.DrawTools.Clear();
+							}
+						});
+						break;
+				}
+			},
+
+			/**
+			 * 移除地形开挖
+			 */
+			removeTerrainExcavate() {
+				jt3d.TerrainAnalysis.TerrainExcavation.clear();
+				//还原左键单击事件
+				this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+			},
+			/**
+			 * 地形开挖
+			 */
+			terrainExcavate(type) {
+				let _self = this;
+				//功能初始化
+				_self.init();
+				
+				if (type === "add") {
+					jt3d.DrawTools.draw('polygon', {
+						onComplete(aa, points) {
+							jt3d.DrawTools.Clear();
+							let pointsArray = [];
+							points.forEach((coordinate, index) => {
+								pointsArray.push([
+									coordinate.lng,
+									coordinate.lat,
+									coordinate.height
+								]);
+							});
+							jt3d.TerrainAnalysis.TerrainExcavation.add(pointsArray, {
+								excavateDepth: _self.terrainExcavation.excavateDepth
+							});
+
+						}
+					});
+				} else if (type === "remove") {
+					_self.removeTerrainExcavate();
+				}
+			},
+
+			/**
+			 * 功能初始化
+			 */
+			init() {
+				//移除左键单击事件
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); //移除事件
+				}
+
+				jt3d.DrawTools.Clear();
+
+				jt3d.TerrainAnalysis.TerrainExcavation.clear();; //清除地形开挖
+				jt3d.TerrainAnalysis.SlopeAspect.clearAll(); //移除坡度坡向分析	
+			}
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.el-switch{
+		font-size: 14rem !important;
+		line-height: 20rem !important;
+		align-items: self-start !important;
+	}
+	::v-deep .is-checked .el-switch__core .el-switch__action{
+		margin-left: calc(-1rem - 14rem);
+	}
+	
+	::v-deep .el-switch__core .el-switch__action{
+		top:1rem;
+	}
+	
+	::v-deep .el-switch__core .el-switch__action{
+		width: 14rem;
+		height: 14rem;
+	}
+	
+	::v-deep .el-switch__core{
+		width: 40rem !important;
+		height: 20rem !important;
+	}
+	::v-deep .el-switch__label{
+		height: 20rem !important;
+		font-size: 14rem !important;
+	}
+	::v-deep .el-switch__label *{
+		font-size: 14rem !important;
+	}
+	
+	::v-deep .el-switch__label--left{
+		margin-right: 10rem;
+	}
+	
+	.jt-analysisTerrain {
+		position: relative;
+		.iconfont {
+			padding: 0 10rem;
+		}
+
+		.el-collapse {
+			--el-collapse-border-color: rgb(0 44 126 / 0%);
+
+			--el-collapse-header-text-color: #ffffff;
+			--el-collapse-header-font-size: 13rem;
+			--el-collapse-content-bg-color: rgb(0 44 126 / 0%);
+			--el-collapse-content-font-size: 13rem;
+			--el-collapse-content-text-color: rgb(216 240 255);
+
+			--el-collapse-header-height: 40rem;
+			--el-collapse-header-bg-color: rgb(30 130 255);
+
+			--el-fill-color-blank: rgb(0 44 126 / 68%);
+			--el-text-color-regular: rgb(216 240 255);
+			--el-border-color: rgb(35 135 255);
+
+			.el-collapse-item__content {
+				padding: 10rem;
+				// padding-bottom: 0rem;
+			}
+		}
+	}
+
+	::v-deep .el-collapse-item__content {
+		padding: 10rem;
+		// padding-bottom: 0rem;
+		overflow-y: hidden;
+	}
+
+	::v-deep .el-collapse-item__header {
+		background: url(@/assets/images/bg_collapse_title.png) no-repeat;
+		background-size: 350rem 40rem;
+		// background-color: rgb(22 90 190);
+		// background-color: rgb(5 45 100 /60%);
+		background-color: rgb(30 130 255);
+		border-bottom: 0;
+	}
+</style>

+ 0 - 0
src/views/Map3d/components/basicLayer.vue → src/views/Map3d - 副本/components/basicLayer.vue


+ 386 - 0
src/views/Map3d - 副本/components/coordsTool.vue

@@ -0,0 +1,386 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+<template>
+	<div class="jt-coordsTool">
+		<el-collapse v-model="activeName" accordion>
+			<el-collapse-item name="坐标定位">
+				<template #title>
+					<i class='iconfont icon-dituzuobiao' />坐标定位
+				</template>
+				<div class="el-collapse-item__content">
+					<div style="line-height: 2em; table-layout: fixed; word-wrap: break-word; word-break: normal; text-align:justify; text-justify: inter-ideograph;color: #ffffff60;">
+						提示: 填写格式:x1,y1,z1;x2,y2,z2;x3,y3,z3;......;标点符号必须采用英文半角。
+					</div>
+					<el-form label-width="80rem">
+						<el-form-item label="定位类型:">
+							<el-radio-group v-model="position.locationType">
+								<el-radio label="point">点</el-radio>
+								<el-radio label="polyline">线</el-radio>
+								<el-radio label="polygon">多边形</el-radio>
+							</el-radio-group>
+						</el-form-item>
+					</el-form>
+					<el-input v-model="position.locationCoords" type="textarea" :autosize="{ minRows: 6, maxRows: 6 }" />
+					<div class="jt-btn" style="margin-top: 10rem;">
+						<el-button color="rgb(20 136 255)" @click="Position">坐标定位</el-button>
+						<el-button color="rgb(255 100 100)" @click="emptyLoc"><span style="color: #fff;">清除定位</span></el-button>
+					</div>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="坐标拾取">
+				<template #title>
+					<i class='iconfont icon-chaxunzuobiaozhi' />坐标拾取
+				</template>
+				<div class="el-collapse-item__content">
+					<div style="line-height: 2em; table-layout: fixed; word-wrap: break-word; word-break: normal; text-align:justify; text-justify: inter-ideograph;color: #ffffff60;">
+						提示:点击【坐标拾取】按钮,在地图上点击获取坐标。
+					</div>
+					<el-input v-model="pickCoords" type="textarea" :autosize="{ minRows: 6, maxRows: 6 }" />
+					<div class="jt-btn" style="margin-top: 10rem;">
+						<el-button color="rgb(20 136 255)" @click="pickUp">坐标拾取</el-button>
+						<el-button color="rgb(20 136 255)" @click="undo">撤销</el-button>
+						<el-button color="rgb(255 100 100)" @click="emptyPic"><span style="color: #fff;">清空</span></el-button>
+					</div>
+				</div>
+			</el-collapse-item>
+		</el-collapse>
+	</div>
+</template>
+<script>
+	let jt3d = undefined;
+
+	export default {
+		props: {
+
+		},
+		watch: {
+			pickCoordsLable: function(val) {
+				this.setPickCoordsLable(val);
+			},
+
+		},
+
+		/* 数据 */
+		data() {
+			return {
+				activeName: "坐标定位",
+
+				position: {
+					locationType: "point", //定位类型
+					locationCoords: "", //定位坐标
+				},
+
+				pickCoords: "", //坐标拾取
+				pickCoordsArray: [],
+				pickCoordsLable: 1,
+
+				pointEntities: []
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			/**
+			 * 设置点的lable
+			 */
+			setPickCoordsLable(val) {
+				jt3d.CommonTools._sketchViewModel._lineLabel = val.toString();
+			},
+
+			/**
+			 * 坐标拾取
+			 */
+			pickUp() {
+				let _self = this;
+
+				//移除左键单击事件
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
+				}
+
+				jt3d.CommonTools._sketchViewModel._lineLabel = _self.pickCoordsLable.toString();
+				jt3d.CommonTools._sketchViewModel.sketchTools('point', {
+					onComplete(cPoint, gPoint) {
+						_self.pickCoordsArray.push(gPoint.lng.toFixed(6) + ',' + gPoint.lat.toFixed(6) + ',' + gPoint.height.toFixed(2)) + ";";
+						_self.pickCoords = _self.pickCoordsArray.join(";\n");
+						_self.pickCoordsLable++;
+
+						//还原左键单击事件
+						_self.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+					},
+					onError(message) {
+						
+					}
+				});
+			},
+
+			/**
+			 * 坐标拾取 - 撤销
+			 */
+			undo() {
+				this.pickCoordsArray.pop();
+				this.pickCoords = this.pickCoordsArray.join(";\n");
+				this.pickCoordsLable--;
+
+				//移除最后一个元素
+				let lastPointEntity = jt3d.CommonTools._sketchViewModel._pointEntitys[jt3d.CommonTools._sketchViewModel._pointEntitys.length - 1];
+				jt3d._entities.remove(lastPointEntity);
+				jt3d.CommonTools._sketchViewModel._pointEntitys.pop();
+			},
+
+			/**
+			 * 坐标拾取 - 清空
+			 */
+			empty() {
+				this.pickCoords = "";
+				this.pickCoordsArray = [];
+				this.pickCoordsLable = 1;
+				jt3d.CommonTools._sketchViewModel.sketchClear();
+				jt3d.CommonTools._sketchViewModel._clearEvent();
+				jt3d.CommonTools._sketchViewModel._clearEvent(jt3d.CommonTools._sketchViewModel._sketchEventHandler);
+
+				this.position.locationCoords = "";
+				jt3d._viewer.entities.remove(jt3d.LocateUtil._locationEntity);
+
+				for (let i = 0; i < this.pointEntities.length; i++) {
+					jt3d._viewer.entities.remove(this.pointEntities[i]);
+				}
+				this.pointEntities = []; //脏数据,存储entities
+			},
+			
+			/**
+			 * 坐标拾取 - 清空
+			 */
+			emptyPic() {
+				this.pickCoords = "";
+				this.pickCoordsArray = [];
+				this.pickCoordsLable = 1;
+				jt3d.CommonTools._sketchViewModel.sketchClear();
+				jt3d.CommonTools._sketchViewModel._clearEvent();
+				jt3d.CommonTools._sketchViewModel._clearEvent(jt3d.CommonTools._sketchViewModel._sketchEventHandler);
+			
+				jt3d._viewer.entities.remove(jt3d.LocateUtil._locationEntity);
+			
+				for (let i = 0; i < this.pointEntities.length; i++) {
+					jt3d._viewer.entities.remove(this.pointEntities[i]);
+				}
+				this.pointEntities = []; //脏数据,存储entities
+			},
+			
+			/**
+			 * 坐标定位 - 清空
+			 */
+			emptyLoc() {
+				this.pickCoordsArray = [];
+				this.pickCoordsLable = 1;
+				jt3d.CommonTools._sketchViewModel.sketchClear();
+				jt3d.CommonTools._sketchViewModel._clearEvent();
+				jt3d.CommonTools._sketchViewModel._clearEvent(jt3d.CommonTools._sketchViewModel._sketchEventHandler);
+			
+				this.position.locationCoords = "";
+				jt3d._viewer.entities.remove(jt3d.LocateUtil._locationEntity);
+			
+				for (let i = 0; i < this.pointEntities.length; i++) {
+					jt3d._viewer.entities.remove(this.pointEntities[i]);
+				}
+				this.pointEntities = []; //脏数据,存储entities
+			},
+
+			/**
+			 * 坐标定位
+			 */
+			Position() {
+				let _self = this;
+
+				let endstring = _self.position.locationCoords.substring(_self.position.locationCoords.length - 1);
+				if (endstring != ";") {
+					ElMessage("最后一位请用;结束!");
+					return false;
+				}
+
+				let coords = _self.position.locationCoords.substr(0, _self.position.locationCoords.length - 1);
+				let coordArray = coords.split(';');
+				let pointArray = [];
+				coordArray.forEach((coordinate, index) => {
+					let xyArray = coordinate.split(',');
+					if (xyArray.length != 2 && xyArray.length != 3) {
+						ElMessage("坐标不是成对出现,请检查!");
+						throw Error(); //forEach()本身无法跳出循环,所以,这里使用了抛异常的方法来终止它。
+					} else {
+						let longitude = xyArray[0];
+						let latitude = xyArray[1];
+
+						if (xyArray[2]) {
+							let height = xyArray[2];
+							let point = [Number(longitude), Number(latitude), Number(height)];
+
+							pointArray.push(point);
+							//点标记
+							jt3d.CommonTools._sketchViewModel._lineLabel = (index + 1).toString();
+							jt3d.CommonTools._sketchViewModel.sketchDrawFeacture(point, 'drawPoint');
+
+							if (index === (coordArray.length - 1)) {
+								loc();
+							}
+						} else {
+
+							let terrainAltitude = _self.jt3dSDK.common.getHeigthByPointsMostDetailed(jt3d._viewer, [
+								[Number(longitude), Number(latitude)]
+							]);
+							terrainAltitude.then(function(updatedPositions) {
+								let point = [Number(longitude), Number(latitude), Number(updatedPositions[0].height)];
+								pointArray.push(point);
+								//点标记
+								jt3d.CommonTools._sketchViewModel._lineLabel = (index + 1).toString();
+								jt3d.CommonTools._sketchViewModel.sketchDrawFeacture(point, 'drawPoint');
+
+								if (index === (coordArray.length - 1)) {
+									loc();
+								}
+							});
+						}
+					}
+				});
+
+				function loc() {
+					switch (_self.position.locationType) {
+						case "point":
+							if (coordArray.length === 1) {
+
+								let point = jt3d.PointObject.generatePoint(
+									pointArray[0]
+								);
+								point.then(function(entity) {
+									_self.flyToEntity(entity);
+								});
+							} else {
+								let line = jt3d.PolylineObject.drawSpecifyColorLine(pointArray, {
+									color: [255, 0, 0, 0]
+								});
+								line.then(function(entity) {
+									_self.flyToEntity(entity);
+								});
+							}
+							break;
+						case "polyline":
+							let line = jt3d.PolylineObject.drawSpecifyColorLine(pointArray, {
+								color: [255, 255, 0, 0.8]
+							});
+							line.then(function(entity) {
+								_self.flyToEntity(entity);
+							});
+
+							break;
+						case "polygon":
+							let polygon = jt3d.PolygonObject.generatePolygonByPoints(pointArray, {
+								color: [255, 255, 0, 0.8]
+							});
+							polygon.then(function(entity) {
+								_self.flyToEntity(entity);
+							});
+							break;
+					}
+
+				}
+
+			},
+
+			flyToEntity(entity) {
+				let flyToEntity = jt3d.LocateUtil.flyToEntity(entity, {
+					duration: 3,
+					heading: -45,
+					pitch: -20,
+					range: 6000
+				});
+				flyToEntity.then(function(entity) {
+					if (entity.point) {
+						jt3d._viewer.entities.remove(entity);
+					}
+				});
+			},
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.el-radio-group {
+		height: 32rem;
+		line-height: 32rem;
+		flex-wrap: nowrap;
+	}
+
+	::v-deep .el-radio__label {
+		font-size: 14rem !important;
+		padding-left: 8rem !important;
+	}
+
+	.jt-coordsTool {
+		position: relative;
+
+		.iconfont {
+			padding: 0 10rem;
+		}
+
+		.el-collapse {
+			--el-collapse-border-color: rgb(0 44 126 / 0%);
+
+			--el-collapse-header-text-color: #ffffff;
+			--el-collapse-header-font-size: 13rem;
+			--el-collapse-content-bg-color: rgb(0 44 126 / 0%);
+			--el-collapse-content-font-size: 13rem;
+			--el-collapse-content-text-color: rgb(216 240 255);
+
+			--el-collapse-header-height: 40rem;
+			--el-collapse-header-bg-color: rgb(30 130 255);
+
+			--el-fill-color-blank: rgb(0 44 126 / 68%);
+			--el-text-color-regular: rgb(216 240 255);
+			--el-border-color: rgb(35 135 255);
+
+			.el-collapse-item__content {
+				padding: 10rem;
+				// padding-bottom: 0rem;
+			}
+		}
+	}
+
+	::v-deep .el-collapse-item__content {
+		padding: 10rem;
+		// padding-bottom: 0rem;
+		overflow-y: hidden;
+	}
+
+	::v-deep .el-collapse-item__header {
+		background: url(@/assets/images/bg_collapse_title.png) no-repeat;
+		background-size: 350rem 40rem;
+		// background-color: rgb(22 90 190);
+		// background-color: rgb(5 45 100 /60%);
+		background-color: rgb(30 130 255);
+		border-bottom: 0;
+	}
+
+	::v-deep .el-form-item {
+		margin-bottom: 10rem;
+	}
+
+	::v-deep .el-radio {
+		margin-right: 10rem;
+	}
+</style>

+ 462 - 0
src/views/Map3d - 副本/components/drawEdit.vue

@@ -0,0 +1,462 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+	import {
+		inject
+	} from "vue";
+	import {
+		ArrowLeft,
+		ArrowRight,
+		Delete,
+		Edit,
+		Share
+	} from '@element-plus/icons-vue';
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-drawTool">
+		<div style="margin-bottom: 0rem;">
+			<el-select class="selectInfo" v-model="value" @change="handleClick" placeholder="请选择" style="width: 65%; margin-bottom: 10rem;margin-right: 10rem;">
+				<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
+			</el-select>
+			<el-button type="danger" :icon="Delete" style="margin-top: 8rem;width: 30%;" @click="removeAll()">清除</el-button>
+		</div>
+		<div v-show="value=='二维平面类'">
+			<el-row :gutter="20" style="margin-left: 0rem; margin-right: 0rem">
+				<el-col v-for="(item,index) in towDimension" :span="8" @click="createGraphics(item.drawType,index)">
+					<el-avatar shape="circle" :size="70" :class="currentIndex===index?'selectStyle':'defaultStyle'">
+						<i :class="[item.icon,currentIndex===index?'selectFontStyle':'']" />
+					</el-avatar>
+					<div style="margin-top: 5rem; font-size: 14rem;" :class="currentIndex===index?'selectFontStyle':''">{{item.label}}</div>
+				</el-col>
+			</el-row>
+		</div>
+		<div v-show="value=='三维立体类'">
+			<el-row :gutter="20" style="margin-left: 0rem; margin-right: 0rem">
+				<el-col v-for="(item,index) in threeDimension" :span="8" @click="createGraphics(item.drawType,index)">
+					<el-avatar shape="circle" :size="70" :class="currentIndex===index?'selectStyle':'defaultStyle'">
+						<i :class="[item.icon,currentIndex===index?'selectFontStyle':'']" />
+					</el-avatar>
+					<div style="margin-top: 5rem; font-size: 14rem;" :class="currentIndex===index?'selectFontStyle':''">{{item.label}}</div>
+				</el-col>
+			</el-row>
+		</div>
+		<div v-show="value=='军事标绘类'">
+			<el-row :gutter="20" style="margin-left: 0rem; margin-right: 0rem">
+				<el-col v-for="(item,index) in militaryPlotting" :span="8" @click="createMilitaryPlot(item.drawType,index)">
+					<el-avatar shape="circle" :size="70" :class="currentIndex===index?'selectStyle':'defaultStyle'">
+						<i :class="[item.icon,currentIndex===index?'selectFontStyle':'']" />
+					</el-avatar>
+					<div style="margin-top: 5rem; font-size: 14rem;" :class="currentIndex===index?'selectFontStyle':''">{{item.label}}</div>
+				</el-col>
+			</el-row>
+		</div>
+		<div v-show="value=='点标绘类'">
+			<el-row :gutter="20" style="margin-left: 0rem; margin-right: 0rem">
+				<el-col v-for="(item,index) in point" :span="8" @click="createDrawPoint(item.drawType,index)">
+					<el-avatar shape="circle" :size="70" :class="currentIndex===index?'selectStyle':'defaultStyle'">
+						<i :class="[item.icon,currentIndex===index?'selectFontStyle':'']" />
+					</el-avatar>
+					<div style="margin-top: 5rem; font-size: 14rem;" :class="currentIndex===index?'selectFontStyle':''">{{item.label}}</div>
+				</el-col>
+			</el-row>
+		</div>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+	let tipEntity = undefined;
+	export default {
+		props: {},
+		watch: {},
+		/* 数据 */
+		data() {
+			return {
+				currentIndex: -1,
+				value: "二维平面类",
+				options: [{
+						value: '点标绘类',
+						label: '点标绘类',
+					}, {
+						value: '二维平面类',
+						label: '二维平面类',
+					},
+					{
+						value: '三维立体类',
+						label: '三维立体类',
+					},
+					{
+						value: '军事标绘类',
+						label: '军事标绘类',
+					},
+				],
+				towDimension: [{
+						label: '贴地线',
+						drawType: 'polyline',
+						number: 0,
+						icon: 'iconfont icon-svgtiedixian'
+					},
+					{
+						label: '箭头线',
+						drawType: 'arrowPolyline',
+						number: 1,
+						icon: 'iconfont icon-svgjiantouxian'
+					},
+					{
+						label: '贴地面',
+						drawType: 'polygon', //polygon
+						number: 2,
+						icon: 'iconfont icon-svgtiedimian'
+					},
+					{
+						label: '动态线',
+						drawType: 'dynamicPolyline',
+						number: 3,
+						icon: 'iconfont icon-svgliudongxian'
+					},
+					{
+						label: '发光线',
+						drawType: '发光线',
+						number: 4,
+						icon: 'iconfont icon-svgfaguangxian'
+					},
+					{
+						label: '描边线',
+						drawType: 'outlinePolyline',
+						number: 5,
+						icon: 'iconfont icon-svgmiaobianxian'
+					},
+					{
+						label: '动态圆',
+						drawType: 'dynamicCircle',
+						number: 6,
+						icon: 'iconfont icon-svgdongtaiyuan'
+					},
+					{
+						label: '普通圆',
+						drawType: 'circle',
+						number: 7,
+						icon: 'iconfont icon-svgputongyuan'
+					},
+					{
+						label: '矩形',
+						drawType: 'rectangle',
+						number: 8,
+						icon: 'iconfont icon-svgjuxing'
+					},
+
+				],
+				threeDimension: [{
+						label: '空间线',
+						drawType: 'spatialLine',
+						number: 0,
+						icon: 'iconfont icon-svgkongjianxian'
+					},
+					{
+						label: '动态墙',
+						drawType: 'dynamicWall',
+						number: 1,
+						icon: 'iconfont icon-svgdongtaiqiang'
+					},
+					{
+						label: '房屋',
+						drawType: 'house',
+						number: 2,
+						icon: 'iconfont icon-svgfangwu'
+					},
+					{
+						label: '文字',
+						drawType: 'text',
+						number: 3,
+						icon: 'iconfont icon-svgzi'
+					},
+					{
+						label: '视频墙',
+						drawType: 'videoWall',
+						number: 4,
+						icon: 'iconfont icon-svgshipinqiang'
+					},
+					{
+						label: '普通墙',
+						drawType: 'normalWall',
+						number: 5,
+						icon: 'iconfont icon-svgputongqiang'
+					},
+				],
+				militaryPlotting: [{
+						label: '直线箭头',
+						drawType: 'straightArrow',
+						number: 1,
+						icon: 'iconfont icon-zhijiantou'
+					},
+					{
+						label: '攻击箭头',
+						drawType: 'attackArrow',
+						number: 2,
+						icon: 'iconfont icon-tujifangxiang'
+					},
+					{
+						label: '钳击箭头',
+						drawType: 'pincerArrow',
+						number: 3,
+						icon: 'iconfont icon-qianji'
+					}
+				],
+				point: [{
+						label: '小模型',
+						drawType: 'model',
+						number: 1,
+						icon: 'iconfont icon-jihedi'
+					}, {
+						label: '文字',
+						drawType: 'label',
+						number: 2,
+						icon: 'iconfont icon-jihedi'
+					},
+					{
+						label: '点',
+						drawType: 'point',
+						number: 3,
+						icon: 'iconfont icon-jihedi'
+					},
+					{
+						label: '点及文字',
+						drawType: 'point2Label',
+						number: 4,
+						icon: 'iconfont icon-jihedi'
+					},
+					{
+						label: '广告牌',
+						drawType: 'billboard',
+						number: 5,
+						icon: 'iconfont icon-jihedi'
+					},
+					{
+						label: '广告牌及文字',
+						drawType: 'billboard2Label',
+						number: 6,
+						icon: 'iconfont icon-jihedi'
+					}
+				],
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			//清除全部
+			removeAll() {
+				jt3d.DrawToolsEdit.Clear();
+				jt3d.DrawMilitaryPlot.clearAll();
+				jt3d.DrawPointEdit.clearAll();
+
+				this.currentIndex = -1;
+
+				//还原左键单击事件
+				this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+			},
+
+			//选择绘制类型
+			//头部标题点击事件
+			handleClick(val) {
+				console.log(val)
+				this.currentIndex = -1;
+				this.value = val
+			},
+
+			//创建军事标会
+			createMilitaryPlot(type, index) {
+				let _self = this;
+				this.currentIndex = index;
+
+				//移除左键单击事件
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
+				}
+
+				/* 创建监听 */
+				jt3d.DrawMilitaryPlot.onEditProperty = {};
+				// 开始绘制
+				jt3d.DrawMilitaryPlot.draw(type, {
+					onComplete(cPoint, gPoint) {
+						// _self.$parent.$parent.param = param;
+						// _self.$parent.$parent.showDialog = true;
+					}
+				});
+			},
+
+			//创建二维标会和三维标会
+			createGraphics(type, index) {
+				let _self = this;
+				this.currentIndex = index;
+
+				//移除左键单击事件
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
+				}
+
+				/* 创建监听 */
+				jt3d.DrawToolsEdit.onEditProperty = {};
+				// 开始绘制
+				jt3d.DrawToolsEdit.draw(type, {
+					isEdit: true,
+					onComplete(cPoint, gPoint) {
+
+					},
+					onError(message) {
+						console.log('错误原因', message)
+					}
+				});
+			},
+
+			//创建点类标绘
+			createDrawPoint(type, index) {
+				let _self = this;
+				this.currentIndex = index;
+
+				//移除左键单击事件
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
+				}
+
+				/* 创建监听 */
+				jt3d.DrawPointEdit.onEditProperty = {};
+				// 开始绘制
+				jt3d.DrawPointEdit.draw(type, {
+					isEdit: true,
+					onComplete(cPoint, gPoint) {
+
+					},
+					onError(message) {
+						console.log('错误原因', message)
+					}
+				});
+			}
+
+		},
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.el-avatar {
+		width: 70rem !important;
+		height: 70rem !important;
+		font-size: 14px !important;
+		cursor: pointer;
+	}
+
+	// .el-popper{
+	// 	padding: 5rem 11rem;
+	// 	font-size: 12rem;
+	// 	line-height: 20rem;
+	// 	min-height: 10rem;
+	// 	width: 322rem;
+	// 	height: 311rem;
+	// 	left: 15rem !important;
+	// 	top: 175rem !important;
+	// }
+
+	::v-deep .el-scrollbar {
+		background-color: gainsboro !important;
+	}
+
+	.el-select-dropdown__item {
+		color: #409eff !important;
+		padding: 0 32rem 0 20rem;
+		height: 34rem;
+		line-height: 34rem;
+		font-size: 14rem;
+	}
+
+	.jt-drawTool {
+		--el-avatar-size: 70rem !important;
+
+
+		.el-col {
+			padding: 10rem;
+			// color: rgba(90, 172, 255, 1.0);
+			color: #fff;
+		}
+
+		i {
+			display: inline-block;
+			width: 100%;
+			height: 36rem;
+			line-height: 36rem;
+			text-align: center;
+			border-radius: 5rem;
+			font-size: 40rem;
+			// color: rgba(90, 172, 255, 1.0);
+			color: #fff;
+			transition: all .3s;
+			-webkit-transition: all .3s
+		}
+
+		.selectStyle {
+			// background: rgba(135, 182, 254, 0.5);
+			background: rgb(0 44 126);
+			--el-avatar-size: 70rem !important;
+		}
+
+		.defaultStyle {
+			background: #ffffff00;
+			--el-avatar-size: 70rem !important;
+		}
+
+		.selectFontStyle {
+			color: #fff;
+		}
+
+		.el-button.is-text {
+			background-color: rgba(255, 255, 255, 0.5);
+		}
+
+		el-option {
+			margin-top: -15rem !important;
+		}
+
+		.iconactive {
+			box-shadow: 0 0 3rem 3rem rgba(12, 123, 200, .6);
+		}
+
+		.active {
+			color: #409eff
+		}
+
+		::v-deep .el-input__wrapper {
+			background-color: rgba(255, 255, 255, 0);
+			color: #fff;
+		}
+
+		::v-deep .el-input__inner {
+			color: #fff;
+		}
+
+		.selectInfo {
+			top: 10rem !important;
+		}
+
+		.el-select-dropdown__wrap {
+			margin-top: 10rem;
+		}
+
+		.el-select-dropdown__item {
+			background-color: rgba(255, 255, 255, 1) !important;
+
+		}
+
+		.el-select-dropdown__item:hover {
+			background-color: rgba(255, 255, 235, 1) !important;
+		}
+
+	}
+</style>

+ 0 - 0
src/views/Map3d/components/layer.vue → src/views/Map3d - 副本/components/layer.vue


+ 345 - 0
src/views/Map3d - 副本/components/map.vue

@@ -0,0 +1,345 @@
+<template>
+	<div id="cesiumContainer2" class="ViewerSplitScreen" style="display: none; border-right: 5rem solid #fff"></div>
+	<div id="cesiumContainer" class="jt-map" ref="cesiumContainer"></div>
+</template>
+
+<script>
+	import {
+		Store
+	} from '@/store/index'
+	let store = Store();
+
+	import map_xzqh_zj from '@/assets/dataFile/map_xzqh_zj.json';
+
+	let jt3d = undefined;
+	export default {
+
+		/* 数据 */
+		data() {
+			return {
+				LocateId: 'locate_ID_remove', //标记定位所用ID
+				entity: ''
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			//定位方法
+			startLocation() {
+				let that = this
+				plusGPSListenerOn(function(lat, lon) {
+					console.log('位置坐标', lat, lon)
+					let terrainProvider = jt3d._viewer.terrainProvider;
+					//异步函数
+					return new Promise((resolve, reject) => {
+						lon = Number(lon)
+						lat = Number(lat)
+						let promise = new Cesium.sampleTerrainMostDetailed(terrainProvider, [Cesium
+							.Cartographic.fromDegrees(lon, lat)
+						]);
+						promise.then(function(updatedPositions) {
+							if (that.entity) {
+								jt3d._viewer.entities.remove(that.entity)
+							}
+							// if that.entity && jt3d._viewer.entities.remove(that.entity)
+							console.log('高度', updatedPositions[0].height)
+							let height = updatedPositions[0].height
+
+							that.entity = new Cesium.Entity({
+								name: "add billboard",
+								//位置
+								position: Cesium.Cartesian3.fromDegrees(lon, lat, height),
+								//图片标签
+								billboard: {
+									image: 'jt3dSDK/imgs/point/point.png',
+									horizontalOrigin: Cesium.HorizontalOrigin.CENTER, //水平
+									verticalOrigin: Cesium.VerticalOrigin.BOTTOM, //垂直位置
+									// scale: billboard.scale, //尺寸
+									// pixelOffset: new Cesium.Cartesian2(0, billboard.pixelOffset),
+									disableDepthTestDistance: Number.POSITIVE_INFINITY,
+									scale: 1,
+									scaleByDistance: new Cesium.NearFarScalar(1.5e2, 1, 2400, 0) //按距离缩放,即距离大于180米时,图标不显示  Cesium.NearFarScalar(near, nearValue, far, farValue)相机范围的下界。相机范围下界的值。相机范围的上限。该值位于摄像机范围的上界。
+								}
+							});
+							jt3d._viewer.entities.add(that.entity, {
+								range: 1000
+							});
+
+							// let LocateNowTime = jt3d.PointObject.addBillboard([lon, lat,height], {
+							// 	// id: that.LocateId
+							// })
+							// LocateNowTime.then(entity => {
+							// 	that.entity = entity
+							// })
+							resolve(updatedPositions);
+						});
+					})
+					// let getHeight = new that.jt3dSDK.common.getHeigthByPointsMostDetailed(jt3d._viewer,[[lon,lat]])
+					// getHeight.then(height=>{
+					// 	// if that.entity && jt3d._viewer.entities.remove(that.entity)
+					// 	console.log('高度',height)
+					// 	let LocateNowTime = jt3d.PointObject.addBillboard([lon,lat,height],{
+					// 		id:that.LocateId
+					// 	})
+					// 	LocateNowTime.then(entity=>{
+					// 		that.entity = entity
+					// 	})
+					// })
+				});
+			},
+			/**
+			 * 初始化
+			 */
+			init(el) {
+				//初始化大球
+				this.initMap3d(el);
+
+				//设置默认视图
+				this.setView(jt3d);
+
+				// 初始化项目区域范围视角
+				this.fullMap(jt3d);
+
+				//加载天空盒子
+				this.addSkybox(jt3d);
+
+				//调用父组件的方法,onload是在父组件的的动态组件component上面的方法,并将jt3d传过去
+				this.$emit("onload", jt3d);
+				// console.log(this.$parent)
+				this.$parent.jtMap3DOnload(jt3d);
+
+				//单击事件
+				this.clickEntity(jt3d);
+
+				//添加镇街边界线——精灵线
+				this.addBoundaryLine(jt3d);
+
+			},
+			/**
+			 * 添加镇街边界线——精灵线
+			 */
+			addBoundaryLine(jt3d) {
+				jt3d.PolylineObject.drawPolylineByGeoJson(map_xzqh_zj, {
+					width: 5,
+					color: '#04FFFF',
+					isImageAlpha: true, //用图片自带颜色
+					duration: 3000,
+					imgUrl: "jt3dSDK/imgs/polylinematerial/spriteline1.png"
+				});
+			},
+
+			/**
+			 * 单击事件
+			 */
+			clickEntity(jt3d) {
+
+				let _self = this;
+
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); //移除事件
+				}
+
+				jt3d.handlerLeftClick = new Cesium.ScreenSpaceEventHandler(
+					jt3d._viewer.scene.canvas
+				);
+				//注册大球单机事件
+				jt3d.handlerLeftClick.setInputAction(function(e) {
+					var pick = jt3d._viewer.scene.pick(e.position); //拾取当前的entity对象
+					var cartesian = jt3d._viewer.scene.pickPosition(e.position); //获取当前点坐标
+					if (Cesium.defined(cartesian)) {
+						//将笛卡尔坐标转换为地理坐标
+						let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
+						//将弧度转为度的十进制度表示
+						let lng = Cesium.Math.toDegrees(cartographic.longitude);
+						let lat = Cesium.Math.toDegrees(cartographic.latitude);
+						let alt = cartographic.height; //高度
+
+						_self.$parent.$refs._refQueryGraphics.initQuery({
+							spatialType: '点',
+							coordinate: lng + " " + lat,
+							buffer: ''
+						});
+					}
+				}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+			},
+
+			/**
+			 * 创建大球
+			 */
+			initMap3d(el) {
+
+				jt3d = new this.jt3dSDK.jtMap3d({
+					container: el,
+				});
+
+				jt3d.statusBar.show = true;
+
+				jt3d.layer = new this.jt3dSDK.layer(jt3d._viewer);
+
+				jt3d.CommonTools = new this.jt3dSDK.CommonTools(jt3d._viewer, {
+					isClear: false,
+					isDrawPoint: true,
+					isRetainDrawPoint: false,
+					iconType: 'blue',
+				});
+				jt3d.SketchViewModel = new this.jt3dSDK.SketchViewModel(jt3d._viewer, {
+					isClear: true,
+					isDrawPoint: false,
+					isRetainDrawPoint: false,
+					iconType: 'blue',
+				});
+				jt3d.DrawTools = new this.jt3dSDK.DrawTools(jt3d._viewer, {
+					isDrawPoint: true, //是否标记参考点
+					isRetainDrawPoint: false, //绘制完成是否保留绘制点
+					iconType: 'blue',
+				});
+				jt3d.DrawToolsEdit = new this.jt3dSDK.DrawTools(jt3d._viewer, {
+					isDrawPoint: true, //是否标记参考点
+					isRetainDrawPoint: true, //绘制完成是否保留绘制点
+					iconType: 'blue',
+				});
+				jt3d.DrawMilitaryPlot = new this.jt3dSDK.DrawMilitaryPlot(jt3d._viewer);
+				jt3d.DrawPointEdit = new this.jt3dSDK.DrawPoint(jt3d._viewer);
+
+				jt3d.LocateUtil = new this.jt3dSDK.LocateUtil(jt3d._viewer);
+
+				// jt3d.getHeigthByLngLat = new this.jt3dSDK.getHeigthByLngLat(jt3d._viewer) //获取高度
+
+				jt3d.SpatialAnalysis = {};
+				jt3d.SpatialAnalysis.SightLine = new this.jt3dSDK.SpatialAnalysis.SightLine(jt3d._viewer);
+				jt3d.SpatialAnalysis.ViewShed = new this.jt3dSDK.SpatialAnalysis.ViewShed(jt3d._viewer);
+				jt3d.SpatialAnalysis.SunshineShadow = new this.jt3dSDK.SpatialAnalysis.SunshineShadow(jt3d._viewer);
+				jt3d.SpatialAnalysis.Profile = new this.jt3dSDK.SpatialAnalysis.Profile(jt3d._viewer);
+				jt3d.SpatialAnalysis.CutFill = new this.jt3dSDK.SpatialAnalysis.CutFill(jt3d._viewer);
+				jt3d.SpatialAnalysis.HeightLimit = new this.jt3dSDK.SpatialAnalysis.HeightLimit(jt3d._viewer);
+				jt3d.SpatialAnalysis.Cutting = new this.jt3dSDK.SpatialAnalysis.Cutting(jt3d._viewer);
+				jt3d.SpatialAnalysis.GeologyClipPlan = new this.jt3dSDK.SpatialAnalysis.GeologyClipPlan(jt3d._viewer);
+
+				jt3d.TerrainAnalysis = {};
+				jt3d.TerrainAnalysis.TerrainExcavation = new this.jt3dSDK.TerrainAnalysis.TerrainExcavation(jt3d._viewer);
+				jt3d.TerrainAnalysis.SlopeAspect = new this.jt3dSDK.TerrainAnalysis.SlopeAspect(jt3d._viewer);
+
+				jt3d.SceneEffects = {};
+				jt3d.SceneEffects.Weather = new this.jt3dSDK.SceneEffects.Weather(jt3d._viewer);
+				jt3d.SceneEffects.SkyBox = new this.jt3dSDK.SceneEffects.SkyBox(jt3d._viewer);
+				jt3d.SceneEffects.ParticleSystem = new this.jt3dSDK.SceneEffects.ParticleSystem(jt3d._viewer);
+
+				jt3d.TrackRoam = new this.jt3dSDK.TrackRoam(jt3d._viewer);
+				jt3d.PolylineObject = new this.jt3dSDK.PolylineObject(jt3d._viewer);
+				jt3d.PointObject = new this.jt3dSDK.PointObject(jt3d._viewer);
+				jt3d.PolygonObject = new this.jt3dSDK.PolygonObject(jt3d._viewer);
+
+				window["viewer"] = jt3d._viewer;
+				window["viewer"].scene.terrainExaggeration = 100;
+
+				//显示帧率
+				window["viewer"].scene.debugShowFramesPerSecond = true;
+			},
+
+			/**
+			 * 设置默认视图-初始化中国区域范围视角
+			 */
+			setView(jt3d) {
+				// jt3d.flytoChina();
+
+				//初始化中国区域范围视角
+				jt3d.setViewChina();
+
+				// jt3d.setView({
+				// 	longitude: 103.84, //经度
+				// 	latitude: 31.15, // 维度
+				// 	height: 24000000, // 高度
+				// 	heading: 0, // 偏航
+				// 	pitch: -90, // 俯仰,人如果在赤道上空,俯仰角为0可见地球。如果在北纬,俯仰角为负才能见地球
+				// 	roll: 0.0 // 翻滚
+				// });
+			},
+
+			/**
+			 * 全图-飞行到项目区域范围视角
+			 */
+			fullMap(jt3d) {
+				// 初始化项目区域范围视角
+				let optionsS = {
+					west: 121.563298,
+					south: 37.284514,
+					east: 121.565298,
+					north: 37.286514,
+					isRemove: false, //定位完成后是否删除
+					duration: 3, //飞行时间
+					heading: 0,
+					pitch: -90,
+					range: 115000
+				};
+
+				let optionsE = {
+					west: 121.563298,
+					south: 37.284514,
+					east: 121.565298,
+					north: 37.286514,
+					isRemove: true, //定位完成后是否删除
+					duration: 3, //飞行时间
+					heading: 0,
+					pitch: -60,
+					range: 115000
+				};
+
+				var fullMapPromise = jt3d.fullMap(optionsS);
+				fullMapPromise.then(function(flyPromise) {
+					jt3d.fullMap(optionsE);
+				});
+			},
+
+			/**
+			 * 设置天空盒子
+			 */
+			addSkybox(jt3d) {
+				//设置天空盒子,默认蓝天
+				jt3d.SceneEffects.SkyBox.setGroundSkyBox();
+			},
+		},
+
+		mounted() {
+
+			this.init("cesiumContainer");
+			// if (store.userport == 'APP') {
+			// 	setTimeout(res => {
+			// 		this.startLocation()
+			// 	}, 100)
+			// 	setTimeout(res => {
+			// 		jt3d.LocateUtil.flyToEntity(this.entity)
+			// 	}, 10000)
+			// }
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.lk-status-bar {
+		font-size: 16rem !important;
+	}
+
+	.jt-map {
+		// width: calc(100% - 0rem);
+		// height: calc(100vh - 70rem);
+		height: 100vh;
+		margin: 0;
+		padding: 0;
+		overflow: hidden;
+		background-color: blue;
+		border: 0rem solid red;
+	}
+
+	//分屏样式
+	.ViewerSplitScreen {
+		float: left;
+		width: calc(50% - 2.5rem);
+		// height: calc(100vh - 70rem);
+		height: 100vh;
+		margin: 0;
+
+		.lk-status-bar {
+			width: calc(50% - 0rem) !important;
+		}
+	}
+</style>

+ 0 - 0
src/views/Map3d/components/mapNavigate.vue → src/views/Map3d - 副本/components/mapNavigate.vue


+ 242 - 0
src/views/Map3d - 副本/components/measure.vue

@@ -0,0 +1,242 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-measure">
+		<el-row :gutter="20" style="margin-left: 0rem; margin-right: 0rem; ">
+			<el-col :span="8" v-for="(item,index) in measure" @click="handleMeasure(item.type,index)">
+				<el-avatar shape="circle" :size="70" :class="currentIndex===index?'selectStyle':'defaultStyle'">
+					<i :class="[item.icon,currentIndex===index?'selectFontStyle':'']" />
+				</el-avatar>
+				<div style="margin-top: 5rem; font-size: 14rem;" :class="currentIndex===index?'selectFontStyle':''">{{item.label}}</div>
+			</el-col>
+		</el-row>
+		<div class="jt-btn" style="margin: 8rem;">
+			<el-button color="rgb(255 100 100)" @click="clearMeasurementData"><span style="color: #fff;width: 300rem;">清空测量数据</span></el-button>
+		</div>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+	let popup = undefined;
+
+	export default {
+		props: {
+
+		},
+		watch: {
+
+		},
+
+		/* 数据 */
+		data() {
+			return {
+				currentIndex: -1,
+				measure: [{
+						label: '长度测量(贴地)',
+						type: 'measureLength',
+						number: 0,
+						icon: 'iconfont icon-thin-_pencil_rul'
+					},
+					{
+						label: '面积测量(贴地)',
+						type: 'measureArea',
+						number: 1,
+						icon: 'iconfont icon-svgmianjiceliang'
+					},
+					{
+						label: '高度测量',
+						type: 'measureHeight',
+						number: 2,
+						icon: 'iconfont icon-svggaoduceliang'
+					},
+					{
+						label: '空间距离',
+						type: 'measureSpatialLength',
+						number: 3,
+						icon: 'iconfont icon-svgkongjianceliang'
+					},
+					{
+						label: '三角测量',
+						type: 'measureTriangle',
+						number: 4,
+						icon: 'iconfont icon-svgsanjiaoceliang'
+					},
+					{
+						label: '坐标测量',
+						type: 'pickUp',
+						number: 5,
+						icon: 'iconfont icon-svgzuobiaoceliang'
+					},
+				],
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			/**
+			 * 测量事件
+			 * @param {Object} type 测量类型
+			 * @param {Object} index 第几个被选中
+			 */
+			handleMeasure(type, index) {
+				this.currentIndex = index;
+
+				//移除左键单击事件
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
+				}
+
+				jt3d.CommonTools.clear();
+
+				switch (type) {
+					case "measureLength": //长度测量(贴地)
+						jt3d.CommonTools.measureLength(function(error) {
+							ElMessage.error(error)
+						});
+						break;
+					case "measureArea": //面积测量(贴地)
+						jt3d.CommonTools.measureArea(function(error) {
+							ElMessage.error(error)
+						});
+						break;
+					case "measureHeight": //高度测量
+						jt3d.CommonTools.measureHeight()
+						break;
+					case "measureSpatialLength": //空间距离
+						jt3d.CommonTools.measureSpatialLength(function(error) {
+							ElMessage.error(error)
+						});
+						break;
+					case "measureTriangle": //三角测量
+						jt3d.CommonTools.measureTriangle()
+						break;
+					case "pickUp": //坐标测量
+						ElMessage("点击位置开始测量");
+						this.pickUp();
+						break;
+				}
+			},
+
+			/**
+			 * 坐标测量
+			 */
+			pickUp() {
+				let _self = this;
+
+				if (popup) {
+					popup.close();
+				}
+
+				jt3d.SketchViewModel.sketchTools('point', {
+					onComplete(cPoint, gPoint) {
+						if (gPoint.lng) {
+							let html = "";
+							html += "<div style='text-align: left;'>";
+							html += "<p>经度:" + gPoint.lng.toFixed(6) + "</p>";
+							html += "<p>纬度:" + gPoint.lat.toFixed(6) + "</p>";
+							html += "<p>高度:" + gPoint.height.toFixed(2) + "米</p>";
+							html += "</div>";
+
+							let position = {
+								x: Number(gPoint.lng),
+								y: Number(gPoint.lat),
+								z: Number(gPoint.height)
+							}
+
+							// popup = new  _self.jt3dSDK.PopupWindow.HtmlWindow(window["viewer"], position, "位置信息", html,40);
+							popup = new _self.jt3dSDK.PopupWindow.HtmlWindow(window["viewer"], cPoint, "位置信息", html, -30);
+						}
+					},
+					onError(message) {
+						
+					}
+				});
+			},
+
+			/**
+			 * 清空测量数据
+			 */
+			clearMeasurementData() {
+				this.currentIndex = -1;
+				jt3d.CommonTools.clear();
+				if (popup) {
+					popup.close();
+				}
+
+				//还原左键单击事件
+				this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+			},
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.el-avatar{
+		width: 70rem !important;
+		height: 70rem !important;
+		font-size: 14px !important;
+		cursor: pointer;
+	}
+	
+	.el-button{
+		height: 32rem;
+		font-size: 16rem;
+		padding: 8rem 15rem;
+	}
+	
+	.jt-measure {
+		.el-col {
+			padding: 10rem;
+			// color: rgba(90, 172, 255, 1.0);
+			color: #fff;
+		}
+
+		i {
+			display: inline-block;
+			width: 100%;
+			height: 36rem;
+			line-height: 36rem;
+			text-align: center;
+			border-radius: 5rem;
+			font-size: 40rem;
+			// color: rgba(90, 172, 255, 1.0);
+			color: #fff;
+			transition: all .3s;
+			-webkit-transition: all .3s
+		}
+
+		.selectStyle {
+			// background: rgba(135, 182, 254, 0.5);
+			background: rgb(0 44 126);
+			--el-avatar-size: 70rem !important;
+		}
+
+		.defaultStyle {
+			background: #ffffff00;
+			--el-avatar-size: 70rem !important;
+		}
+
+		.selectFontStyle {
+			color: #fff;
+		}
+	}
+</style>

+ 278 - 0
src/views/Map3d - 副本/components/navigation.vue

@@ -0,0 +1,278 @@
+<script setup>
+
+	import jt3dNavigation from 'cesium-navigation-es6';
+
+	import {
+		inject
+	} from "vue";
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	
+</template>
+
+<script>
+	let jt3d = undefined;
+	export default {
+		props: {
+
+		},
+
+		/**
+		 * 数据
+		 */
+		data() {
+			return {
+		
+			}
+		},
+
+		/**
+		 * 方法
+		 */
+		methods: {
+			/**
+			 * 比例尺、指南针
+			 */
+			initNavigation(jt3d) {
+				let options = {};
+				// 用于在使用重置导航重置地图视图时设置默认视图控制。接受的值是Cesium.Cartographic 和 Cesium.Rectangle.
+				options.defaultResetView = Cesium.Rectangle.fromDegrees(121.13766, 36.99670, 121.94984, 37.55286);
+				// options.defaultResetView = Cesium.Cartographic.fromDegrees(103.84,31.15,24000);
+				// options.defaultResetView = Cesium.Cartographic.fromDegrees(Cesium.Math.toRadians(103.84),Cesium.Math.toRadians(31.15),Cesium.Math.toRadians(24000));
+				options.orientation = {
+					heading: Cesium.Math.toRadians(0),
+					pitch: Cesium.Math.toRadians(-90),
+					roll: 0
+				};
+			
+				//相机延时
+				options.duration = 4; //默认为3s
+			
+				// 用于启用或禁用罗盘。
+				options.enableCompass = true;
+				// 用于启用或禁用指南针外环。
+				options.enableCompassOuterRing = true;
+				// 用于启用或禁用缩放控件。
+				options.enableZoomControls = true;
+				// 用于启用或禁用距离图例。
+				options.enableDistanceLegend = false;
+			
+				//修改重置视图的tooltip
+				options.resetTooltip = "重置视图";
+				//修改放大按钮的tooltip
+				options.zoomInTooltip = "放大";
+				//修改缩小按钮的tooltip
+				options.zoomOutTooltip = "缩小";
+			
+				//如需自定义罗盘控件,请看下面的自定义罗盘控件
+				new jt3dNavigation(jt3d._viewer, options);
+			},
+
+		},
+
+		mounted() {
+			//比例尺、指南针
+			this.initNavigation(jt3d);
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	$jt3d-text-color:#fff;
+	$jt3d-content-color:#fff;
+
+	$jt3d-select-bg:red;
+
+	.query-keyword {
+		position: absolute;
+		top: 80rem;
+		width: 200rem;
+		left: 10rem;
+		border: 1rem solid rgb(0 44 126 / 100%);
+
+		.el-input {
+			--el-input-bg-color: rgb(0 44 126 / 50%);
+			--el-input-border-color: rgb(0 44 126 / 50%);
+			--el-input-placeholder-color: #fff;
+
+			--el-fill-color-blank: rgb(0 44 126 / 80%);
+			--el-text-color-regular: #fff;
+			--el-color-primary: #fff --el-border-radius-base:0rem;
+			--el-border-radius-base: 0rem;
+
+			.el-button {
+				background-color: rgb(0 44 126 / 100%);
+				color: #fff;
+			}
+		}
+
+		.autocomplete {
+			--el-fill-color-blank: rgb(0 44 126 / 0%);
+		}
+	}
+
+	.autocomplete ul {
+		font-family: sans-serif;
+		position: absolute;
+		list-style: none;
+		background: rgb(0 44 126 / 30%);
+		margin: 0;
+		width: 80%;
+		margin-top: 1rem;
+		margin-left: -1rem;
+		border: 1rem solid rgb(0 44 126 / 100%);
+	}
+
+	.autocomplete ul li {
+		text-decoration: none;
+		display: block;
+		background: rgb(0 44 126 / 30%);
+		color: #fff;
+		padding: 5rem;
+		margin-left: -40rem;
+		text-align: left;
+	}
+
+	.autocomplete ul li:hover,
+	.autocomplete ul li.focus-list {
+		color: white;
+		background: #2F9AF7;
+	}
+
+	.query-result {
+		position: absolute;
+		border-top: none;
+		padding-bottom: 0rem;
+		width: 100%;
+		z-index: 100;
+		border: 1rem solid rgb(0 44 126 / 100%);
+		background: rgb(0 44 126 / 30%);
+		margin-left: -1rem;
+
+		--el-fill-color-blank: rgb(0 44 126 / 0%);
+		--color: #fff;
+		--el-color-primary: #fff;
+
+		.query-result__item {
+			height: 80rem;
+			padding: 0 10rem;
+			display: flex;
+			justify-content: flex-start;
+			align-items: center;
+			margin-left: -40rem;
+			text-align: left;
+
+			&:hover {
+				// background-color: var(--mars-select-bg);
+			}
+
+			.query-result__context {
+				flex-grow: 1;
+				width: 90%;
+
+				.query-result-text {
+					font-size: 16rem;
+					width: 200rem;
+					font-family: Source Han Sans CN;
+					font-weight: 400;
+					// color: var($jt3d-text-color);
+					color: $jt3d-text-color;
+
+					.query-result-text_num {
+						width: 20rem;
+						height: 20rem;
+						margin-right: 5rem;
+						display: inline-block;
+						text-align: center;
+						background: rgb(0 44 126 / 100%);
+					}
+				}
+
+				.query-result-sub {
+					font-size: 14rem;
+					width: 200rem;
+					margin-left: 19rem;
+					font-family: Source Han Sans CN;
+					font-weight: 400;
+					// color: var($jt3d-content-color);
+					color: $jt3d-content-color;
+				}
+			}
+
+			.query-result__more {
+				font-size: 14rem;
+				font-family: Source Han Sans CN;
+				font-weight: 400;
+				// color: var($jt3d-content-color);
+				color: $jt3d-content-color;
+			}
+		}
+
+		.query-result__page {
+			display: flex;
+			justify-content: space-between;
+			padding: 5rem;
+
+			.query-result-allcount {
+				font-size: 14rem;
+				// color: var($jt3d-text-color);
+				color: $jt3d-text-color;
+			}
+		}
+	}
+	
+	/* 四个边角样式 */
+	// .borderstyle {
+	// 	position: relative;
+	// 	width: 100%;
+	// 	height: 490rem;
+	// 	padding: 10rem;
+	// 	border: 1rem solid #008aff70 !important;
+	// 	background-color: rgba(5, 45, 115, 0.7) !important;
+	// 	box-shadow: 0 4rem 15rem 1rem #02213bb3;
+	
+
+		.angle-border {
+			position: absolute;
+			width: 12rem;
+			height: 12rem;
+		}
+	
+		.angle-border-blue {
+			position: absolute;
+			width: 70rem;
+			height: 30rem;
+		}
+	
+		.left-top-border {
+			top: -2rem;
+			left: -2rem;
+			border-left: 2rem solid #008affdd;
+			border-top: 2rem solid #008affdd;
+		}
+	
+		.right-top-border {
+			top: -2rem;
+			right: -2rem;
+			border-right: 2rem solid #008affdd;
+			border-top: 2rem solid #008affdd;
+		}
+	
+		.left-bottom-border {
+			bottom: -2rem;
+			left: -2rem;
+			border-bottom: 2rem solid #FFFFFF;
+			border-left: 2rem solid #FFFFFF;
+		}
+	
+		.right-bottom-border {
+			bottom: -2rem;
+			right: -2rem;
+			border-right: 2rem solid #FFFFFF;
+			border-bottom: 2rem solid #FFFFFF;
+		}
+	// }
+</style>

+ 318 - 0
src/views/Map3d - 副本/components/printmap.vue

@@ -0,0 +1,318 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	import {
+		ref
+	} from "vue";
+	import {
+		inject
+	} from "vue";
+	import html2canvas from "html2canvas";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-MapPrinting">
+		<div class="middleviewer">
+			<el-input v-model="inputValue.mapname" placeholder="请输入地图名称" @focus="getfous" @blur="onblur" />
+			<div class="viewer">
+				<div id="printbox" ref="print"></div>
+				<div class="viewertop" display='block' ref="thumbnailmap"></div>
+				<div style="display:none" ref="originalmap"></div>
+			</div>
+		</div>
+		<div class="viewerbottom">
+			<!-- <el-button color="rgb(20 136 255)" v-print="printObj"><span style="color: #fff;font-size: 16rem;">打 印</span></el-button> -->
+			<el-button color="rgb(255 100 100)" @click="download"><span style="color: #fff;font-size: 16rem;">下 载</span></el-button>
+		</div>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+	export default {
+		data() {
+			return {
+				inputValue: {
+					mapname: "默认地图",
+				},
+
+				printObj: {
+					id: "printbox",
+					popTitle: "", // 打印配置页上方的标题
+					extraCss: "background-color:red",
+					preview: false, // 是否启动预览模式,默认是false
+					previewTitle: " 关闭预览", // 打印预览的标题
+					previewPrintBtnLabel: "点击打印", // 打印预览的标题下方的按钮文本,点击可进入打印
+					zIndex: 20002, // 预览窗口的z-index,默认是20002,最好比默认值更高
+					previewBeforeOpenCallback() {
+						console.log("正在加载预览窗口!")
+					}, // 预览窗口打开之前的callback
+					previewOpenCallback() {
+						console.log("已经加载完预览窗口,预览打开了!");
+					}, // 预览窗口打开时的callback
+					beforeOpenCallback() {
+						console.log("开始打印之前!");
+					}, // 开始打印之前的callback
+					openCallback() {
+						console.log("执行打印了!");
+					}, // 调用打印时的callback
+					closeCallback() {
+						console.log("关闭了打印工具!");
+					},
+					clickMounted() {
+						console.log("点击v-print绑定的按钮了!");
+					},
+					standard: "",
+					extarCss: "",
+				},
+			};
+		},
+		methods: {
+			//当选择器的输入框获得焦点时触发,标题获取焦点清空输入框
+			getfous() {
+				this.inputValue.mapname = ""
+			},
+
+			//当选择器的输入框失去焦点时触发
+			onblur() {
+				//删除print组件的内容
+				this.$refs.print.innerHTML = "";
+				// 获取标题
+				let value = this.inputValue.mapname;
+
+				//获取输入框的缺省内容
+				let text = value.length > 0 ? value : '默认地图标题';
+				let canvas = this.changcanvastitile(this.$refs.originalmap.lastChild, text);
+				let url = canvas.toDataURL('image/png', 5.0)
+				let img = document.createElement('img');
+				img.style.display = "block"
+				img.style.width = canvas.style.width;
+				img.style.height = canvas.style.height;
+				img.src = url
+				this.$refs.print.appendChild(img);
+			},
+
+			//下载按钮
+			download() {
+				if (this.$refs.originalmap.children.length <= 0) {
+					ElMessage.error("截图未成功");
+					return
+				}
+				let value = this.inputValue.mapname;
+				//获取输入框的缺省内容
+				let text = value.length > 0 ? value : '默认地图标题';
+
+				let img = this.$refs.print.lastChild;
+				let a = document.createElement('a');
+				a.style.display = 'none';
+				a.download = text + '.png';
+				a.href = img.src;
+				document.body.appendChild(a);
+				a.click();
+				document.body.removeChild(a);
+			},
+
+			//更新打印标题
+			changcanvastitile(canvas, text) {
+
+				//清理标题位置区域
+				let width = parseInt(canvas.style.width.slice(0, -2));
+				let height = parseInt(canvas.style.height.slice(0, -2));
+				//获取上下文
+				const ctx = canvas.getContext('2d');
+				//清理标题问题
+				ctx.clearRect(0, 0, width, 160)
+				//设置字体
+				ctx.font = "bold 50rem arial";
+				document.fonts.load(ctx.font);
+				//设置填充颜色
+				ctx.fillStyle = "black";
+				//循环输入标题,字间距50rem
+				for (let i = 0; i < text.length; i++) {
+					//第I个字的水平位置=((canvs.leght)/2-(text.legth)*letterspace/2+i*letterspace)
+					let x = Math.ceil(width / 2) - (text.length - 1) * 50 + i * 100
+					//水平绘制填充文本
+					ctx.fillText(text[i], x, 100);
+				}
+				return canvas;
+			},
+
+			//打印地图截屏
+			screenshot() {
+				this.$refs.print.innerHTML = "";
+				this.$refs.thumbnailmap.innerHTML = ""
+				this.$refs.originalmap.innerHTML = '';
+				this.inputValue.mapname = "默认地图"
+				html2canvas(this.$parent.$parent.$refs.refMap3d.$refs.cesiumContainer, {
+
+					// backgroundColor: null, //画出来的图片有白色的边框,不要可设置背景为透明色(null)
+					useCORS: true, //支持图片跨域
+					scale: 1, //设置放大的倍数
+					// tainTest:false,
+					// foreignObjectRendering: true,//// 是否在浏览器支持的情况下使用ForeignObject渲染
+					dpi: 300,
+					// width:1920,
+					// height:1080
+
+				}).then(
+					(canvas) => {
+						let url = canvas.toDataURL('image/png', 5.0)
+						let img = document.createElement('img');
+						img.style.display = "block"
+						img.style.width = "calc(100% - 0rem)"
+						img.style.height = "calc(100% - 0rem)";
+						img.src = url
+						//缩略图
+						this.$refs.thumbnailmap.appendChild(img);
+						//创建新的canvas
+						let canvasnew = this.createmap(canvas)
+						let urla = canvasnew.toDataURL('image/png', 5.0)
+						let imga = document.createElement('img');
+						imga.style.display = "block"
+						imga.style.width = canvas.style.width / 2;
+						imga.style.height = canvas.style.height / 2;
+						imga.src = urla
+						//原图
+						this.$refs.originalmap.appendChild(canvasnew);
+						//打印图
+						this.$refs.print.appendChild(imga)
+					}
+				)
+			},
+
+			createmap(img) {
+				//渲染之前先清理掉所有所有指定canvas
+				if (document.getElementById('canvasid')) {
+					document.getElementById('canvasid').remove();
+				}
+				let width = parseInt(img.style.width.slice(0, -2));
+				let height = parseInt(img.style.height.slice(0, -2));
+
+				let canvas = this.createHDCanvas(width + 60, height + 160, 'block')
+
+				//获取上下文
+				const ctx = canvas.getContext('2d');
+				//获取图片对象
+				ctx.drawImage(img, 30, 120, width, height)
+				// let value = this.$refs.refinput.value;
+				let value = this.inputValue.mapname;
+				let text = value.length > 0 ? value : '默认地图标题';
+				console.log("text")
+				console.log(text)
+				ctx.clearRect(0, 0, width, 120)
+				//设置字体
+				ctx.font = "bold 50rem arial";
+				//设置填充颜色
+				ctx.fillStyle = "black";
+				//循环输入标题,字间距50rem
+				for (let i = 0; i < text.length; i++) {
+					//第I个字的水平位置=((canvs.leght)/2-(text.legth)*letterspace/2+i*letterspace)
+					let x = Math.ceil(width / 2) - (text.length - 1) * 50 + i * 100
+					//水平绘制填充文本
+					ctx.fillText(text[i], x, 100);
+				}
+				return canvas;
+			},
+			createHDCanvas(w = 300, h = 150, display = 'block') {
+				let ratio = window.devicePixelRatio * 1 || 1;
+				let canvas = document.createElement('canvas');
+				canvas.id = "canvasid";
+				canvas.width = w * ratio; // 实际渲染像素
+				canvas.height = h * ratio; // 实际渲染像素
+				canvas.style.display = display;
+				canvas.style.width = `${w}rem`; // 控制显示大小
+				canvas.style.height = `${h}rem`; // 控制显示大小
+				canvas.style.backgroundColor = "red";
+				// setTransform() 允许您缩放、旋转、移动并倾斜当前的环境
+				canvas.getContext('2d').setTransform(ratio, 0, 0, ratio, 0, 0);
+				return canvas;
+			},
+		},
+
+		mounted() {
+			// //获取角色
+			// this.info = JSON.parse(localStorage.getItem("person"));
+			// //获取角色id
+			// this.id = this.info.id;
+			// this.$bus.on("screenshot", (e) => {
+			// 	console.log("aaaaa")
+			// 	this.screenshot()
+			// })
+		},
+	};
+</script>
+
+<style lang="scss" scoped>
+	.jt-MapPrinting {
+		width: 100%;
+		height: 100%;
+		overflow: hidden;
+
+		--el-fill-color-blank: rgb(0 44 126 / 68%);
+		--el-text-color-regular: rgb(216 240 255);
+		--el-border-color: rgb(35 135 255);
+
+		.middleviewer {
+			height: 92%;
+
+			.viewer {
+				position: relative;
+				width: 100% !important;
+				height: calc(100% - 29rem) !important;
+				overflow: hidden;
+
+				.viewertop {
+					width: calc(100% - 2rem);
+					height: calc(100% - 2rem);
+					border: 1rem solid rgb(35 135 255);
+					position: absolute;
+					top: 0;
+					left: 0;
+				}
+			}
+		}
+
+		.viewerbottom {
+			margin: 10rem;
+		}
+	}
+
+	::v-deep .el-input {
+		flex-grow: 0 !important;
+		width: calc(100%);
+		height: 30rem !important;
+		letter-spacing: 100rem;
+	}
+
+	//输入框文字颜色
+	::v-deep .el-input__inner {
+		color: rgb(255, 255, 255);
+		text-align: center;
+	}
+
+	//输入框背景色
+	::v-deep .el-input__wrapper {
+		background-color: rgba(255, 255, 255, 0) !important;
+	}
+
+	::v-deep .el-button {
+		border-radius: 3rem !important;
+		height: 32rem;
+	}
+
+	::v-deep .el-button--primary {
+		background-color: rgba(64, 158, 255, 0.6) !important;
+	}
+
+	::-webkit-scrollbar {
+		width: 0rem;
+	}
+</style>

+ 465 - 0
src/views/Map3d - 副本/components/query-graphics.vue

@@ -0,0 +1,465 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage,
+		ElLoading
+	} from 'element-plus';
+
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-query-graphics">
+		<el-row :gutter="20" style="margin-left: 0rem; margin-right: 0rem">
+			<el-col :span="8" v-for="(item,index) in queryGraphics" @click="handleQueryGraphics(item.type,index)">
+				<el-avatar shape="circle" :size="70" :class="currentIndex===index?'selectStyle':'defaultStyle'">
+					<i :class="[item.icon,currentIndex===index?'selectFontStyle':'']" />
+				</el-avatar>
+				<div style="margin-top: 5rem; font-size: 14rem;" :class="currentIndex===index?'selectFontStyle':''">{{item.label}}</div>
+			</el-col>
+		</el-row>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+	let loading = undefined;
+
+	import {
+		Store
+	} from '@/store/index'
+	let store = Store();
+
+	import {
+		deepTree
+	} from "@/utils/deepTree.js";
+
+	export default {
+		props: {
+
+		},
+		watch: {
+
+		},
+
+		/* 数据 */
+		data() {
+			return {
+				currentIndex: -1,
+				queryGraphics: [{
+						label: '点查询',
+						type: 'Point',
+						number: 0,
+						icon: 'iconfont icon-svgdianchaxun'
+					},
+					{
+						label: '线查询',
+						type: 'Line',
+						number: 1,
+						icon: 'iconfont icon-svgxianchaxun'
+					},
+					{
+						label: '圆形查询',
+						type: 'Circle',
+						number: 2,
+						icon: 'iconfont icon-svgyuanxingchaxun'
+					},
+					{
+						label: '矩形查询',
+						type: 'Rectangle',
+						number: 3,
+						icon: 'iconfont icon-svgjuxingchaxun'
+					},
+					{
+						label: '多边形',
+						type: 'Polygon',
+						number: 4,
+						icon: 'iconfont icon-svgduobianxingchaxun'
+					},
+					{
+						label: '清除',
+						type: 'clear',
+						number: 5,
+						icon: 'iconfont icon-shanchu'
+					},
+				],
+			}
+		},
+
+		/* 方法 */
+		methods: {
+			/**
+			 * 查询事件
+			 * @param {Object} type 查询类型
+			 * @param {Object} index 第几个被选中
+			 */
+			handleQueryGraphics(type, index) {
+				let _self = this;
+				this.currentIndex = index;
+
+				//移除左键单击事件
+				if (jt3d.handlerLeftClick) {
+					jt3d.handlerLeftClick.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); //移除事件
+				}
+
+				jt3d.CommonTools.clear();
+				switch (type) {
+					case "Point": //点查询
+						jt3d.CommonTools.queryByPoint(function(coordinates) {
+							console.log(coordinates)
+
+							//还原左键单击事件
+							_self.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+
+							/* 转换坐标 */
+							let points = coordinates.split(',');
+
+							_self.initQuery({
+								spatialType: '点',
+								coordinate: Number(points[0]) + " " + Number(points[1]),
+								buffer: ''
+							});
+
+						});
+						break;
+					case "Line": //线查询
+						jt3d.CommonTools.queryByLine(function(coordinates) {
+							console.log(coordinates)
+
+							//还原左键单击事件
+							_self.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+
+							/* 转换坐标 */
+							let points = coordinates.split(',');
+							let pointsArray = [];
+							for (let i = 0; i < points.length;) {
+								pointsArray.push(Number(points[i]) + " " + Number(points[i + 1]));
+								i = i + 2;
+							}
+
+							_self.initQuery({
+								spatialType: '线',
+								coordinate: pointsArray.join(','),
+								buffer: ''
+							});
+						});
+						break;
+					case "Circle": //圆形查询
+						jt3d.CommonTools.queryByCircle(function(coordinates, radius) {
+							console.log("圆点:" + coordinates + ",半径:" + radius)
+
+							//还原左键单击事件
+							_self.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+
+							/* 转换坐标 */
+							let points = coordinates.split(',');
+
+							_self.initQuery({
+								spatialType: '点',
+								coordinate: Number(points[0]) + " " + Number(points[1]),
+								buffer: radius
+							});
+
+						});
+						break;
+					case "Rectangle": //矩形查询
+						jt3d.CommonTools.queryByRectangle(function(coordinates) {
+							console.log(coordinates)
+
+							//还原左键单击事件
+							_self.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+
+							/* 转换坐标 */
+							let points = coordinates.split(',');
+							let pointsArray = [];
+							for (let i = 0; i < points.length;) {
+								pointsArray.push(Number(points[i]) + " " + Number(points[i + 1]));
+								i = i + 2;
+							}
+
+							_self.initQuery({
+								spatialType: '面',
+								coordinate: pointsArray.join(','),
+								buffer: ''
+							});
+
+						});
+						break;
+					case "Polygon": //多边形查询
+						jt3d.CommonTools.queryByPolygon(function(coordinates) {
+							console.log(coordinates)
+
+							//还原左键单击事件
+							_self.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+
+							/* 转换坐标 */
+							let points = coordinates.split(',');
+							let pointsArray = [];
+							for (let i = 0; i < points.length;) {
+								pointsArray.push(Number(points[i]) + " " + Number(points[i + 1]));
+								i = i + 2;
+							}
+
+							_self.initQuery({
+								spatialType: '面',
+								coordinate: pointsArray.join(','),
+								buffer: ''
+							});
+
+						});
+						break;
+					case "clear": //清除查询效果
+						this.currentIndex = -1;
+
+						//清除绘制
+						jt3d.CommonTools.clear();
+
+						//还原左键单击事件
+						this.$parent.$parent.$refs.refMap3d.clickEntity(jt3d);
+
+						//清除高亮显示
+						let list = jt3d._dataSources.getByName("单击高亮显示")
+						list.forEach(res => {
+							jt3d._dataSources.remove(res)
+						})
+
+						//清除定位样式
+						if (jt3d.LocateUtil._locationEntity) {
+							window["viewer"].entities.remove(jt3d.LocateUtil._locationEntity);
+						}
+						break;
+				}
+			},
+
+			/**
+			 * @param {Object} options
+			 */
+			initQuery(options) {
+				let _self = this;
+				let treeNodes = [];
+
+				//清除高亮显示
+				let list = jt3d._dataSources.getByName("单击高亮显示")
+				list.forEach(res => {
+					jt3d._dataSources.remove(res)
+				})
+
+				//清除定位样式
+				if (jt3d.LocateUtil._locationEntity) {
+					window["viewer"].entities.remove(jt3d.LocateUtil._locationEntity);
+				}
+
+				const getData = () => {
+
+					if (store.queryMapTables.length > 0) {
+						//查询等待框
+						loading = ElLoading.service({
+							lock: true,
+							text: 'Loading',
+							background: 'rgba(0, 0, 0, 0.7)',
+						});
+
+						let data = [];
+						store.queryMapTables.forEach((itemTable, index) => {
+							let result = getAxios(itemTable, options);
+							data.push(result);
+						})
+
+						Promise.all(data).then(itemList => {
+
+							console.log("itemList", itemList) //itemList返回的数据是按顺序的
+							//执行自己接下来的操作
+							//doSomething
+
+							itemList.forEach((item, index) => {
+								let field = item.table;
+								let tableName = item.table[0].tableName;
+								let tableDescription = item.table[0].tableDescription;
+
+								if (item.data.features.length > 0) {
+									//添加父节点
+									let parentNode = {
+										id: tableName,
+										parentid: "CIM",
+										label: tableDescription + "(" + item.data.features.length + ")",
+									};
+									treeNodes.push(parentNode);
+
+									item.data.features.forEach((itemData, index) => {
+
+										//**************高亮显示****************
+
+										// /* 转换坐标 */
+										// let positions = itemData.geometry.coordinates[0][0].map(point => {
+										// 	return Cesium.Cartesian3.fromDegrees(point[0], point[1], point[2] || 0);
+										// });
+
+										// //先创建一个CustomDataSource源,然后把entity存入这里面
+										// let Polygon = new Cesium.CustomDataSource("单击高亮显示");
+										// jt3d._dataSources.add(Polygon);
+										// //添加数据的方式
+										// Polygon.entities.add({
+										// 	polygon: {
+										// 		hierarchy: new Cesium.PolygonHierarchy(positions),
+										// 		material: Cesium.Color.fromCssColorString("rgba(255,0,255,.7)"),
+										// 		classificationType: Cesium.ClassificationType.BOTH,
+										// 	},
+										// });
+
+										//**************高亮显示****************
+
+										let childNode = {
+											id: itemData.properties["id"],
+											parentid: tableName,
+											field: field,
+											data: itemData,
+										};
+
+										switch (tableName) {
+											//==============规划管理数据-重要控制线=========================
+											case "yjjbnt": //永久基本农田
+												childNode.label = itemData.properties["cfzr"] + "(" + itemData.properties["zzsxmc"] + ")"
+												break;
+											case "yjtz": //永久基本农田调整
+												childNode.label = itemData.properties["zldwmc"] + "(" + itemData.properties["dlmc"] + ")"
+												break;
+											case "bnrgdbh": //不纳入耕地保护目标
+												childNode.label = itemData.properties["zldwmc"] + "(" + itemData.properties["dlmc"] + ")"
+												break;
+											case "gdbhrw": //耕地保护任务
+												childNode.label = itemData.properties["zldwmc"] + "(" + itemData.properties["dlmc"] + ")"
+												break;
+
+												//==============规划管理数据-历史规划==============
+											case "tdzgh": //土地利用总体规划
+												childNode.label = itemData.properties["ghdlmc"]
+												break;
+											case "jsyd": //建设用地管制区
+												childNode.label = itemData.properties["id"]
+												break;
+
+												//==============现状类数据-森林资源-森林资源调查==============
+											case "slyzt": //2019年森林资源管理一张图
+												childNode.label = itemData.properties["id"]
+												break;
+
+												//==============现状类数据-国土调查==============
+											case "ed2009": //二调
+												childNode.label = itemData.properties["zldwmc"] + "(" + itemData.properties["dlmc"] + ")"
+												break;
+											case "ed2020": //二调2020
+												childNode.label = itemData.properties["zldwmc"] + "(" + itemData.properties["dlmc"] + ")"
+												break;
+											case "ed2021": //二调2021
+												childNode.label = itemData.properties["zldwmc"] + "(" + itemData.properties["dlmc"] + ")"
+												break;
+											case "sddltb": //三调   
+												childNode.label = itemData.properties["zldwmc"] + "(" + itemData.properties["dlmc"] + ")"
+												break;
+										}
+
+										treeNodes.push(childNode);
+									});
+								}
+							});
+
+							//处理查询结果树
+							if (treeNodes.length > 0) {
+
+								_self.$parent.$parent.$refs.refQueryResult.expandedKeys = []
+								_self.$parent.$parent.$refs.refQueryResultPopup.isshow = true;
+								_self.$parent.$parent.$refs.refQueryResult.treeData = deepTree(treeNodes);
+
+								//默认选中第一个节点并赋予选中样式
+								_self.$nextTick(function() {
+									let currentNode = _self.$parent.$parent.$refs.refQueryResult.treeData[0].children[0];
+									let currentKey = currentNode.id;
+									_self.$parent.$parent.$refs.refQueryResult.currentKey = currentKey;
+									_self.$parent.$parent.$refs.refQueryResult.$refs.tree.setCurrentKey(currentKey);
+									_self.$parent.$parent.$refs.refQueryResult.handleNodeClick(currentNode);
+								});
+
+								//expandedKeys默认展开treedata第一层,加载第一层数据
+								_self.$parent.$parent.$refs.refQueryResult.expandedKeys.push(_self.$parent.$parent.$refs.refQueryResult.treeData[0].id)
+							}
+
+							//清除绘制
+							jt3d.CommonTools.clear();
+
+							//关闭等待框
+							loading.close()
+
+						})
+					}
+				}
+
+				const getAxios = (itemTable, options) => {
+					return new Promise(function(resolve, reject) {
+						_self.$http.get('/getSpatialQuery', {
+							tableName: itemTable,
+							spatialType: options.spatialType,
+							coordinate: options.coordinate,
+							buffer: options.buffer
+						}).then(res => {
+							resolve(res)
+						});
+					}).catch(err => {
+
+					})
+				}
+
+				getData();
+			},
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.jt-query-graphics {
+		.el-col {
+			padding: 10rem;
+			// color: rgba(90, 172, 255, 1.0);
+			//color: #55ffff;
+			color: #fff;
+		}
+
+		i {
+			display: inline-block;
+			width: 100%;
+			height: 36rem;
+			line-height: 36rem;
+			text-align: center;
+			border-radius: 5rem;
+			font-size: 40rem;
+			// color: rgba(90, 172, 255, 1.0);
+			// color: #55ffff;
+			color: #fff;
+			transition: all .3s;
+			-webkit-transition: all .3s
+		}
+
+		.selectStyle {
+			// background: rgba(135, 182, 254, 0.5);
+			background: rgb(0 44 126);
+		}
+
+		.defaultStyle {
+			background: #ffffff00;
+		}
+
+		.selectFontStyle {
+			color: #fff;
+		}
+	}
+</style>

+ 365 - 0
src/views/Map3d - 副本/components/query-keyword.vue

@@ -0,0 +1,365 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	/**
+	 * element-plus字体
+	 */
+	import {
+		Search,
+		DArrowRight
+	} from '@element-plus/icons-vue';
+	import {
+		inject
+	} from "vue";
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="query-keyword fadein-left">
+		<el-input v-model="search.searchKey" placeholder="请输入查询关键字" @change="searchKeyChange" @input="searchKeyChange" clearable>
+			<template #append>
+				<el-button :icon="Search" @click="btnSearchClick" />
+			</template>
+		</el-input>
+		<div class="autocomplete " v-if="search.searchListShow">
+			<ul>
+				<li v-for="(item,index) in search.searchCompleteData" :key="index" @click="SearchSelect(index)">
+					{{ item }}
+				</li>
+			</ul>
+		</div>
+		<div class="query-result" v-if="resultListShow">
+			<template v-if="resultCompleteData && resultCompleteData.length">
+				<ul>
+					<li v-for="(item, i) in resultCompleteData" :key="i" class="query-result__item" @click.stop="flyTo(item)">
+						<div class="query-result__context">
+							<p class="query-result-text" :title="item.name">
+								<span class="query-result-text_num">{{ i + 1 }}</span>
+								{{ item.name }}
+							</p>
+							<p class="query-result-sub">{{ item.label }}</p>
+						</div>
+						<p class="query-result__more">
+							<el-icon>
+								<DArrowRight />
+							</el-icon>
+						</p>
+					</li>
+				</ul>
+				<div class="query-result__page">
+					<p class="query-result-allcount">共{{ resultCompleteData.length }}条结果</p>
+					<el-pagination layout="prev, pager, next" size="small" :total="resultCompleteData.length" pageSize="1" :simple="true" />
+				</div>
+			</template>
+		</div>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+	export default {
+		props: {
+
+		},
+
+		/**
+		 * 数据
+		 */
+		data() {
+			return {
+				search: {
+					searchKey: "", // input框输入的值,用v-model双向绑定
+					searchDataList: [], // autocomplete查询数据,一般由后端返回
+					searchCompleteData: [], // autocomplete查询到的数据
+					searchListShow: false,
+				},
+				resultCompleteData: [], // 查询结果
+				resultListShow: false,
+				pagination: {
+					size: "small",
+					total: 0,
+					pageSize: 6,
+					simple: true
+				}
+			}
+		},
+
+		/**
+		 * 方法
+		 */
+		methods: {
+			
+			/**
+			 * 在 Input 值改变时触发
+			 * 当 modelValue 改变时,当输入框失去焦点或用户按Enter时触发
+			 */
+			searchKeyChange() {
+				let _self = this;
+				this.search.searchListShow = true;
+				this.resultListShow = false;
+				let searchRegex = new RegExp(this.search.searchKey, 'i');
+				this.search.searchCompleteData = []; // 先把原有的数据清空,重新查询
+				if (this.search.searchKey === '') return; //如果什么都没有输入,则不用查找
+				this.search.searchDataList.forEach((item) => {
+					if (searchRegex.test(item.label)) {
+						_self.search.searchCompleteData.push(item.label)
+					}
+				});
+			},
+
+			/**
+			 * 选中联想查询数据
+			 * @param {Object} index
+			 */
+			SearchSelect(index) {
+				this.search.searchListShow = false;
+				console.log(this.search.searchCompleteData[index]);
+				this.getSearchData(this.search.searchCompleteData[index]);
+			},
+
+			/**
+			 * 查询按钮
+			 */
+			btnSearchClick() {
+				if (this.search.searchKey === "") {
+					ElMessage("请输入查询关键字");
+					return;
+				}
+				this.getSearchData(this.search.searchKey);
+			},
+
+			/**
+			 * 数据查询
+			 * @param {Object} queryString
+			 */
+			getSearchData(queryString) {
+				let _self = this;
+				_self.$http.get('/getTableList', {
+					tableName: 'base_sys_role',
+					sqlWhere: " label like '%" + queryString + "%'",
+					orderByField: ''
+				}).then(res => {
+					console.log('从服务端搜索数据', res.data)
+					_self.resultCompleteData = res.data;
+					_self.resultListShow = true;
+					_self.search.searchListShow = false;
+				});
+			}
+		},
+
+		mounted() {
+			let _self = this;
+			_self.$http.get('/getTableList', {
+				tableName: 'base_sys_role',
+				sqlWhere: '',
+				orderByField: ''
+			}).then(res => {
+				console.log('从服务端搜索数据', res.data)
+				_self.search.searchDataList = res.data;
+			});
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	$jt3d-text-color:#fff;
+	$jt3d-content-color:#fff;
+
+	$jt3d-select-bg:red;
+
+	.query-keyword {
+		position: absolute;
+		top: 80rem;
+		width: 200rem;
+		left: 10rem;
+		border: 1rem solid rgb(0 44 126 / 100%);
+
+		.el-input {
+			--el-input-bg-color: rgb(0 44 126 / 50%);
+			--el-input-border-color: rgb(0 44 126 / 50%);
+			--el-input-placeholder-color: #fff;
+
+			--el-fill-color-blank: rgb(0 44 126 / 80%);
+			--el-text-color-regular: #fff;
+			--el-color-primary: #fff --el-border-radius-base:0rem;
+			--el-border-radius-base: 0rem;
+
+			.el-button {
+				background-color: rgb(0 44 126 / 100%);
+				color: #fff;
+			}
+		}
+
+		.autocomplete {
+			--el-fill-color-blank: rgb(0 44 126 / 0%);
+		}
+	}
+
+	.autocomplete ul {
+		font-family: sans-serif;
+		position: absolute;
+		list-style: none;
+		background: rgb(0 44 126 / 30%);
+		margin: 0;
+		width: 80%;
+		margin-top: 1rem;
+		margin-left: -1rem;
+		border: 1rem solid rgb(0 44 126 / 100%);
+	}
+
+	.autocomplete ul li {
+		text-decoration: none;
+		display: block;
+		background: rgb(0 44 126 / 30%);
+		color: #fff;
+		padding: 5rem;
+		margin-left: -40rem;
+		text-align: left;
+	}
+
+	.autocomplete ul li:hover,
+	.autocomplete ul li.focus-list {
+		color: white;
+		background: #2F9AF7;
+	}
+
+	.query-result {
+		position: absolute;
+		border-top: none;
+		padding-bottom: 0rem;
+		width: 100%;
+		z-index: 100;
+		border: 1rem solid rgb(0 44 126 / 100%);
+		background: rgb(0 44 126 / 30%);
+		margin-left: -1rem;
+
+		--el-fill-color-blank: rgb(0 44 126 / 0%);
+		--color: #fff;
+		--el-color-primary: #fff;
+
+		.query-result__item {
+			height: 80rem;
+			padding: 0 10rem;
+			display: flex;
+			justify-content: flex-start;
+			align-items: center;
+			margin-left: -40rem;
+			text-align: left;
+
+			&:hover {
+				// background-color: var(--mars-select-bg);
+			}
+
+			.query-result__context {
+				flex-grow: 1;
+				width: 90%;
+
+				.query-result-text {
+					font-size: 16rem;
+					width: 200rem;
+					font-family: Source Han Sans CN;
+					font-weight: 400;
+					// color: var($jt3d-text-color);
+					color: $jt3d-text-color;
+
+					.query-result-text_num {
+						width: 20rem;
+						height: 20rem;
+						margin-right: 5rem;
+						display: inline-block;
+						text-align: center;
+						background: rgb(0 44 126 / 100%);
+					}
+				}
+
+				.query-result-sub {
+					font-size: 14rem;
+					width: 200rem;
+					margin-left: 19rem;
+					font-family: Source Han Sans CN;
+					font-weight: 400;
+					// color: var($jt3d-content-color);
+					color: $jt3d-content-color;
+				}
+			}
+
+			.query-result__more {
+				font-size: 14rem;
+				font-family: Source Han Sans CN;
+				font-weight: 400;
+				// color: var($jt3d-content-color);
+				color: $jt3d-content-color;
+			}
+		}
+
+		.query-result__page {
+			display: flex;
+			justify-content: space-between;
+			padding: 5rem;
+
+			.query-result-allcount {
+				font-size: 14rem;
+				// color: var($jt3d-text-color);
+				color: $jt3d-text-color;
+			}
+		}
+	}
+	
+	/* 四个边角样式 */
+	// .borderstyle {
+	// 	position: relative;
+	// 	width: 100%;
+	// 	height: 490rem;
+	// 	padding: 10rem;
+	// 	border: 1rem solid #008aff70 !important;
+	// 	background-color: rgba(5, 45, 115, 0.7) !important;
+	// 	box-shadow: 0 4rem 15rem 1rem #02213bb3;
+	
+
+		.angle-border {
+			position: absolute;
+			width: 12rem;
+			height: 12rem;
+		}
+	
+		.angle-border-blue {
+			position: absolute;
+			width: 70rem;
+			height: 30rem;
+		}
+	
+		.left-top-border {
+			top: -2rem;
+			left: -2rem;
+			border-left: 2rem solid #008affdd;
+			border-top: 2rem solid #008affdd;
+		}
+	
+		.right-top-border {
+			top: -2rem;
+			right: -2rem;
+			border-right: 2rem solid #008affdd;
+			border-top: 2rem solid #008affdd;
+		}
+	
+		.left-bottom-border {
+			bottom: -2rem;
+			left: -2rem;
+			border-bottom: 2rem solid #FFFFFF;
+			border-left: 2rem solid #FFFFFF;
+		}
+	
+		.right-bottom-border {
+			bottom: -2rem;
+			right: -2rem;
+			border-right: 2rem solid #FFFFFF;
+			border-bottom: 2rem solid #FFFFFF;
+		}
+	// }
+</style>

+ 300 - 0
src/views/Map3d - 副本/components/queryResult.vue

@@ -0,0 +1,300 @@
+<script setup>
+	import {
+		formattingTime
+	} from '@/assets/js/localtime.js';
+
+	import {
+		inject
+	} from "vue";
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+<template>
+	<div class="jt-queryResult">
+		<div class="_left">
+			<el-tree class="tree-line queryResultTree" ref="tree" node-key="id" :data="treeData" :default-expanded-keys="expandedKeys" :current-node-key="currentKey" @node-click="handleNodeClick" highlight-current />
+		</div>
+		<div class="_right">
+			<div id="detailDiv"></div>
+		</div>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+
+	export default {
+		props: {
+			tree: {
+				type: Object,
+				default () {
+					return []
+				}
+			}
+		},
+		data() {
+			return {
+				treeData: this.tree,
+				currentKey: "",
+				expandedKeys: [], //对应要展开的节点id
+			}
+		},
+		methods: {
+			/**
+			 * 树单击事件
+			 */
+			handleNodeClick(treeNode) {
+
+				let _self = this;
+
+				return new Promise((resolve, reject) => {
+
+					if (treeNode.parentid != 'CIM') {
+
+						//清除高亮显示
+						let list = jt3d._dataSources.getByName("单击高亮显示")
+						list.forEach(res => {
+							jt3d._dataSources.remove(res)
+						})
+
+						//高亮显示并定位显示详细信息
+						jt3d.PolygonObject.generatePolygonByPoints(treeNode.data.geometry.coordinates[0][0], {
+							color: [255, 0, 255, 0],
+							outline: true,
+							outlineWidth: 5,
+							outlineColor: [0, 255, 180, 1]
+						}).then((locationEntity) => {
+							// 初始化定位参数
+							let options = {};
+							options.duration = Cesium.defaultValue(options.duration, 2);
+							options.heading = Cesium.defaultValue(options.heading, 0);
+							options.pitch = Cesium.defaultValue(options.pitch, -60);
+							options.range = Cesium.defaultValue(options.range, 800.0);
+
+							let flyToEntity = jt3d.LocateUtil.flyToEntity(locationEntity, options);
+							flyToEntity.then(function(flag) {
+								//详细信息
+								let strHtml = "";
+								strHtml += "<table>";
+								strHtml += "<thead>";
+								strHtml += "<tr>";
+								strHtml += "<th>属性名</th>";
+								strHtml += "<th>属性值</th>";
+								strHtml += "</tr> ";
+								strHtml += " </thead>";
+								strHtml += "<tbody>";
+
+								var field = treeNode.field;
+								var properties = treeNode.data.properties
+								field.forEach(itemField => {
+									if (itemField.isDisplay === 1) {
+										var fieldDesc = itemField.fieldDescription || itemField
+											.fieldName;
+										var fieldVals = properties[itemField.fieldName];
+
+										//日期格式
+										if (itemField.fieldType === 1) {
+											let time = new Date(fieldVals).getTime();
+											fieldVals = formattingTime(time);
+										}
+
+										if (fieldVals != null && fieldVals != "" && fieldVals !=
+											undefined) {
+											strHtml += "<tr>";
+											strHtml += "<td>" + fieldDesc + "</td>";
+											strHtml += "<td>" + fieldVals + "</td>";
+											strHtml += "</tr>";
+										}
+									}
+								});
+
+								strHtml += "</tbody>";
+								strHtml += "</table>";
+
+								let divb = document.getElementById('detailDiv')
+								divb.innerHTML = strHtml; //设置显示的数据,可以是标签.
+
+							});
+
+						});
+					}
+
+					resolve(1)
+				})
+			},
+
+		},
+		mounted() {}
+	}
+</script>
+
+<style lang="scss">
+	.jt-queryResult {
+		overflow: hidden;
+
+		//左侧树
+		&>div:nth-child(1) {
+			width: 220rem;
+			height: 380rem;
+			float: left;
+			overflow: auto;
+			border-right: 5rem solid #ddd;
+
+			.el-tree {
+				background: rgb(28 59 112 / 0%);
+				height: calc(100% - 2rem);
+				color: #fff;
+				--el-tree-node-hover-bg-color: #2a67c3;
+				--el-font-size-base: 14rem;
+
+				.overflowtext {
+					width: auto !important;
+					padding: 0;
+				}
+			}
+
+
+
+			.tree-line {
+				.el-tree-node {
+					position: relative;
+				}
+
+				.el-tree-node__children {
+					padding-left: 16rem !important; // 缩进量
+
+					.el-tree-node__content {
+						padding-left: 18rem !important;
+					}
+				}
+
+				//高亮显示选中样式
+				.el-tree-node.is-current>.el-tree-node__content {
+					background: #2a67c3;
+				}
+
+				// 竖线
+				.el-tree-node::before {
+					content: "";
+					height: 100%;
+					width: 1rem;
+					position: absolute;
+					left: -3rem;
+					top: -26rem;
+					border-width: 1rem;
+					border-left: 1rem dashed rgba(255, 255, 255, .8);
+				}
+
+				// 当前层最后一个节点的竖线高度固定
+				.el-tree-node:last-child::before {
+					height: 38rem; // 可以自己调节到合适数值
+				}
+
+				// 横线
+				.el-tree-node::after {
+					content: "";
+					width: 24rem;
+					height: 20rem;
+					position: absolute;
+					left: -3rem;
+					top: 12rem;
+					border-width: 1rem;
+					border-top: 1rem dashed rgba(255, 255, 255, .8);
+				}
+
+				// 去掉最顶层的虚线,放最下面样式才不会被上面的覆盖了
+				&>.el-tree-node::after {
+					border-top: none;
+				}
+
+				&>.el-tree-node::before {
+					border-left: none;
+				}
+
+				// 展开关闭的icon
+				.el-tree-node__expand-icon {
+					font-size: 16rem;
+
+					// 叶子节点(无子节点)
+					&.is-leaf {
+						color: transparent;
+						display: none; // 也可以去掉
+					}
+				}
+			}
+
+		}
+
+		//右侧基本信息
+		&>div:nth-child(2) {
+			width: calc(100% - 240rem);
+			height: calc(100% - 0rem);
+			float: left;
+			margin-left: 10rem;
+			font-size: 14rem;
+			padding-top: 5rem;
+
+			table {
+				border-collapse: collapse;
+				margin: 0 auto;
+				text-align: center;
+				width: 100%;
+			}
+
+			table td,
+			table th {
+				// border: 1rem solid #ddd;
+				color: #fff;
+				height: 30rem;
+			}
+
+			table thead th {
+				background-color: rgb(28 59 112 / 100%);
+				border: 2rem solid #ddd;
+			}
+
+			table tr:nth-child(odd) {
+				background: rgb(40 89 172 / 60%);
+				border-left: 2rem solid #ddd;
+				border-right: 2rem solid #ddd;
+				border-bottom: 1rem solid #ddd;
+			}
+
+			table tr:nth-child(even) {
+				background: rgb(28 59 112 / 60%);
+				border-left: 2rem solid #ddd;
+				border-right: 2rem solid #ddd;
+				border-bottom: 1rem solid #ddd;
+			}
+
+			// thead 表头固定,tbody 滚动
+			table>thead>tr {
+				display: table;
+				width: 100%;
+				table-layout: fixed;
+			}
+
+			table>tbody {
+				display: block;
+				height: 340rem;
+				/* 隐藏水平溢出内容 */
+				overflow-x: hidden;
+				/* 当垂直内容超出显示高度时以滚动条形式展示 */
+				overflow-y: auto;
+			}
+
+			table>tbody>tr {
+				/* 将tr设置为table元素,以此达到内容沾满table的效果 */
+				display: table;
+				/* 将tr宽度设置为100%,以此达到内容沾满table的效果 */
+				width: 100%;
+				/* 设置table-layout为fixed以达到首行和内容行对其的效果 */
+				table-layout: fixed;
+			}
+
+			table>tbody>tr>td {
+				border-right: 2rem solid #ddd;
+			}
+		}
+	}
+</style>

+ 401 - 0
src/views/Map3d - 副本/components/special-effects.vue

@@ -0,0 +1,401 @@
+<script setup>
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="jt-weather-effects">
+		<el-collapse v-model="activeName" accordion>
+			<el-collapse-item name="特效效果">
+				<template #title>
+					<span class='iconfont icon-tianqizitiku43' />天气特效
+				</template>
+				<el-row :gutter="20">
+					<el-col :span="8" v-for="(item,index) in weather" @click="handleWeatherEffects(item.type,index)">
+						<el-avatar shape="circle" style="width:70rem;height: 70rem;" :class="currentIndex===index?'selectStyle':'defaultStyle'">
+							<i :class="[item.icon,currentIndex===index?'selectFontStyle':'']" />
+						</el-avatar>
+						<div style="margin-top: 5rem; font-size: 14rem;" :class="currentIndex===index?'selectFontStyle':''">{{item.label}}</div>
+					</el-col>
+				</el-row>
+			</el-collapse-item>
+			<el-collapse-item name="天空样式">
+				<template #title>
+					<span class='iconfont icon-tianqizitiku43' />天空样式
+				</template>
+				<el-row :gutter="20">
+					<el-col :span="8" v-for="(item,index) in skybox" @click="handleSkybox(item.type,index)">
+						<!-- <el-avatar :src="item.url" /> -->
+						<el-avatar shape="circle" src="https://empty" style="width:70rem;height: 70rem;">
+							<img :src="item.url" />
+						</el-avatar>
+						<div style="margin-top: 5rem; font-size: 14rem;" :class="currentIndex===index?'selectFontStyle':''">{{item.label}}</div>
+					</el-col>
+				</el-row>
+			</el-collapse-item>
+			<!-- <el-collapse-item name="粒子效果">
+				<template #title>
+					<span class='iconfont icon-tianqizitiku43' />粒子效果
+				</template>
+				<div class="el-collapse-item__content">
+					<el-button color="rgb(20 136 255)" @click="ParticleSystem('add')">加载粒子效果</el-button>
+					<el-button color="rgb(255 100 100)" @click="ParticleSystem('remove')"><span style="color: #fff;">清除粒子效果</span></el-button>
+				</div>
+			</el-collapse-item>
+			<el-collapse-item name="热力图">
+				<template #title>
+					<span class='iconfont icon-tianqizitiku43' />热力图
+				</template>
+				<div class="el-collapse-item__content">
+					<el-button color="rgb(20 136 255)" @click="HeatMap('add')">添加热力图</el-button>
+					<el-button color="rgb(255 100 100)" @click="HeatMap('remove')"><span style="color: #fff;">清除热力图</span></el-button>
+				</div>
+			</el-collapse-item> -->
+		</el-collapse>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+
+	export default {
+		data() {
+			return {
+				activeName: "特效效果",
+				currentIndex: -1,
+				weather: [{
+						label: '雨天',
+						type: 'rain',
+						number: 0,
+						icon: 'iconfont icon-yu'
+					},
+					{
+						label: '雪天',
+						type: 'snow',
+						number: 1,
+						icon: 'iconfont icon-huaban'
+					},
+					{
+						label: '雾天',
+						type: 'fog',
+						number: 2,
+						icon: 'iconfont icon-tianqizitiku43'
+					},
+					{
+						label: '关闭天气',
+						type: 'remove',
+						number: 3,
+						icon: 'iconfont icon-cloudofftianqiguanbi'
+					},
+				],
+				skybox: [{
+						label: '晚霞',
+						type: '晚霞',
+						number: 0,
+						url: 'jt3dSDK/imgs/skybox/01/py.png'
+					},
+					{
+						label: '蓝天',
+						type: '蓝天',
+						number: 1,
+						url: 'jt3dSDK/imgs/skybox/03/py.jpg'
+					},
+					{
+						label: '阴天',
+						type: '阴天',
+						number: 2,
+						url: 'jt3dSDK/imgs/skybox/02/py.jpg'
+					},
+					{
+						label: '蓝色星空',
+						type: '蓝色星空',
+						number: 3,
+						url: 'jt3dSDK/imgs/skybox/05/pz.jpg'
+					},
+					{
+						label: '紫色星空',
+						type: '紫色星空',
+						number: 4,
+						url: 'jt3dSDK/imgs/skybox/04/ny.jpg'
+					},
+				],
+			}
+		},
+		props: {},
+		watch: {},
+
+		/* 方法 */
+		methods: {
+			/**
+			 * 天空盒子事件
+			 * @param {Object} type 天空盒子类型
+			 * @param {Object} index 第几个被选中
+			 */
+			handleSkybox(type, index) {
+				this.currentIndex = index;
+
+				jt3d.SceneEffects.SkyBox.setGroundSkyBox({
+					type: type
+				});
+			},
+
+			/**
+			 * 天气特效事件
+			 * @param {Object} type 天气类型
+			 * @param {Object} index 第几个被选中
+			 */
+			handleWeatherEffects(type, index) {
+				this.currentIndex = index;
+				switch (type) {
+					case "rain": //雨天
+						jt3d.SceneEffects.Weather.removeEffect();
+						jt3d.SceneEffects.Weather.addRainEffect({
+							tiltAngle: 0.3,
+							rainSize: 0.5,
+							rainSpeed: 70
+						});
+						break;
+					case "snow": //雪天
+						jt3d.SceneEffects.Weather.removeEffect();
+						jt3d.SceneEffects.Weather.addSnowEffect();
+						break;
+					case "fog": //雾天
+						jt3d.SceneEffects.Weather.removeEffect();
+						jt3d.SceneEffects.Weather.addFogEffect();
+						break;
+					case "remove": //移除天气特效
+						this.currentIndex = -1;
+						jt3d.SceneEffects.Weather.removeEffect()
+						break;
+
+				}
+			},
+
+			/**
+			 * 粒子效果
+			 */
+			ParticleSystem(type) {
+				let options = {};
+				// 初始化参数默认值
+				options.duration = Cesium.defaultValue(options.duration, 2);
+				options.heading = Cesium.defaultValue(options.heading, 0.5); //指向,默认值0.0(北)
+				options.pitch = Cesium.defaultValue(options.pitch, -40); //俯仰角, 垂直向下。默认值-90(向下看)。
+				options.range = Cesium.defaultValue(options.range, 150); //距目标点距离
+
+				const position = {
+					x: 121.554042,
+					y: 37.395186,
+					z: 25.60
+				};
+
+				// 定位到点
+				let flyToPoint = jt3d.LocateUtil.flyToPoint({
+					longitude: position.x,
+					latitude: position.y,
+					height: position.z,
+					duration: options.duration,
+					heading: options.heading,
+					pitch: options.pitch,
+					range: options.range,
+				});
+				flyToPoint.then(function() {
+					// alert(1111)
+				});
+
+				if (type === "add") {
+
+					const positionF = {
+						x: 121.554042,
+						y: 37.395186,
+						z: 25.60
+					};
+
+					this.fireArr = [];
+					this.waterArr = [];
+
+					let fireEntity = jt3d.SceneEffects.ParticleSystem.createParticleFire([positionF.x, positionF.y, positionF.z])
+					this.fireArr.push(fireEntity)
+
+					const positionW = {
+						x: 121.553975,
+						y: 37.395075,
+						z: 18.10
+					};
+
+					let waterEntity = jt3d.SceneEffects.ParticleSystem.createParticleWater([positionW.x, positionW.y, positionW.z])
+					this.waterArr.push(waterEntity)
+
+				}
+				if (type === "remove") {
+					for (var i = 0; i < this.fireArr.length; i++) {
+						this.fireArr[i].remove()
+					}
+					for (var i = 0; i < this.waterArr.length; i++) {
+						this.waterArr[i].remove()
+					}
+				}
+			},
+
+			/**
+			 * 热力图
+			 */
+			HeatMap(type) {
+
+				if (type === "add") {
+					let viewer = this.viewer = window["viewer"];
+
+					// 矩形坐标
+					var bounds = {
+						west: 121.563298,
+						south: 37.284514,
+						east: 121.565298,
+						north: 37.286514,
+					};
+
+					// 初始化CesiumHeatmap
+					var heatMap = this.heatMap = CesiumHeatmap.create(
+						viewer, // 视图层
+						bounds, // 矩形坐标
+						// heatmap相应参数
+						{
+							backgroundColor: "rgba(0, 0, 0, 0)",
+							radius: 50,
+							maxOpacity: .5,
+							minOpacity: 0,
+							blur: .75
+						}
+					);
+
+					//加载数据,生成热力图
+					// 添加数据 最小值,最大值,数据集
+					heatMap.setWGS84Data(0, 100, getData(300));
+					viewer.zoomTo(viewer.entities);
+
+					if (this._layer) {
+						//移除热力图
+						this.viewer.entities.remove(this.heatMap._layer);
+					} else {
+						this._layer = this.heatMap._layer;
+					}
+
+					// 数据格式:动态数据 [{x: -97.6433525165054, y: 45.61443064377248, value: 11.409122369106317}]
+					function getData(length) {
+						var data = [];
+						for (var i = 0; i < length; i++) {
+							var x = 121.563298 + Math.random() * (121.565298 - 121.563298);
+							var y = 37.284514 + Math.random() * (37.286514 - 37.284514);
+							var value = Math.random() * 100;
+							data.push({
+								x: x,
+								y: y,
+								value: value
+							});
+						}
+						return data;
+					}
+				}
+				if (type === "remove") {
+
+					//移除热力图
+					this.viewer.entities.remove(this.heatMap._layer);
+				}
+			}
+		},
+
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.el-avatar{
+		width: 70rem !important;
+		height: 70rem !important;
+		font-size: 14px !important;
+		cursor: pointer;
+	}
+	
+	::v-deep .el-collapse-item__content {
+		padding: 10rem;
+		// padding-bottom: 0rem;
+		overflow-y: hidden;
+	}
+
+	::v-deep .el-collapse-item__header {
+		background: url(@/assets/images/bg_collapse_title.png) no-repeat;
+		background-size: 350rem 40rem;
+		// background-color: rgb(22 90 190);
+		// background-color: rgb(5 45 100 /60%);
+		background-color: rgb(30 130 255);
+		border-bottom: 0;
+	}
+
+	.el-col {
+		padding: 10rem;
+		// color: rgba(90, 172, 255, 1.0);
+		color: #fff;
+	}
+
+	.jt-weather-effects {
+		position: relative;
+
+		.iconfont {
+			padding: 0 10rem;
+		}
+
+		.el-collapse {
+			--el-collapse-border-color: rgb(0 44 126 / 0%);
+
+			--el-collapse-header-text-color: #ffffff;
+			--el-collapse-header-font-size: 13rem;
+			--el-collapse-content-bg-color: rgb(0 44 126 / 0%);
+			--el-collapse-content-font-size: 13rem;
+			--el-collapse-content-text-color: rgb(216 240 255);
+
+			--el-collapse-header-height: 40rem;
+			--el-collapse-header-bg-color: rgb(30 130 255);
+
+			--el-fill-color-blank: rgb(0 44 126 / 68%);
+			--el-text-color-regular: rgb(216 240 255);
+			--el-border-color: rgb(35 135 255);
+
+			.el-collapse-item__content {
+				padding: 10rem;
+				// padding-bottom: 0rem;
+			}
+		}
+
+		i {
+			display: inline-block;
+			width: 100%;
+			height: 36rem;
+			line-height: 36rem;
+			text-align: center;
+			border-radius: 5rem;
+			font-size: 40rem;
+			// color: rgba(90, 172, 255, 1.0);
+			color: #fff;
+			transition: all .3s;
+			-webkit-transition: all .3s
+		}
+
+		.selectStyle {
+			// background: rgba(135, 182, 254, 0.5);
+			background: rgb(0 44 126);
+		}
+
+		.defaultStyle {
+			background: #ffffff00;
+		}
+
+		.selectFontStyle {
+			// color: #fff;
+			color: #55ffff;
+		}
+	}
+</style>

+ 445 - 0
src/views/Map3d - 副本/components/toolbars - 副本.vue

@@ -0,0 +1,445 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	/**
+	 * element-plus字体
+	 */
+	import {
+		ArrowDown
+	} from '@element-plus/icons-vue';
+	import {
+		Store
+	} from '@/store/index';
+	store = Store()
+	import {
+		inject
+	} from "vue";
+	import html2canvas from "html2canvas";
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="toolbars fadein-right">
+		<!-- <div class="toolbar-item" @click="PolylineObject()">
+			<i class="iconfont icon-winfo-icon-tucengkongzhi"></i>
+			<span class="title">
+				测试动态线
+			</span>
+		</div> -->
+		<div class="toolbar-item" @click="showWidget('rotateCamera')">
+			<i class="iconfont icon-chaxunzuobiaozhi" />
+			<span class="title">
+				绕点旋转
+			</span>
+		</div>
+		<div class="toolbar-item" @click="showWidget('fullMap')">
+			<i class="iconfont icon-chaxunzuobiaozhi" />
+			<span class="title">
+				全图
+			</span>
+		</div>
+		<div class="toolbar-item" @click="showWidget('basicLayer')">
+			<i class="iconfont icon-dituzuobiao" />
+			<span class="title">
+				底图
+			</span>
+		</div>
+		<div class="toolbar-item" @click="showWidget('layers')">
+			<i class="iconfont icon-winfo-icon-tucengkongzhi"></i>
+			<span class="title">
+				图层
+			</span>
+		</div>
+		<el-dropdown class="toolbar-item" :hide-on-click="false" @command="handleCommand">
+			<span class="el-dropdown-link">
+				<i class="iconfont icon-xitong1" />
+				<span class="title">
+					工具
+				</span>
+				<el-icon class="el-icon--right">
+					<ArrowDown />
+				</el-icon>
+			</span>
+			<template #dropdown>
+				<span slot="slot" class="text"></span>
+				<el-dropdown-menu>
+					<el-dropdown-item command="DialogEdit"><i class="iconfont minsize icon-dituhuizhi"></i>图上标绘</el-dropdown-item>
+					<el-dropdown-item command="navigate"><i class="iconfont icon-zhijiantou"></i>地区导航</el-dropdown-item>
+					<el-dropdown-item command="viewerlabel"><i class="iconfont minsize icon-fushi"></i>视角标签</el-dropdown-item>
+					<el-dropdown-item v-if="store.userport=='PC'" command="printmap"><i class="iconfont maxsize icon-svgdayin"></i>打印地图</el-dropdown-item>
+					<el-dropdown-item command="measure"><i class="iconfont minsize icon-icon_measureTool"></i>图上量算</el-dropdown-item>
+					<el-dropdown-item command="query-graphics"><i class="iconfont icon-search"></i>图形查询</el-dropdown-item>
+					<el-dropdown-item command="analysis-data"><i class="iconfont maxsize icon-svgjiexiwenjian"></i>文件解析</el-dropdown-item>
+					<el-dropdown-item command="analysis-space"><i class="iconfont icon-duodiankeshiyu"></i>空间分析</el-dropdown-item>
+					<el-dropdown-item command="analysis-terrain"><i class="iconfont icon-iconfonttubiao_dixing"></i>地形分析</el-dropdown-item>
+					<el-dropdown-item command="special-effects"><i class="iconfont icon-yu"></i>特效效果</el-dropdown-item>
+					<el-dropdown-item command="coordsTool"><i class="iconfont icon-zuobiao"></i>坐标定位</el-dropdown-item>
+					<el-dropdown-item command="TrackRoam"><i class="iconfont maxsize icon-jurassic_jiankong"></i>路径漫游</el-dropdown-item>
+					<el-dropdown-item command="ImageLayerSplit"><i class="iconfont maxsize icon-juanlian"></i>卷帘对比</el-dropdown-item>
+					<el-dropdown-item command="ViewerSplitScreen"><i class="iconfont minsize icon-fenping"></i>分屏对比</el-dropdown-item>
+				</el-dropdown-menu>
+			</template>
+		</el-dropdown>
+		<div class="toolbar-item" @click="showWidget('clearAll')">
+			<i class="iconfont minsize icon-shanchu"></i>
+			<span class="title">
+				清除
+			</span>
+		</div>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+	let store = undefined
+	export default {
+		name: "toolbars",
+		data() {
+			return {}
+		},
+		/* 方法 */
+		methods: {
+			/**
+			 * 测试动态线
+			 */
+			PolylineObject() {
+				let lines = [
+					[
+						[107.3609526659472, 26.405330345862833],
+						[107.40025603208434, 26.402244579822174]
+					],
+					[
+						[107.3609801462563, 26.40314629662853],
+						[107.3999374877451, 26.400165614674155]
+					],
+					[
+						[107.36081944593964, 26.40080706752495],
+						[107.40012685036773, 26.39813952738571],
+					],
+					[
+						[107.36067906760677, 26.398625963837965],
+						[107.40034550598207, 26.39670894997551],
+					],
+				];
+
+				//定位
+				jt3d._viewer.scene.camera.setView({
+					duration: 1,
+					destination: {
+						x: -1709251.0767395466,
+						y: 5461386.32337908,
+						z: 2820645.238657382
+					},
+					orientation: {
+						heading: 0.13762265446730737,
+						pitch: -1.460307026543739,
+						roll: 0.003401834066556475
+					}
+				});
+
+				lines.forEach((item, index) => {
+
+					if (index === 0) {
+						let a1 = jt3d.PolylineObject.PolylineLinkPulseMaterialProperty(item, {
+							width: 11,
+							color: 'RED',
+							duration: 20000,
+							imgUrl: "jt3dSDK/imgs/polylinematerial/LinkPulse.png",
+							isImageAlpha: false,
+						});
+						a1.then(function() {
+
+						});
+					}
+
+					if (index === 1) {
+						jt3d.PolylineObject.PolylineArrowMaterialProperty(item, {
+							width: 10,
+							color: "YELLOW",
+							duration: 1000,
+							count: 5,
+							direction: "horizontal",
+							order: "+",
+							imgUrl: "jt3dSDK/imgs/polylinematerial/arrowopacity.png",
+							isImageAlpha: false,
+						});
+					}
+
+					if (index === 2) {
+						jt3d.PolylineObject.PolylineArrowMaterialProperty(item, {
+							width: 10,
+							color: 'BLUE',
+							duration: 1000,
+							count: 20,
+							direction: "horizontal",
+							order: "+",
+							imgUrl: "jt3dSDK/imgs/polylinematerial/arrowopacity.png",
+							isImageAlpha: false,
+						});
+					}
+
+					if (index === 3) {
+						jt3d.PolylineObject.PolylineLinkPulseMaterialProperty(item, {
+							width: 10,
+							color: 'GREEN',
+							duration: 10000,
+							imgUrl: "jt3dSDK/imgs/polylinematerial/20201124170520929.png",
+							isImageAlpha: false,
+						});
+					}
+				});
+			},
+
+			showWidget: function(type) {
+				if (type === "layers") {
+					this.closePopup()
+					this.$parent.$refs.refLayerPopup.isshow = true;
+				} else if (type === "fullMap") {
+					this.$parent.$refs.refMap3d.fullMap(jt3d);
+				} else if (type === "rotateCamera") {
+					ElMessage.warning('在地图上单击进行自旋,再次单击停止自旋')
+					jt3d.SketchViewModel.sketchTools('point', {
+						onComplete(cPoint, gPoint) {
+							jt3d.setMapSpinByPoint(cPoint);
+						},
+						onError(message) {}
+					});
+				} else if (type == "viewerlabel") {
+					this.closePopup()
+					this.$parent.$refs.refviewerlabel.isshow = true
+				} else if (type == "clearAll") {//清除所有
+					jt3d.DrawToolsEdit.Clear();
+					jt3d.DrawMilitaryPlot.clearAll();
+					
+					//清除测量
+					jt3d.CommonTools.clear();
+					this.$parent.$refs._refMeasure.currentIndex = -1;
+					if (this.$parent.$refs._refMeasure.popup) {
+						this.$parent.$refs._refMeasure.popup.close();
+					}
+					
+					//移除光照分析
+					if (!jt3d.statusBar.show) {
+						jt3d.statusBar.show = true;
+					}
+					jt3d.SpatialAnalysis.SunshineShadow.remove();
+					
+					//移除剖面分析结果
+					this.$parent.closeDrawerSectionAnalysis();
+					
+					//清除坐标定位
+					this.$parent.$refs._refCoordsTool.empty();
+					
+					//清除空间分析
+					this.$parent.$refs._refAnalysisSpace.init();
+					
+					//清除地形分析
+					this.$parent.$refs._refAnalysisTerrain.init();
+					
+					//还原左键单击事件
+					this.$parent.$refs.refMap3d.clickEntity(jt3d);
+					
+					/* 开启地形检测 必须开启 否则会导致获取地形高度时异常 导致鼠标移动时位置哆嗦 */
+					jt3d._viewer.scene.globe.depthTestAgainstTerrain = true;
+				}else {
+					this.closePopup()
+					this.$parent.showbasicLayer = true
+				}
+
+			},
+
+			//关闭所有弹框
+			closePopup() {
+				this.$parent.$refs.refMeasure.isshow = false;
+				this.$parent.$refs.refQueryGraphics.isshow = false;
+				this.$parent.$refs.refAnalysisData.isshow = false;
+				this.$parent.$refs.refAnalysisSpace.isshow = false;
+				this.$parent.$refs.refAnalysisTerrain.isshow = false;
+				this.$parent.$refs.refSpecialEffects.isshow = false;
+				this.$parent.$refs.refCoordsTool.isshow = false;
+				this.$parent.$refs.refTrackRoam.isshow = false;
+				this.$parent.$refs.refViewerSplitScreen.isshow = false;
+				this.$parent.$refs.refImageLayerSplit.isshow = false;
+				this.$parent.$refs.refmapNavigate.isshow = false;
+				this.$parent.$refs.refviewerlabel.isshow = false;
+				this.$parent.$refs.refprintmap.isshow = false;
+				this.$parent.$refs.refDialogEdit.isshow = false;
+				this.$parent.showbasicLayer = false;
+				this.$parent.$refs.refLayerPopup.isshow = false;
+				if (this.$parent.$refs._refImageLayerSplit) {
+					this.$parent.$refs._refImageLayerSplit.removeSplitLayer(); //关闭卷帘
+				}
+				if (this.$parent.$refs._refViewerSplitScreen) {
+					this.$parent.$refs._refViewerSplitScreen.removeSplitScreen(); //关闭分屏
+				}
+			},
+			/**
+			 * dropdown下拉列表事件
+			 */
+			handleCommand(command) {
+				//图上绘制组件
+				if (command === 'DialogEdit') {
+					this.closePopup()
+					this.$parent.$refs.refDialogEdit.isshow = true
+				}
+				//区域导航
+				if (command === 'navigate') {
+					this.closePopup()
+					this.$parent.$refs.refmapNavigate.isshow = true
+				}
+				//视角标签
+				if (command === 'viewerlabel') {
+					this.closePopup()
+					this.$parent.$refs.refviewerlabel.isshow = true
+				}
+				//打印地图
+				if (command === 'printmap') {
+					this.closePopup()
+					// this.$bus.emit("screenshot")
+					this.$parent.$refs._refprintmap.screenshot();
+					setTimeout(() => {
+						this.$parent.$refs.refprintmap.isshow = true
+					}, 50);
+				}
+				//图上量算
+				if (command === 'measure') {
+					this.closePopup()
+					this.$parent.$refs.refMeasure.isshow = true;
+				}
+				//图形查询
+				if (command === 'query-graphics') {
+					this.closePopup()
+					this.$parent.$refs.refQueryGraphics.isshow = true;
+				}
+				//数据分析
+				if (command === 'analysis-data') {
+					this.closePopup()
+					this.$parent.$refs.refAnalysisData.isshow = true;
+				}
+				//空间分析
+				if (command === 'analysis-space') {
+					this.closePopup()
+					this.$parent.$refs.refAnalysisSpace.isshow = true;
+				}
+				//地形分析
+				if (command === 'analysis-terrain') {
+					this.closePopup()
+					this.$parent.$refs.refAnalysisTerrain.isshow = true;
+				}
+				//特效效果
+				if (command === 'special-effects') {
+					this.closePopup()
+					this.$parent.$refs.refSpecialEffects.isshow = true;
+				}
+				//坐标定位拾取
+				if (command === 'coordsTool') {
+					this.closePopup()
+					this.$parent.$refs.refCoordsTool.isshow = true;
+				}
+				//飞行漫游
+				if (command === 'TrackRoam') {
+					this.closePopup()
+					this.$parent.$refs.refTrackRoam.isshow = true;
+				}
+				//卷帘对比
+				if (command === 'ImageLayerSplit') {
+					this.closePopup();
+					this.$parent.$refs.refImageLayerSplit.isshow = true;
+					this.$parent.$refs._refImageLayerSplit.initSplitLayer(); //开启卷帘
+				}
+				//分屏对比
+				if (command === 'ViewerSplitScreen') {
+					this.closePopup();
+					this.$parent.$refs.refViewerSplitScreen.isshow = true;
+					this.$parent.$refs.refLayerPopup.isshow = true;
+					this.$parent.$refs._refViewerSplitScreen.initSplitScreen(); //开启分屏
+				}
+			},
+		},
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.text::before {
+		position: absolute;
+		width: 0rem;
+		height: 0rem;
+		left: calc(50% - 5rem);
+		top: -5rem;
+		content: '';
+		transform: rotate(45deg);
+		z-index: 10;
+		box-sizing: border-box;
+		border-bottom: 5rem solid transparent;
+		border-right: 5rem solid transparent;
+		border-top: 5rem solid rgba(255, 255, 255, 1);
+		border-left: 5rem solid rgba(255, 255, 255, 1);
+		// background: rgba(5, 45, 115, .8) !important;
+	}
+
+	.toolbars {
+		position: absolute;
+		top: 80rem;
+		width: 540rem;
+		right: 20rem;
+		cursor: pointer !important;
+		padding: 0rem !important;
+		margin: 0rem !important;
+		background-image: none !important;
+		border: 1rem solid;
+		border: none;
+		border-radius: 2rem !important;
+		background-color: rgb(0 44 126 / 65%);
+		height: 40rem;
+		box-sizing: border-box;
+		line-height: 38rem;
+		text-align: left;
+		user-select: none;
+
+		cursor: default;
+
+		.toolbar-item {
+			display: inline-block;
+			padding: 0rem 12rem;
+
+			margin: 0rem;
+			height: calc(100% - 4rem);
+			color: #fff;
+			font-size: 15rem;
+			vertical-align: middle;
+
+			&:hover {
+				background-color: rgba(255, 255, 255, 0.3);
+			}
+
+			.title {
+				font-size: 16rem;
+			}
+		}
+
+		.toolbar-item:nth-last-child(1) {
+			padding-right: 0rem;
+		}
+
+		.el-icon {
+			margin-right: 5rem;
+			color: #fff;
+		}
+
+		.el-dropdown {
+			// vertical-align: middle;
+			height: 40rem;
+			line-height: 38rem;
+			box-sizing: border-box;
+		}
+	}
+</style>

+ 386 - 0
src/views/Map3d - 副本/components/toolbars.vue

@@ -0,0 +1,386 @@
+<script setup>
+	/**
+	 * element-plus组件
+	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
+	/**
+	 * element-plus字体
+	 */
+	import {
+		ArrowDown
+	} from '@element-plus/icons-vue';
+
+	import {
+		Store
+	} from '@/store/index';
+	store = Store()
+
+	import {
+		inject
+	} from "vue";
+
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="toolbars fadein-right">
+		<template v-for="(item, i) in toolDatas" :key="i">
+			<div v-if="item.widget && !item.children" class="toolbar-item" @click="showWidget(item.widget)">
+				<i :class="item.icon" />
+				<span class="title">{{ item.name }}</span>
+			</div>
+			<!-- 	<mars-dropdown-menu v-if="item.children && !item.widget" trigger="hover" placement="bottomRight">
+				<div class="toolbar-item">
+					<mars-icon :icon="item.icon" width="18"></mars-icon>
+					<span class="title">{{ item.name }}</span>
+					<mars-icon icon="down" width="18"></mars-icon>
+				</div>
+				<template #overlay>
+					<a-menu @click="clickMenu">
+						<a-menu-item v-for="child in item.children" :key="child.widget" :title="child.name">
+							<mars-icon :icon="child.icon" width="18"></mars-icon>
+							<span>{{ child.name }}</span>
+						</a-menu-item>
+					</a-menu>
+				</template>
+			</mars-dropdown-menu> -->
+			<el-dropdown v-if="item.children && !item.widget" class="toolbar-item" :hide-on-click="false" @command="handleCommand">
+				<span class="el-dropdown-link">
+					<i :class="item.icon" />
+					<span class="title">{{ item.name }}</span>
+					<el-icon class="el-icon--right">
+						<ArrowDown />
+					</el-icon>
+				</span>
+				<template #dropdown>
+					<span slot="slot" class="text"></span>
+					<el-dropdown-menu>
+						<el-dropdown-item v-for="child in item.children" :key="child.widget" :title="child.name" @click="showWidget(child.widget)">
+							<i :class="child.icon" />
+							<span>{{ child.name }}</span>
+						</el-dropdown-item>
+					</el-dropdown-menu>
+				</template>
+			</el-dropdown>
+		</template>
+	</div>
+</template>
+
+<script>
+	let jt3d = undefined;
+	let store = undefined
+	export default {
+		name: "toolbars",
+		data() {
+			return {
+				toolDatas: [{
+						name: "绕点自旋",
+						icon: "iconfont icon-chaxunzuobiaozhi",
+						widget: "rotateCamera"
+					},
+					{
+						name: "全图",
+						icon: "iconfont icon-chaxunzuobiaozhi",
+						widget: "fullMap"
+					},
+					{
+						name: "底图",
+						icon: "iconfont icon-dituzuobiao",
+						widget: "basicLayer"
+					},
+					{
+						name: "图层",
+						icon: "iconfont icon-winfo-icon-tucengkongzhi",
+						widget: "layers"
+					},
+					{
+						name: "工具",
+						icon: "iconfont icon-xitong1",
+						children: [{
+								name: "图上标绘",
+								icon: "iconfont icon-dituhuizhi",
+								widget: "DialogEdit"
+							},
+							{
+								name: "地区导航",
+								icon: "iconfont icon-zhijiantou",
+								widget: "navigate"
+							},
+							{
+								name: "视角标签",
+								icon: "iconfont icon-fushi",
+								widget: "viewerlabel"
+							},
+						]
+					},
+					{
+						name: "清除",
+						icon: "iconfont icon-shanchu",
+						widget: "clearAll"
+					},
+				]
+			}
+		},
+		/* 方法 */
+		methods: {
+			showWidget: function(type) {
+				//全图
+				if (type === "fullMap") {
+					this.$parent.$refs.refMap3d.fullMap(jt3d);
+				}
+				//绕点自旋
+				if (type === "rotateCamera") {
+					ElMessage.warning('在地图上单击进行自旋,再次单击停止自旋')
+					jt3d.SketchViewModel.sketchTools('point', {
+						onComplete(cPoint, gPoint) {
+							jt3d.setMapSpinByPoint(cPoint);
+						},
+						onError(message) {}
+					});
+				}
+				//清除所有
+				if (type == "clearAll") {
+					jt3d.DrawToolsEdit.Clear();
+					jt3d.DrawMilitaryPlot.clearAll();
+
+					//清除测量
+					jt3d.CommonTools.clear();
+					this.$parent.$refs._refMeasure.currentIndex = -1;
+					if (this.$parent.$refs._refMeasure.popup) {
+						this.$parent.$refs._refMeasure.popup.close();
+					}
+
+					//移除光照分析
+					if (!jt3d.statusBar.show) {
+						jt3d.statusBar.show = true;
+					}
+					jt3d.SpatialAnalysis.SunshineShadow.remove();
+
+					//移除剖面分析结果
+					this.$parent.closeDrawerSectionAnalysis();
+
+					//清除坐标定位
+					this.$parent.$refs._refCoordsTool.empty();
+
+					//清除空间分析
+					this.$parent.$refs._refAnalysisSpace.init();
+
+					//清除地形分析
+					this.$parent.$refs._refAnalysisTerrain.init();
+
+					//还原左键单击事件
+					this.$parent.$refs.refMap3d.clickEntity(jt3d);
+
+					/* 开启地形检测 必须开启 否则会导致获取地形高度时异常 导致鼠标移动时位置哆嗦 */
+					jt3d._viewer.scene.globe.depthTestAgainstTerrain = true;
+				}
+				
+				//图层控制
+				if (type === "layers") {
+					// this.closePopup()
+					// this.$parent.$refs.refLayerPopup.isshow = true;
+					
+						this.$myPop('layer',{isShow:true})
+				}
+				//底图切换
+				if (type === "basicLayer") {
+					this.closePopup()
+					this.$parent.showbasicLayer = true
+				}
+
+				//视角标签
+				if (type == "viewerlabel") {
+					this.closePopup()
+					this.$parent.$refs.refviewerlabel.isshow = true
+				}
+
+				//图上绘制组件
+				if (type === 'DialogEdit') {
+					this.closePopup()
+					this.$parent.$refs.refDialogEdit.isshow = true
+				}
+				//区域导航
+				if (type === 'navigate') {
+					this.closePopup()
+					this.$parent.$refs.refmapNavigate.isshow = true
+				}
+				//视角标签
+				if (type === 'viewerlabel') {
+					this.closePopup()
+					this.$parent.$refs.refviewerlabel.isshow = true
+				}
+				//打印地图
+				if (type === 'printmap') {
+					this.closePopup()
+					// this.$bus.emit("screenshot")
+					this.$parent.$refs._refprintmap.screenshot();
+					setTimeout(() => {
+						this.$parent.$refs.refprintmap.isshow = true
+					}, 50);
+				}
+				//图上量算
+				if (type === 'measure') {
+					this.closePopup()
+					this.$parent.$refs.refMeasure.isshow = true;
+				}
+				//图形查询
+				if (type === 'query-graphics') {
+					this.closePopup()
+					this.$parent.$refs.refQueryGraphics.isshow = true;
+				}
+				//数据分析
+				if (type === 'analysis-data') {
+					this.closePopup()
+					this.$parent.$refs.refAnalysisData.isshow = true;
+				}
+				//空间分析
+				if (type === 'analysis-space') {
+					this.closePopup()
+					this.$parent.$refs.refAnalysisSpace.isshow = true;
+				}
+				//地形分析
+				if (type === 'analysis-terrain') {
+					this.closePopup()
+					this.$parent.$refs.refAnalysisTerrain.isshow = true;
+				}
+				//特效效果
+				if (type === 'special-effects') {
+					this.closePopup()
+					this.$parent.$refs.refSpecialEffects.isshow = true;
+				}
+				//坐标定位拾取
+				if (type === 'coordsTool') {
+					this.closePopup()
+					this.$parent.$refs.refCoordsTool.isshow = true;
+				}
+				//飞行漫游
+				if (type === 'TrackRoam') {
+					this.closePopup()
+					this.$parent.$refs.refTrackRoam.isshow = true;
+				}
+				//卷帘对比
+				if (type === 'ImageLayerSplit') {
+					this.closePopup();
+					this.$parent.$refs.refImageLayerSplit.isshow = true;
+					this.$parent.$refs._refImageLayerSplit.initSplitLayer(); //开启卷帘
+				}
+				//分屏对比
+				if (type === 'ViewerSplitScreen') {
+					this.closePopup();
+					this.$parent.$refs.refViewerSplitScreen.isshow = true;
+					this.$parent.$refs.refLayerPopup.isshow = true;
+					this.$parent.$refs._refViewerSplitScreen.initSplitScreen(); //开启分屏
+				}
+			},
+
+			//关闭所有弹框
+			closePopup() {
+				this.$parent.$refs.refMeasure.isshow = false;
+				this.$parent.$refs.refQueryGraphics.isshow = false;
+				this.$parent.$refs.refAnalysisData.isshow = false;
+				this.$parent.$refs.refAnalysisSpace.isshow = false;
+				this.$parent.$refs.refAnalysisTerrain.isshow = false;
+				this.$parent.$refs.refSpecialEffects.isshow = false;
+				this.$parent.$refs.refCoordsTool.isshow = false;
+				this.$parent.$refs.refTrackRoam.isshow = false;
+				this.$parent.$refs.refViewerSplitScreen.isshow = false;
+				this.$parent.$refs.refImageLayerSplit.isshow = false;
+				this.$parent.$refs.refmapNavigate.isshow = false;
+				this.$parent.$refs.refviewerlabel.isshow = false;
+				this.$parent.$refs.refprintmap.isshow = false;
+				this.$parent.$refs.refDialogEdit.isshow = false;
+				this.$parent.showbasicLayer = false;
+				this.$parent.$refs.refLayerPopup.isshow = false;
+				if (this.$parent.$refs._refImageLayerSplit) {
+					this.$parent.$refs._refImageLayerSplit.removeSplitLayer(); //关闭卷帘
+				}
+				if (this.$parent.$refs._refViewerSplitScreen) {
+					this.$parent.$refs._refViewerSplitScreen.removeSplitScreen(); //关闭分屏
+				}
+			},
+		},
+		mounted() {
+
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.text::before {
+		position: absolute;
+		width: 0rem;
+		height: 0rem;
+		left: calc(50% - 5rem);
+		top: -5rem;
+		content: '';
+		transform: rotate(45deg);
+		z-index: 10;
+		box-sizing: border-box;
+		border-bottom: 5rem solid transparent;
+		border-right: 5rem solid transparent;
+		border-top: 5rem solid rgba(255, 255, 255, 1);
+		border-left: 5rem solid rgba(255, 255, 255, 1);
+		// background: rgba(5, 45, 115, .8) !important;
+	}
+
+	.toolbars {
+		position: absolute;
+		top: 80rem;
+		width: 540rem;
+		right: 20rem;
+		cursor: pointer !important;
+		padding: 0rem !important;
+		margin: 0rem !important;
+		background-image: none !important;
+		border: 1rem solid;
+		border: none;
+		border-radius: 2rem !important;
+		background-color: rgb(0 44 126 / 65%);
+		height: 40rem;
+		box-sizing: border-box;
+		line-height: 38rem;
+		text-align: left;
+		user-select: none;
+
+		cursor: default;
+
+		.toolbar-item {
+			display: inline-block;
+			padding: 0rem 12rem;
+
+			margin: 0rem;
+			height: calc(100% - 4rem);
+			color: #fff;
+			font-size: 15rem;
+			vertical-align: middle;
+
+			&:hover {
+				background-color: rgba(255, 255, 255, 0.3);
+			}
+
+			.title {
+				font-size: 16rem;
+			}
+		}
+
+		.toolbar-item:nth-last-child(1) {
+			padding-right: 0rem;
+		}
+
+		.el-icon {
+			margin-right: 5rem;
+			color: #fff;
+		}
+
+		.el-dropdown {
+			// vertical-align: middle;
+			height: 40rem;
+			line-height: 38rem;
+			box-sizing: border-box;
+		}
+	}
+</style>

+ 316 - 0
src/views/Map3d - 副本/components/viewerlabel.vue

@@ -0,0 +1,316 @@
+<script setup>
+	import {
+		inject
+	} from "vue";
+	import html2canvas from 'html2canvas';
+	import {Store} from '@/store/index';
+	store = Store()
+	import {
+		blobToBase64,
+		base64ToBlob
+	} from '@/assets/js/blobtobase64';
+	const getMapInstance = inject("getMapInstance");
+	jt3d = getMapInstance();
+</script>
+
+<template>
+	<div class="mainview">
+		<div class="header">
+			<input @input="getName()" id="inputValue" type="text" placeholder="创建视角标签" />
+			<el-button v-if="store.userport=='PC'" type="primary" @click="addviewer" size="small">添加</el-button>
+			<el-button type="primary" @click="searchviewer" size="small">查询</el-button>
+		</div>
+		<div class="middleviewer">
+			<div class="viewer" v-for="(res,index) in ImgurlList" :key="index">
+				<div class="viewertop">
+					<img :src="res.url" @click="flyto(res.info)">
+				</div>
+				<div class="viewerbottom">
+					{{res.name}}
+					<img src="@/assets/images/delete.png" class="deleteImg" @click="deleteviewer(res,index)" />
+				</div>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script>
+	let store = undefined;
+	let jt3d = undefined;
+	export default {
+		data() {
+			return {
+				viewersName: '', //视角标签名称
+				ImgurlList: [], //截图地址列表
+			}
+		},
+		methods: {
+			//获取输入框值
+			getName() {
+				this.viewersName = document.getElementById("inputValue").value;
+			},
+
+			//跳转方法
+			flyto(options) {
+				jt3d.LocateUtil.flyToPoint(options)
+			},
+
+			//删除方法,传keyvalue以及需要修改属性
+			deleteviewer(item, index) {
+				//删除对应数组内的对象
+				this.ImgurlList.splice(index, 1)
+				if (item.id) {
+					this.$http.get('/delete', {
+						tableName: 'map_angle',
+						keyValue: item.id,
+					}).then(res => {
+						console.log(res.data)
+					})
+				}
+			},
+
+			//添加视角标签,当前页存数组,向数据库传入相机参数
+			addviewer() {
+				//获取当前界面截图方法
+				html2canvas(
+					this.$parent.$parent.$refs.refMap3d.$refs.cesiumContainer, {
+						// backgroundColor: null, //画出来的图片有白色的边框,不要可设置背景为透明色(null)
+						useCORS: true, //支持图片跨域
+						scale: 1 / 8, //设置放大的倍数
+					}
+				).then(canvas => {
+					//截图用img元素承装,显示在页面的上
+					let url = canvas.toDataURL('image/png')
+					//经纬度、高度
+					// 获取 相机姿态信息
+					let heading = window["viewer"].scene.camera.heading
+					let pitch = window["viewer"].scene.camera.pitch
+					let roll = window["viewer"].scene.camera.roll
+					let position = window["viewer"].scene.camera.positionCartographic
+					let longitude = Cesium.Math.toDegrees(position.longitude) //y
+					let latitude = Cesium.Math.toDegrees(position.latitude) //x
+					let height = position.height
+					let info = {
+						latitude: latitude,
+						longitude: longitude,
+						height: height,
+						pitch: Cesium.Math.toDegrees(pitch),
+						roll: Cesium.Math.toDegrees(roll),
+						heading: Cesium.Math.toDegrees(heading)
+					}
+					//dom for循环渲染列表
+					this.ImgurlList.unshift({
+						url: url,
+						name: this.viewersName,
+						info: info
+					})
+
+					//base64转换为二进制文件
+					// let blob = base64ToBlob(url)
+					// //文件转为文件流
+					// let formData = new FormData();
+					// formData.append('file',blob)
+
+					let data = {
+						name: this.viewersName,
+						x: latitude,
+						y: longitude,
+						z: height,
+						pitch: Cesium.Math.toDegrees(pitch),
+						roll: Cesium.Math.toDegrees(roll),
+						heading: Cesium.Math.toDegrees(heading),
+						screenshot: url,
+						// screenshot: '',
+						userId: this.id,
+						// id:0
+					}
+
+					//添加数据接口
+					this.$http.post('/postSubmit', {
+						tableName: 'map_angle',
+						keyValue: '',
+						formData: data,
+					}).then(res => {
+						console.log(res)
+						if (res.success == true) {
+							console.log('添加成功')
+							document.getElementById("inputValue").value = ''
+						}
+					})
+				}).catch(err => {
+					console.log(err)
+				})
+			},
+			searchviewer() {
+				this.info = JSON.parse(localStorage.getItem('person'))
+				this.id = this.info.id
+				//获取所有图片数据
+				this.$http.get('/getTableList', {
+					tableName: 'map_angle', //
+					sqlWhere: "name like '%" + this.viewersName + "%'",
+					orderByField: ''
+				}).then(res => {
+					console.log('获取图片', res.data)
+					this.ImgurlList = [];
+					res.data.forEach(item => {
+						let info = {
+							latitude: item.x,
+							longitude: item.y,
+							height: item.z,
+							pitch: item.pitch,
+							roll: item.roll,
+							heading: item.heading
+						}
+						// let url = blobToBase64(item.screenshot)
+						//dom for循环渲染列表
+						this.ImgurlList.push({
+							url: item.screenshot,
+							name: item.name,
+							info: info,
+							id: item.id
+						})
+					})
+
+					// console.log('img列表',this.ImgurlList)
+				})
+			}
+		},
+
+		mounted() {
+			this.info = JSON.parse(localStorage.getItem('person'))
+			this.id = this.info.id
+			//获取所有图片数据
+			this.$http.get('/getTableList', {
+				tableName: 'map_angle', //
+				sqlWhere: '', //+ this.loginForm.id
+				orderByField: ''
+			}).then(res => {
+				console.log('获取图片', res.data)
+				if(res.data.length == 0) return
+				res.data.forEach(item => {
+					let info = {
+						latitude: item.x,
+						longitude: item.y,
+						height: item.z,
+						pitch: item.pitch,
+						roll: item.roll,
+						heading: item.heading
+					}
+					// let url = blobToBase64(item.screenshot)
+					//dom for循环渲染列表
+					this.ImgurlList.push({
+						url: item.screenshot,
+						name: item.name,
+						info: info,
+						id: item.id
+					})
+				})
+
+				// console.log('img列表',this.ImgurlList)
+			})
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.el-button--small{
+		--el-button-size:24rem;
+		font-size:12rem;
+		padding: 5rem 12rem;
+	}
+	
+	.mainview {
+		width: 100%;
+		height: 100%;
+
+		.header {
+			width: 100%;
+			display: flex;
+
+			input,
+			input:focus {
+				outline: none;
+				width: 185rem !important;
+				border: 1rem solid rgba(255, 255, 255, 0.8);
+				margin-right: 10rem;
+				height: 26rem !important;
+				color: rgba(255, 255, 255, 1);
+				background-color: rgba(255, 255, 255, 0) !important;
+				border-radius: 3rem;
+			}
+		}
+
+		.middleviewer {
+			width: 322rem;
+			height: 100%;
+			margin-left: 7rem;
+
+			.viewer {
+				width: 322rem !important;
+				height: 240rem !important;
+				margin-top: 15rem;
+				border: 1rem solid #ffffff !important;
+				border-radius: 1rem !important;
+
+				.viewertop {
+					width: 322rem !important;
+					height: 210rem !important;
+
+					img {
+						width: 100% !important;
+						height: 100% !important;
+					}
+				}
+
+				.viewerbottom {
+					line-height: 30rem !important;
+					text-align: center !important;
+					width: 322rem !important;
+					height: 30rem !important;
+					position: relative;
+					background-color: rgba(15, 145, 185, 0.7);
+
+					.deleteImg {
+						width: 24rem;
+						height: 24rem;
+						right: 5rem;
+						top: 3rem;
+						position: absolute;
+					}
+				}
+			}
+		}
+	}
+
+	::v-deep .el-input {
+		flex-grow: 0 !important;
+		width: 200rem !important;
+		// display: inline !important;
+		// margin-left: 5rem;
+		margin-right: 10rem;
+		height: 30rem !important;
+	}
+
+	//输入框文字颜色
+	::v-deep .el-input__inner {
+		color: rgba(255, 255, 255, 1)
+	}
+
+	//输入框背景色
+	::v-deep .el-input__wrapper {
+		background-color: rgba(255, 255, 255, 0) !important;
+	}
+
+	::v-deep .el-button {
+		border-radius: 3rem !important;
+
+	}
+
+	::v-deep .el-button--primary {
+		background-color: rgba(64, 158, 255, 0.6) !important;
+	}
+
+	::-webkit-scrollbar {
+		width: 0rem;
+	}
+</style>

+ 43 - 0
src/views/Map3d - 副本/index.js

@@ -0,0 +1,43 @@
+import components from './json/options.json'
+
+export default {
+	// 注册myPop
+	install(Vue) {
+		// 使用闭包实现单例模式
+		var OldCase; 
+		// 接收name和opts,name是组件名,opts是传过去的值
+		Vue.prototype.$myPop = (name, opts) => {
+			// 从json表中获取所有配置参数
+			let myComponents = components.components;
+			// 遍历json表,寻找相应的组件
+			myComponents.forEach((item) => {
+				if (item.name === name) {
+					// 导入组件
+					let myCom = import('./' + item.componentsName + '.vue');
+					myCom.then(res => {
+						// 生成一个Vue的子类
+						let MyTpl = Vue.extend(res.default);
+						// 生成一个该子类的实例
+						let NewCase = new MyTpl().$mount()
+						// 如果还没有任何实例就使用新实例
+						if (OldCase === undefined) {
+							OldCase = NewCase;
+						// 如果已经有实例,就清除旧的实例,再使用新的实例
+						} else if (OldCase.$options.name !== NewCase.$options.name) {
+							document.body.removeChild(OldCase.$el);
+							OldCase = NewCase;
+						}
+						// 将此div加入全局挂载点内部
+						document.body.appendChild(OldCase.$el);
+						// 把传进来的参数传过去组件中
+						Object.keys(opts).forEach(key => {
+							OldCase[key] = opts[key];
+						})
+					})
+
+				}
+			})
+
+		}
+	}
+}

+ 49 - 0
src/views/Map3d - 副本/new_file.vue

@@ -0,0 +1,49 @@
+<template>
+	<component :is="componentKey" ref="custom"></component>
+</template>
+<script>
+	import {
+		reactive,
+		ref,
+		shallowReactive,
+		onActivated,
+		defineAsyncComponent,
+	} from 'vue';
+
+	//声明componentkey,用于告诉component当前挂载什么组件,components为一个对象,存放多个不确定的自定义组件。
+	const componentKey = ref(null);
+	const components: any = shallowReactive({});
+
+	// 组件挂载
+	const initTableConfig = (gridId, type) => {
+		queryTableConfig({
+			gridId
+		}).then(({
+			data
+		}) => {
+			if (type === 'main') {
+				Object.assign(mainConfig, data);
+				tabsKey.value = -1;
+			} else {
+				tabsDetail.value.push(data);
+				tabsKey.value = tabsDetail.value.length - 1;
+			}
+			// 涉及到自定义组件的部分,这里需要提前挂载,在用到时不至于ref为null
+			XEUtils.objectEach(data.action, (action, key) => {
+				if (
+					action.modalCfg &&
+					action.modalCfg.type === 'CustomModal' &&
+					action.modalCfg.src
+				) {
+					components[action.actionId] = defineAsyncComponent(
+						() => import(`../../../${action.modalCfg.src}`)
+					);
+					//注意:这里的路径后端只能返回相对路径,不能使用@/xxx/xxx.vue ,不能使用src/xxx/xxx.vue,只能./xxx.vue或者../../xxx/xxx.vue。由于并不确定组件在什么位置,避免容易出错的原则,我在前端通过../../../的形式将路径回退到src下,后端只需要从src下配置路径即可,不用考虑那么多了。如后端src的值为src/xxx/xxx/xxx.vue 则在前端合成的路径就为../../../src/xx/xxx/xxx.vue
+					componentKey.value = components[action.actionId];
+					// 为什么componentKey.vue在这里赋值,在后面点击窗口后又赋值,这里能不能省略。
+					//	答:这里省略的话,到点击按钮触发时会报错,第一次点击会报错,第二次点击不会报错,窗口正常弹出。可能是因为,组件挂载时并没有引入组件,只在使用时才引入,如果上面不提前将挂载好的组件引入进来,后面触发事件触发时引入在调用ref,执行太快,costom就会报错,所以才会点两次才弹窗。
+				}
+			});
+		});
+	};
+</script>

+ 146 - 407
src/views/Map3d/Map3DMain.vue

@@ -1,205 +1,92 @@
 <script setup>
 	/**
-	 * 业务组件,在components中进行注册
+	 * element-plus组件
 	 */
+	import {
+		ElMessage
+	} from 'element-plus';
+
 	//组件异步加载
 	import {
-		defineAsyncComponent
+		defineAsyncComponent,
+		markRaw,
+		computed,
+		provide,
+		ref
 	} from 'vue';
-	// const TrackRoam = defineAsyncComponent(() => import('./components/TrackRoam.vue'));
-	// const ImageLayerSplit = defineAsyncComponent(() => import('./components/ImageLayerSplit.vue'));
-	// const ViewerSplitScreen = defineAsyncComponent(() => import('./components/ViewerSplitScreen.vue'));
-	// const viewerlabel = defineAsyncComponent(() => import('./components/viewerlabel.vue'));
-	// const printmap = defineAsyncComponent(() => import('./components/printmap.vue'));
-	// const dialogEdit = defineAsyncComponent(() => import('./components/drawEdit.vue'));
-	// const queryResult = defineAsyncComponent(() => import('./components/queryResult.vue'));
-	// const analysisSpace = defineAsyncComponent(() => import('./components/analysis-space.vue'));
-	// const analysisTerrain = defineAsyncComponent(() => import('./components/analysis-terrain.vue'));
-	// const analysisData = defineAsyncComponent(() => import('./components/analysis-data.vue'));
-	// const layer = defineAsyncComponent(() => import('./components/layer.vue'));
-	// const measure = defineAsyncComponent(() => import('./components/measure.vue'));
-	// const queryGraphics = defineAsyncComponent(() => import('./components/query-graphics.vue'));
-	// const SpecialEffects = defineAsyncComponent(() => import('./components/special-effects.vue'));
-	// const coordsTool = defineAsyncComponent(() => import('./components/coordsTool.vue'));
-	// const basicLayer = defineAsyncComponent(() => import('./components/basicLayer.vue'));
-	// const queryKeyword = defineAsyncComponent(() => import('./components/query-keyword.vue'));
-	// const toolbars = defineAsyncComponent(() => import('./components/toolbars.vue'));
-	// const map3d = defineAsyncComponent(() => import('./components/map.vue'));
-
-	const navigation = defineAsyncComponent(() => import('./components/navigation.vue'));
 
-	import map3d from './components/map.vue';
-	import queryKeyword from './components/query-keyword.vue';
-	import toolbars from './components/toolbars.vue';
-	import layer from './components/layer.vue';
-	import measure from './components/measure.vue';
-	import queryGraphics from './components/query-graphics.vue';
-	import SpecialEffects from './components/special-effects.vue';
-	import coordsTool from './components/coordsTool.vue';
-	import basicLayer from './components/basicLayer.vue'
-	import analysisSpace from './components/analysis-space.vue';
-	import analysisTerrain from './components/analysis-terrain.vue';
-	import analysisData from './components/analysis-data.vue';
-	import mapNavigate from './components/mapNavigate.vue';
-	import TrackRoam from './components/TrackRoam.vue';
-	import ImageLayerSplit from './components/ImageLayerSplit.vue';
-	import ViewerSplitScreen from './components/ViewerSplitScreen.vue';
-	import viewerlabel from './components/viewerlabel.vue';
-	import printmap from './components/printmap.vue';
-	import dialogEdit from "./components/drawEdit.vue";
-	import queryResult from "./components/queryResult.vue";
-	import {
-		provide
-	} from "vue";
 	import {
 		Store
 	} from '@/store/index'
 	store = Store()
 
-	/**
-	 * 通过provide/inject可以轻松实现跨级访问父组件的数据
-	 * provide和inject是成对出现的
-	 * 必须放在setup内
-	 * 简单的来说就是在父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量
-	 * provide 和 inject 绑定并不是可响应的。这是刻意为之的。
-	 * 代码执行顺序data->provide->created->mounted
-	 */
+	import {
+		useWidgetStore,
+		Widget
+	} from "@/common/store/widget"
+
+	import map3d from './components/map.vue';
+	import JtWidget from "./widget.vue"
+
+	const widgetStore = useWidgetStore()
+	// widgetStore.state.widgets = store.aa;
+
+	// widgetStore.state.widgets = [{
+	// 	component: markRaw(defineAsyncComponent(() => import("@/views/map3d/components/layer.vue"))),
+	// 	name: "layer",
+	// 	autoDisable: true,
+	// 	group: "manage",
+	// } ];
+
+	const widgets = computed(() => widgetStore.state.widgets);
+	const openAtStart = computed(() => widgetStore.state.openAtStart);
+
+	let jtMap3dInstance = null;
+	let isJTMap3DOnload = ref(false);
+	const jtMap3DOnload = (map) => {
+		console.log("map构造完成", map)
+		jtMap3dInstance = map;
+		isJTMap3DOnload.value = true
+	}
 	provide("getMapInstance", () => {
-		return jt3d;
+		return jtMap3dInstance;
 	});
 </script>
 
 <template>
-	<div class="jt-mapMain">
+	<div class="jt-map3dMain">
 
 		<!-- 地图组件 -->
 		<map3d @onload="jtMap3DOnload" ref="refMap3d" />
 
 		<!-- 地图加载完成后,在加载其他组件 -->
-		<template v-if="mapLoaded">
-			<!-- 底图组件 -->
-			<basicLayer v-show="showbasicLayer" ref="basicLayers"></basicLayer>
-
-			<!-- 弹出框组件,tabs组件测试 -->
-			<jt-popup title="地区导航" ref="refmapNavigate" :isEmit="true" @closeJTPopup="closeMapNavigate">
-				<mapNavigate ref="_refmapNavigate"></mapNavigate>
-			</jt-popup>
-
-			<!-- 关键字查询组件 -->
-			<queryKeyword ref="queryword" />
-
-			<!-- 比例尺、指南针 -->
-			<navigation ref="refNavigation"/>
-
-			<!-- 视角标签 -->
-			<jt-popup title="视角标签" ref="refviewerlabel">
-				<viewerlabel ref="_refviewerlabel"></viewerlabel>
-			</jt-popup>
-
-			<!-- 打印地图 -->
-			<jt-popup :showfooter="isshowfooter" longheader="1" right="calc(50% - 480rem)" width="960rem" top="calc(50% - 270rem)" height="600rem" title="打印地图" ref="refprintmap">
-				<printmap ref="_refprintmap"></printmap>
-			</jt-popup>
-
-			<!-- 工具栏组件 -->
-			<toolbars />
-
-			<!-- 图上量算组件 -->
-			<jt-popup title="图上量算" ref="refMeasure" :isEmit="true" @closeJTPopup="closeMeasure">
-				<measure ref="_refMeasure" />
-			</jt-popup>
-
-			<!-- 数据分析组件 -->
-			<jt-popup title="数据分析" ref="refAnalysisData">
-				<analysisData />
-			</jt-popup>
-
-			<!-- 空间分析组件 -->
-			<jt-popup title="空间分析" ref="refAnalysisSpace">
-				<analysisSpace />
-			</jt-popup>
-
-			<!-- 剖面分析结果组件 -->
-			<jt-drawer ref="refDrawerSectionAnalysis" title="剖面分析结果" direction="btt" size="30vh" @closeJTDrawer="closeDrawerSectionAnalysis">
-				<jt-charts id="sectionAnalysisChart" width='98vw' height="20vh" :option='ChartTestData' />
-			</jt-drawer>
-
-			<!-- 图形查询组件 -->
-			<jt-popup title="图形查询" ref="refQueryGraphics" :isEmit="true" @closeJTPopup="closeQuery">
-				<queryGraphics ref="_refQueryGraphics" />
-			</jt-popup>
-
-			<!-- 特效组件 -->
-			<jt-popup title="特效效果" ref="refSpecialEffects">
-				<SpecialEffects />
-			</jt-popup>
-
-			<!-- 坐标定位拾取组件 -->
-			<jt-popup title="坐标定位拾取" ref="refCoordsTool">
-				<coordsTool />
-			</jt-popup>
-
-			<!-- 地形分析组件 -->
-			<jt-popup title="地形分析" ref="refAnalysisTerrain" :isEmit="true" @closeJTPopup="closeAnalysisTerrain">
-				<analysisTerrain ref="_refAnalysisTerrain" />
-			</jt-popup>
-
-			<!-- 跟踪漫游组件 -->
-			<jt-popup minWidth="294rem" title="跟踪漫游" ref="refTrackRoam">
-				<TrackRoam />
-			</jt-popup>
-
-			<!-- 卷帘对比组件 -->
-			<jt-popup :showfooter="isshowfooter" height="150rem" width="520rem" title="卷帘对比" ref="refImageLayerSplit" :isEmit="true" @closeJTPopup="closeImageLayerSplit">
-				<ImageLayerSplit ref="_refImageLayerSplit" />
-			</jt-popup>
-
-			<!-- 分屏对比组件 -->
-			<jt-popup title="分屏对比" animationClass="fadein-left" ref="refViewerSplitScreen" :isEmit="true" @closeJTPopup="closeViewerSplitScreen">
-				<ViewerSplitScreen ref="_refViewerSplitScreen" />
-			</jt-popup>
-
-			<!-- 图层控jt-popup制组件 -->
-			<jt-popup title="图层控制" ref="refLayerPopup">
-				<layer ref="refLayer"/>
-			</jt-popup>
-
-			<!--图上标绘组件-->
-			<jt-popup title="图上标绘" ref="refDialogEdit">
-				<dialogEdit />
-			</jt-popup>
-
-			<!-- 查询结果 -->
-			<jt-popup :showfooter='isshowfooter' animationClass="fadein-left" height="400rem" width="800rem" title="信息展示" ref="refQueryResultPopup" :isEmit="true" @closeJTPopup="closeQueryResult">
-				<queryResult ref="refQueryResult" />
-			</jt-popup>
-
-			<!-- <video id="trailer" style="display: none;"  autoplay loop crossorigin controls>
-				<source src="@/assets/dataFile/jt.mp4" type="video/mp4">
-			</video> -->
+		<template v-if="isJTMap3DOnload">
+
+			<template v-for="comp in widgets" :key="comp.key">
+				<jt-widget v-if="openAtStart.includes(comp.name) && comp.visible" v-model:visible="comp.visible" :widget="comp" />
+			</template>
 
 		</template>
 	</div>
 </template>
 
 <script>
-	import * as echarts from "echarts";
+	import useLifecycle from "@/common/uses/use-lifecycle"
+	import * as mapWork from "./map"
 	let store = undefined
-	let jt3d = undefined;
-	let tipEntity = undefined;
+
+	// 启用map.ts生命周期
+	useLifecycle(mapWork)
 
 	export default {
-		name: "Map3DMain",
+		name: "JtMap3DMain",
 
 		/**
 		 *  数据 
 		 */
 		data() {
 			return {
-				isshowfooter: false,
-				mapLoaded: false,
-				showbasicLayer: false, //控制地图组件显示隐藏
-				ChartTestData: {}, //剖面分析结果chart
+
 			}
 		},
 
@@ -207,264 +94,116 @@
 		 *  方法 
 		 */
 		methods: {
+			init() {
 
-			/**
-			 * 关闭分屏对比
-			 */
-			closeViewerSplitScreen() {
-				this.$refs._refViewerSplitScreen.removeSplitScreen();
-			},
-
-			/**
-			 * 关闭卷帘对比
-			 */
-			closeImageLayerSplit() {
-				this.$refs._refImageLayerSplit.removeSplitLayer();
-			},
-
-			/**
-			 * 关闭地形分析弹窗
-			 */
-			closeAnalysisTerrain() {
-				//工具初始化
-				this.$refs._refAnalysisTerrain.init();
-				//还原左键单击事件
-				this.$refs.refMap3d.clickEntity(jt3d);
-				window["viewer"].scene.screenSpaceCameraController.enableCollisionDetection = true; //相机与地形的碰撞检测
-			},
-
-			/**
-			 * 关闭地区导航
-			 */
-			closeMapNavigate() {
-				this.$refs._refmapNavigate.remove();
-			},
-
-			/**
-			 * 清除测量结果
-			 */
-			closeMeasure() {
-				this.$refs._refMeasure.clearMeasurementData();
-			},
-
-			/**
-			 * 清除查询结果
-			 */
-			closeQuery() {
-				this.$refs._refQueryGraphics.clearQuery();
-			},
-
-			/**
-			 * 关闭查询结果
-			 */
-			closeQueryResult() {
-				//清除高亮显示
-				let list = jt3d._dataSources.getByName("单击高亮显示")
-				list.forEach(res => {
-					jt3d._dataSources.remove(res)
-				})
-
-				//清除定位样式
-				if (jt3d.LocateUtil._locationEntity) {
-					window["viewer"].entities.remove(jt3d.LocateUtil._locationEntity);
-				}
-			},
-
-			/**
-			 * 关闭剖面分析结果
-			 */
-			closeDrawerSectionAnalysis() {
-				this.$refs.refDrawerSectionAnalysis.drawerVisible = false;
-
-				if (tipEntity) {
-					window.viewer.entities.remove(tipEntity);
-					tipEntity = undefined;
-				}
-				jt3d.SpatialAnalysis.Profile.removeProfileAnalysis();
-				jt3d.DrawTools.Clear();
-
-				//还原左键单击事件
-				this.$refs.refMap3d.clickEntity(jt3d);
-			},
-
-			/**
-			 * 构建剖面分析结果chart
-			 */
-			initEchartsData(sectionAnalysisData) {
-				if (tipEntity) {
-					window.viewer.entities.remove(tipEntity);
-					tipEntity = undefined;
-				}
-				// jt3d.SpatialAnalysis.Profile.removeProfileAnalysis();
-
-				let datas = [],
-					coords = [];
-				let pointsData = sectionAnalysisData;
-
-				let maxDistance = pointsData[pointsData.length - 1].distance;
-				let xAixMax = Math.ceil(maxDistance);
-				for (let index = 0; index < pointsData.length; index++) {
-					let element = pointsData[index];
-					let curData = [
-						parseFloat(element.distance.toFixed(2)),
-						parseFloat(element.position.height.toFixed(2))
-					];
-					datas.push(curData);
-					let curCoords = [element.position.lon, element.position.lat];
-					coords.push(curCoords);
-				}
-
-				let ChartTestData = {
-					tooltip: {
-						show: true,
-						trigger: 'item',
-						formatter(params) {
-							let xy = coords[params.dataIndex];
-							let tipData = params["data"];
-							if (params.name === "Max" || params.name === "Min") {
-								tipData = params["data"].coord;
-							}
+				//默认加载图层控制
+				mapWork.getLayers().then(layers => {
+					layers.map((item) => {
+						if (item.isinit === '1') {
 
-							if (!tipEntity) {
-								tipEntity = window.viewer.entities.add({
-									position: Cesium.Cartesian3.fromDegrees(xy[0], xy[1], Number(tipData[1])),
-									billboard: {
-										image: 'jt3dSDK/imgs/point/point.png',
-										horizontalOrigin: Cesium.HorizontalOrigin.center,
-										verticalOrigin: Cesium.VerticalOrigin.bottom,
-										scale: 1,
-										pixelOffset: new Cesium.Cartesian2(0, 0),
-										disableDepthTestDistance: Number.POSITIVE_INFINITY,
-									},
-								});
+							//图层ID
+							let serviceId = "service_" + item.layercode + item.layerorder;
+							item.serviceId = serviceId;
+
+							//透明度
+							let opacity = 1;
+							if (item.opacity == null) {
+								opacity = 1;
 							} else {
-								tipEntity.position = Cesium.Cartesian3.fromDegrees(xy[0], xy[1], Number(tipData[1]));
+								opacity = Number(item.opacity);
 							}
+							item.opacity = opacity;
 
-							//定位到点
-							// jt3d.LocateUtil.flyToPoint({
-							// 	longitude: xy[0],
-							// 	latitude: xy[1],
-							// 	height: Number(tipData[1])
-							// });
+							//默认加载
+							mapWork.setLayersControl(window.viewer, item, true).then(res => {
+								if (res === true) {
 
-							return "距离:" + tipData[0] + "m<br>" + "高度:" + tipData[1] + "m<br>" + "坐标:" + xy[0].toFixed(
-								5) + "," + xy[1].toFixed(5);
+								} else {
+									ElMessage(res)
+								}
+							});
 						}
-					},
-					grid: {
-						bottom: '10%',
-						left: '5%',
-						right: '5%',
-					},
-					xAxis: {
-						type: "value",
-						max: xAixMax,
-						axisLabel: { //文字属性
-							textStyle: {
-								color: 'rgb(216 240 255)'
-							},
-							formatter: '{value} m'
-						},
-						axisLine: { //轴线属性
-							lineStyle: {
-								color: 'rgb(216 240 255)',
-								width: 2
-							},
-						},
-						splitLine: { //分割线属性
-							lineStyle: {
-								type: 'dashed'
-							}
+
+						//默认展开
+						if (item.isexpand === '1') {
+							store.expandedKeys.push(item.id);
 						}
-					},
-					yAxis: {
-						type: "value",
-						axisLabel: { //文字属性
-							textStyle: {
-								color: 'rgb(216 240 255)'
-							},
-							formatter: '{value} m'
-						},
-						axisLine: { //轴线属性
-							lineStyle: {
-								color: 'rgb(216 240 255)',
-								width: 2
-							},
-						},
-						splitLine: { //分割线属性
-							lineStyle: {
-								type: 'dashed'
-							}
+
+						// 复选框默认选中
+						if (item.isinit === '1') {
+							store.checkedkeys.push(item.id);
 						}
-					},
-					series: [{
-						type: "line",
-						data: datas,
-						markPoint: {
-							symbol: 'path://m 0,0 h 48 v 20 h -30 l -6,10 l -6,-10 h -6 z', // 'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow', path://m 0,0 h 48 v 20 h -30 l -6,10 l -6,-10 h -6 z,  path://m 0,0 h 48 v 20 h -34 l -6,10 l -6,-10 h -2 z
-							symbolSize: [60, 60], // 容器大小
-							symbolOffset: ['34%', '-50%'], //位置偏移
-							symbolKeepAspect: true, // 如果 symbol 是 path:// 的形式,是否在缩放时保持该图形的长宽比。
-							label: {
-								textStyle: {
-									color: 'rgb(216,240,255)'
-								},
-								position: "insideTop",
-								distance: 7,
-							},
-							data: [{
-									type: 'max',
-									name: '最大值',
-									itemStyle: { //背景色
-										color: 'rgb(255, 70, 131)',
-									}
-								},
-								{
-									type: 'min',
-									name: '最小值',
-									itemStyle: { //背景色
-										color: 'rgb(255, 70, 131)',
+					})
+				});
+
+				// 默认加载底图切换
+				mapWork.getBaseMaps().then(baseMaps => {
+					baseMaps.map((item) => {
+						//图层ID
+						let serviceId = "service_" + item.layercode + item.layerorder;
+						item.serviceId = serviceId;
+
+						//透明度
+						let opacity = 1;
+						if (item.opacity == null) {
+							opacity = 1;
+						} else {
+							opacity = Number(item.opacity);
+						}
+						item.opacity = opacity;
+
+						if (item.layertype === '地形') {
+							store.terrain.terrainData = item;
+
+							if (item.isinit === '1') {
+								store.terrain.isTerrain = true;
+
+								//默认加载的地形
+								mapWork.setLayersControl(window.viewer, item, true).then(res => {
+									if (res === true) {
+
+									} else {
+										ElMessage(res)
 									}
-								}
-							]
-						},
-						itemStyle: {
-							color: 'rgba(85,254,139,1)',
-						},
-						areaStyle: {
-							color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
-									offset: 0,
-									color: 'rgba(85,254,139,0.8)'
-								},
-								{
-									offset: 1,
-									color: 'rgba(14,245,210,0.2)'
-								}
-							])
-						},
-					}]
-				};
-				this.ChartTestData = ChartTestData;
-			},
+								});
+							}
+						} else if (item.layertype === '标注') {
+							store.mark.markData = item;
 
-			/**
-			 * 地图初始化
-			 * @param {Object} map
-			 */
-			jtMap3DOnload(map) {
-				jt3d = map;
-				this.mapLoaded = true;
-			},
+							if (item.isinit === '1') {
+								store.mark.isMark = true;
 
+								//默认加载的标注
+								mapWork.setLayersControl(window.viewer, item, true).then(res => {
+									if (res === true) {
 
+									} else {
+										ElMessage(res)
+									}
+								});
+							}
+						} else {
+							if (item.isinit === '1') {
+								store.basemap.selectBaseMap = item;
+								store.basemap.selectImg = item.layerorder;
 
+								//默认加载的底图
+								mapWork.setLayersControl(window.viewer, item, true).then(res => {
+									if (res === true) {
+
+									} else {
+										ElMessage(res)
+									}
+								});
+							}
+						}
+					})
+				});
+			}
 		},
-		created() {
-			store.queryMapTables = []
-		},
-		mounted() {
 
+		mounted() {
+			this.init();
 		}
 	};
 </script>

+ 1 - 1
src/views/Map3d/components/TrackRoam.vue

@@ -133,7 +133,7 @@
 						//清除绘制
 						jt3d.DrawTools.Clear();
 
-						_self.Roaming = new _self.jt3dSDK.Roaming(jt3d._viewer, cartesian3d, {
+						_self.Roaming = new jt3dSDK.Roaming(jt3d._viewer, cartesian3d, {
 							time: 360,
 							role: 2,
 							label: {

+ 1 - 1
src/views/Map3d/components/coordsTool.vue

@@ -237,7 +237,7 @@
 							}
 						} else {
 
-							let terrainAltitude = _self.jt3dSDK.common.getHeigthByPointsMostDetailed(jt3d._viewer, [
+							let terrainAltitude = jt3dSDK.common.getHeigthByPointsMostDetailed(jt3d._viewer, [
 								[Number(longitude), Number(latitude)]
 							]);
 							terrainAltitude.then(function(updatedPositions) {

Some files were not shown because too many files changed in this diff