高德图源的vue-cesium项目
parent
0050d45110
commit
e7d6b9ab9e
|
@ -7,10 +7,12 @@ yarn-error.log*
|
||||||
pnpm-debug.log*
|
pnpm-debug.log*
|
||||||
lerna-debug.log*
|
lerna-debug.log*
|
||||||
|
|
||||||
|
.vscode
|
||||||
node_modules
|
node_modules
|
||||||
dist
|
dist
|
||||||
dist-ssr
|
dist-ssr
|
||||||
*.local
|
*.local
|
||||||
|
public/Cesium
|
||||||
|
|
||||||
# Editor directories and files
|
# Editor directories and files
|
||||||
.vscode/*
|
.vscode/*
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview --port 10005"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cesium": "^1.92.0",
|
"cesium": "^1.92.0",
|
||||||
|
|
10
src/App.vue
10
src/App.vue
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
<LonlatForm id="lonlat-form"></LonlatForm>
|
<LonlatForm id="lonlat-form"></LonlatForm>
|
||||||
<LonlatTable id="lonlat-table"></LonlatTable>
|
<LonlatTable id="lonlat-table"></LonlatTable>
|
||||||
|
<HotLandmark id="hotlandmark"></HotLandmark>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
@ -15,8 +16,9 @@ import { VcConfigProvider } from 'vue-cesium'
|
||||||
import Earth from '/@/components/Earth.vue'
|
import Earth from '/@/components/Earth.vue'
|
||||||
import LonlatForm from '/@/components/LonlatForm.vue'
|
import LonlatForm from '/@/components/LonlatForm.vue'
|
||||||
import LonlatTable from '/@/components/LonlatTable.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 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')
|
const CESIUM_PATH = (process.env.NODE_ENV === 'development' ? './node_modules/cesium/Build/Cesium/Cesium.js': './Cesium/Cesium.js')
|
||||||
</script>
|
</script>
|
||||||
|
@ -40,4 +42,10 @@ html, body, #app {
|
||||||
top: 100px;
|
top: 100px;
|
||||||
left: 15px;
|
left: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#hotlandmark {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 30px;
|
||||||
|
right: 10px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 4.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 5.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 5.5 KiB |
|
@ -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>
|
|
@ -1,76 +1,95 @@
|
||||||
<template>
|
<template>
|
||||||
<vc-viewer
|
<vc-viewer :showCredit="false" @ready="ready" @leftDoubleClick="leftDoubleClick" :info-box="false">
|
||||||
:showCredit="false"
|
|
||||||
@ready="ready"
|
|
||||||
@leftDoubleClick="leftDoubleClick">
|
|
||||||
|
|
||||||
<vc-layer-imagery>
|
<vc-layer-imagery>
|
||||||
<vc-imagery-provider-urltemplate
|
<vc-imagery-provider-urltemplate
|
||||||
:projectionTransforms="projectionTransforms"
|
:projectionTransforms="projectionTransforms"
|
||||||
:url="img_url"
|
:url="img_url"
|
||||||
></vc-imagery-provider-urltemplate>
|
>
|
||||||
|
</vc-imagery-provider-urltemplate>
|
||||||
</vc-layer-imagery>
|
</vc-layer-imagery>
|
||||||
|
|
||||||
<vc-layer-imagery>
|
<vc-layer-imagery>
|
||||||
<vc-imagery-provider-urltemplate
|
<vc-imagery-provider-urltemplate
|
||||||
:projectionTransforms="projectionTransforms"
|
:projectionTransforms="projectionTransforms"
|
||||||
:url="ann_url"
|
:url="ann_url"
|
||||||
></vc-imagery-provider-urltemplate>
|
>
|
||||||
|
</vc-imagery-provider-urltemplate>
|
||||||
</vc-layer-imagery>
|
</vc-layer-imagery>
|
||||||
|
|
||||||
<vc-status-bar />
|
<vc-status-bar />
|
||||||
|
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
|
|
||||||
|
<vc-navigation
|
||||||
|
:offset="[10, 30]"
|
||||||
|
:position="'bottom-left'"
|
||||||
|
:printOpts="false"
|
||||||
|
:locationOpts="false"
|
||||||
|
:otherOpts="false"
|
||||||
|
/>
|
||||||
|
<Compass @Pointing = "pointTo"/>
|
||||||
</vc-viewer>
|
</vc-viewer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { usePointStore } from '/@/stores/point'
|
import Compass from '/@/components/Compass.vue'
|
||||||
import { usePositionStore } from '/@/stores/position'
|
import { usePointStore } from "/@/stores/point";
|
||||||
import { VcViewer, VcStatusBar, VcLayerImagery, VcImageryProviderUrltemplate } from 'vue-cesium'
|
import { usePositionStore } from "/@/stores/position";
|
||||||
import { isLnglat } from '/@/api/util';
|
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 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 ann_url = "https://webst01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&style=8";
|
||||||
|
|
||||||
let Cesium = null, viewer = null
|
let Cesium = null,
|
||||||
const ready = readyObj => {
|
viewer = null;
|
||||||
Cesium = readyObj.Cesium
|
const ready = (readyObj) => {
|
||||||
viewer = readyObj.viewer
|
Cesium = readyObj.Cesium;
|
||||||
}
|
viewer = readyObj.viewer;
|
||||||
|
|
||||||
const point = usePointStore()
|
viewer._selectionIndicator = false;
|
||||||
|
//不显示选中指示器
|
||||||
|
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
|
||||||
|
//屏蔽Cesium的默认双击追踪选中entity行为
|
||||||
|
};
|
||||||
|
|
||||||
|
const point = usePointStore();
|
||||||
const leftDoubleClick = ({ position }) => {
|
const leftDoubleClick = ({ position }) => {
|
||||||
if (!viewer) return
|
if (!viewer) return;
|
||||||
|
|
||||||
if (point.index >= point.length) {
|
if (point.index >= point.length) {
|
||||||
alert(`最多只能够添加 ${point.length} 个点`);
|
alert(`最多只能够添加 ${point.length} 个点`);
|
||||||
return
|
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 => {
|
const cartesian2Lonlat = (cartesian) => {
|
||||||
if ( !Cesium ) return
|
if (!Cesium) return;
|
||||||
|
|
||||||
const cartographic = Cesium.Cartographic.fromCartesian(cartesian)
|
const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
|
||||||
const lng = Cesium.Math.toDegrees(cartographic.longitude).toFixed(8);
|
const lng = Cesium.Math.toDegrees(cartographic.longitude).toFixed(8);
|
||||||
const lat = Cesium.Math.toDegrees(cartographic.latitude).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) => {
|
position.$subscribe((_, state) => {
|
||||||
// import { MutationType } from 'pinia' 改变触发的类型
|
// import { MutationType } from 'pinia' 改变触发的类型
|
||||||
// mutation.type // 'direct' | 'patch object' | 'patch function'
|
// mutation.type // 'direct' | 'patch object' | 'patch function'
|
||||||
|
@ -81,11 +100,21 @@ position.$subscribe((_, state) => {
|
||||||
|
|
||||||
// 侦听到state变化时,把state存在localStorage中
|
// 侦听到state变化时,把state存在localStorage中
|
||||||
// localStorage.setItem('cart', JSON.stringify(state))
|
// localStorage.setItem('cart', JSON.stringify(state))
|
||||||
|
if (!isLnglat(state)) return;
|
||||||
if ( !isLnglat(state) ) return
|
|
||||||
|
|
||||||
viewer.camera.flyTo({
|
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>
|
</script>
|
|
@ -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>
|
|
@ -33,6 +33,7 @@ table {
|
||||||
border-radius: 7px;
|
border-radius: 7px;
|
||||||
border-collapse: separate;
|
border-collapse: separate;
|
||||||
border-spacing: 2px;
|
border-spacing: 2px;
|
||||||
|
text-align:center;
|
||||||
}
|
}
|
||||||
|
|
||||||
table th:first-child {
|
table th:first-child {
|
||||||
|
|
Loading…
Reference in New Issue