Compare commits

...

2 Commits

Author SHA1 Message Date
杨晓凡 05e205811a 地图工具栏 2023-08-24 09:01:34 +08:00
杨晓凡 ff78eb366d 1 2023-08-23 11:39:55 +08:00
17 changed files with 269 additions and 18 deletions

View File

@ -6,7 +6,9 @@ module.exports = {
es6: true
},
globals: {
Cesium: true
Cesium: true,
viewer: true,
scene: true
},
extends: [
'plugin:vue/vue3-recommended',

68
package-lock.json generated
View File

@ -12,10 +12,12 @@
"@vicons/antd": "^0.10.0",
"@vicons/ionicons5": "^0.10.0",
"ali-oss": "^6.17.1",
"animate.css": "^4.1.1",
"axios": "^0.26.1",
"dayjs": "^1.11.2",
"mockjs": "^1.1.0",
"pinia": "^2.0.13",
"pinia-plugin-persist": "^1.0.0",
"tinymce": "^5.10.2",
"vue": "^3.2.16",
"vue-router": "^4.0.14",
@ -2243,6 +2245,11 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"node_modules/animate.css": {
"version": "4.1.1",
"resolved": "https://registry.npmmirror.com/animate.css/-/animate.css-4.1.1.tgz",
"integrity": "sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ=="
},
"node_modules/ansi-colors": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
@ -8380,6 +8387,46 @@
}
}
},
"node_modules/pinia-plugin-persist": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/pinia-plugin-persist/-/pinia-plugin-persist-1.0.0.tgz",
"integrity": "sha512-M4hBBd8fz/GgNmUPaaUsC29y1M09lqbXrMAHcusVoU8xlQi1TqgkWnnhvMikZwr7Le/hVyMx8KUcumGGrR6GVw==",
"dependencies": {
"vue-demi": "^0.12.1"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0",
"pinia": "^2.0.0",
"vue": "^2.0.0 || >=3.0.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/pinia-plugin-persist/node_modules/vue-demi": {
"version": "0.12.5",
"resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.12.5.tgz",
"integrity": "sha512-BREuTgTYlUr0zw0EZn3hnhC3I6gPWv+Kwh4MCih6QcAeaTlaIX0DwOVN0wHej7hSvDPecz4jygy/idsgKfW58Q==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/pinia/node_modules/vue-demi": {
"version": "0.13.1",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.1.tgz",
@ -13893,6 +13940,11 @@
}
}
},
"animate.css": {
"version": "4.1.1",
"resolved": "https://registry.npmmirror.com/animate.css/-/animate.css-4.1.1.tgz",
"integrity": "sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ=="
},
"ansi-colors": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
@ -18456,6 +18508,22 @@
}
}
},
"pinia-plugin-persist": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/pinia-plugin-persist/-/pinia-plugin-persist-1.0.0.tgz",
"integrity": "sha512-M4hBBd8fz/GgNmUPaaUsC29y1M09lqbXrMAHcusVoU8xlQi1TqgkWnnhvMikZwr7Le/hVyMx8KUcumGGrR6GVw==",
"requires": {
"vue-demi": "^0.12.1"
},
"dependencies": {
"vue-demi": {
"version": "0.12.5",
"resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.12.5.tgz",
"integrity": "sha512-BREuTgTYlUr0zw0EZn3hnhC3I6gPWv+Kwh4MCih6QcAeaTlaIX0DwOVN0wHej7hSvDPecz4jygy/idsgKfW58Q==",
"requires": {}
}
}
},
"platform": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz",

View File

@ -13,6 +13,7 @@
"@vicons/antd": "^0.10.0",
"@vicons/ionicons5": "^0.10.0",
"ali-oss": "^6.17.1",
"animate.css": "^4.1.1",
"axios": "^0.26.1",
"dayjs": "^1.11.2",
"mockjs": "^1.1.0",
@ -46,4 +47,4 @@
"vite-plugin-mock": "^2.9.6",
"vite-plugin-vue-setup-extend": "^0.4.0"
}
}
}

View File

