feat: 增加地图实时经纬高、十进制经纬度与度分秒转换

pull/3/head
zhaipx 1 year ago
parent 07abfcbcd0
commit 3e449ebca0

@ -1,11 +1,13 @@
<template>
<div id="map">
<SceneViewer id="scene-viewer"></SceneViewer>
<BottomBar></BottomBar>
</div>
</template>
<script setup lang="ts">
import SceneViewer from './components/map/SceneViewer.vue'
import BottomBar from "@/components/map/BottomBar.vue";
</script>
<style>

@ -0,0 +1,102 @@
<!--
文件描述地图底部信息条
创建时间2024/3/29 8:53
创建人Zhaipeixiu
-->
<script setup lang="ts">
import { DecimalDegree2DMS_Point} from '@/utils/map/coordinate.ts'
import {ScreenSpaceEventHandler, Math, ScreenSpaceEventType} from 'cesium'
import {coordPoint} from "@/utils/map/geometry.ts";
import {onMounted, ref} from "vue";
let nowLatStr: string, nowLonStr: string
let lonlatStr = ref('')
let isDecimal = ref(true)
let coord_dms : coordPoint = {
lon: '',
lat: ''
}
onMounted(()=>{
let _viewer = window.Viewer
let canvas = _viewer.scene.canvas
let handler = new ScreenSpaceEventHandler(canvas)
handler.setInputAction((e:any)=> {
//
let position: any = _viewer.scene.pickPosition(e.endPosition)
if (!position) {
position = _viewer.scene.camera.pickEllipsoid(
e.startPosition,
_viewer.scene.globe.ellipsoid);
}
if (position) {
//
let cartographic = _viewer.scene.globe.ellipsoid.cartesianToCartographic(position);
try{
//
nowLatStr = Math.toDegrees(cartographic.latitude).toFixed(3) //
nowLonStr = Math.toDegrees(cartographic.longitude).toFixed(3) //
let camera_alt = (_viewer.camera.positionCartographic.height / 1000) //
// 250-80
let needElevation: boolean = camera_alt < 250 && (_viewer.camera.pitch < -(Math.PI/180)*80)
let elevStr = needElevation? _viewer.scene.globe.getHeight(cartographic)?.toFixed(2)?? '-' : '-' //
if(isDecimal.value) { //
lonlatStr.value = `经度:${nowLonStr} , 纬度:${nowLatStr} , 海拔:${elevStr} + m`
}
else {
coord_dms = DecimalDegree2DMS_Point(Number(nowLonStr), Number(nowLatStr))
lonlatStr.value = `经度:${coord_dms.lon} , 纬度:${coord_dms.lat} , 海拔:${elevStr} + m`
}
} catch (e) {}
}
}, ScreenSpaceEventType.MOUSE_MOVE)
})
function lonlatClick() {
let elevStr = lonlatStr.value.split('海拔')[1]
if(isDecimal.value){
coord_dms = DecimalDegree2DMS_Point(Number(nowLonStr), Number(nowLatStr))
lonlatStr.value = `经度:${coord_dms.lon} , 纬度:${coord_dms.lat} , 海拔` + elevStr
}
else {
lonlatStr.value = `经度:${nowLonStr} , 纬度:${nowLatStr} , 海拔` + elevStr
}
isDecimal.value = !isDecimal.value
}
</script>
<template>
<div id="map-footer">
<button id="lonlatText" @click="lonlatClick">
{{ lonlatStr }}
</button>
</div>
</template>
<style scoped>
#map-footer {
position: absolute;
bottom: 1px;
left: 0;
width: 100vw;
height: 2.3rem;
background-color: rgba(47, 53, 60, 0.8);
color: #fff;
font-size: 0.7rem;
text-align: center;
z-index: 1;
padding: 0;
display: flex;
align-items: center;
}
#lonlatText{
margin-left: 2rem;
background: none;
border: none;
color: #FFFFFF;
font-size: .8rem;
}
#lonlatText:hover{
cursor: pointer;
}
</style>

