高德图源的vue-cesium项目
parent
0050d45110
commit
e7d6b9ab9e
|
@ -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/*
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
"preview": "vite preview --port 10005"
|
||||
},
|
||||
"dependencies": {
|
||||
"cesium": "^1.92.0",
|
||||
|
|
10
src/App.vue
10
src/App.vue
|
@ -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>
|
||||
|
|
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>
|
||||
<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);
|
||||
//屏蔽Cesium的默认双击追踪选中entity行为
|
||||
};
|
||||
|
||||
const point = usePointStore();
|
||||
const leftDoubleClick = ({ position }) => {
|
||||
if (!viewer) return
|
||||
if (!viewer) return;
|
||||
|
||||
if (point.index >= 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 => {
|
||||
if ( !Cesium ) return
|
||||
const cartesian2Lonlat = (cartesian) => {
|
||||
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 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) => {
|
|||
|
||||
// 侦听到state变化时,把state存在localStorage中
|
||||
// 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>
|
|
@ -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-collapse: separate;
|
||||
border-spacing: 2px;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
table th:first-child {
|
||||
|
|
Loading…
Reference in New Issue