@ -16,7 +16,7 @@ class Earth {
const viewer = new Cesium.Viewer(elementId, {
...configs,
infoBox: false, // 关闭信息展示
navigation: false, // 指南针
navigation: true, // 指南针
animation: false, // 原生左下角动画空间
timeline: true, // 时间线
// 右上角按钮
@ -31,7 +31,6 @@ class Earth {
// contextOptions: {
// requestWebgl1: true // 指定上下文使用webgl1的上下文
// },
selectionIndicator: false // 去除绿色选择框
})
viewer._cesiumWidget._creditContainer.style.display = 'none'

View File

@ -7,11 +7,12 @@
// }
// }
// export default layerManager
import { TDT_TOKEN } from '@/components/earth/tokens.js'
class LayerManager {
constructor(viewer) {
this.viewer = viewer
this.tilesetList = []
this.baseLayer = null
}
async add3DTilesetByUrl(url, name) {
@ -54,8 +55,43 @@ class LayerManager {
},
props: point
})
return entity
})
}
loadBaseLayerByType(option) {
const type = option.code
const imgProvider = new Cesium.WebMapTileServiceImageryProvider({
url: `http://{s}.tianditu.com/${type}_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=${type}&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=${TDT_TOKEN}`,
subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
layer: `${type}`,
style: 'default',
format: 'image/jpeg',
tileMatrixSetID: 'GoogleMapsCompatible',
maximumLevel: 18,
show: true
})
const baseLayer = viewer.imageryLayers.addImageryProvider(imgProvider)
if (type !== 'cva') {
this.baseLayer = {
name: option.name,
layer: baseLayer
}
} else {
this.annotationLayer = {
name: option.name,
layer: baseLayer
}
}
return baseLayer
}
removeLayer(layer) {
if (layer) {
viewer.imageryLayers.remove(layer)
}
}
}
export default LayerManager

View File

@ -0,0 +1,3 @@
export const CESIUM_TOKEN = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkZWJjOTRmOS04ZWVlLTQ2Y2QtYjk1Zi1mMTlhYTI5YjRjZGQiLCJpZCI6Njg1MDEsImlhdCI6MTYzMjc5Nzk5NX0.Y - SNJskkiSEYtqKERD6sib6lYKQuzXf_z_z3mBVpEjI'
export const TDT_TOKEN = 'b48998cf12f83e0215989b14acf59e3f'

View File