@ -1,11 +1,13 @@
<template>
<div id="cesium-viewer" ref="viewerDivRef"></div>
<div id="cesium-viewer" ref="viewerDivRef">
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue'
// import * as Cesium from 'cesium'
import { Viewer } from 'cesium'
import { Viewer, Ion } from 'cesium'
import 'cesium/Build/Cesium/Widgets/widgets.css'
import {
TDTLayerType,
@ -15,13 +17,14 @@ import {
} from '@/utils/map/TDTProvider'
import { initViewer, perfViewer, showNavigator } from '@/utils/map/sceneViewer'
import { flyToChina } from '@/utils/map/camera'
import BottomBar from "@/components/map/BottomBar.vue";
const viewerDivRef = ref<HTMLDivElement>()
let viewer: Viewer
window.CESIUM_BASE_URL = 'node_modules/cesium/Build/Cesium/'
// window.CESIUM_BASE_URL = 'libs/cesium/' //
window.Cesium.Ion.defaultAccessToken =
Ion.defaultAccessToken =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI3YjU4MjJlMS0wMWE4LTRhOWQtYjQ1OC04MTgzMzFhMzQ5ZjAiLCJpZCI6MTE1ODUxLCJpYXQiOjE2NjkyMDM1MzN9.8ajEuv3VKYg8wvFiQlUWWY6Ng6JfY4PuVgRyStL1B-E'
//
// window.Cesium.Camera.DEFAULT_VIEW_RECTANGLE =
@ -56,6 +59,7 @@ onMounted(() => {
// window
window.Viewer = viewer
})
</script>
<style scoped>

@ -3,19 +3,20 @@
/*比例尺背景*/
.distance-legend {
position: absolute;
border-radius: 15px;
padding-left: .5rem;
padding-right: .5rem;
padding-left: 0;
padding-right: 0;
right: .1rem;
height: 2rem;
bottom: .2rem;
font-weight: bolder;
box-sizing: content-box;
z-index: 2;
}
/*比例尺文本*/
.distance-legend-label {
display: inline-block;
font-family: 'Roboto', sans-serif;
padding-left: .5rem;
font-size: .9rem;
line-height: 1rem;
color: #FFFFFF;

6
src/global.d.ts vendored

@ -3,12 +3,10 @@ import type { Cesium, Viewer } from 'cesium'
// 扩展全局变量
declare global {
// 定义全局Cesium类型
const Cesium: Cesium
// 允许扩展 Window
interface Window {
Cesium: Cesium
CESIUM_BASE_URL: string
// Cesium: Cesium,
CESIUM_BASE_URL: string,
Viewer: Viewer
}
}

@ -4,6 +4,8 @@ import {
GeographicTilingScheme,
WebMercatorTilingScheme,
} from 'cesium'
import axios from "axios"
//地图服务枚举类型_c为墨卡托投影_w为经纬度投影
enum TDTLayerType {
Vec = 'vec', //矢量底图
@ -84,4 +86,23 @@ export function getTDTTerrainProvider() {
})
return provider
}
/**
*
* @param word
*/
export function Geocoder(word: string) {
let url = `http://api.tianditu.gov.cn/geocoder?ds={"keyWord":"${word}"}&tk=`
return axios.get(url + TDT_tk)
}
/**
*
* @param lon
* @param lat
*/
export function reverseGeocoder(lon:number, lat: number ) {
let url = `http://api.tianditu.gov.cn/geocoder?postStr={'lon':${lon},'lat':${lat},'ver':1}&type=geocode&tk=`
return axios.get(url + TDT_tk)
}
export { TDTLayerType, TDTProjectionType }

@ -6,6 +6,8 @@
* @Description:
*/
import { Cartesian2, Viewer, Math, Cartographic } from 'cesium'
import type {coordPoint} from '@/utils/map/geometry.ts'
/**
*
* @param viewer
@ -34,4 +36,38 @@ function cartesian2ToWGS84(viewer: Viewer, windowPosition: Cartesian2) {
return [lon, lat, alt]
} else return []
}
export { cartesian2ToCartesian3, cartesian2ToWGS84 }
/**
*
* @param lon
* @param lat
* @constructor
*/
function DecimalDegree2DMS_Point(lon: number, lat: number): coordPoint {
let coord_dms : coordPoint = {
lon: '',
lat: ''
}
coord_dms.lon = DecimalDegree2DMS(lon)
coord_dms.lat = DecimalDegree2DMS(lat)
return coord_dms
}
function DecimalDegree2DMS(decimal_var: number|string): string {
if(!decimal_var.toString().includes('.'))
return decimal_var.toString() + '°0\'0\'\''
let decimalStr = decimal_var.toString().split('.')
let degreeStr = decimalStr[0]
if (decimalStr[1]){
let minutes = Number(decimalStr[1]) * 60 / 1000 //十进制度默认显示小数点后3位
if(!minutes.toString().includes('.'))
return degreeStr + '°'+ minutes.toString() +'\'0\'\''
let minuteSecondsStr = minutes.toString().split('.')
if (minuteSecondsStr[1]){
let secondStr = (Number(minuteSecondsStr[1]) * 60).toFixed(0)
return degreeStr + '°'+ minuteSecondsStr[0] +'\'' + secondStr.slice(0,2) + '\'\''
}
}
return ''
}
export { cartesian2ToCartesian3, cartesian2ToWGS84, DecimalDegree2DMS_Point }

@ -131,4 +131,12 @@ class Polyline extends PrimitiveCollection {
})
}
}
// 坐标点
type coordPoint = {
lon: number | string,
lat: number | string,
alt?: number
}
export { PointEntity, Polyline, PolylineEntity, PolygonEntity }
export type { coordPoint }

@ -9,9 +9,11 @@
import {
Viewer,
TileMapServiceImageryProvider,
ScreenSpaceEventType,
ImageryLayer,
RequestScheduler,
SceneMode,
Rectangle,
buildModuleUrl,
} from 'cesium'
import CesiumNavigation from 'cesium-navigation-es6'
@ -59,10 +61,10 @@ function initViewer(container: string | Element): Viewer {
viewer.scene.screenSpaceCameraController.maximumZoomDistance = 20000000 //相机高度的最大值
// 去掉entity的点击事件双击、单击
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK,
ScreenSpaceEventType.LEFT_DOUBLE_CLICK,
)
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
Cesium.ScreenSpaceEventType.LEFT_CLICK,
ScreenSpaceEventType.LEFT_CLICK,
)
return viewer
}
@ -89,12 +91,12 @@ function perfViewer(viewer: Viewer) {
}
function showNavigator(viewer: Viewer){
let options: any = {}
const options: any = {}
// 用于在使用重置导航重置地图视图时设置默认视图控制。接受的值是Cesium.Cartographic 和 Cesium.Rectangle
options.defaultResetView = Cesium.Rectangle.fromDegrees(80, 22, 130, 50)
options.defaultResetView = Rectangle.fromDegrees(80, 22, 130, 50)
options.enableCompass = true //罗盘组件 true启用false禁用
options.enableCompassOuterRing = true //罗盘外环组件 true启用false禁用
options.enableZoomControls = true //缩放组件 true启用false禁用
options.enableZoomControls = true //缩放组件 true启用false禁用
options.enableDistanceLegend = true //比例尺组件 true启用false禁用
new CesiumNavigation(viewer, options)
}

Loading…
Cancel
Save