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