@ -1,7 +1,7 @@
<template>
<div class="baseMapManager">
<!-- <n-modal v-model:show="isOptionShow">
<div v-show="isOptionShow" class="options">
<div class="baseMapManager" @mouseleave="showOptions(false)">
<transition name="move" enter-active-class="animate__animated animate__fadeInRight" leave-active-class="animate__animated animate__fadeOutRight">
<div v-show="isOptionShow" class="options ">
<div v-for="(option,index) in options" :key="index" class="option" @click="handleCheck(option)">
<img :src="option.imgUrl" alt="">
<div class="title">
@ -9,14 +9,10 @@
</div>
</div>
</div>
</n-modal> -->
<div v-show="isOptionShow" class="options" @mouseleave="showOptions(false)">
<div v-for="(option,index) in options" :key="index" class="option" @click="handleCheck(option)">
<img :src="option.imgUrl" alt="">
<div class="title">
{{ option.name }}
</div>
</div>
</transition>
<div class="annotation">
<n-checkbox size="large" label="注记" @update:checked="handleCheckedChange" />
</div>
<div class="checked option" @click="showOptions(true)">
<img :src="checked.imgUrl" alt="">
@ -31,7 +27,7 @@
<script setup >
// eslint-disable-next-line no-unused-vars
import { ref, reactive, toRefs, watch, onMounted, getCurrentInstance } from 'vue'
import LayeManager from '@/components/earth/layerManager/layerManager.js'
// const emit = defineEmits([""])
// const props = defineProps({
// propData: {
@ -61,6 +57,25 @@ function handleCheck(obj) {
checked.value = obj
isOptionShow.value = false
}
const layeManager = new LayeManager(window.viewer)
let annotationLayer
function handleCheckedChange(checked) {
if (checked) {
annotationLayer = layeManager.loadBaseLayerByType({ name: '注记', code: 'cva' })
} else {
layeManager.removeLayer(annotationLayer)
}
}
watch(() => checked.value, newV => {
if (layeManager.baseLayer?.layer) {
layeManager.removeLayer(layeManager.baseLayer.layer)
}
layeManager.loadBaseLayerByType(newV)
if (annotationLayer) {
viewer.imageryLayers.raiseToTop(annotationLayer)
}
})
</script>
<style lang="scss" scoped>
.baseMapManager{
@ -74,6 +89,15 @@ function handleCheck(obj) {
.checked{
border: 1px solid rgb(74,131,247);
}
.annotation{
position: absolute;
right: 0;
bottom: 100px;
background: rgba(0,0,0,0.1);
width: 80px;
text-align: center;
color: white;
}
}
.option{
width: 120px;
@ -97,4 +121,8 @@ function handleCheck(obj) {
width: 30px;
}
}
:deep(.n-checkbox__label){
color: white;
}
</style>

View File

@ -1,6 +1,7 @@
<template>
<div>
<baseMapManager class="baseMap" />
<map-tools class="mapTools" />
</div>
</template>
@ -8,6 +9,7 @@
// eslint-disable-next-line no-unused-vars
import { ref, reactive, toRefs, watch, onMounted, getCurrentInstance } from 'vue'
import baseMapManager from '@/components/mapUI/baseMapManager/baseMapManager.vue'
import mapTools from './mapTools/mapTools.vue'
// const emit = defineEmits([""])
// const props = defineProps({
@ -25,4 +27,9 @@ import baseMapManager from '@/components/mapUI/baseMapManager/baseMapManager.vue
bottom: 20px;
right: 10px;
}
.mapTools{
position: fixed;
bottom: 200px;
right: 30px;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -0,0 +1,107 @@
<template>
<div class="mapTools">
<div v-for="(item,index) in toolsList" :key="index" class="btn" :title="item.title" @click="item.func">
<img :src="item.icon" alt="">
</div>
</div>
</template>
<script setup >
// eslint-disable-next-line no-unused-vars
import { ref, reactive, toRefs, watch, onMounted, getCurrentInstance } from 'vue'
// const emit = defineEmits([""])
// const props = defineProps({
// propData: {
// type: String,
// default: ''
// },
// })
// const { } = toRefs(props);
const toolsList = reactive([
{
title: '放大',
func: zoomIn,
icon: new URL('./img/zoomIn.png', import.meta.url)
},
{
title: '缩小',
func: zoomOut,
icon: new URL('./img/zoomOut.png', import.meta.url)
},
{
title: '向左旋转',
func: left,
icon: new URL('./img/left.png', import.meta.url)
},
{
title: '向右旋转',
func: right,
icon: new URL('./img/right.png', import.meta.url)
},
{
title: '全屏',
func: fullScreen,
icon: new URL('./img/fullScreen.png', import.meta.url)
},
{
title: '鸟瞰',
func: birdEye,
icon: new URL('./img/birdEye.png', import.meta.url)
},
{
title: '导出',
func: exportMap,
icon: new URL('./img/export.png', import.meta.url)
}
])
function zoomIn() {
// viewer.camera.height -= 100
const position = viewer.camera.positionCartographic
viewer.camera.moveForward(position.height * 0.5)
}
function zoomOut() {
const position = viewer.camera.positionCartographic
viewer.camera.moveBackward(position.height * 0.5)
}
function left() {
viewer.camera.twistLeft(Cesium.Math.toDegrees(0.005).toFixed(2))
}
function right() {
viewer.camera.twistRight(Cesium.Math.toDegrees(0.005).toFixed(2))
}
function fullScreen() {
Cesium.Fullscreen.requestFullscreen(scene.canvas)
}
function birdEye() {
// const position = viewer.camera.positionWC
// const heading = Cesium.Math.toRadians(50)// -
// const pitch = Cesium.Math.toRadians(-90) // --
// const range = 0 //
// viewer.camera.lookAt(position, new Cesium.HeadingPitchRange(heading, pitch, range))
}
function exportMap() {
}
</script>
<style lang="scss" scoped>
.mapTools{
width: 36px;
// height: 400px;
padding: 2px;
.btn{
width: 100%;
height: 30px;
margin-top: 5px;
background: rgba($color: white, $alpha: 0.3);
border: 1px solid rgb(33,62,100);
padding: 2px;
cursor: pointer;
img{
width: 100%;
}
}
}
</style>

View File

@ -1,6 +1,6 @@
import '@/styles/index.scss'
import 'uno.css'
import 'animate.css/animate.min.css'
import { createApp } from 'vue'
import { setupRouter } from '@/router'
import { setupStore } from '@/store'