Files
sdk4.0/src/Obj/Base/Road/index.js
2025-08-22 18:28:38 +08:00

387 lines
16 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Base from "../index";
import PolylineImageTrailMaterialProperty from "../../Materail/PolylineImageTrailMaterialProperty";
class Corridor extends Base {
// /**
// * @constructor
// * @description 道路
// * @param sdk
// * @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)
}
let length = this.computeDistance2(positions)
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),
// color: Cesium.Color.TOMATO
// })
// }
// });
}
// 编辑框
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 = `
uniform sampler2D image;
uniform vec4 color;
uniform vec2 repeat;
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