高德图源的vue-cesium项目

master
qubiaobiao 2024-02-20 14:55:52 +08:00
parent 0050d45110
commit e7d6b9ab9e
10 changed files with 248 additions and 47 deletions

2
.gitignore vendored
View File

@ -7,10 +7,12 @@ yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
.vscode
node_modules
dist
dist-ssr
*.local
public/Cesium
# Editor directories and files
.vscode/*

View File

@ -5,7 +5,7 @@
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
"preview": "vite preview --port 10005"
},
"dependencies": {
"cesium": "^1.92.0",

View File

@ -8,6 +8,7 @@
<LonlatForm id="lonlat-form"></LonlatForm>
<LonlatTable id="lonlat-table"></LonlatTable>
<HotLandmark id="hotlandmark"></HotLandmark>
</template>
<script setup>
@ -15,8 +16,9 @@ import { VcConfigProvider } from 'vue-cesium'
import Earth from '/@/components/Earth.vue'
import LonlatForm from '/@/components/LonlatForm.vue'
import LonlatTable from '/@/components/LonlatTable.vue'
import MarkPoints from "/@/components/MarkPoints.vue";
import MarkPoints from "/@/components/MarkPoints.vue"
import LocatingPoint from '/@/components/LocatingPoint.vue'
import HotLandmark from '/@/components/HotLandmark.vue'
const CESIUM_PATH = (process.env.NODE_ENV === 'development' ? './node_modules/cesium/Build/Cesium/Cesium.js': './Cesium/Cesium.js')
</script>
@ -40,4 +42,10 @@ html, body, #app {
top: 100px;
left: 15px;
}
#hotlandmark {
position: absolute;
bottom: 30px;
right: 10px;
}
</style>

BIN
src/assets/compass.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
src/assets/down.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

BIN
src/assets/up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -0,0 +1,32 @@
<template>
<div class="compass" @click="Compass">
<img class="north" src="../assets/compass.png">
</div>
</template>
<script setup>
import {defineEmits} from 'vue'
const emit = defineEmits(['Pointing'])
const Compass = () => {
emit('Pointing')
}
</script>
<style scoped>
.compass{
width:50px;
height:50px;
padding:5px;
padding-top:0;
border-radius:50%;
background-color:#fff;
position:fixed;
bottom:245px;
left:42px;
z-index:99;
}
.north{
width:40px;
}
</style>

View File

@ -1,76 +1,95 @@
<template>
<vc-viewer
:showCredit="false"
@ready="ready"
@leftDoubleClick="leftDoubleClick">
<vc-viewer :showCredit="false" @ready="ready" @leftDoubleClick="leftDoubleClick" :info-box="false">
<vc-layer-imagery>
<vc-imagery-provider-urltemplate
:projectionTransforms="projectionTransforms"
:url="img_url"
></vc-imagery-provider-urltemplate>
>
</vc-imagery-provider-urltemplate>
</vc-layer-imagery>
<vc-layer-imagery>
<vc-imagery-provider-urltemplate
:projectionTransforms="projectionTransforms"
:url="ann_url"
></vc-imagery-provider-urltemplate>
>
</vc-imagery-provider-urltemplate>
</vc-layer-imagery>
<vc-status-bar />
<slot></slot>
<vc-navigation
:offset="[10, 30]"
:position="'bottom-left'"
:printOpts="false"
:locationOpts="false"
:otherOpts="false"
/>
<Compass @Pointing = "pointTo"/>
</vc-viewer>
</template>
<script setup>
import { usePointStore } from '/@/stores/point'
import { usePositionStore } from '/@/stores/position'
import { VcViewer, VcStatusBar, VcLayerImagery, VcImageryProviderUrltemplate } from 'vue-cesium'
import { isLnglat } from '/@/api/util';
import Compass from '/@/components/Compass.vue'
import { usePointStore } from "/@/stores/point";
import { usePositionStore } from "/@/stores/position";
import {
VcViewer,
VcStatusBar,
VcLayerImagery,
VcImageryProviderUrltemplate,
VcNavigation,
} from "vue-cesium";
import { isLnglat } from "/@/api/util";
const projectionTransforms = { from : 'GCJ02', to : 'WGS84' }
const projectionTransforms = { from: "GCJ02", to: "WGS84" };
const img_url = 'https://webst02.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&style=6'
const ann_url = 'https://webst01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&style=8'
const img_url = "https://webst02.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&style=6";
const ann_url = "https://webst01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&style=8";
let Cesium = null, viewer = null
const ready = readyObj => {
Cesium = readyObj.Cesium
viewer = readyObj.viewer
}
let Cesium = null,
viewer = null;
const ready = (readyObj) => {
Cesium = readyObj.Cesium;
viewer = readyObj.viewer;
const point = usePointStore()
viewer._selectionIndicator = false;
//
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
//Cesiumentity
};
const point = usePointStore();
const leftDoubleClick = ({ position }) => {
if (!viewer) return
if (!viewer) return;
if (point.index >= point.length) {
alert(`最多只能够添加 ${ point.length } 个点`);
return
alert(`最多只能够添加 ${point.length} 个点`);
return;
}
const cartesian = viewer.camera.pickEllipsoid(position, viewer.scene.globe.ellipsoid)
const cartesian = viewer.camera.pickEllipsoid(position, viewer.scene.globe.ellipsoid);
if (!cartesian) return
if (!cartesian) return;
const lnglat = cartesian2Lonlat(cartesian)
const lnglat = cartesian2Lonlat(cartesian);
point.addItem( lnglat )
}
point.addItem(lnglat);
};
const cartesian2Lonlat = cartesian => {
if ( !Cesium ) return
const cartesian2Lonlat = (cartesian) => {
if (!Cesium) return;
const cartographic = Cesium.Cartographic.fromCartesian(cartesian)
const lng = Cesium.Math.toDegrees(cartographic.longitude).toFixed(8);
const lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(8);
const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
const lng = Cesium.Math.toDegrees(cartographic.longitude).toFixed(8);
const lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(8);
return { lng, lat }
}
return { lng, lat };
};
const position = usePositionStore()
const position = usePositionStore();
position.$subscribe((_, state) => {
// import { MutationType } from 'pinia'
// mutation.type // 'direct' | 'patch object' | 'patch function'
@ -81,11 +100,21 @@ position.$subscribe((_, state) => {
// statestatelocalStorage
// localStorage.setItem('cart', JSON.stringify(state))
if ( !isLnglat(state) ) return
if (!isLnglat(state)) return;
viewer.camera.flyTo({
destination : Cesium.Cartesian3.fromDegrees(state.lng, state.lat, 2000)
destination: Cesium.Cartesian3.fromDegrees(state.lng, state.lat, 2000.0),
});
})
});
// 广 116.39140105, 39.90452844 2000.0
const pointTo = () => {
let initialPosition = Cesium.Cartesian3.fromDegrees(position.lng?position.lng:116.39140105, position.lat?position.lat:39.90452844, 2000.0);
let initialOrientation = Cesium.HeadingPitchRoll.fromDegrees(0.0, -90.0, 0.0);
viewer.camera.flyTo({
destination: initialPosition,
orientation: initialOrientation,
endtransform: Cesium.Matrix4.IDENTITY,
});
}
</script>

View File

@ -0,0 +1,129 @@
<template>
<div>
<div v-show="!showit" class="switch" style="position:absolute;top:-40px;right:0;z-index:99;" @click="showLandmark">
<img class="icon" src="../assets/up.png">
</div>
<div v-show="showit" class="switch" style="position:absolute;top:-50px;right:0;z-index:99;" @click="showLandmark">
<img class="icon" src="../assets/down.png">
</div>
<div class="landmark">
<table v-if="showit">
<thead>
<tr>
<th>景点名称</th>
<th>经度</th>
<th>纬度</th>
<th>访问景点</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in landmarkArr" :key="index">
<td>{{ item ? item.landmark : index+1 }}</td>
<td>{{ item ? item.lng : "" }}</td>
<td>{{ item ? item.lat : "" }}</td>
<td><button @click="write(item.lng,item.lat)">访</button></td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { usePositionStore } from '/@/stores/position'
const landmarkArr = [
{
landmark:'北京天安门',
lng:116.391243,
lat:39.907202
},
{
landmark:'北京鸟巢',
lng:116.390502,
lat:39.991396
},
{
landmark:'上海东方明珠',
lng:121.495263,
lat:31.241829
},
{
landmark:'香港迪斯尼',
lng:114.042287,
lat:22.313002
},
{
landmark:'布达拉宫',
lng:91.117684,
lat:29.656959
}
]
let showit = ref(false);
const showLandmark = () => {
showit.value = !showit.value;
}
const position = usePositionStore()
const write = (lng,lat) => {
position.set({ lng: lng, lat: lat })
}
</script>
<style scoped>
.landmark {
max-height: 360px;
overflow-y:scroll;
}
.switch {
width:42px;
height:42px;
border-radius: 50%;
background-color:#fff;
padding-top:9px;
padding-left:3px;
}
.icon {
width:36px;
}
table {
color: #FFFFFF;
background-color: #242424;
padding: 10px;
border-radius: 7px;
border-collapse: separate;
border-spacing: 2px;
text-align:center;
}
table th:first-child {
width: 120px;
}
table th:not(:first-child) {
width: 100px;
}
table thead tr {
background-color: rgba(84, 84, 84, 0.8);
}
table tbody tr:nth-child(even) {
background-color: rgba(84, 84, 84, 0.8);
}
table tbody tr:nth-child(odd) {
background-color: rgba(84, 84, 84, 0.25);
}
table th, table td {
padding: 3px 5px;
}
</style>

View File

@ -33,6 +33,7 @@ table {
border-radius: 7px;
border-collapse: separate;
border-spacing: 2px;
text-align:center;
}
table th:first-child {