绘制线、多边形方法,添加绘制点数字信息和线/面等宽度延伸
解决方案:
获取到polyline的坐标后,根据这些坐标数据,额外添加一个bufferPolygon。方法如下:
let bufferPolygonLayer = null;
// 计算缓冲区多边形,根据polyline坐标以及扩散半径绘制缓冲区
let bufferPolygonLayer = null;
// 计算缓冲区多边形,根据polyline坐标以及扩散半径绘制缓冲区
const drawBufferPolygon = (positions) =>{
let bufferPolygonPos = [];
if(positions.length > 0) {
positions.map(item => {
bufferPolygonPos.push(item[0],item[1],item[2])
})
}
if(bufferPolygonLayer) {
graphicLayer.removeGraphic(bufferPolygonLayer);
}
// 原始折线坐标(经纬度高程)
const polylinePositions = Cesium.Cartesian3.fromDegreesArrayHeights(bufferPolygonPos);
// 计算缓冲区多边形
const bufferPolygon = createBufferPolygon(polylinePositions, 50);
// 添加缓冲区多边形
bufferPolygonLayer = new mars3d.graphic.PolygonEntity({
positions: bufferPolygon.positions,
style: {
color: "#3388ff",
material: Cesium.Color.DEEPSKYBLUE.withAlpha(0.2),
outline: true,
outlineWidth: 2,
outlineColor: Cesium.Color.CORAL,
clampToGround: true
},
})
graphicLayer.addGraphic(bufferPolygonLayer)
}
/**创建折线的缓冲区多边形@chancelai {Cesium.Cartesian3[]} positions 折线坐标数组@chancelai {number} distance 缓冲距离(米)@Returns {Cesium.Cartesian3[]} 缓冲区多边形坐标/function createBufferPolygon(positions, distance) {// 将Cartesian3坐标转换为经纬度数组const cartographics = positions.map(pos =>Cesium.Cartographic.fromCartesian(pos));// 存储左侧和右侧的点const leftPositions = [];const rightPositions = [];// 计算每个线段的缓冲区for (let i = 0; i < positions.length; i++) {let bearing;if (i === 0) {// 第一个点,使用第一个线段的方向bearing = calculateBearing(cartographics[i], cartographics[i + 1]);} else if (i === positions.length - 1) {// 最后一个点,使用最后一个线段的方向bearing = calculateBearing(cartographics[i - 1], cartographics[i]);} else {// 中间点,使用前后两个方向的平均值const bearing1 = calculateBearing(cartographics[i - 1], cartographics[i]);const bearing2 = calculateBearing(cartographics[i], cartographics[i + 1]);// 计算平均方向(处理角度环绕)bearing = Math.atan2((Math.sin(bearing1) + Math.sin(bearing2)) / 2,(Math.cos(bearing1) + Math.cos(bearing2)) / 2);}// 计算左右偏移点const left = calculateDestination(cartographics[i], bearing - Math.PI/2, distance);const right = calculateDestination(cartographics[i], bearing + Math.PI/2, distance);leftPositions.push(left);rightPositions.unshift(right); // 右侧点反向添加以便形成闭合环}// 合并左右点形成多边形环const bufferPositions = [...leftPositions, ...rightPositions];// 将Cartographic坐标转换回Cartesian3return new Cesium.PolygonHierarchy(bufferPositions.map(cartographic =>Cesium.Cartesian3.fromRadians(cartographic.longitude,cartographic.latitude,cartographic.height)));}/*计算两点之间的方位角(弧度)/function calculateBearing(start, end) {const lon1 = start.longitude;const lat1 = start.latitude;const lon2 = end.longitude;const lat2 = end.latitude;const dLon = lon2 - lon1;const y = Math.sin(dLon) * Math.cos(lat2);const x = Math.cos(lat1) * Math.sin(lat2) -Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);return Math.atan2(y, x);}/*计算从起点出发,沿指定方位角前进指定距离后的点*/function calculateDestination(start, bearing, distance) {const radius = 6378137; // 地球半径(米)const angularDistance = distance / radius;const lat1 = start.latitude;const lon1 = start.longitude;const lat2 = Math.asin(Math.sin(lat1) * Math.cos(angularDistance) +Math.cos(lat1) * Math.sin(angularDistance) * Math.cos(bearing));const lon2 = lon1 + Math.atan2(Math.sin(bearing) * Math.sin(angularDistance) * Math.cos(lat1),Math.cos(angularDistance) - Math.sin(lat1) * Math.sin(lat2));return new Cesium.Cartographic(lon2, lat2, start.height);}
效果: