cesium 距离计算
根据两点间的经纬度可以计算出两点间的实际距离
// positions为存放经纬度坐标的数组
// 计算距离函数
function getSpaceDistance(positions) {
var distance = 0;
for (var i = 0; i < positions.length - 1; i++) {
var point1cartographic = Cesium.Cartographic.fromCartesian(
positions[i]
);
var point2cartographic = Cesium.Cartographic.fromCartesian(
positions[i + 1]
);
/**根据经纬度计算出距离**/
var geodesic = new Cesium.EllipsoidGeodesic();
geodesic.setEndPoints(point1cartographic, point2cartographic);
var s = geodesic.surfaceDistance;
//返回两点之间的距离
s = Math.sqrt(
Math.pow(s, 2) +
Math.pow(point2cartographic.height - point1cartographic.height, 2)
);
distance = distance + s;
}
return distance.toFixed(2);
}
// 左键点击事件
handler.setInputAction(function (evt) {
let ray = viewer.camera.getPickRay(evt.position);
let cartesian = viewer.scene.globe.pick(ray, viewer.scene);
let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
let longitude = Cesium.Math.toDegrees(cartographic.longitude); // 经度
let latitude = Cesium.Math.toDegrees(cartographic.latitude); // 纬度
if (positions.length === 0) {
positions.push(cartesian.clone());
}
positions.push(cartesian);
//在三维场景中添加Label
var textDisance = distance + "米";
viewer.entities.add({
name: "空间直线距离",
position: positions[positions.length - 1],
point: {
pixelSize: 5,
color: Cesium.Color.RED,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 2,
},
label: {
text: textDisance,
font: "18px sans-serif",
fillColor: Cesium.Color.GOLD,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth: 2,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(20, -20),
},
});
linePositions.value.push({longitude, latitude})
if (linePositions.value.length < 1) return; // 至少具有两组点的坐标 才划线
creatLine(linePositions.value)
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
// 右键点击事件 取消距离计算
handler.setInputAction(function (movement) {
handler.destroy(); //关闭事件句柄
positions.pop(); //最后一个点无效
// viewer.entities.remove(floatingPoint);
// tooltip.style.display = "none";
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
// 鼠标移动事件 计算距离
// 鼠标移动获取坐标
handler.setInputAction(function (movement) {
/******************此部分代码用于获取鼠标移动时所在的经纬度*************************/
//捕获椭球体,将笛卡尔二维平面坐标转为椭球体的笛卡尔三维坐标,返回球体表面的点
var ellipsoid = viewer.scene.globe.ellipsoid;
var cartesian = viewer.camera.pickEllipsoid(movement.endPosition, ellipsoid);
if (cartesian) {
//将笛卡尔三维坐标转为地图坐标(弧度)
var cartographic = viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
//将地图坐标(弧度)转为十进制的度数
var lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(4);
var lng = Cesium.Math.toDegrees(cartographic.longitude).toFixed(4);
var height = (viewer.camera.positionCartographic.height / 1000).toFixed(2);
position.value = lng + ", " + lat + ", " + height;
}
/*****************************************************************************/
let ray = viewer.camera.getPickRay(movement.endPosition);
cartesian = viewer.scene.globe.pick(ray, viewer.scene);
if (positions.length >= 2) {
if (!Cesium.defined(poly)) {
poly = new Cesium.GroundPolylinePrimitive(positions);
} else {
positions.pop();
positions.push(cartesian);
}
distance = getSpaceDistance(positions);
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
cesium 面积计算
// 计算距离函数
function distance(point1, point2) {
var point1cartographic = Cesium.Cartographic.fromCartesian(point1);
var point2cartographic = Cesium.Cartographic.fromCartesian(point2);
/**根据经纬度计算出距离**/
var geodesic = new Cesium.EllipsoidGeodesic();
geodesic.setEndPoints(point1cartographic, point2cartographic);
var s = geodesic.surfaceDistance;
//console.log(Math.sqrt(Math.pow(distance, 2) + Math.pow(endheight, 2)));
//返回两点之间的距离
s = Math.sqrt(
Math.pow(s, 2) +
Math.pow(point2cartographic.height - point1cartographic.height, 2)
);
return s;
}
var radiansPerDegree = Math.PI / 180.0; //角度转化为弧度(rad)
var degreesPerRadian = 180.0 / Math.PI; //弧度转化为角度
/*角度*/
function Angle(p1, p2, p3) {
var bearing21 = Bearing(p2, p1);
var bearing23 = Bearing(p2, p3);
var angle = bearing21 - bearing23;
if (angle < 0) {
angle += 360;
}
return angle;
}
/*方向*/
function Bearing(from, to) {
var lat1 = from.lat * radiansPerDegree;
var lon1 = from.lon * radiansPerDegree;
var lat2 = to.lat * radiansPerDegree;
var lon2 = to.lon * radiansPerDegree;
var 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;
}
angle = angle * degreesPerRadian; //角度
return angle;
}
// 计算多边形面积函数
function getArea(points) {
var res = 0;
//拆分三角曲面
for (var i = 0; i < points.length - 2; i++) {
var j = (i + 1) % points.length;
var k = (i + 2) % points.length;
var totalAngle = Angle(points[i], points[j], points[k]);
var dis_temp1 = distance(positions[i], positions[j]);
var dis_temp2 = distance(positions[j], positions[k]);
res += dis_temp1 * dis_temp2 * Math.abs(Math.sin(totalAngle));
console.log(res);
}
return (res / 1000000.0).toFixed(4);
}
// 右键点击事件 结束点的选取并计算面积
handler.setInputAction(function (movement) {
handler.destroy();
positions.pop();
var textArea = getArea(tempPoints) + "平方公里";
viewer.entities.add({
name: "多边形面积",
position: positions[positions.length - 1],
label: {
text: textArea,
font: "18px sans-serif",
fillColor: Cesium.Color.GOLD,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth: 2,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(20, -40),
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
},
});
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
// 左键点击事件 添加点实体 并选取坐标
handler.setInputAction(function (evt) {
let ray = viewer.camera.getPickRay(evt.position);
const cartesian = viewer.scene.globe.pick(ray, viewer.scene);
if (positions.length === 0) {
positions.push(cartesian.clone());
}
positions.push(cartesian);
//在三维场景中添加点
var cartographic = Cesium.Cartographic.fromCartesian(
positions[positions.length - 1]
);
var longitudeString = Cesium.Math.toDegrees(cartographic.longitude);
var latitudeString = Cesium.Math.toDegrees(cartographic.latitude);
var heightString = cartographic.height;
tempPoints.push({
lon: longitudeString,
lat: latitudeString,
hei: heightString,
});
viewer.entities.add({
name: "多边形面积",
position: positions[positions.length - 1],
point: {
pixelSize: 5,
color: Cesium.Color.RED,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 2,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
},
});
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);