From e1699c4851f6ca397cd0ad1ff63f32c737654836 Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Wed, 02 Apr 2025 19:14:54 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'
---
src/utils/cesium/mapUtil.js | 537 ++++++++++++++++++++++++++++-------------------------------
1 files changed, 257 insertions(+), 280 deletions(-)
diff --git a/src/utils/cesium/mapUtil.js b/src/utils/cesium/mapUtil.js
index 9d3433a..176ecca 100644
--- a/src/utils/cesium/mapUtil.js
+++ b/src/utils/cesium/mapUtil.js
@@ -1,148 +1,134 @@
-import * as Cesium from 'cesium';
-import * as turf from '@turf/turf';
+import * as Cesium from 'cesium'
+import * as turf from '@turf/turf'
export const getLngLatDistance = (lat1, lng1, lat2, lng2) => {
- const radLat1 = (lat1 * Math.PI) / 180.0
- const radLat2 = (lat2 * Math.PI) / 180.0
- const a = radLat1 - radLat2
- const b = (lng1 * Math.PI) / 180.0 - (lng2 * Math.PI) / 180.0
- let s =
- 2 *
- Math.asin(
- Math.sqrt(
- Math.pow(Math.sin(a / 2), 2) +
- Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2),
- ),
- )
- s = s * 6378.137 // EARTH_RADIUS;
- s = Math.round(s * 10000) / 10000
- return s * 1000
+ const radLat1 = (lat1 * Math.PI) / 180.0
+ const radLat2 = (lat2 * Math.PI) / 180.0
+ const a = radLat1 - radLat2
+ const b = (lng1 * Math.PI) / 180.0 - (lng2 * Math.PI) / 180.0
+ let s =
+ 2 *
+ Math.asin(
+ Math.sqrt(
+ Math.pow(Math.sin(a / 2), 2) +
+ Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)
+ )
+ )
+ s = s * 6378.137 // EARTH_RADIUS;
+ s = Math.round(s * 10000) / 10000
+ return s * 1000
}
// 获取限polyline长度
-export const getPolylineLength = (entity) => {
- let length = 0
+export const getPolylineLength = entity => {
+ let length = 0
- // 获取Polyline的所有顶点位置
- const positions = entity.polyline.positions.getValue()
+ // 获取Polyline的所有顶点位置
+ const positions = entity.polyline.positions.getValue()
- for (let i = 0; i < positions.length - 1; ++i) {
- const startPosition = positions[i]
- const endPosition = positions[i + 1]
+ for (let i = 0; i < positions.length - 1; ++i) {
+ const startPosition = positions[i]
+ const endPosition = positions[i + 1]
- // 使用Cesium提供的distanceBetween函数计算两个顶点之间的距离
- const distance = Cesium.Cartesian3.distance(startPosition, endPosition)
+ // 使用Cesium提供的distanceBetween函数计算两个顶点之间的距离
+ const distance = Cesium.Cartesian3.distance(startPosition, endPosition)
- // 将每个顶点之间的距离相加得到总长度
- length += distance
- }
+ // 将每个顶点之间的距离相加得到总长度
+ length += distance
+ }
- return length
+ return length
}
// 创建三角广告牌
export const createTriangleMarker = (title, color) => {
- // 创建canvas绘制广告牌
- const billboard = document.createElement('canvas')
- billboard.width = 30
- billboard.height = 30
- const ctx = billboard.getContext('2d')
- ctx.beginPath()
- ctx.moveTo(0, 0)
- ctx.lineTo(30, 0)
- ctx.lineTo(15, 22)
- ctx.fillStyle = color
- ctx.fill()
- ctx.font = '18px serif'
- ctx.fillStyle = '#ffffff'
- ctx.fillText(title, 10, 15)
- ctx.closePath()
- return billboard
+ // 创建canvas绘制广告牌
+ const billboard = document.createElement('canvas')
+ billboard.width = 30
+ billboard.height = 30
+ const ctx = billboard.getContext('2d')
+ ctx.beginPath()
+ ctx.moveTo(0, 0)
+ ctx.lineTo(30, 0)
+ ctx.lineTo(15, 22)
+ ctx.fillStyle = color
+ ctx.fill()
+ ctx.font = '18px serif'
+ ctx.fillStyle = '#ffffff'
+ ctx.fillText(title, 10, 15)
+ ctx.closePath()
+ return billboard
}
export const createCircleBillboard = (title, color) => {
- const billboard = document.createElement('canvas')
- const ctx = billboard.getContext('2d')
- ctx.beginPath()
- ctx.ellipse(150, 90, 11, 11, 0, 0, Math.PI * 2)
- ctx.fillStyle = color
- ctx.fill()
- ctx.font = 'bold 15px serif'
- ctx.textAlign = 'center'
- ctx.fillStyle = '#ffffff'
- ctx.fillText(title, 150, 95)
- ctx.closePath()
- return billboard
+ const billboard = document.createElement('canvas')
+ const ctx = billboard.getContext('2d')
+ ctx.beginPath()
+ ctx.ellipse(150, 90, 11, 11, 0, 0, Math.PI * 2)
+ ctx.fillStyle = color
+ ctx.fill()
+ ctx.font = 'bold 15px serif'
+ ctx.textAlign = 'center'
+ ctx.fillStyle = '#ffffff'
+ ctx.fillText(title, 150, 95)
+ ctx.closePath()
+ return billboard
}
// 获取当前经纬度海拔
export const getHaeHeight = (start, end) => {
- const ellipsoid = Cesium.Ellipsoid.WGS84 // 选择合适的椭圆体模型
- // const { longitude, latitude, height } = start
- // const { longitude: endLng, latitude: endLat, height: endHeight } = end
- // const startC3Position = new Cesium.Cartographic(longitude, latitude, height)
- // const endC3Position = new Cesium.Cartographic(endLng, endLat, endHeight)
- // const startCartesianPosition = ellipsoid.cartographicToCartesian(startC3Position)
- // const endCartesianPosition = ellipsoid.cartographicToCartesian(endC3Position)
- // // 计算两个位置之间的距离
- // const distance = new Cesium.EllipsoidGeodesic(startCartesianPosition, endCartesianPosition, ellipsoid)
- // return distance
- const { longitude, latitude, height } = end
- const cartographic = Cesium.Cartographic.fromDegrees(
- longitude,
- latitude,
- height,
- )
- const cartesianPosition = ellipsoid.cartographicToCartesian(cartographic)
- const haeHeight = ellipsoid.cartesianToCartographic(cartesianPosition).height
- return haeHeight
+ const ellipsoid = Cesium.Ellipsoid.WGS84 // 选择合适的椭圆体模型
+ // const { longitude, latitude, height } = start
+ // const { longitude: endLng, latitude: endLat, height: endHeight } = end
+ // const startC3Position = new Cesium.Cartographic(longitude, latitude, height)
+ // const endC3Position = new Cesium.Cartographic(endLng, endLat, endHeight)
+ // const startCartesianPosition = ellipsoid.cartographicToCartesian(startC3Position)
+ // const endCartesianPosition = ellipsoid.cartographicToCartesian(endC3Position)
+ // // 计算两个位置之间的距离
+ // const distance = new Cesium.EllipsoidGeodesic(startCartesianPosition, endCartesianPosition, ellipsoid)
+ // return distance
+ const { longitude, latitude, height } = end
+ const cartographic = Cesium.Cartographic.fromDegrees(longitude, latitude, height)
+ const cartesianPosition = ellipsoid.cartographicToCartesian(cartographic)
+ const haeHeight = ellipsoid.cartesianToCartographic(cartesianPosition).height
+ return haeHeight
}
// Cesium Cartesian3 转正常经纬度
export const cartesian3Convert = (cartesian3Position, viewer) => {
- // 转换为经纬度
- const ellipsoid = viewer.scene.globe.ellipsoid
- const cartographicPosition = Cesium.Cartographic.fromCartesian(
- cartesian3Position,
- ellipsoid,
- )
- const longitude = Cesium.Math.toDegrees(cartographicPosition.longitude)
- const latitude = Cesium.Math.toDegrees(cartographicPosition.latitude)
- const height = cartographicPosition.height
+ // 转换为经纬度
+ const ellipsoid = viewer.scene.globe.ellipsoid
+ const cartographicPosition = Cesium.Cartographic.fromCartesian(cartesian3Position, ellipsoid)
+ const longitude = Cesium.Math.toDegrees(cartographicPosition.longitude)
+ const latitude = Cesium.Math.toDegrees(cartographicPosition.latitude)
+ const height = cartographicPosition.height
- // console.log('经度: ' + longitude);
- // console.log('纬度: ' + latitude);
- // console.log('高度: ' + height);
+ // console.log('经度: ' + longitude);
+ // console.log('纬度: ' + latitude);
+ // console.log('高度: ' + height);
- return {
- longitude,
- latitude,
- height,
- }
+ return {
+ longitude,
+ latitude,
+ height,
+ }
}
// Cesium Cartesian2 转正常经纬度
export const cartesian2Convert = (position, viewer) => {
- const ellipsoid = viewer.scene.globe.ellipsoid
- const c3Position = viewer.scene.globe.pick(
- viewer.camera.getPickRay(position),
- viewer.scene,
- )
- const c2Postion = ellipsoid.cartesianToCartographic(c3Position)
- const longitude = Cesium.Math.toDegrees(c2Postion.longitude)
- const latitude = Cesium.Math.toDegrees(c2Postion.latitude)
- return { longitude, latitude }
+ const ellipsoid = viewer.scene.globe.ellipsoid
+ const c3Position = viewer.scene.globe.pick(viewer.camera.getPickRay(position), viewer.scene)
+ const c2Postion = ellipsoid.cartesianToCartographic(c3Position)
+ const longitude = Cesium.Math.toDegrees(c2Postion.longitude)
+ const latitude = Cesium.Math.toDegrees(c2Postion.latitude)
+ return { longitude, latitude }
}
// 根据经纬度获取距离
export const getLnglatDist = (lng1, lat1, lng2, lat2) => {
- const start = new Cesium.Cartesian3.fromDegrees(
- Number(lng1),
- Number(lat1),
- 0,
- )
- const end = new Cesium.Cartesian3.fromDegrees(Number(lng2), Number(lat2), 0)
- return Cesium.Cartesian3.distance(start, end)
+ const start = new Cesium.Cartesian3.fromDegrees(Number(lng1), Number(lat1), 0)
+ const end = new Cesium.Cartesian3.fromDegrees(Number(lng2), Number(lat2), 0)
+ return Cesium.Cartesian3.distance(start, end)
}
/**
@@ -150,37 +136,37 @@
* @param coordinateList {Array<Array<Object>>} [[{lat, lng}]]
* @return { Object } {lat lng}
*/
-export const getCenterPoint = (coordinateList) => {
- coordinateList = coordinateList.map((item) => {
- const [lng, lat] = item
- return [{ lat, lng }]
- })
- const geoCoordinateListFlat = coordinateList.reduce((s, v) => {
- return (s = s.concat(v))
- }, [])
- const total = geoCoordinateListFlat.length
- let X = 0
- let Y = 0
- let Z = 0
- for (const g of geoCoordinateListFlat) {
- const lat = (g.lat * Math.PI) / 180
- const lon = (g.lng * Math.PI) / 180
- const x = Math.cos(lat) * Math.cos(lon)
- const y = Math.cos(lat) * Math.sin(lon)
- const z = Math.sin(lat)
- X += x
- Y += y
- Z += z
- }
+export const getCenterPoint = coordinateList => {
+ coordinateList = coordinateList.map(item => {
+ const [lng, lat] = item
+ return [{ lat, lng }]
+ })
+ const geoCoordinateListFlat = coordinateList.reduce((s, v) => {
+ return (s = s.concat(v))
+ }, [])
+ const total = geoCoordinateListFlat.length
+ let X = 0
+ let Y = 0
+ let Z = 0
+ for (const g of geoCoordinateListFlat) {
+ const lat = (g.lat * Math.PI) / 180
+ const lon = (g.lng * Math.PI) / 180
+ const x = Math.cos(lat) * Math.cos(lon)
+ const y = Math.cos(lat) * Math.sin(lon)
+ const z = Math.sin(lat)
+ X += x
+ Y += y
+ Z += z
+ }
- X = X / total
- Y = Y / total
- Z = Z / total
- const Lon = Math.atan2(Y, X)
- const Hyp = Math.sqrt(X * X + Y * Y)
- const Lat = Math.atan2(Z, Hyp)
+ X = X / total
+ Y = Y / total
+ Z = Z / total
+ const Lon = Math.atan2(Y, X)
+ const Hyp = Math.sqrt(X * X + Y * Y)
+ const Lat = Math.atan2(Z, Hyp)
- return { lng: (Lon * 180) / Math.PI, lat: (Lat * 180) / Math.PI }
+ return { lng: (Lon * 180) / Math.PI, lat: (Lat * 180) / Math.PI }
}
/**
@@ -190,183 +176,174 @@
* @return {*} { index: 1 }
*/
export const getShortestDistance = (lnglat1, lnglat2) => {
- const arr = []
- lnglat1.forEach((v, i) => {
- const [lng, lat] = v
- lnglat2.forEach((s, i2) => {
- const [vLng, vLat] = s
- const distance = getLnglatDist(lng, lat, vLng, vLat)
- arr.push({
- distance,
- index: [i, i2],
- lnglat: [v, s],
- })
- })
- })
- const newArr = arr.sort((a, b) => a.distance - b.distance)
- return newArr[0]
+ const arr = []
+ lnglat1.forEach((v, i) => {
+ const [lng, lat] = v
+ lnglat2.forEach((s, i2) => {
+ const [vLng, vLat] = s
+ const distance = getLnglatDist(lng, lat, vLng, vLat)
+ arr.push({
+ distance,
+ index: [i, i2],
+ lnglat: [v, s],
+ })
+ })
+ })
+ const newArr = arr.sort((a, b) => a.distance - b.distance)
+ return newArr[0]
}
// 获取当前经纬度地形数据
export const getLnglatAltitude = (longitude, latitude, viewer) => {
- return new Promise((resolve, reject) => {
- // 假设 viewer 已经初始化并且 terrainProvider 是有效的
- const terrainProvider = viewer?.terrainProvider
+ return new Promise((resolve, reject) => {
+ // 假设 viewer 已经初始化并且 terrainProvider 是有效的
+ const terrainProvider = viewer?.terrainProvider
- // 创建 Cartographic 对象
- const cartographic = Cesium.Cartographic.fromDegrees(longitude, latitude)
+ // 创建 Cartographic 对象
+ const cartographic = Cesium.Cartographic.fromDegrees(longitude, latitude)
- // 获取地形数据的Promise
- const promise = Cesium.sampleTerrainMostDetailed(terrainProvider, [
- cartographic,
- ])
+ // 获取地形数据的Promise
+ const promise = Cesium.sampleTerrainMostDetailed(terrainProvider, [cartographic])
- // 使用 Cesium.when 处理 Promise
- promise
- .then(function (updatedPositions) {
- // updatedPositions 是一个数组,包含更新后的 Cartographic 对象
- const updatedPosition = updatedPositions[0]
- const height = updatedPosition.height
+ // 使用 Cesium.when 处理 Promise
+ promise
+ .then(function (updatedPositions) {
+ // updatedPositions 是一个数组,包含更新后的 Cartographic 对象
+ const updatedPosition = updatedPositions[0]
+ const height = updatedPosition.height
- resolve({
- longitude,
- latitude,
- height,
- })
- // 在这里,你可以使用 height 值进行后续操作
- })
- .catch(function (error) {
- // console.error('获取高程时发生错误:', error);
- reject(error)
- })
- })
+ resolve({
+ longitude,
+ latitude,
+ height,
+ })
+ // 在这里,你可以使用 height 值进行后续操作
+ })
+ .catch(function (error) {
+ // console.error('获取高程时发生错误:', error);
+ reject(error)
+ })
+ })
}
// 批量获取经纬度对应高度信息
export const getPositionsHeight = (data, viewer, droneHeight = null) => {
- return new Promise((resolve, reject) => {
- if (!data || !data.length) {
- resolve([])
+ return new Promise((resolve, reject) => {
+ if (!data || !data.length) {
+ resolve([])
- return
- }
+ return
+ }
- // 假设 viewer 已经初始化并且 terrainProvider 是有效的
- const terrainProvider = viewer?.terrainProvider
+ // 假设 viewer 已经初始化并且 terrainProvider 是有效的
+ const terrainProvider = viewer?.terrainProvider
- // 创建 Cartographic 对象
- const cartographics = data.map((item) => {
- const [lng, lat] = item?.['Point']?.['coordinates']?.['#text'].split(',')
+ // 创建 Cartographic 对象
+ const cartographics = data.map(item => {
+ const [lng, lat] = item?.['Point']?.['coordinates']?.['#text'].split(',')
- return Cesium.Cartographic.fromDegrees(Number(lng), Number(lat))
- })
+ return Cesium.Cartographic.fromDegrees(Number(lng), Number(lat))
+ })
- // 获取地形数据的Promise
- const promise = Cesium.sampleTerrainMostDetailed(
- terrainProvider,
- cartographics,
- )
+ // 获取地形数据的Promise
+ const promise = Cesium.sampleTerrainMostDetailed(terrainProvider, cartographics)
- // 使用 Cesium.when 处理 Promise
- promise
- .then(function (updatedPositions) {
- // updatedPositions 是一个数组,包含更新后的 Cartographic 对象
- const newPosition = updatedPositions.map((item, index) => {
- const longitude = Cesium.Math.toDegrees(item.longitude)
- const latitude = Cesium.Math.toDegrees(item.latitude)
+ // 使用 Cesium.when 处理 Promise
+ promise
+ .then(function (updatedPositions) {
+ // updatedPositions 是一个数组,包含更新后的 Cartographic 对象
+ const newPosition = updatedPositions.map((item, index) => {
+ const longitude = Cesium.Math.toDegrees(item.longitude)
+ const latitude = Cesium.Math.toDegrees(item.latitude)
- let FinalHeight = Number(data[index]?.['ellipsoidHeight']?.['#text']) + Number(item.height)
+ let FinalHeight =
+ Number(data[index]?.['ellipsoidHeight']?.['#text']) + Number(item.height)
- if (droneHeight) {
- FinalHeight = Number(data[index]?.['ellipsoidHeight']?.['#text']) + droneHeight
- }
+ if (droneHeight) {
+ FinalHeight = Number(data[index]?.['ellipsoidHeight']?.['#text']) + droneHeight
+ }
- return {
- ...data[index],
- longitude,
- latitude,
- FinalHeight,
- customHeight: Number(item.height),
- }
- })
+ return {
+ ...data[index],
+ longitude,
+ latitude,
+ FinalHeight,
+ customHeight: Number(item.height),
+ }
+ })
- resolve(newPosition)
- // 在这里,你可以使用 height 值进行后续操作
- })
- .catch(function (error) {
- // console.error('获取高程时发生错误:', error);
- reject(error)
- })
- })
+ resolve(newPosition)
+ // 在这里,你可以使用 height 值进行后续操作
+ })
+ .catch(function (error) {
+ // console.error('获取高程时发生错误:', error);
+ reject(error)
+ })
+ })
}
// 获取面中最高点
export const getPolygonMaxHeight = (turfPolygon, viewer) => {
- return new Promise((resolve, reject) => {
- const turfExtent = turf.bbox(turfPolygon)
+ return new Promise((resolve, reject) => {
+ const turfExtent = turf.bbox(turfPolygon)
- const turfSamplePoints = turf.pointGrid(turfExtent, 0.01, {
- units: 'kilometers',
- mask: turfPolygon,
- })
+ const turfSamplePoints = turf.pointGrid(turfExtent, 0.01, {
+ units: 'kilometers',
+ mask: turfPolygon,
+ })
- // 假设 viewer 已经初始化并且 terrainProvider 是有效的
- const terrainProvider = viewer?.terrainProvider
+ // 假设 viewer 已经初始化并且 terrainProvider 是有效的
+ const terrainProvider = viewer?.terrainProvider
- const cesiumSamplePoints = []
- for (let i = 0; i < turfSamplePoints.features.length; i++) {
- const coord = turfSamplePoints.features[i].geometry.coordinates
- cesiumSamplePoints.push(
- Cesium.Cartographic.fromDegrees(coord[0], coord[1]),
- )
- }
+ const cesiumSamplePoints = []
+ for (let i = 0; i < turfSamplePoints.features.length; i++) {
+ const coord = turfSamplePoints.features[i].geometry.coordinates
+ cesiumSamplePoints.push(Cesium.Cartographic.fromDegrees(coord[0], coord[1]))
+ }
- // 获取地形数据的Promise
- const promise = Cesium.sampleTerrainMostDetailed(
- terrainProvider,
- cesiumSamplePoints,
- )
+ // 获取地形数据的Promise
+ const promise = Cesium.sampleTerrainMostDetailed(terrainProvider, cesiumSamplePoints)
- promise
- .then(function (updatedPositions) {
- const newPosition = updatedPositions.map((item) => Number(item.height))
+ promise
+ .then(function (updatedPositions) {
+ const newPosition = updatedPositions.map(item => Number(item.height))
- resolve(Math.max(...newPosition))
- })
- .catch(function (error) {
- reject(error)
- })
- })
+ resolve(Math.max(...newPosition))
+ })
+ .catch(function (error) {
+ reject(error)
+ })
+ })
}
// 展示当前的高度
-export const getWaylineShowHeight = (positions) => {
- const { lng, lat } = getCenterPoint(positions)
- let maxDist = 0
- positions.forEach((item) => {
- const [lng1, lat1] = item
- let pointsDist = getLnglatDist(lng1, lat1, lng, lat)
- if (pointsDist > maxDist) {
- maxDist = pointsDist
- }
- })
- return {
- lng,
- lat,
- showHeight: maxDist * 8,
- }
+export const getWaylineShowHeight = positions => {
+ const { lng, lat } = getCenterPoint(positions)
+ let maxDist = 0
+ positions.forEach(item => {
+ const [lng1, lat1] = item
+ let pointsDist = getLnglatDist(lng1, lat1, lng, lat)
+ if (pointsDist > maxDist) {
+ maxDist = pointsDist
+ }
+ })
+ return {
+ lng,
+ lat,
+ showHeight: maxDist * 8,
+ }
}
// 获取当前面是否有交叉点
-export const isIntersection = (coordinates) => {
- const polyDikuai = turf.polygon([coordinates])
- const result = turf.kinks(polyDikuai)
- const resultFeatures = result.features
- if (resultFeatures.length == 0) {
- //无相交
- return false
- } else {
- //有相交
- return true
- }
+export const isIntersection = coordinates => {
+ const polyDikuai = turf.polygon([coordinates])
+ const result = turf.kinks(polyDikuai)
+ const resultFeatures = result.features
+ if (resultFeatures.length == 0) {
+ //无相交
+ return false
+ } else {
+ //有相交
+ return true
+ }
}
--
Gitblit v1.9.3