Commit caf237a8 by jlc

update:内置算法代码结构的修改

parent beacbd9b
export function addDistanceTwoPoints() { export function addDistanceTwoPoints(viewer) {
const script = document.createElement('script'); let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
script.src = 'https://cesium.com/downloads/cesiumjs/releases/1.99/Build/Cesium/Cesium.js'; viewer.scene.globe.depthTestAgainstTerrain = true; //务必开启,否则无论是否有地形,绘制点偏移都很大
script.onload = () => { document.getElementById("cesiumContainer").style.cursor = "crosshair"
window.Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI3Njg4ZWU5Yi1iZDhiLTRhYmUtOTRiYS04YjM5NmUwNjVmMDMiLCJpZCI6MjI3MzQ3LCJpYXQiOjE3MjA1MjA4Mjh9.E5XW4LnwgfVAaBC-znaYr61m4yK0-j2qEQhi9qwFFPE' let tempEntities = []
let pointNum = 0
const viewer = new window.Cesium.Viewer('cesiumContainer', { let floatingPoint = undefined
selectionIndicator:false, let activeShape = undefined
infoBox:false, let position = []
// terrain:Cesium.Terrain.fromWorldTerrain(), let tempPoints = []
// imageryProvider: new Cesium.ArcGisMapServerImageryProvider({ let activeShapePoints = []
// url: "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer"
// }),
});
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); /* 空间两点距离计算函数 */
viewer.scene.globe.depthTestAgainstTerrain = true; //务必开启,否则无论是否有地形,绘制点偏移都很大 function getLength(start, end) {
document.getElementById("cesiumContainer").style.cursor = "crosshair" // 将起点与终点位置信息从笛卡尔坐标形式转换为Cartographic形式
let tempEntities = [] let startCartographic = Cesium.Cartographic.fromCartesian(start)
let pointNum = 0 let endCartographic = Cesium.Cartographic.fromCartesian(end)
let floatingPoint = undefined // 初始化测地线
let activeShape = undefined let geodesic = new Cesium.EllipsoidGeodesic()
let position = [] // 设置测地线起点和终点,EllipsoidGeodesic中setEndPoints常与surfaceDistance搭配使用
let tempPoints = [] geodesic.setEndPoints(startCartographic, endCartographic)
let activeShapePoints = [] // 获取起点和终点之间的表面距离,单位为km,规定四舍五入保留两位小数
// surfaceDistance返回number 单位为m,带小数
/* 空间两点距离计算函数 */ // console.log((geodesic.surfaceDistance / 1000).toFixed(2))
function getLength(start, end) { return (geodesic.surfaceDistance / 1000).toFixed(2)
// 将起点与终点位置信息从笛卡尔坐标形式转换为Cartographic形式 }
let startCartographic = Cesium.Cartographic.fromCartesian(start) /* 空间两点计算中点函数 */
let endCartographic = Cesium.Cartographic.fromCartesian(end) function getMidpoint(start, end) {
// 初始化测地线 let startPoint = Cesium.Cartographic.fromCartesian(start)
let geodesic = new Cesium.EllipsoidGeodesic() let endPoint = Cesium.Cartographic.fromCartesian(end)
// 设置测地线起点和终点,EllipsoidGeodesic中setEndPoints常与surfaceDistance搭配使用 let geodesic = new Cesium.EllipsoidGeodesic()
geodesic.setEndPoints(startCartographic, endCartographic) geodesic.setEndPoints(startPoint, endPoint)
// 获取起点和终点之间的表面距离,单位为km,规定四舍五入保留两位小数 let geoPoint = geodesic.interpolateUsingFraction(0.5)
// surfaceDistance返回number 单位为m,带小数 console.log(Cesium.Ellipsoid.WGS84.cartographicToCartesian(geoPoint))
// console.log((geodesic.surfaceDistance / 1000).toFixed(2)) return Cesium.Ellipsoid.WGS84.cartographicToCartesian(geoPoint)
return (geodesic.surfaceDistance / 1000).toFixed(2) }
function addLabel(midPoint, labelLength) {
return viewer.entities.add({
name: "中点",
position: midPoint,
label: {
text: labelLength + "km",
font: "20px sans-serif",
fillColor: Cesium.Color.WHITE,
outlineWidth: 2,
backgroundColor: Cesium.Color.BLACK,
showBackground: true,
style: Cesium.LabelStyle.FILL,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance: Number.POSITIVE_INFINITY
} }
/* 空间两点计算中点函数 */ })
function getMidpoint(start, end) { }
let startPoint = Cesium.Cartographic.fromCartesian(start) /* 测量空间面积 */
let endPoint = Cesium.Cartographic.fromCartesian(end) // 方向
let geodesic = new Cesium.EllipsoidGeodesic() function Bearing(from, to) {
geodesic.setEndPoints(startPoint, endPoint) let fromCartographic = Cesium.Cartographic.fromCartesian(from)
let geoPoint = geodesic.interpolateUsingFraction(0.5) let toCartographic = Cesium.Cartographic.fromCartesian(to)
console.log(Cesium.Ellipsoid.WGS84.cartographicToCartesian(geoPoint)) let lat1 = fromCartographic.latitude
return Cesium.Ellipsoid.WGS84.cartographicToCartesian(geoPoint) let lon1 = fromCartographic.longitude
let lat2 = toCartographic.latitude
let lon2 = toCartographic.longitude
let angle = -Math.atan2(Math.sin(lon1 - lon2) * Math.cos(lat2), Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon1 - lon2))
if (angle < 0) {
angle += Math.PI * 2.0
} }
function addLabel(midPoint, labelLength) { return angle
return viewer.entities.add({ }
name: "中点", // 角度
position: midPoint, function pointAngle(point1, point2, point3) {
let bearing21 = Bearing(point2, point1)
let bearing23 = Bearing(point2, point3)
let angle = bearing21 - bearing23
if (angle < 0) {
angle += Math.PI * 2.0
}
return angle
}
function getArea(positions) {
let res = 0
for (let i = 0; i < positions.length - 2; i++) {
let j = (i + 1) % positions.length
let k = (i + 2) % positions.length
let totalAngle = pointAngle(positions[i], positions[j], positions[k])
let tempLength1 = getLength(positions[j], positions[0])
let tempLength2 = getLength(positions[k], positions[0])
res += tempLength1 * tempLength2 * Math.sin(totalAngle) / 2
}
res = res.toFixed(2)
// console.log(res)
res = parseFloat(res)
// console.log(Math.abs(res))
return Math.abs(res)
}
function addArea(area, positions) {
return viewer.entities.add({
name: "多边形面积",
position: positions[positions.length - 1],
label: { label: {
text: labelLength + "km", text: area + "平方公里",
font: "20px sans-serif", font: "20px sans-serif",
fillColor: Cesium.Color.WHITE, fillColor: Cesium.Color.WHITE,
outlineWidth: 2, outlineWidth: 2,
backgroundColor: Cesium.Color.BLACK, backgroundColor: Cesium.Color.BLACK,
showBackground: true, showBackground: true,
style: Cesium.LabelStyle.FILL, style: Cesium.LabelStyle.FILL,
pixelOffset: new Cesium.Cartesian2(60, -60),
verticalOrigin: Cesium.VerticalOrigin.BOTTOM, verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER, horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance: Number.POSITIVE_INFINITY disableDepthTestDistance: Number.POSITIVE_INFINITY
} }
}) })
} }
/* 测量空间面积 */ /* 绘制函数 */
// 方向 function drawPointLabel(position, pointNum) {
function Bearing(from, to) { // 本质上就是添加一个点的实体
let fromCartographic = Cesium.Cartographic.fromCartesian(from) return viewer.entities.add({
let toCartographic = Cesium.Cartographic.fromCartesian(to) name: "点几何对象",
let lat1 = fromCartographic.latitude position: position,
let lon1 = fromCartographic.longitude point: {
let lat2 = toCartographic.latitude color: Cesium.Color.WHEAT,
let lon2 = toCartographic.longitude pixelSize: 5,
let angle = -Math.atan2(Math.sin(lon1 - lon2) * Math.cos(lat2), Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon1 - lon2)) outlineWidth: 3,
if (angle < 0) { disableDepthTestDistance: Number.POSITIVE_INFINITY, //
angle += Math.PI * 2.0 heightReference: Cesium.HeightReference.CLAMP_TO_GROUND // 规定贴地
} },
return angle label: {
} text: pointNum,
// 角度 font: "30px sans-serif",
function pointAngle(point1, point2, point3) { fillColor: Cesium.Color.WHITE,
let bearing21 = Bearing(point2, point1) outlineWidth: 2,
let bearing23 = Bearing(point2, point3) backgroundColor: Cesium.Color.BLACK,
let angle = bearing21 - bearing23 showBackground: true,
if (angle < 0) { style: Cesium.LabelStyle.FILL,
angle += Math.PI * 2.0 verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
} horizontalOrigin: Cesium.HorizontalOrigin.CENTER
return angle
}
function getArea(positions) {
let res = 0
for (let i = 0; i < positions.length - 2; i++) {
let j = (i + 1) % positions.length
let k = (i + 2) % positions.length
let totalAngle = pointAngle(positions[i], positions[j], positions[k])
let tempLength1 = getLength(positions[j], positions[0])
let tempLength2 = getLength(positions[k], positions[0])
res += tempLength1 * tempLength2 * Math.sin(totalAngle) / 2
} }
res = res.toFixed(2) })
// console.log(res) }
res = parseFloat(res) function drawPoint(position) {
// console.log(Math.abs(res)) // 本质上就是添加一个点的实体
return Math.abs(res) return viewer.entities.add({
} position: position,
function addArea(area, positions) { point: {
return viewer.entities.add({ color: Cesium.Color.WHEAT,
name: "多边形面积", pixelSize: 5,
position: positions[positions.length - 1], outlineWidth: 3,
label: { disableDepthTestDistance: Number.POSITIVE_INFINITY,
text: area + "平方公里", heightReference: Cesium.HeightReference.CLAMP_TO_GROUND // 规定贴地
font: "20px sans-serif",
fillColor: Cesium.Color.WHITE,
outlineWidth: 2,
backgroundColor: Cesium.Color.BLACK,
showBackground: true,
style: Cesium.LabelStyle.FILL,
pixelOffset: new Cesium.Cartesian2(60, -60),
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance: Number.POSITIVE_INFINITY
}
})
}
/* 绘制函数 */
function drawPointLabel(position, pointNum) {
// 本质上就是添加一个点的实体
return viewer.entities.add({
name: "点几何对象",
position: position,
point: {
color: Cesium.Color.WHEAT,
pixelSize: 5,
outlineWidth: 3,
disableDepthTestDistance: Number.POSITIVE_INFINITY, //
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND // 规定贴地
},
label: {
text: pointNum,
font: "30px sans-serif",
fillColor: Cesium.Color.WHITE,
outlineWidth: 2,
backgroundColor: Cesium.Color.BLACK,
showBackground: true,
style: Cesium.LabelStyle.FILL,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER
}
})
}
function drawPoint(position) {
// 本质上就是添加一个点的实体
return viewer.entities.add({
position: position,
point: {
color: Cesium.Color.WHEAT,
pixelSize: 5,
outlineWidth: 3,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND // 规定贴地
}
})
}
function drawPolyline(positions) {
if (positions.length < 1) return
return viewer.entities.add({
name: "线几何对象",
polyline: {
positions: positions,
width: 5.0,
material: new Cesium.PolylineGlowMaterialProperty({
// eslint-disable-next-line new-cap
color: Cesium.Color.WHEAT
}),
depthFailMaterial: new Cesium.PolylineGlowMaterialProperty({
// eslint-disable-next-line new-cap
color: Cesium.Color.WHEAT
}),
clampToGround: true
}
})
}
/* 清除实体 */
function clearAllDrawn() {
tempEntities = []
pointNum = 0
viewer.entities.removeAll()
}
// 开启深度检测
viewer.scene.globe.depthTestAgainstTerrain = true
// 创建场景的HTML canvas元素
// 取消鼠标双击事件
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
// 监听鼠标移动
handler.setInputAction(function (movement) {
if (Cesium.defined(floatingPoint)) {
let newPosition = viewer.scene.pickPosition(movement.endPosition)
if (Cesium.defined(newPosition)) {
floatingPoint.position.setValue(newPosition)
activeShapePoints.pop()
activeShapePoints.push(newPosition)
}
} }
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE) })
// 左键单击开始画线 }
handler.setInputAction(function (click) { function drawPolyline(positions) {
let earthPosition = viewer.scene.pickPosition(click.position) if (positions.length < 1) return
if (Cesium.defined(earthPosition)) { return viewer.entities.add({
floatingPoint = drawPoint(earthPosition) name: "线几何对象",
polyline: {
positions: positions,
width: 5.0,
material: new Cesium.PolylineGlowMaterialProperty({
// eslint-disable-next-line new-cap
color: Cesium.Color.WHEAT
}),
depthFailMaterial: new Cesium.PolylineGlowMaterialProperty({
// eslint-disable-next-line new-cap
color: Cesium.Color.WHEAT
}),
clampToGround: true
} }
// 获取位置信息 })
// 从相机位置创建一条射线,这条射线通过世界中movement.position像素所在的坐标,返回Cartesian3坐标 }
let ray = viewer.camera.getPickRay(click.position)
// 找到射线与渲染的地球表面之间的交点。射线必须以世界坐标给出。返回Cartesian3坐标 /* 清除实体 */
position = viewer.scene.globe.pick(ray, viewer.scene) function clearAllDrawn() {
tempPoints.push(position) // 记录点位 tempEntities = []
pointNum += 1 pointNum = 0
let tempLength = tempPoints.length // 记录点数 viewer.entities.removeAll()
// 调用绘制点的接口 }
let point = drawPointLabel(tempPoints[tempPoints.length - 1], JSON.stringify(pointNum))
tempEntities.push(point) // 开启深度检测
// 存在超过一个点时 viewer.scene.globe.depthTestAgainstTerrain = true
if (tempLength > 1) { // 创建场景的HTML canvas元素
// 绘制线 // 取消鼠标双击事件
let pointLength = getLength(tempPoints[tempPoints.length - 2], tempPoints[tempPoints.length - 1]) viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
let midPosition = getMidpoint(tempPoints[tempPoints.length - 2], tempPoints[tempPoints.length - 1]) // 监听鼠标移动
let pointline = drawPolyline([tempPoints[tempPoints.length - 2], tempPoints[tempPoints.length - 1]]) handler.setInputAction(function (movement) {
let pointLabel = addLabel(midPosition, pointLength) if (Cesium.defined(floatingPoint)) {
tempEntities.push(pointline) // 保存记录 let newPosition = viewer.scene.pickPosition(movement.endPosition)
tempEntities.push(pointLabel) if (Cesium.defined(newPosition)) {
floatingPoint.position.setValue(newPosition)
activeShapePoints.pop()
activeShapePoints.push(newPosition)
} }
}, Cesium.ScreenSpaceEventType.LEFT_CLICK) }
// 右键单击结束画线 }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
handler.setInputAction(function (click) { // 左键单击开始画线
console.log(pointNum) handler.setInputAction(function (click) {
activeShapePoints.pop() let earthPosition = viewer.scene.pickPosition(click.position)
viewer.entities.remove(activeShapePoints) if (Cesium.defined(earthPosition)) {
viewer.entities.remove(floatingPoint) floatingPoint = drawPoint(earthPosition)
tempPoints = [] // 清空点位记录 }
handler.destroy() // 获取位置信息
handler = null // 从相机位置创建一条射线,这条射线通过世界中movement.position像素所在的坐标,返回Cartesian3坐标
floatingPoint = undefined let ray = viewer.camera.getPickRay(click.position)
activeShape = undefined // 找到射线与渲染的地球表面之间的交点。射线必须以世界坐标给出。返回Cartesian3坐标
activeShapePoints = [] position = viewer.scene.globe.pick(ray, viewer.scene)
console.log(pointNum) tempPoints.push(position) // 记录点位
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK) pointNum += 1
let tempLength = tempPoints.length // 记录点数
}; // 调用绘制点的接口
document.head.appendChild(script); let point = drawPointLabel(tempPoints[tempPoints.length - 1], JSON.stringify(pointNum))
tempEntities.push(point)
const link = document.createElement('link'); // 存在超过一个点时
link.rel = 'stylesheet'; if (tempLength > 1) {
link.href = 'https://cesium.com/downloads/cesiumjs/releases/1.119/Build/Cesium/Widgets/widgets.css'; // 绘制线
document.head.appendChild(link); let pointLength = getLength(tempPoints[tempPoints.length - 2], tempPoints[tempPoints.length - 1])
let midPosition = getMidpoint(tempPoints[tempPoints.length - 2], tempPoints[tempPoints.length - 1])
let pointline = drawPolyline([tempPoints[tempPoints.length - 2], tempPoints[tempPoints.length - 1]])
let pointLabel = addLabel(midPosition, pointLength)
tempEntities.push(pointline) // 保存记录
tempEntities.push(pointLabel)
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
// 右键单击结束画线
handler.setInputAction(function (click) {
console.log(pointNum)
activeShapePoints.pop()
viewer.entities.remove(activeShapePoints)
viewer.entities.remove(floatingPoint)
tempPoints = [] // 清空点位记录
handler.destroy()
handler = null
floatingPoint = undefined
activeShape = undefined
activeShapePoints = []
console.log(pointNum)
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
} }
<template> <template>
<div id="cesiumContainer" class="cesium-container"></div> <div id="cesiumContainer" class="cesium-container"></div>
</template> </template>
<script setup> <script setup>
import { onMounted } from 'vue'; import { onMounted } from 'vue';
import { addDistanceTwoPoints } from './function'; import { addDistanceTwoPoints } from './function';
let viewer;
onMounted(() => { onMounted(() => {
addDistanceTwoPoints() const script = document.createElement('script');
script.src = 'https://cesium.com/downloads/cesiumjs/releases/1.99/Build/Cesium/Cesium.js';
script.onload = () => {
window.Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI3Njg4ZWU5Yi1iZDhiLTRhYmUtOTRiYS04YjM5NmUwNjVmMDMiLCJpZCI6MjI3MzQ3LCJpYXQiOjE3MjA1MjA4Mjh9.E5XW4LnwgfVAaBC-znaYr61m4yK0-j2qEQhi9qwFFPE'
viewer = new window.Cesium.Viewer('cesiumContainer', {
selectionIndicator:false,
infoBox:false,
});
addDistanceTwoPoints(viewer)
};
document.head.appendChild(script);
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'https://cesium.com/downloads/cesiumjs/releases/1.119/Build/Cesium/Widgets/widgets.css';
document.head.appendChild(link);
}); });
</script> </script>
<style> <style>
.cesium-container { .cesium-container {
width: 100%; width: 100%;
height: 100vh; height: 100vh;
} }
</style> </style>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment