Files
sdk4.0/src/Obj/Base/Road/index.js

387 lines
16 KiB
JavaScript
Raw Normal View History

2025-07-03 13:54:01 +08:00
import Base from "../index";
import PolylineImageTrailMaterialProperty from "../../Materail/PolylineImageTrailMaterialProperty";
class Corridor extends Base {
// /**
// * @constructor
// * @description 道路
2025-08-22 18:28:38 +08:00
// * @param sdk
2025-07-03 13:54:01 +08:00
// * @param options {object} 属性
// * @param options.name{string} 名称
// * @param options.image{string | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement} 指定 Image、URL、Canvas 或 Video 的属性
// * @param options.width=10{number} 宽度
// * @param options.height=0{number} 高度
// * */
constructor(sdk, options = {}) {
super(sdk, options);
this.options.name = options.name || ''
this.options.image = options.image
this.options.width = options.width || 10
this.options.height = options.height || 0
}
create(positions) {
this.computeRoad(positions)
let fromDegreesArray = []
for (let i = 0; i < positions.length; i++) {
fromDegreesArray.push(positions[i].lng, positions[i].lat)
}
2025-07-15 10:37:23 +08:00
let length = this.computeDistance2(positions)
2025-07-03 13:54:01 +08:00
let geometry = new Cesium.CorridorGeometry({
positions: Cesium.Cartesian3.fromDegreesArray(fromDegreesArray),
width: this.options.width,
height: this.options.height,
cornerType: Cesium.CornerType.MITERED,
vertexFormat: Cesium.MaterialAppearance.MaterialSupport.ALL.vertexFormat
})
// console.log(Cesium.CorridorGeometry.createGeometry(geometry))
// this.entity = this.sdk.viewer.scene.primitives.add(new Cesium.Primitive({//GroundPrimitive贴地
// geometryInstances: new Cesium.GeometryInstance({
// geometry: geometry,
// attributes: {
// color: Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 1.0, 1.0, 0.5))
// }
// }),
// appearance: new Cesium.MaterialAppearance({
// material: Cesium.Material.fromType('Image', {
// image: this.options.image,
// repeat: new Cesium.Cartesian2(length / this.options.width * 2, 1.0)
// }),
// faceForward: true,
// renderState: {
// blending: Cesium.BlendingState.ALPHA_BLEND
// }
// })
// }));
// console.log(this.entity, Outlinegeometry)
// this.entity = this.sdk.viewer.entities.add({
// name: "Red corridor on surface with rounded corners",
// corridor: {
// positions: Cesium.Cartesian3.fromDegreesArray(fromDegreesArray),
// width: this.options.width,
// height: 10,
// cornerType: Cesium.CornerType.MITERED,
// material: new Cesium.ImageMaterialProperty({
// image: this.options.image,
// repeat: new Cesium.Cartesian2(100, 1.0),
2025-08-22 18:28:38 +08:00
// color: Cesium.Color.TOMATO
2025-07-03 13:54:01 +08:00
// })
// }
// });
}
// 编辑框
async edit(state) { }
remove() {
this.sdk.viewer.scene.primitives.remove(this.entity)
this.entity = null
}
computeRoad(positions) {
let fromDegreesArray = []
for (let i = 0; i < positions.length; i++) {
fromDegreesArray.push(positions[i].lng, positions[i].lat)
}
let Outlinegeometry = new Cesium.CorridorGeometry({
positions: Cesium.Cartesian3.fromDegreesArray(fromDegreesArray),
width: this.options.width,
cornerType: Cesium.CornerType.MITERED,
vertexFormat: Cesium.MaterialAppearance.MaterialSupport.ALL.vertexFormat
})
let geometry = Cesium.CorridorGeometry.createGeometry(Outlinegeometry)
console.log(geometry)
let initposition = []
for (let i = 0; i < geometry.attributes.position.values.length; i += 3) {
console.log(geometry.attributes.position.values[i], geometry.attributes.position.values[i + 1], geometry.attributes.position.values[i + 2])
initposition.push(new Cesium.Cartesian3(geometry.attributes.position.values[i], geometry.attributes.position.values[i + 1], geometry.attributes.position.values[i + 2]))
}
console.log(initposition, Cesium.Cartesian3.fromDegrees(91.08567036051947, 24.990201656481236))
let flag = true
let bearing
this.entityArray = []
// 创建一个矩形实体,顶点坐标为世界坐标
const rectangle = this.sdk.viewer.entities.add({
rectangle: {
coordinates: Cesium.Rectangle.fromDegrees(-100.0, 20.0, -90.0, 30.0),
material: new Cesium.ImageMaterialProperty({
image: this.options.image,
repeat: new Cesium.Cartesian2(10, 1.0),
}),
},
});
for (let i = 0; i < geometry.indices.length; i += 3) {
// console.log(bearing)
let angleInDegrees
let theta
if (flag) {
let a = this.cartesian3Towgs84(initposition[geometry.indices[i]], this.sdk.viewer)
let b = this.cartesian3Towgs84(initposition[geometry.indices[i + 2]], this.sdk.viewer)
let point1 = turf.point([a.lng, a.lat]);
let point2 = turf.point([b.lng, b.lat]);
bearing = turf.bearing(point1, point2);
// 计算两点之间的角度
let angle = Cesium.Cartesian3.angleBetween(initposition[geometry.indices[i]], initposition[geometry.indices[i + 2]]);
// 转换角度为角度而不是弧度
angleInDegrees = Cesium.Math.toDegrees(angle)
//以a点为原点建立局部坐标系东方向为x轴,北方向为y轴,垂直于地面为z轴得到一个局部坐标到世界坐标转换的变换矩阵
let localToWorld_Matrix = Cesium.Transforms.eastNorthUpToFixedFrame(initposition[geometry.indices[i]]);
//求世界坐标到局部坐标的变换矩阵
let worldToLocal_Matrix = Cesium.Matrix4.inverse(localToWorld_Matrix, new Cesium.Matrix4());
//a点在局部坐标的位置其实就是局部坐标原点
let localPosition_A = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix, initposition[geometry.indices[i]], new Cesium.Cartesian3());
//B点在以A点为原点的局部的坐标位置
let localPosition_B = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix, initposition[geometry.indices[i + 2]], new Cesium.Cartesian3());
//弧度
let angle2 = Cesium.Math.fastApproximateAtan2((localPosition_B.y - localPosition_A.y), (localPosition_B.x - localPosition_A.x))
//角度
theta = angle2 * (180 / Cesium.Math.PI);
}
else {
let a = this.cartesian3Towgs84(initposition[geometry.indices[i + 1]], this.sdk.viewer)
let b = this.cartesian3Towgs84(initposition[geometry.indices[i + 2]], this.sdk.viewer)
let point1 = turf.point([a.lng, a.lat]);
let point2 = turf.point([b.lng, b.lat]);
bearing = turf.bearing(point1, point2);
// 计算两点之间的角度
let angle = Cesium.Cartesian3.angleBetween(initposition[geometry.indices[i + 1]], initposition[geometry.indices[i + 2]]);
// 转换角度为角度而不是弧度
angleInDegrees = Cesium.Math.toDegrees(angle)
//以a点为原点建立局部坐标系东方向为x轴,北方向为y轴,垂直于地面为z轴得到一个局部坐标到世界坐标转换的变换矩阵
let localToWorld_Matrix = Cesium.Transforms.eastNorthUpToFixedFrame(initposition[geometry.indices[i + 1]]);
//求世界坐标到局部坐标的变换矩阵
let worldToLocal_Matrix = Cesium.Matrix4.inverse(localToWorld_Matrix, new Cesium.Matrix4());
//a点在局部坐标的位置其实就是局部坐标原点
let localPosition_A = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix, initposition[geometry.indices[i + 1]], new Cesium.Cartesian3());
//B点在以A点为原点的局部的坐标位置
let localPosition_B = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix, initposition[geometry.indices[i + 2]], new Cesium.Cartesian3());
//弧度
let angle2 = Cesium.Math.fastApproximateAtan2((localPosition_B.y - localPosition_A.y), (localPosition_B.x - localPosition_A.x))
//角度
theta = angle2 * (180 / Cesium.Math.PI);
}
let point1 = Cesium.Cartesian3.fromDegrees(91, 24.990201656481236);
let point2 = Cesium.Cartesian3.fromDegrees(91, 24.626517401118033);
// 计算两点之间的角度
let angle = Cesium.Cartesian3.angleBetween(point1, point2);
// 转换角度为角度而不是弧度
let xx = Cesium.Math.toDegrees(angle)
flag = !flag
bearing = bearing - 90 + 0.145
console.log(bearing, angleInDegrees, angle, xx, theta)
//以a点为原点建立局部坐标系东方向为x轴,北方向为y轴,垂直于地面为z轴得到一个局部坐标到世界坐标转换的变换矩阵
let localToWorld_Matrix = Cesium.Transforms.eastNorthUpToFixedFrame(point1);
//求世界坐标到局部坐标的变换矩阵
let worldToLocal_Matrix = Cesium.Matrix4.inverse(localToWorld_Matrix, new Cesium.Matrix4());
//a点在局部坐标的位置其实就是局部坐标原点
let localPosition_A = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix, point1, new Cesium.Cartesian3());
//B点在以A点为原点的局部的坐标位置
let localPosition_B = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix, point2, new Cesium.Cartesian3());
//弧度
let angle2 = Cesium.Math.fastApproximateAtan2((localPosition_B.z - localPosition_A.z), (localPosition_B.x - localPosition_A.x))
//角度
let theta2 = angle2 * (180 / Cesium.Math.PI);
// alert(theta2)
// let entity = this.sdk.viewer.entities.add({
// show: this.options.show,
// polygon: {
// hierarchy: new Cesium.PolygonHierarchy([initposition[geometry.indices[i]], initposition[geometry.indices[i + 1]], initposition[geometry.indices[i + 2]]]),
// perPositionHeight: false,
// // material: new PolylineImageTrailMaterialProperty({
// // image: this.options.image,
// // repeat: new Cesium.Cartesian2(10, 1.0),
// // color: Cesium.Color.TOMATO,
// // rotate: 0
// // }),
// material: new Cesium.ImageMaterialProperty({
// image: this.options.image,
// repeat: new Cesium.Cartesian2(1000, 1.0),
// }),
// stRotation: Cesium.Math.toRadians(theta - 90 - 0.0128),
// outline: true,
// outlineColor: Cesium.Color.BLACK,
// }
// })
let aa = 0
const shader = `
2025-08-22 18:28:38 +08:00
uniform sampler2D image;
2025-07-03 13:54:01 +08:00
uniform vec4 color;
uniform vec2 repeat;
2025-08-22 18:28:38 +08:00
2025-07-03 13:54:01 +08:00
czm_material czm_getMaterial(czm_materialInput materialInput){
czm_material material=czm_getDefaultMaterial(materialInput);
mat2 rotationMatrix = mat2(cos(radians(-rotate)), sin(radians(-rotate)), -sin(radians(-rotate)), cos(radians(-rotate)));
vec2 st=repeat*materialInput.st*rotationMatrix;
float time=fract(czm_frameNumber);
vec4 colorImage=texture2D(image,vec2(fract(st.s-time),st.t));
material.alpha=colorImage.a;
material.diffuse=colorImage.rgb;
return material;
}`
console.log(Cesium.Math.toRadians(theta - 90))
let entity = this.sdk.viewer.scene.primitives.add(new Cesium.GroundPrimitive({
geometryInstances: new Cesium.GeometryInstance({
geometry: new Cesium.PolygonGeometry({
polygonHierarchy: new Cesium.PolygonHierarchy([initposition[geometry.indices[i]], initposition[geometry.indices[i + 1]], initposition[geometry.indices[i + 2]]]),
}),
}),
appearance: new Cesium.EllipsoidSurfaceAppearance({
aboveGroud: true,
material: new Cesium.Material({
fabric: {
uniforms: {
color: new Cesium.Color(1.0, 0.0, 0.0, 0.1),
image: this.options.image,
repeat: new Cesium.Cartesian2(1000, 1.0),
rotate: 0
},
source: shader
},
}),
}),
}));
// console.log(entity)
// let geometryInstances2 = new Cesium.GeometryInstance({
// geometry: new Cesium.PolygonGeometry({
// polygonHierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray([100, 1, 101, 1, 101, -1, 100, -1])),
// }),
// })
// let entity2 = this.sdk.viewer.scene.primitives.add(new Cesium.GroundPrimitive({
// geometryInstances: geometryInstances2,
// appearance: new Cesium.EllipsoidSurfaceAppearance({
// aboveGroud: true,
// material: new Cesium.Material({
// fabric: {
// uniforms: {
// color: new Cesium.Color(1.0, 0.0, 0.0, 0.1),
// image: this.options.image,
// repeat: new Cesium.Cartesian2(1000, 1.0),
// rotate: 0
// },
// source: shader
// },
// }),
// }),
// }));
// console.log(geometryInstances2)
// // 获取多边形的边界矩形
// let boundingSphere = geometryInstances2.geometry.boundingSphere;
// // 创建一个矩阵,它表示多边形的本地坐标到世界坐标的转换
// let matrix = Cesium.Transforms.eastNorthUpToFixedFrame(boundingSphere.center);
// console.log(entity2, matrix)
// setInterval(() => {
// }, 100);
this.entityArray.push(entity)
console.log(entity)
}
// let entity = this.sdk.viewer.entities.add({
// show: this.options.show,
// polygon: {
// hierarchy: new Cesium.PolygonHierarchy([
// new Cesium.Cartesian3(1201222.3498141132, 5794200.4246190665, 2372132.932514765),
// new Cesium.Cartesian3(1200929.6921250424, 5794615.962987943, 2371271.7244476764),
// new Cesium.Cartesian3(1199139.8791256004, 5794316.892300814, 2372896.7988495603)]),
// perPositionHeight: true,
// material: new PolylineImageTrailMaterialProperty({
// image: this.options.image,
// repeat: new Cesium.Cartesian2(10, 1.0),
// color: Cesium.Color.TOMATO,
// rotate: 0
// }),
// outline: true,
// outlineColor: Cesium.Color.BLACK,
// }
// })
// console.log(entity)
// 创建新材质
let newMaterial = new Cesium.Material({
fabric: {
type: 'Color',
uniforms: {
color: new Cesium.Color(1.0, 0.0, 0.0, 1.0) // 红色
}
}
});
console.log(newMaterial)
// this.entity = this.sdk.viewer.entities.add({
// show: this.options.show,
// polygon: {
// hierarchy: new Cesium.PolygonHierarchy(initposition),
// perPositionHeight: false,
// material: new Cesium.ImageMaterialProperty({
// image: this.options.image,
// repeat: new Cesium.Cartesian2(100, 1.0),
// color: Cesium.Color.AQUA
// })
// }
// })
for (let i = 0; i < initposition.length; i++) {
let entity = this.sdk.viewer.entities.add({
name: 'node-secondary-edit-point',
index: i,
position: initposition[i],
billboard: {
image: this.getSourceRootPath() + '/img/point.png',
width: 15,
height: 15,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
color: Cesium.Color.WHITE.withAlpha(0.99)
},
label: {
text: '' + i,
pixelOffset: { x: 0, y: -20 },
},
})
}
this.sdk.viewer.entities.add({
name: 'node-secondary-edit-point',
position: Cesium.Cartesian3.fromDegrees(91.08567036051947, 24.990201656481236),
billboard: {
image: this.getSourceRootPath() + '/img/point.png',
width: 15,
height: 15,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
color: Cesium.Color.WHITE.withAlpha(0.99)
},
})
this.sdk.viewer.entities.add({
name: 'node-secondary-edit-point',
position: Cesium.Cartesian3.fromDegrees(91.08588488854294, 24.626517401118033),
billboard: {
image: this.getSourceRootPath() + '/img/point.png',
width: 15,
height: 15,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
color: Cesium.Color.WHITE.withAlpha(0.99)
},
})
}
test(v) {
for (let i = 0; i < this.entityArray.length; i++) {
this.entityArray[i].polygon.stRotation = Cesium.Math.toRadians(v)
}
}
}
export default Corridor