3 files modified
22 files added
| | |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2024-10-25 16:35:31 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2024-10-31 18:22:25 |
| | | * @LastEditTime: 2024-11-06 10:35:00 |
| | | * @FilePath: \bigScreen\src\router\index.js |
| | | * @Description: |
| | | * |
| | |
| | | title: '救援队伍' |
| | | }, |
| | | component: () => import('@/views/rt/index.vue') |
| | | }, |
| | | { |
| | | path: 'sub', |
| | | name: 'sub', |
| | | component: () => import('@/views/sub/index.vue'), |
| | | redirect: '/layout/sub/a', |
| | | children: [ |
| | | { |
| | | path: 'a', |
| | | meta: { |
| | | title: 'a示例' |
| | | }, |
| | | component: () => import('@/views/a/index.vue') |
| | | }, |
| | | ] |
| | | } |
| | | ] |
| | | }, |
| New file |
| | |
| | | /* |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2024-11-06 10:46:45 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2024-11-06 10:56:14 |
| | | * @FilePath: \bigScreen\src\store\router.js |
| | | * @Description: |
| | | * |
| | | * Copyright (c) 2024 by shuishen, All Rights Reserved. |
| | | */ |
| | | // src/stores/useUserStore.js |
| | | import { defineStore } from 'pinia' |
| | | |
| | | export const useRouterStore = defineStore('useRouterStore', { |
| | | // 存储状态的地方,相当于 Vuex 的 state |
| | | state: () => ({ |
| | | loadSub: false |
| | | }), |
| | | |
| | | // 相当于 Vuex 的 getters,用于计算状态 |
| | | getters: { |
| | | |
| | | }, |
| | | |
| | | // 相当于 Vuex 的 mutations 和 actions,用于同步或异步地修改状态 |
| | | actions: { |
| | | setLoadSub (flag) { |
| | | this.loadSub = flag |
| | | }, |
| | | }, |
| | | |
| | | persist: { |
| | | enabled: true, |
| | | strategies: [ |
| | | { |
| | | key: 'loadSub', |
| | | paths: ['loadSub'], |
| | | storage: localStorage, |
| | | }, |
| | | ] |
| | | } |
| | | }) |
| New file |
| | |
| | | <!-- |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2023-03-13 14:54:26 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2023-03-13 15:00:55 |
| | | * @FilePath: \forest-fire\src\views\statistics\components\box\dataContent.vue |
| | | * @Description: |
| | | * |
| | | * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. |
| | | --> |
| | | <script setup> |
| | | import publicContent from './publicContent.vue' |
| | | </script> |
| | | |
| | | <template> |
| | | <public-content> |
| | | <template #content> |
| | | <div> |
| | | |
| | | </div> |
| | | </template> |
| | | </public-content> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped></style> |
| New file |
| | |
| | | <!-- |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2023-03-13 14:54:26 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2023-03-13 15:00:55 |
| | | * @FilePath: \forest-fire\src\views\statistics\components\box\dataContent.vue |
| | | * @Description: |
| | | * |
| | | * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. |
| | | --> |
| | | <script setup> |
| | | import publicContent from './publicContent.vue' |
| | | </script> |
| | | |
| | | <template> |
| | | <public-content> |
| | | <template #content> |
| | | <div> |
| | | |
| | | </div> |
| | | </template> |
| | | </public-content> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped></style> |
| New file |
| | |
| | | <!-- |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2023-03-13 14:54:26 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2023-03-13 15:00:55 |
| | | * @FilePath: \forest-fire\src\views\statistics\components\box\dataContent.vue |
| | | * @Description: |
| | | * |
| | | * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. |
| | | --> |
| | | <script setup> |
| | | import publicContent from './publicContent.vue' |
| | | </script> |
| | | |
| | | <template> |
| | | <public-content> |
| | | <template #content> |
| | | <div> |
| | | |
| | | </div> |
| | | </template> |
| | | </public-content> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped></style> |
| New file |
| | |
| | | <!-- |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2023-03-13 14:54:26 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2023-03-13 15:00:55 |
| | | * @FilePath: \forest-fire\src\views\statistics\components\box\dataContent.vue |
| | | * @Description: |
| | | * |
| | | * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. |
| | | --> |
| | | <script setup> |
| | | import publicContent from './publicContent.vue' |
| | | </script> |
| | | |
| | | <template> |
| | | <public-content> |
| | | <template #content> |
| | | <div> |
| | | |
| | | </div> |
| | | </template> |
| | | </public-content> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped></style> |
| New file |
| | |
| | | <!-- |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2023-03-13 14:54:26 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2023-03-13 15:00:55 |
| | | * @FilePath: \forest-fire\src\views\statistics\components\box\dataContent.vue |
| | | * @Description: |
| | | * |
| | | * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. |
| | | --> |
| | | <script setup> |
| | | import publicContent from './publicContent.vue' |
| | | </script> |
| | | |
| | | <template> |
| | | <public-content> |
| | | <template #content> |
| | | <div> |
| | | |
| | | </div> |
| | | </template> |
| | | </public-content> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped></style> |
| New file |
| | |
| | | <!-- |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2023-03-13 14:54:26 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2024-10-25 18:33:46 |
| | | * @FilePath: \bigScreen\src\views\statistics\components\box\publicContent.vue |
| | | * @Description: |
| | | * |
| | | * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. |
| | | --> |
| | | <script setup> |
| | | |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="content"> |
| | | <slot></slot> |
| | | </div> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped> |
| | | .content { |
| | | padding: 20px 0; |
| | | height: calc(100% - 32px); |
| | | } |
| | | </style> |
| New file |
| | |
| | | <!-- |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2023-03-13 14:54:26 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2023-03-13 15:00:55 |
| | | * @FilePath: \forest-fire\src\views\statistics\components\box\dataContent.vue |
| | | * @Description: |
| | | * |
| | | * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. |
| | | --> |
| | | <script setup> |
| | | import publicContent from './publicContent.vue' |
| | | </script> |
| | | |
| | | <template> |
| | | <public-content> |
| | | <template #content> |
| | | <div> |
| | | |
| | | </div> |
| | | </template> |
| | | </public-content> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped></style> |
| New file |
| | |
| | | <!-- |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2023-03-10 15:27:59 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2024-10-25 18:43:23 |
| | | * @FilePath: \bigScreen\src\views\statistics\components\leftContainer.vue |
| | | * @Description: |
| | | * |
| | | * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. |
| | | --> |
| | | <script setup> |
| | | import dataContent from './box/dataContent.vue' |
| | | import unitContent from './box/unitContent.vue' |
| | | import fireContent from './box/fireContent.vue' |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="left-container"> |
| | | <div class="data box"> |
| | | <title-box> |
| | | <template #titleName> |
| | | 数据概览 |
| | | </template> |
| | | </title-box> |
| | | <div class="content-box"> |
| | | <data-content></data-content> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="unit box"> |
| | | <title-box> |
| | | <template #titleName> |
| | | 入住单位统计 |
| | | </template> |
| | | </title-box> |
| | | <div class="content-box"> |
| | | <unit-content></unit-content> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="fire box"> |
| | | <title-box> |
| | | <template #titleName> |
| | | 实时火警事件 |
| | | </template> |
| | | </title-box> |
| | | <div class="content-box"> |
| | | <fire-content></fire-content> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped></style> |
| New file |
| | |
| | | <!-- |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2023-03-10 15:27:59 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2024-10-26 14:49:05 |
| | | * @FilePath: \bigScreen\src\views\survey\components\rightContainer.vue |
| | | * @Description: |
| | | * |
| | | * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. |
| | | --> |
| | | <script setup> |
| | | import fireSource from './box/fireSource.vue' |
| | | import fireTrend from './box/fireTrend.vue' |
| | | import occurStatistics from './box/occurStatistics.vue' |
| | | import publicContent from './box/publicContent.vue' |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="right-container"> |
| | | <div class="fire-source box"> |
| | | <title-box> |
| | | <template #titleName> |
| | | 火警事件来源 |
| | | </template> |
| | | </title-box> |
| | | <div class="content-box"> |
| | | <fire-source></fire-source> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="occur-statistics box"> |
| | | <title-box> |
| | | <template #titleName> |
| | | 易发区统计 |
| | | </template> |
| | | </title-box> |
| | | <div class="content-box"> |
| | | <fire-trend></fire-trend> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="fire-trend box"> |
| | | <title-box> |
| | | <template #titleName> |
| | | 火警上报趋势 |
| | | </template> |
| | | </title-box> |
| | | <div class="content-box"> |
| | | <occur-statistics></occur-statistics> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped> |
| | | .right-container { |
| | | display: flex; |
| | | flex-direction: column; |
| | | padding: 20px; |
| | | position: absolute; |
| | | top: 0; |
| | | right: 0; |
| | | width: 440px; |
| | | height: 100%; |
| | | pointer-events: auto; |
| | | |
| | | .box { |
| | | margin-top: 20px; |
| | | |
| | | .header { |
| | | height: 32px; |
| | | background: url(/img/bg/sub-title.png) no-repeat; |
| | | } |
| | | } |
| | | |
| | | .fire-source { |
| | | flex: 3; |
| | | } |
| | | |
| | | .occur-statistics { |
| | | flex: 3; |
| | | } |
| | | |
| | | .fire-trend { |
| | | flex: 4; |
| | | } |
| | | |
| | | .box:first-child { |
| | | margin-top: 0; |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | <!-- |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2023-03-10 15:27:59 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2023-03-13 16:02:07 |
| | | * @FilePath: \forest-fire\src\views\statistics\index.vue |
| | | * @Description: 综合设计 |
| | | * |
| | | * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. |
| | | --> |
| | | <script setup> |
| | | import leftContainer from './components/leftContainer.vue' |
| | | import rightContainer from './components/rightContainer.vue' |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="container page-container"> |
| | | <left-container></left-container> |
| | | |
| | | <right-container></right-container> |
| | | </div> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped> |
| | | .container { |
| | | position: absolute; |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | </style> |
| | |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2022-08-18 16:18:24 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2024-11-01 20:00:52 |
| | | * @LastEditTime: 2024-11-06 11:05:46 |
| | | * @FilePath: \bigScreen\src\views\layout\index.vue |
| | | * @Description: |
| | | * |
| | |
| | | <map-container ref="MapContainer"> |
| | | <template #content> |
| | | <div v-if="showContent" class="main-content" id="MainContent"> |
| | | <div class="main-header"> |
| | | <div class="title">吉水化工园区“一园一策一图”VR平台</div> |
| | | |
| | | <div class="login-out" @click="signOut"> |
| | | <img :src="loginOutBg" class="img" /> |
| | | <span>退出</span> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="main-container"> |
| | | <!-- 地图区域 --> |
| | | <router-view ref="target-name"></router-view> |
| | | </div> |
| | | |
| | | <main-search></main-search> |
| | | <main-tool></main-tool> |
| | | <main-menu></main-menu> |
| | | |
| | | <div v-if="!showSubLayout" class="w100 h100"> |
| | | <div class="main-header"> |
| | | <div class="title">吉水化工园区“一园一策一图”VR平台</div> |
| | | |
| | | <div class="login-out" @click="signOut"> |
| | | <img :src="loginOutBg" class="img" /> |
| | | <span>退出</span> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="main-container"> |
| | | <!-- 地图区域 --> |
| | | <router-view></router-view> |
| | | </div> |
| | | |
| | | <main-menu></main-menu> |
| | | </div> |
| | | |
| | | <div v-if="showSubLayout" class="w100 h100"> |
| | | <router-view></router-view> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | </map-container> |
| | |
| | | import { useLogin } from 'store/login' |
| | | const loginStore = useLogin() |
| | | import { useMap } from 'store/map' |
| | | import { useRouterStore } from 'store/router' |
| | | const store = useMap() |
| | | const storeRouter = useRouterStore() |
| | | const showContent = ref(false) |
| | | const showSubLayout = ref(false) |
| | | |
| | | // 监听createB的变化 |
| | | watch( |
| | | () => store.loadMap, |
| | | (newValue) => { |
| | | if (newValue) { |
| | | [ |
| | | () => store.loadMap, |
| | | () => storeRouter.loadSub, |
| | | ], |
| | | ([newLoadMap, newLoadSub]) => { |
| | | if (newLoadMap) { |
| | | showContent.value = true |
| | | } |
| | | |
| | | console.log(newLoadSub, 5555) |
| | | showSubLayout.value = newLoadSub |
| | | }, |
| | | { immediate: true } // 设置immediate为true以便在组件挂载时立即检查createB的值 |
| | | ) |
| New file |
| | |
| | | <template> |
| | | <div class="page-mode"> |
| | | <div @mouseenter="item.childrenFlag = true" :class="{ active: currentUrl.indexOf(item.path) != -1 }" |
| | | @mouseleave="item.childrenFlag = false" @click="goToPath(item)" v-for="(item, index) in menuList" :key="index"> |
| | | {{ item.menuName }} |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, watch } from 'vue' |
| | | import { useRouter, useRoute } from 'vue-router' |
| | | import { Search } from '@element-plus/icons-vue' |
| | | import { getTime } from '@/utils/getTime.js' |
| | | let router = useRouter() |
| | | let currentUrl = ref('statistics') |
| | | |
| | | const menuList = ref( |
| | | [ |
| | | { |
| | | menuName: '园区概况', |
| | | path: '/layout/survey' |
| | | }, |
| | | { |
| | | menuName: '固定风险源', |
| | | path: '/layout/rs' |
| | | }, |
| | | { |
| | | menuName: '应急空间', |
| | | path: '/layout/space' |
| | | }, |
| | | { |
| | | menuName: '应急物资', |
| | | path: '/layout/supplies' |
| | | }, |
| | | { |
| | | menuName: '三级防控', |
| | | path: '/layout/pac' |
| | | }, |
| | | { |
| | | menuName: '救援队伍', |
| | | path: '/layout/rt' |
| | | }, |
| | | ] |
| | | ) |
| | | |
| | | const goToPath = (params) => { |
| | | if (params.children && params.children.length > 0) return |
| | | |
| | | if (params.path) { |
| | | if (router.currentRoute.value.path == params.path) return |
| | | router.push(params.path) |
| | | } else { |
| | | params.childrenFlag = !params.childrenFlag |
| | | } |
| | | } |
| | | |
| | | watch( |
| | | () => router.currentRoute.value, |
| | | (newValue, oldValue) => { |
| | | |
| | | currentUrl.value = newValue.path |
| | | |
| | | }, |
| | | { immediate: true } |
| | | ) |
| | | |
| | | const userName = ref('管理员') |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .page-mode { |
| | | position: absolute; |
| | | top: auto; |
| | | bottom: 55px; |
| | | left: 50%; |
| | | z-index: 99; |
| | | transform: translateX(-50%); |
| | | display: flex; |
| | | pointer-events: auto; |
| | | |
| | | &>div { |
| | | background-image: url(/images/mode-tab.png); |
| | | background-size: cover; |
| | | width: 150px; |
| | | height: 50px; |
| | | font-size: 16px; |
| | | text-align: center; |
| | | font-weight: bold; |
| | | color: #BFD3E5; |
| | | line-height: 32px; |
| | | padding-top: 12px; |
| | | margin-right: -20px; |
| | | font-style: italic; |
| | | cursor: pointer; |
| | | box-sizing: border-box; |
| | | |
| | | &:last-child { |
| | | margin-right: 0px; |
| | | } |
| | | |
| | | &.active { |
| | | color: #F6FCFF; |
| | | background-image: url(/images/mode-tab-ac.png); |
| | | } |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | <!-- |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2024-10-26 16:09:35 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2024-10-28 11:04:58 |
| | | * @FilePath: \bigScreen\src\views\layout\components\mainSearch.vue |
| | | * @Description: |
| | | * |
| | | * Copyright (c) 2024 by shuishen, All Rights Reserved. |
| | | --> |
| | | <template> |
| | | <div class="page-search"> |
| | | <el-input size="medium" placeholder="请输入内容" :suffix-icon="Search" @input="onSearch()" v-model="searchVal" |
| | | @focus="onFocus"></el-input> |
| | | <div class="page-search-value-box" v-show="isShowSearchSKValBox"> |
| | | <ul> |
| | | <li v-for="(item, index) in searchSKValList" :key="index" @click="sKValItemClick(item)">{{ item.name }} |
| | | </li> |
| | | </ul> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | // 搜索栏相关 |
| | | let isShowSearchSKValBox = false |
| | | let searchVal = '' |
| | | let searchSKValList = [] |
| | | |
| | | const onSearch = () => { |
| | | if (searchVal == '') { |
| | | isShowSearchSKValBox = false |
| | | } else { |
| | | isShowSearchSKValBox = true |
| | | } |
| | | } |
| | | |
| | | const onFocus = () => { |
| | | onSearch() |
| | | } |
| | | |
| | | const sKValItemClick = (item) => { |
| | | isShowSearchSKValBox = false |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .page-search { |
| | | position: absolute; |
| | | left: 488px; |
| | | z-index: 99; |
| | | top: 110px; |
| | | pointer-events: auto; |
| | | |
| | | ::v-deep(.el-input) { |
| | | height: 38px; |
| | | width: 280px; |
| | | |
| | | .el-input__wrapper { |
| | | font-size: 16px; |
| | | font-weight: 400; |
| | | border: 1px solid #4081CB; |
| | | border-radius: 4px; |
| | | background: rgba(135, 158, 199, 0.3); |
| | | box-shadow: inset 0px 3px 7px 0px rgba(42, 138, 236, 0.95); |
| | | |
| | | .el-input__inner { |
| | | color: #BFD3E5; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .page-search-value-box { |
| | | position: absolute; |
| | | width: 100%; |
| | | height: 200px; |
| | | left: 0; |
| | | top: 40px; |
| | | background: rgba(135, 158, 199, 0.3); |
| | | border-radius: 2px; |
| | | overflow-y: scroll; |
| | | |
| | | ul>li { |
| | | color: #ffffff; |
| | | cursor: pointer; |
| | | height: 20px; |
| | | line-height: 20px; |
| | | padding-left: 10px; |
| | | } |
| | | |
| | | ul>li:hover { |
| | | background-color: #0e1a35; |
| | | } |
| | | } |
| | | |
| | | .page-search-value-box::-webkit-scrollbar { |
| | | display: none |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | <div class="toolBarRight animation-slide-top no-print-view"> |
| | | <el-button v-for="item, index in btnGroup" :key="index" @click="btnClick(item)" |
| | | class="btn btn-link toolBarRight-btn"> |
| | | <i :class="item.icon"></i>{{ item.name }} |
| | | </el-button> |
| | | </div> |
| | | |
| | | <base-map v-show="currentComponent == 'map'" @close="closeBox"></base-map> |
| | | <layers-control v-show="currentComponent == 'layers'" @close="closeBox"></layers-control> |
| | | <tool-list :moreToolShow="moreToolShow" @close="closeBox"></tool-list> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import baseMap from './scomponents/baseMap.vue' |
| | | import layersControl from './scomponents/layersControl.vue' |
| | | import toolList from './scomponents/toolList.vue' |
| | | |
| | | const currentComponent = ref('') |
| | | let moreToolShow = ref(false) |
| | | |
| | | const btnGroup = [ |
| | | { |
| | | name: '底图', |
| | | icon: 'fa fa-map', |
| | | key: 'map', |
| | | }, |
| | | { |
| | | name: '图层', |
| | | icon: 'fa fa-tasks', |
| | | key: 'layers', |
| | | }, |
| | | { |
| | | name: '工具', |
| | | icon: 'fa fa-cubes', |
| | | key: 'tool', |
| | | }, |
| | | ] |
| | | |
| | | const btnClick = (item) => { |
| | | if (item.key == 'tool') { |
| | | moreToolShow.value = !moreToolShow.value |
| | | } else { |
| | | currentComponent.value = item.key |
| | | } |
| | | } |
| | | |
| | | const closeBox = (type) => { |
| | | if (type == 'tool') { |
| | | moreToolShow.value = false |
| | | } else { |
| | | currentComponent.value = '' |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .toolBarRight { |
| | | display: flex; |
| | | flex-wrap: nowrap; |
| | | position: absolute; |
| | | right: 540px; |
| | | z-index: 99; |
| | | top: 110px; |
| | | |
| | | border: 1px solid #4081CB; |
| | | border-radius: 4px; |
| | | background: rgba(135, 158, 199, 0.3); |
| | | box-shadow: inset 0px 3px 7px 0px rgba(42, 138, 236, 0.95); |
| | | pointer-events: auto; |
| | | |
| | | ::v-deep(.el-button) { |
| | | margin-left: 0; |
| | | border: none; |
| | | border-radius: 0; |
| | | background: transparent; |
| | | |
| | | &.btn { |
| | | padding: 4px 12px; |
| | | font-size: 14px; |
| | | line-height: 1.6; |
| | | -webkit-transition: border .2s linear, color .2s linear, width .2s linear, background-color .2s linear; |
| | | -o-transition: border .2s linear, color .2s linear, width .2s linear, background-color .2s linear; |
| | | transition: border .2s linear, color .2s linear, width .2s linear, background-color .2s linear; |
| | | } |
| | | |
| | | &.btn-link { |
| | | font-weight: 400; |
| | | color: #007bff; |
| | | text-decoration: none; |
| | | } |
| | | |
| | | &.toolBarRight-btn { |
| | | list-style-type: none; |
| | | cursor: pointer; |
| | | border-right: solid 1px #2b2c2f; |
| | | color: #edffff; |
| | | } |
| | | |
| | | &.toolBarRight-btn:last-child { |
| | | border-right: none; |
| | | } |
| | | |
| | | i { |
| | | margin-right: 4px; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | <!-- |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2024-10-28 11:44:45 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2024-11-05 18:39:20 |
| | | * @FilePath: \bigScreen\src\views\layout\components\scomponents\baseMap.vue |
| | | * @Description: |
| | | * |
| | | * Copyright (c) 2024 by shuishen, All Rights Reserved. |
| | | --> |
| | | <template> |
| | | <public-box> |
| | | <template #name> |
| | | <div class="name"><i class="fa fa-map"></i> 底图</div> |
| | | </template> |
| | | |
| | | <template #close> |
| | | <div class="close" @click="$emit('close', 'map')"><i class="fa fa-close"></i></div> |
| | | </template> |
| | | |
| | | <template #content> |
| | | <div class="layers-box-content"> |
| | | <ul class="layers-box"> |
| | | <li :class="{ on: item.mode == curMode }" v-for="item, index in baseMaps" :key="index" |
| | | @click="loadLAYER(item.mode, index)"> |
| | | <div><img :src="item.src"></div> |
| | | <div>{{ item.name }}</div> |
| | | </li> |
| | | </ul> |
| | | </div> |
| | | |
| | | <div class="show-terrain" style="margin-left:10px;color:#fff"> |
| | | <el-checkbox @change="terrainChange" v-model="showTerrainFlag" label="显示地形" size="large" /> |
| | | </div> |
| | | </template> |
| | | </public-box> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { getAssetsFile } from 'utils/utils' |
| | | import AmapMercatorTilingScheme from './cesium/AmapMercatorTilingScheme/index' |
| | | |
| | | const { appContext } = getCurrentInstance() |
| | | const global = appContext.config.globalProperties |
| | | const Cesium = DC.getLib('Cesium') |
| | | const cesiumToken = |
| | | 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkYTZlNGNlYS01NTU1LTQ1MGEtYmNlZS0yNTE2NDk5YWM2MjEiLCJpZCI6MTc5Njk2LCJpYXQiOjE3MDA1NDcwMjV9.qcl4AH2731cfFd0-I1ZLUINPXqvglLkDFD-UGR2zU5M' |
| | | Cesium.Ion.defaultAccessToken = cesiumToken |
| | | |
| | | const TDT_Token = 'c6eea7dad4fa1e2d1e32ec0e7c9735db' |
| | | // 天地图Key |
| | | // 天地图地图 |
| | | const TDT_IMG_C = 'https://{s}.tianditu.gov.cn/img_c/wmts?service=wmts&request=GetTile&version=1.0.0' + |
| | | '&LAYER=img&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}' + |
| | | '&style=default&format=tiles&tk=' + TDT_Token |
| | | // 天地图注记 |
| | | const TDT_ZJ = 'https://{s}.tianditu.gov.cn/cia_c/wmts?service=wmts&request=GetTile&version=1.0.0' + |
| | | '&LAYER=cia&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}' + |
| | | '&style=default&format=tiles&tk=' + TDT_Token |
| | | // 标准地图注记 |
| | | const TID_STAND = 'https://{s}.tianditu.gov.cn/vec_w/wmts?service=wmts&request=GetTile&version=1.0.0' + |
| | | '&LAYER=img&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}' + |
| | | '&style=default&format=tiles&tk=' + TDT_Token |
| | | |
| | | const imageryProvider_standZh = new Cesium.UrlTemplateImageryProvider({ |
| | | url: 'https://t{s}.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c', |
| | | subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'], |
| | | maximumLevel: 18, |
| | | credit: 'stand_zj', |
| | | }) |
| | | |
| | | const imageryProvider_stand = new Cesium.UrlTemplateImageryProvider({ |
| | | url: 'https://t{s}.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c', |
| | | subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'], |
| | | // format: 'image/jpeg', |
| | | // show: true, |
| | | maximumLevel: 18, |
| | | credit: 'stand_tc', |
| | | }) |
| | | |
| | | const annotation = new Cesium.WebMapTileServiceImageryProvider({ |
| | | url: TDT_ZJ, |
| | | layer: 'tdtZwImg_c', |
| | | style: 'default', |
| | | format: 'tiles', |
| | | tileMatrixSetID: 'c', |
| | | subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'], |
| | | tilingScheme: new Cesium.GeographicTilingScheme(), |
| | | tileMatrixLabels: [ |
| | | '1', |
| | | '2', |
| | | '3', |
| | | '4', |
| | | '5', |
| | | '6', |
| | | '7', |
| | | '8', |
| | | '9', |
| | | '10', |
| | | '11', |
| | | '12', |
| | | '13', |
| | | '14', |
| | | '15', |
| | | '16', |
| | | '17', |
| | | '18', |
| | | '19', |
| | | ], |
| | | maximumLevel: 50, |
| | | }) |
| | | |
| | | const imageryProvider_tdt = new Cesium.WebMapTileServiceImageryProvider({ |
| | | url: TDT_IMG_C, |
| | | layer: 'tdtImg_c', |
| | | style: 'default', |
| | | format: 'tiles', |
| | | tileMatrixSetID: 'c', |
| | | subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'], |
| | | tilingScheme: new Cesium.GeographicTilingScheme(), |
| | | tileMatrixLabels: [ |
| | | '1', |
| | | '2', |
| | | '3', |
| | | '4', |
| | | '5', |
| | | '6', |
| | | '7', |
| | | '8', |
| | | '9', |
| | | '10', |
| | | '11', |
| | | '12', |
| | | '13', |
| | | '14', |
| | | '15', |
| | | '16', |
| | | '17', |
| | | '18', |
| | | '19', |
| | | ], |
| | | maximumLevel: 17, |
| | | }) |
| | | |
| | | const imageryProvider_ammapSL = new Cesium.UrlTemplateImageryProvider({ |
| | | url: 'https://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}', |
| | | layer: 'tdtVecBasicLayer', |
| | | style: 'default', |
| | | format: 'image/png', |
| | | tileMatrixSetID: 'GoogleMapsCompatible', |
| | | subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'], |
| | | maximumLevel: 18, |
| | | tilingScheme: new AmapMercatorTilingScheme(), |
| | | credit: 'amap_SL', |
| | | }) |
| | | |
| | | const imageryProvider_ammap = new Cesium.UrlTemplateImageryProvider({ |
| | | url: 'https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}', |
| | | layer: 'tdtVecBasicLayer', |
| | | style: 'default', |
| | | format: 'image/png', |
| | | tileMatrixSetID: 'GoogleMapsCompatible', |
| | | subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'], |
| | | maximumLevel: 18, |
| | | tilingScheme: new AmapMercatorTilingScheme(), |
| | | credit: 'amap_stand', |
| | | }) |
| | | |
| | | const imageryProvider_ammapBz = new Cesium.UrlTemplateImageryProvider({ |
| | | url: 'https://webst02.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8', |
| | | tilingScheme: new AmapMercatorTilingScheme(), |
| | | minimumLevel: 3, |
| | | }) |
| | | |
| | | let mapLayers = [ |
| | | { |
| | | src: getAssetsFile('stand.png'), |
| | | mode: '0', |
| | | name: '天地图矢量', |
| | | layers: [ |
| | | { key: 'imageryProvider_standZh', layer: imageryProvider_standZh }, |
| | | { key: 'imageryProvider_stand', layer: imageryProvider_stand }, |
| | | ] |
| | | }, |
| | | { |
| | | src: getAssetsFile('satellite.png'), |
| | | mode: '1', |
| | | name: '天地图影像', |
| | | layers: [ |
| | | { key: 'annotation', layer: annotation }, |
| | | { |
| | | key: 'imageryProvider_tdt', |
| | | layer: imageryProvider_tdt, |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | src: getAssetsFile('stand.png'), |
| | | mode: '2', |
| | | name: '高德矢量', |
| | | layers: [ |
| | | { |
| | | key: 'imageryProvider_ammapSL', |
| | | layer: imageryProvider_ammapSL, |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | src: getAssetsFile('satellite.png'), |
| | | mode: '3', |
| | | name: '高德影像', |
| | | layers: [ |
| | | { key: 'imageryProvider_ammap', layer: imageryProvider_ammap }, |
| | | { key: 'imageryProvider_ammapBz', layer: imageryProvider_ammapBz }, |
| | | ] |
| | | } |
| | | ] |
| | | |
| | | let curMode = ref(null) |
| | | let baseMaps = reactive([]) |
| | | |
| | | baseMaps = mapLayers.map(item => { |
| | | return { |
| | | src: item.src, |
| | | mode: item.mode, |
| | | name: item.name, |
| | | } |
| | | }) |
| | | |
| | | let globalBaseMapLayers = [] |
| | | |
| | | const loadLAYER = (mode, ind) => { |
| | | if (mode == curMode.value) return |
| | | |
| | | let curmapLayers = [] |
| | | |
| | | globalBaseMapLayers.length && |
| | | globalBaseMapLayers.forEach((item) => { |
| | | item.mapLayer.show = false |
| | | }) |
| | | |
| | | curmapLayers.push( |
| | | ...mapLayers[ind].layers, |
| | | ) |
| | | |
| | | // 创建一个Set来快速查找array2中的id |
| | | let keyBaseMap = new Set(globalBaseMapLayers.map((item) => item.key)) |
| | | let keyMapLayers = new Set(curmapLayers.map((item) => item.key)) |
| | | |
| | | let keyExistBaseMap = curmapLayers.filter((item) => !keyBaseMap.has(item.key)) |
| | | |
| | | let keyNoExistBaseMap = globalBaseMapLayers.filter((item) => |
| | | keyMapLayers.has(item.key), |
| | | ) |
| | | |
| | | keyExistBaseMap.length && |
| | | keyExistBaseMap.forEach((item) => { |
| | | let curLayer = { |
| | | key: item.key, |
| | | mapLayer: global.$viewer?.imageryLayers.addImageryProvider(item.layer), |
| | | } |
| | | |
| | | curLayer.mapLayer.show = true |
| | | global.$viewer?.imageryLayers.lowerToBottom(curLayer.mapLayer) |
| | | |
| | | globalBaseMapLayers.push(curLayer) |
| | | }) |
| | | |
| | | keyNoExistBaseMap.length && |
| | | keyNoExistBaseMap.forEach((item) => { |
| | | item.mapLayer.show = true |
| | | global.$viewer?.imageryLayers.lowerToBottom(item.mapLayer) |
| | | }) |
| | | |
| | | curMode.value = mode |
| | | } |
| | | |
| | | loadLAYER(1, 1) |
| | | |
| | | const showTerrainFlag = ref(false) |
| | | |
| | | const terrainChange = (e) => { |
| | | if (e) { |
| | | let terrain = DC.TerrainFactory.createTerrain(DC.TerrainType.XYZ, { |
| | | url: 'https://data.marsgis.cn/terrain' |
| | | }) |
| | | global.$viewer.setTerrain(terrain) |
| | | } else { |
| | | global.$viewer.setTerrain() |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .close { |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .layers-box-content { |
| | | .layers-box { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | flex-wrap: wrap; |
| | | width: 354px; |
| | | padding: 0 10px; |
| | | box-sizing: border-box; |
| | | |
| | | li { |
| | | margin-top: 10px; |
| | | cursor: pointer; |
| | | |
| | | &.on, |
| | | &:hover { |
| | | div:first-child { |
| | | border: solid 2px #337fe5; |
| | | } |
| | | |
| | | div:last-child { |
| | | color: #337fe5; |
| | | } |
| | | } |
| | | |
| | | div:first-child { |
| | | width: 76px; |
| | | height: 76px; |
| | | background: red; |
| | | border: 2px solid white; |
| | | box-sizing: border-box; |
| | | |
| | | img { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | } |
| | | |
| | | div:last-child { |
| | | width: 76px; |
| | | height: 20px; |
| | | line-height: 20px; |
| | | color: #fff; |
| | | font-size: 12px; |
| | | text-align: center; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .show-terrain { |
| | | ::v-deep(.el-checkbox) { |
| | | .el-checkbox__label { |
| | | color: #fff; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | // 定义一些常量 |
| | | const BD_FACTOR = (3.14159265358979324 * 3000.0) / 180.0; |
| | | const PI = 3.1415926535897932384626; |
| | | const RADIUS = 6378245.0; |
| | | const EE = 0.00669342162296594323; |
| | | |
| | | class CoordTransform { |
| | | /** |
| | | * BD-09(百度坐标系) To GCJ-02(火星坐标系) |
| | | * @param lng |
| | | * @param lat |
| | | * @returns {number[]} |
| | | */ |
| | | static BD09ToGCJ02(lng, lat) { |
| | | let x = +lng - 0.0065; |
| | | let y = +lat - 0.006; |
| | | let z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * BD_FACTOR); |
| | | let theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * BD_FACTOR); |
| | | let gg_lng = z * Math.cos(theta); |
| | | let gg_lat = z * Math.sin(theta); |
| | | return [gg_lng, gg_lat]; |
| | | } |
| | | |
| | | /** |
| | | * GCJ-02(火星坐标系) To BD-09(百度坐标系) |
| | | * @param lng |
| | | * @param lat |
| | | * @returns {number[]} |
| | | * @constructor |
| | | */ |
| | | static GCJ02ToBD09(lng, lat) { |
| | | lat = +lat; |
| | | lng = +lng; |
| | | let z = |
| | | Math.sqrt(lng * lng + lat * lat) + |
| | | 0.00002 * Math.sin(lat * BD_FACTOR); |
| | | let theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * BD_FACTOR); |
| | | let bd_lng = z * Math.cos(theta) + 0.0065; |
| | | let bd_lat = z * Math.sin(theta) + 0.006; |
| | | return [bd_lng, bd_lat]; |
| | | } |
| | | |
| | | /** |
| | | * WGS-84(世界大地坐标系) To GCJ-02(火星坐标系) |
| | | * @param lng |
| | | * @param lat |
| | | * @returns {number[]} |
| | | */ |
| | | static WGS84ToGCJ02(lng, lat) { |
| | | lat = +lat; |
| | | lng = +lng; |
| | | if (this.out_of_china(lng, lat)) { |
| | | return [lng, lat]; |
| | | } else { |
| | | let d = this.delta(lng, lat); |
| | | return [lng + d[0], lat + d[1]]; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * GCJ-02(火星坐标系) To WGS-84(世界大地坐标系) |
| | | * @param lng |
| | | * @param lat |
| | | * @returns {number[]} |
| | | * @constructor |
| | | */ |
| | | static GCJ02ToWGS84(lng, lat) { |
| | | lat = +lat; |
| | | lng = +lng; |
| | | if (this.out_of_china(lng, lat)) { |
| | | return [lng, lat]; |
| | | } else { |
| | | let d = this.delta(lng, lat); |
| | | let mgLng = lng + d[0]; |
| | | let mgLat = lat + d[1]; |
| | | return [lng * 2 - mgLng, lat * 2 - mgLat]; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * |
| | | * @param lng |
| | | * @param lat |
| | | * @returns {number[]} |
| | | */ |
| | | static delta(lng, lat) { |
| | | let dLng = this.transformLng(lng - 105, lat - 35); |
| | | let dLat = this.transformLat(lng - 105, lat - 35); |
| | | const radLat = (lat / 180) * PI; |
| | | let magic = Math.sin(radLat); |
| | | magic = 1 - EE * magic * magic; |
| | | const sqrtMagic = Math.sqrt(magic); |
| | | dLng = (dLng * 180) / ((RADIUS / sqrtMagic) * Math.cos(radLat) * PI); |
| | | dLat = |
| | | (dLat * 180) / (((RADIUS * (1 - EE)) / (magic * sqrtMagic)) * PI); |
| | | return [dLng, dLat]; |
| | | } |
| | | |
| | | /** |
| | | * |
| | | * @param lng |
| | | * @param lat |
| | | * @returns {number} |
| | | */ |
| | | static transformLng(lng, lat) { |
| | | lat = +lat; |
| | | lng = +lng; |
| | | let ret = |
| | | 300.0 + |
| | | lng + |
| | | 2.0 * lat + |
| | | 0.1 * lng * lng + |
| | | 0.1 * lng * lat + |
| | | 0.1 * Math.sqrt(Math.abs(lng)); |
| | | ret += |
| | | ((20.0 * Math.sin(6.0 * lng * PI) + |
| | | 20.0 * Math.sin(2.0 * lng * PI)) * |
| | | 2.0) / |
| | | 3.0; |
| | | ret += |
| | | ((20.0 * Math.sin(lng * PI) + 40.0 * Math.sin((lng / 3.0) * PI)) * |
| | | 2.0) / |
| | | 3.0; |
| | | ret += |
| | | ((150.0 * Math.sin((lng / 12.0) * PI) + |
| | | 300.0 * Math.sin((lng / 30.0) * PI)) * |
| | | 2.0) / |
| | | 3.0; |
| | | return ret; |
| | | } |
| | | |
| | | /** |
| | | * |
| | | * @param lng |
| | | * @param lat |
| | | * @returns {number} |
| | | */ |
| | | static transformLat(lng, lat) { |
| | | lat = +lat; |
| | | lng = +lng; |
| | | let ret = |
| | | -100.0 + |
| | | 2.0 * lng + |
| | | 3.0 * lat + |
| | | 0.2 * lat * lat + |
| | | 0.1 * lng * lat + |
| | | 0.2 * Math.sqrt(Math.abs(lng)); |
| | | ret += |
| | | ((20.0 * Math.sin(6.0 * lng * PI) + |
| | | 20.0 * Math.sin(2.0 * lng * PI)) * |
| | | 2.0) / |
| | | 3.0; |
| | | ret += |
| | | ((20.0 * Math.sin(lat * PI) + 40.0 * Math.sin((lat / 3.0) * PI)) * |
| | | 2.0) / |
| | | 3.0; |
| | | ret += |
| | | ((160.0 * Math.sin((lat / 12.0) * PI) + |
| | | 320 * Math.sin((lat * PI) / 30.0)) * |
| | | 2.0) / |
| | | 3.0; |
| | | return ret; |
| | | } |
| | | |
| | | /** |
| | | * 判断是否在国内。不在国内不做偏移 |
| | | * @param lng |
| | | * @param lat |
| | | * @returns {boolean} |
| | | */ |
| | | static out_of_china(lng, lat) { |
| | | lat = +lat; |
| | | lng = +lng; |
| | | return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55); |
| | | } |
| | | } |
| | | |
| | | export default CoordTransform; |
| New file |
| | |
| | | /* |
| | | * @Author: GuLiMmo 2820890765@qq.com |
| | | * @Date: 2024-05-11 09:18:29 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2024-10-28 20:14:09 |
| | | * @FilePath: \bigScreen\src\views\layout\components\scomponents\cesium\AmapMercatorTilingScheme\index.js |
| | | * @Description: 高德地图纠偏 |
| | | * Copyright (c) 2024 by GuLiMmo, All Rights Reserved. |
| | | */ |
| | | const { |
| | | WebMercatorProjection, |
| | | WebMercatorTilingScheme, |
| | | Math, |
| | | Cartographic, |
| | | Cartesian2, |
| | | } = DC.__namespace.Cesium |
| | | import CoordTransform from './CoordTransform' |
| | | |
| | | class AmapMercatorTilingScheme extends WebMercatorTilingScheme { |
| | | constructor() { |
| | | super() |
| | | |
| | | let projection = new WebMercatorProjection() |
| | | |
| | | this._projection.project = function (cartographic, result) { |
| | | result = CoordTransform.WGS84ToGCJ02( |
| | | Math.toDegrees(cartographic.longitude), |
| | | Math.toDegrees(cartographic.latitude), |
| | | ) |
| | | result = projection.project( |
| | | new Cartographic( |
| | | Math.toRadians(result[0]), |
| | | Math.toRadians(result[1]), |
| | | ), |
| | | ) |
| | | return new Cartesian2(result.x, result.y) |
| | | } |
| | | |
| | | this._projection.unproject = function (cartesian, result) { |
| | | let cartographic = projection.unproject(cartesian) |
| | | result = CoordTransform.GCJ02ToWGS84( |
| | | Math.toDegrees(cartographic.longitude), |
| | | Math.toDegrees(cartographic.latitude), |
| | | ) |
| | | return new Cartographic( |
| | | Math.toRadians(result[0]), |
| | | Math.toRadians(result[1]), |
| | | ) |
| | | } |
| | | } |
| | | } |
| | | |
| | | export default AmapMercatorTilingScheme |
| New file |
| | |
| | | <!-- |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2024-10-31 10:47:29 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2024-11-05 18:36:54 |
| | | * @FilePath: \bigScreen\src\views\layout\components\scomponents\layersControl.vue |
| | | * @Description: |
| | | * |
| | | * Copyright (c) 2024 by shuishen, All Rights Reserved. |
| | | --> |
| | | <template> |
| | | <public-box> |
| | | <template #name> |
| | | <div class="name"><i class="fa fa-tasks"></i> 图层</div> |
| | | </template> |
| | | |
| | | <template #close> |
| | | <div class="close" @click="$emit('close', 'layers')"><i class="fa fa-close"></i></div> |
| | | </template> |
| | | |
| | | <template #content> |
| | | <div class="tree-content"> |
| | | <el-tree ref="treeRef" :data="data" draggable="" show-checkbox node-key="id" default-expand-all |
| | | :default-checked-keys="['1']" :props="defaultProps" :indent="treeProps['indent']" @check="handleCheckChange"> |
| | | <template v-slot:default="{ node }"> |
| | | <element-tree-line :node="node" :showLabelLine="treeProps['showLabelLine']" :indent="treeProps['indent']"> |
| | | <!-- 自定义label的slot --> |
| | | <template v-slot:node-label> |
| | | <span style="font-size: 12px"> |
| | | {{ node.label }} |
| | | <i class="el-icon-eleme"></i></span> |
| | | </template> |
| | | <!-- 在右边追加内容的slot --> |
| | | <!-- <template v-slot:after-node-label> |
| | | <span style="padding-right: 10px"> |
| | | <el-button type="primary" size="mini" @click.stop="openDrawer(node)">新增子节点</el-button> |
| | | <el-button type="primary" size="mini" @click.stop="openDrawer(node)">修改</el-button> |
| | | <el-button type="danger" size="mini" @click.stop="openDialog">删除</el-button></span> |
| | | </template> --> |
| | | </element-tree-line> |
| | | </template> |
| | | </el-tree> |
| | | </div> |
| | | </template> |
| | | </public-box> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { getPage } from '@/api/indParkInfo' |
| | | import { getList } from "@/api/space/space" |
| | | import { getList as getRiskList } from "@/api/riskSource/riskSource" |
| | | |
| | | const { VITE_APP_BASE } = import.meta.env |
| | | import { getViewer } from 'utils/getViewer' |
| | | const globalViewer = getViewer() |
| | | |
| | | const treeRef = ref(null) |
| | | |
| | | const treeProps = { |
| | | indent: 16, |
| | | showLabelLine: true, |
| | | } |
| | | |
| | | const data = [ |
| | | { |
| | | id: '1', |
| | | label: '化工园区', |
| | | type: 'layer', |
| | | subType: '3Dtile', |
| | | url: VITE_APP_BASE + 'mx/tileset.json', |
| | | layerName: 'hgyq' |
| | | }, |
| | | |
| | | { |
| | | id: '2', |
| | | label: '企业分布', |
| | | type: 'layer', |
| | | subType: 'labelPoint', |
| | | method: getPage, |
| | | params: { |
| | | size: 1000 |
| | | }, |
| | | layerName: 'qyfb' |
| | | }, |
| | | |
| | | { |
| | | id: '3', |
| | | label: '应急空间', |
| | | children: [ |
| | | { |
| | | id: '3-1', |
| | | label: '应急池', |
| | | type: 'layer', |
| | | subType: 'labelPoint', |
| | | method: getList, |
| | | params: { |
| | | type: 1, |
| | | size: 1000 |
| | | }, |
| | | layerName: 'yjc' |
| | | }, |
| | | { |
| | | id: '3-2', |
| | | label: '阀门', |
| | | type: 'layer', |
| | | subType: 'labelPoint', |
| | | method: getList, |
| | | params: { |
| | | type: 2, |
| | | size: 1000 |
| | | }, |
| | | layerName: 'fm' |
| | | }, |
| | | |
| | | { |
| | | id: '3-3', |
| | | label: '公共管网', |
| | | type: 'layer', |
| | | subType: 'labelPoint', |
| | | method: getList, |
| | | params: { |
| | | type: 3, |
| | | size: 1000 |
| | | }, |
| | | layerName: 'gggw' |
| | | }, |
| | | |
| | | { |
| | | id: '3-4', |
| | | label: '污水提升泵站', |
| | | type: 'layer', |
| | | subType: 'labelPoint', |
| | | method: getList, |
| | | params: { |
| | | type: 4, |
| | | size: 1000 |
| | | }, |
| | | layerName: 'wstsbz' |
| | | }, |
| | | |
| | | { |
| | | id: '3-5', |
| | | label: '水库', |
| | | type: 'layer', |
| | | subType: 'labelPoint', |
| | | method: getList, |
| | | params: { |
| | | type: 5, |
| | | size: 1000 |
| | | }, |
| | | layerName: 'sk' |
| | | }, |
| | | |
| | | { |
| | | id: '3-6', |
| | | label: '应急泵', |
| | | type: 'layer', |
| | | subType: 'labelPoint', |
| | | method: getList, |
| | | params: { |
| | | type: 6, |
| | | size: 1000 |
| | | }, |
| | | layerName: 'yjb' |
| | | }, |
| | | |
| | | { |
| | | id: '3-7', |
| | | label: '消防沙', |
| | | type: 'layer', |
| | | subType: 'labelPoint', |
| | | method: getList, |
| | | params: { |
| | | type: 7, |
| | | size: 1000 |
| | | }, |
| | | layerName: 'xfs' |
| | | } |
| | | ] |
| | | }, |
| | | |
| | | { |
| | | id: '4', |
| | | label: '风险源', |
| | | type: 'layer', |
| | | subType: 'labelPoint', |
| | | method: getRiskList, |
| | | params: { |
| | | size: 1000 |
| | | }, |
| | | showParams: 'category', |
| | | layerName: 'fxy' |
| | | }, |
| | | ] |
| | | |
| | | const defaultProps = { |
| | | children: 'children', |
| | | label: 'label', |
| | | } |
| | | |
| | | const checkType = (value) => { |
| | | if (typeof value === 'object' && value !== null && !Array.isArray(value)) { |
| | | return 'obj' |
| | | } else if (Array.isArray(value)) { |
| | | return 'arr' |
| | | } |
| | | } |
| | | // 用于存储收集到的节点的数组 |
| | | const collectedNodes = reactive([]) |
| | | |
| | | // 递归函数,收集所有 flag 为 true 的子节点 |
| | | const collectNodesWithFlag = (nodes) => { |
| | | if (checkType(nodes) == 'obj') { |
| | | if (nodes.type == 'layer') { |
| | | collectedNodes.value.push(nodes) |
| | | } |
| | | if (nodes.children && nodes.children.length > 0) { |
| | | collectNodesWithFlag(nodes.children) |
| | | return |
| | | } |
| | | } |
| | | |
| | | if (checkType(nodes) == 'arr') { |
| | | nodes.forEach(item => { |
| | | if (item.type == 'layer') { |
| | | collectedNodes.value.push(item) |
| | | } |
| | | |
| | | if (item.children && item.children.length > 0) { |
| | | collectNodesWithFlag(item.children) |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | | let addTileLayers = {} |
| | | let tileLayers = new DC.TilesetLayer('tileLayers') |
| | | globalViewer.addLayer(tileLayers) |
| | | |
| | | const handleCheckChange = (data, options) => { |
| | | collectedNodes.value = [] |
| | | collectNodesWithFlag(data) |
| | | |
| | | collectedNodes.value.forEach(item => { |
| | | if (options.checkedKeys.some(i => i == item.id)) { |
| | | if (item.subType == '3Dtile') { |
| | | if (!addTileLayers[item.layerName]) { |
| | | addTileLayers[item.layerName] = new DC.Tileset( |
| | | item.url, |
| | | { |
| | | cullWithChildrenBounds: false, |
| | | maximumScreenSpaceError: 256, |
| | | maximumMemoryUsage: 1024, |
| | | skipLevelOfDetail: true, |
| | | preferLeaves: true |
| | | }) |
| | | |
| | | tileLayers.addOverlay(addTileLayers[item.layerName]) |
| | | } else { |
| | | addTileLayers[item.layerName].show = true |
| | | } |
| | | |
| | | console.log(addTileLayers[item.layerName], 11111111) |
| | | |
| | | globalViewer.flyTo(addTileLayers[item.layerName]) |
| | | } else if (item.subType == 'labelPoint') { |
| | | if (!addTileLayers[item.layerName]) { |
| | | addTileLayers[item.layerName] = new DC.HtmlLayer(addTileLayers[item.layerName]) |
| | | globalViewer.addLayer(addTileLayers[item.layerName]) |
| | | } |
| | | |
| | | item.method(item.params).then(res => { |
| | | let data = res.data.data.records |
| | | |
| | | data.filter(i => i.lng && i.lng != '' && i.lat && i.lat != '').forEach(i => { |
| | | let divIcon = new DC.DivIcon( |
| | | new DC.Position(i.lng, i.lat, 0), |
| | | `<div class="public-map-popup"> |
| | | <div class="marsBlueGradientPnl"> |
| | | <div>${i[item.showParams] || i.name}</div> |
| | | </div> |
| | | </div>` |
| | | ) |
| | | |
| | | addTileLayers[item.layerName].addOverlay(divIcon) |
| | | }) |
| | | }) |
| | | } |
| | | } else { |
| | | if (addTileLayers[item.layerName]) { |
| | | if (item.subType == '3Dtile') { |
| | | addTileLayers[item.layerName].show = false |
| | | } else if (item.subType == 'labelPoint') { |
| | | globalViewer.removeLayer(addTileLayers[item.layerName]) |
| | | } |
| | | |
| | | delete addTileLayers[item.layerName] |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | onMounted(() => { |
| | | handleCheckChange(data.filter(i => i.id == '1'), { |
| | | checkedKeys: ['1'] |
| | | }) |
| | | }) |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .tree-content { |
| | | min-width: 200px; |
| | | padding: 10px; |
| | | |
| | | ::v-deep(.el-tree) { |
| | | color: #fff; |
| | | background: transparent; |
| | | |
| | | /* 鼠标浮动过的背景颜色 */ |
| | | .el-tree-node__content:hover { |
| | | background: #0074b7; |
| | | } |
| | | |
| | | /* 鼠标点击时节点的背景颜色 */ |
| | | .el-tree-node:focus>.el-tree-node__content { |
| | | background-color: #0074b7 !important; |
| | | color: rgb(255, 255, 255); |
| | | } |
| | | |
| | | /* 鼠标失去焦点时节点背景的颜色 */ |
| | | .el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content { |
| | | background: rgb(0, 129, 204); |
| | | } |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { getViewer } from 'utils/getViewer' |
| | | const globalViewer = getViewer() |
| | | globalViewer.exportScene() |
| | | const emit = defineEmits(['closeChild']) |
| | | emit('closeChild') |
| | | </script> |
| | | |
| | | <style lang="scss" scoped></style> |
| New file |
| | |
| | | <!-- |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2024-10-29 15:48:36 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2024-10-29 19:53:49 |
| | | * @FilePath: \bigScreen\src\views\layout\components\scomponents\tool\location.vue |
| | | * @Description: |
| | | * |
| | | * Copyright (c) 2024 by shuishen, All Rights Reserved. |
| | | --> |
| | | <template> |
| | | <public-box style="z-index: 100;"> |
| | | <template #name> |
| | | <div class="name"><i class="fa fa-map-pin"></i> 底图</div> |
| | | </template> |
| | | |
| | | <template #close> |
| | | <div class="close cursor-p" @click="$emit('closeChild')"><i class="fa fa-close"></i></div> |
| | | </template> |
| | | |
| | | <template #content> |
| | | <div class="cur-content"> |
| | | <div> |
| | | <span>经度:</span> |
| | | <el-input v-model="longitude" size="small" placeholder="请输入经度" /> |
| | | </div> |
| | | <div> |
| | | <span>纬度:</span> |
| | | <el-input v-model="latitude" size="small" placeholder="请输入纬度" /> |
| | | </div> |
| | | <div> |
| | | <span>高度:</span> |
| | | <el-input v-model="height" size="small" placeholder="请输入高度" /> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="cur-btn"> |
| | | <el-button color="rgba(13,100,167,.8)" @click="flyTo" type="primary" size="small">坐标定位</el-button> |
| | | </div> |
| | | </template> |
| | | </public-box> |
| | | </template> |
| | | |
| | | <script setup> |
| | | const longitude = ref(0) |
| | | const latitude = ref(0) |
| | | const height = ref(0) |
| | | |
| | | import { getViewer } from 'utils/getViewer' |
| | | const globalViewer = getViewer() |
| | | |
| | | const flyTo = () => { |
| | | globalViewer.flyToPosition(new DC.Position(longitude.value, latitude.value, height.value, 0, -90, 0), () => { }, 3) |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .cur-content { |
| | | &>div { |
| | | margin-top: 10px; |
| | | padding: 0 10px; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | |
| | | span { |
| | | width: 54px; |
| | | } |
| | | |
| | | ::v-deep(.el-input) { |
| | | border: none !important; |
| | | |
| | | .el-input__wrapper { |
| | | background: rgba(63, 72, 84, .7) !important; |
| | | border: none !important; |
| | | box-shadow: none; |
| | | |
| | | input { |
| | | color: #fff; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .cur-btn { |
| | | margin: 10px 0; |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | } |
| | | </style> |
| New file |
| | |
| | | <!-- |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2024-10-29 14:20:49 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2024-10-29 17:21:51 |
| | | * @FilePath: \bigScreen\src\views\layout\components\scomponents\toolList.vue |
| | | * @Description: |
| | | * |
| | | * Copyright (c) 2024 by shuishen, All Rights Reserved. |
| | | --> |
| | | <template> |
| | | <ul v-show="moreToolShow" class="tool-list-box"> |
| | | <li @click="showComponent(item.component)" v-for="item, index in components" :key="index"> |
| | | <i :class="item.icon"></i> {{ item.title }} |
| | | </li> |
| | | </ul> |
| | | |
| | | <component :is="currentComponent" v-if="currentComponent" @closeChild="closeComponent" /> |
| | | </template> |
| | | |
| | | <script setup> |
| | | const { moreToolShow } = defineProps({ |
| | | moreToolShow: { |
| | | type: Boolean, //参数类型 |
| | | default: false, //默认值 |
| | | required: true, //是否必须传递 |
| | | } |
| | | }) |
| | | import location from './tool/location.vue' |
| | | import exportScene from './tool/exportScene.vue' |
| | | import { getViewer } from 'utils/getViewer' |
| | | import component from 'element-plus/es/components/tree-select/src/tree-select-option.mjs' |
| | | const emit = defineEmits(['close']) |
| | | const globalViewer = getViewer() |
| | | |
| | | let currentComponent = shallowRef(null) |
| | | const components = [ |
| | | { |
| | | icon: 'fa fa-calculator', |
| | | title: '图上量算', |
| | | }, |
| | | { |
| | | icon: 'fa fa-bar-chart', |
| | | title: '空间分析', |
| | | }, |
| | | { |
| | | name: 'location', |
| | | icon: 'fa fa-map-pin', |
| | | title: '坐标定位', |
| | | component: location |
| | | }, |
| | | { |
| | | icon: 'fa fa-paper-plane', |
| | | title: '地区导航', |
| | | }, |
| | | { |
| | | icon: 'fa fa-edit', |
| | | title: '我的标记', |
| | | }, |
| | | { |
| | | icon: 'fa fa-tags', |
| | | title: '视角书签', |
| | | }, |
| | | { |
| | | name: 'exportScene', |
| | | icon: 'fa fa-download', |
| | | title: '场景导出', |
| | | component: exportScene |
| | | }, |
| | | { |
| | | icon: 'fa fa-object-group', |
| | | title: '图上标绘', |
| | | }, |
| | | { |
| | | icon: 'fa fa-helicopter', |
| | | title: '飞行漫游', |
| | | }, |
| | | { |
| | | icon: 'fa fa-level-up', |
| | | title: '路线导航', |
| | | }, |
| | | { |
| | | icon: 'fa fa-columns', |
| | | title: '卷帘对比', |
| | | }, |
| | | { |
| | | icon: 'fa fa-window-restore', |
| | | title: '分屏对比', |
| | | }, |
| | | ] |
| | | |
| | | const showComponent = (component) => { |
| | | currentComponent.value = component |
| | | emit('close', 'tool') |
| | | } |
| | | |
| | | const closeComponent = () => { |
| | | currentComponent.value = null |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .tool-list-box { |
| | | position: absolute; |
| | | right: 540px; |
| | | z-index: 101; |
| | | top: 152px; |
| | | background: rgba(63, 72, 84, .7); |
| | | pointer-events: auto; |
| | | |
| | | li { |
| | | padding: 6px 10px; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | color: #fff; |
| | | cursor: pointer; |
| | | |
| | | i { |
| | | margin-right: 5px; |
| | | } |
| | | } |
| | | |
| | | li:hover { |
| | | background: #4db3ff; |
| | | } |
| | | |
| | | li:first-child { |
| | | margin-top: 0; |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | <!-- |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2022-08-18 16:18:24 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2024-11-06 11:07:43 |
| | | * @FilePath: \bigScreen\src\views\sub\index.vue |
| | | * @Description: |
| | | * |
| | | * Copyright (c) 2022 by shuishen 1109946754@qq.com, All Rights Reserved. |
| | | --> |
| | | <template> |
| | | <div> |
| | | <div class="main-header"> |
| | | <div class="title">ssssssss</div> |
| | | </div> |
| | | |
| | | <div class="main-container"> |
| | | <router-view ref="target-name"></router-view> |
| | | </div> |
| | | |
| | | <div class="out"> |
| | | <el-button @click="goHome">退回</el-button> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { useRouter, useRoute } from 'vue-router' |
| | | let router = useRouter() |
| | | import { useRouterStore } from 'store/router' |
| | | const store = useRouterStore() |
| | | |
| | | const goHome = () => { |
| | | store.setLoadSub(false) |
| | | router.push('/layout') |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | $bg-blue: rgba(24, 33, 92, 0.9); |
| | | |
| | | .out { |
| | | position:fixed; |
| | | top: 50%; |
| | | left: 50%; |
| | | pointer-events: all; |
| | | } |
| | | |
| | | .wrapper { |
| | | position: relative; |
| | | width: 100%; |
| | | height: 100%; |
| | | |
| | | #MainContent { |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 100%; |
| | | z-index: 99; |
| | | } |
| | | |
| | | .main-content { |
| | | height: 1080px; |
| | | background: url(/images/header.png) no-repeat center / 100% 100%, |
| | | url(/images/pro-bg.png) no-repeat center / 100% 100%; |
| | | |
| | | pointer-events: none; |
| | | |
| | | .main-header { |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 40px; |
| | | pointer-events: auto; |
| | | |
| | | .title { |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | margin: auto; |
| | | width: 640px; |
| | | height: 40px; |
| | | font-size: 24px; |
| | | font-family: YouSheBiaoTiHei; |
| | | font-weight: 400; |
| | | color: #eff8fc; |
| | | line-height: 40px; |
| | | text-align: center; |
| | | letter-spacing: 8px; |
| | | font-weight: bolder; |
| | | background: linear-gradient(to bottom, |
| | | #e2eaf0 0%, |
| | | #aed1f1 100%); |
| | | -webkit-background-clip: text; |
| | | -webkit-text-fill-color: transparent; |
| | | // opacity: 0.89; |
| | | // text-shadow: 0px 4px 1px rgba(19, 80, 143, 0.66); |
| | | |
| | | // background: linear-gradient(0deg, rgba(119, 186, 255, 0.45) 0%, rgba(233, 248, 255, 0.45) 73.3154296875%, rgba(255, 255, 255, 0.45) 100%); |
| | | // -webkit-background-clip: text; |
| | | // -webkit-text-fill-color: transparent; |
| | | } |
| | | |
| | | |
| | | .login-out { |
| | | position: absolute; |
| | | top: 10px; |
| | | right: 40px; |
| | | height: 36px; |
| | | color: #fff; |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | cursor: pointer; |
| | | |
| | | .img { |
| | | width: 16px; |
| | | height: 16px; |
| | | } |
| | | |
| | | span { |
| | | font-size: 13px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .main-container { |
| | | position: absolute; |
| | | top: 40px; |
| | | left: 40px; |
| | | right: 40px; |
| | | bottom: 40px; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <script setup> |
| | | import { Text } from 'vue' |
| | | import { useRouter, useRoute } from 'vue-router' |
| | | let router = useRouter() |
| | | import { inject, Text } from 'vue' |
| | | const { VITE_APP_BASE } = import.meta.env |
| | | import { getDetail } from '@/api/indParkInfo' |
| | | |
| | | import { getAssetsFile } from 'utils/utils' |
| | | import { useRouterStore } from 'store/router' |
| | | const store = useRouterStore() |
| | | |
| | | let state = reactive({ |
| | | parkInfo: {} |
| | |
| | | }) |
| | | } |
| | | |
| | | |
| | | |
| | | const goSubLayout = () => { |
| | | store.setLoadSub(true) |
| | | router.push('/layout/sub') |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <el-button @click="goSubLayout">跳转a</el-button> |
| | | </div> |
| | | </template> |
| | | |