Files
sdk4.0/src/Obj/Base/RoadObject/index-面大小一致.js
2025-08-22 18:28:38 +08:00

1024 lines
39 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.

/**
* @description 道路
*/
import Dialog from '../../Element/Dialog';
import { html } from "./_element";
import EventBinding from '../../Element/Dialog/eventBinding';
import Base from "../index";
import { syncData } from '../../../Global/MultiViewportMode'
import { setSplitDirection, syncSplitData, setActiveId } from '../../../Global/SplitScreen'
import { setActiveViewer, closeRotateAround, closeViewFollow } from '../../../Global/global'
class Road extends Base {
/**
* @constructor
* @param sdk
* @description 道路
* @param options {object} 道路属性
* @param options.name=未命名对象 {string} 名称
* @param options.carRoadWidth=2 {number} 车道宽度
* @param options.sideWidth=2 {number} 人行道宽度
* @param options.positions=[] {array} 道路positions
* @param options.roadImage='' {string} 车道贴图
* @param options.sideImage='' {string} 人行道贴图
* @param Dialog {object} 弹框对象
* @param Dialog.confirmCallBack {function} 弹框确认时的回调
* */
constructor(sdk, options = {}, _Dialog = {}) {
super(sdk, options);
this.viewer = this.sdk.viewer
this.options.name = options.name || '道路'
this.options.carRoadWidth = options.carRoadWidth || 10
this.options.sideWidth = options.sideWidth || 5
this.options.positions = options.positions || []
this.options.roadImage = options.roadImage || (this.getSourceRootPath() + '/img/roadPhoto.png')
this.options.sideImage = options.sideImage || (this.getSourceRootPath() + '/img/sidePhoto.png')
this.options.show = (options.show || options.show === false) ? options.show : true
this.Dialog = _Dialog
this._EventBinding = new EventBinding()
this._elms = {};
this.positionArea = []
this.positions = []
this.lineEntity = ''
this.crossArr = []
this.pointArr = []
this.sdk.addIncetance(this.options.id, this)
Road.create(this)
}
// 创建道路
static create(that) {
let positions = []
that.options.positions.forEach(v => {
positions.push(new Cesium.Cartesian3.fromDegrees(v.lng, v.lat, v.alt))
})
let newPosi = []
for (let i = 0; i < positions.length - 1; i++) {
const start = positions[i];
const end = positions[i + 1];
newPosi.push([start, end])
that.pointArr = newPosi
}
let area = [[], [], []]
// area[1] = that.getRectangle(positions, that.options.carRoadWidth)
area[1][0] = that.getRectangle(newPosi, that.options.carRoadWidth)
let sideArr = that.getSideRectangle(area[1][0], that.options.sideWidth)
area[0] = sideArr.left
area[2] = sideArr.right
// area[1] = that.createLineBufferPolygon2(positions, that.options.carRoadWidth / 2)
// area[1] = newPositions
// area[0] = that.createLineBufferPolygonSide(area[1][2], -that.options.sideWidth)
// area[2] = that.createLineBufferPolygonSide(area[1][1], that.options.sideWidth)
//判断道路边是否相交
for (let i = 0; i < area[0].length - 1; i++) {
let leftItem = area[0][i]
let leftItem2 = area[0][i + 1]
let rightItem = area[2][i]
let rightItem2 = area[2][i + 1]
let carItem = area[1][0][i]
let carItem2 = area[1][0][i + 1]
let leftLine = that.getIntersects(leftItem[2], leftItem[3], leftItem2[2], leftItem2[3])
let rightLine = that.getIntersects(rightItem[0], rightItem[1], rightItem2[0], rightItem2[1])
console.log(leftLine, rightLine, 'leftLine')
if (leftLine) {//左侧相交
//获取右侧延长交点
let point1 = that.getExtendPoint(rightItem[0], rightItem[1], 1000)
let point2 = that.getExtendPoint(rightItem2[1], rightItem2[0], 1000)
console.log('aaaa')
let rightIntersection = that.getIntersects(rightItem[0], point1, rightItem2[1], point2)
//将其他几条边都延长
let leftLineNeiPoint = that.getExtendPoint(leftItem[0], leftItem[1], 1000)
let carLeftPoint = that.getExtendPoint(carItem[3], carItem[2], 1000)
let carRightPoint = that.getExtendPoint(carItem[0], carItem[1], 1000)
let rightLineNeiPoint = that.getExtendPoint(rightItem[3], rightItem[2], 1000)
console.log(leftLine, rightIntersection, leftItem[0], leftLineNeiPoint, 'bbbb')
//跟左侧里相交点
let leftLineNei = that.getIntersects(leftLine, rightIntersection, leftItem[0], leftLineNeiPoint)
console.log(leftLineNei, 'leftLineNei')
//跟车道左侧相交点
let carLeft = that.getIntersects(leftLine, rightIntersection, carItem[3], carLeftPoint)
//跟车道右侧相交点
let carRight = that.getIntersects(leftLine, rightIntersection, carItem[0], carRightPoint)
let rightLineNei = that.getIntersects(leftLine, rightIntersection, rightItem[3], rightLineNeiPoint)
console.log('ccc')
// let leftLineNei = that.getIntersects(leftLine, rightItem[2], leftItem[0], leftItem[3])
// let carLeft = that.getIntersects(leftLine, rightItem[2], carItem[3], carItem[2])
// let carRight = that.getIntersects(leftLine, rightItem[2], carItem[0], carItem[1])
// let rightLineNei = that.getIntersects(leftLine, rightItem[2], rightItem[0], rightItem[3])
// let leftLineNei = that.getIntersects(leftLine, intersection, leftItem[0], leftItem[3])
// //跟车道左侧相交点
// let carLeft = that.getIntersects(leftLine, intersection, carItem[3], carItem[2])
// //跟车道右侧相交点
// let carRight = that.getIntersects(leftLine, intersection, carItem[0], carItem[1])
// let rightLineNei = that.getIntersects(leftLine, intersection, rightItem[0], rightItem[3])
leftItem[2] = leftLine
leftItem[1] = leftLineNei
carItem[2] = carLeft
carItem[1] = carRight
rightItem[2] = rightLineNei
rightItem[1] = rightIntersection
console.log(leftItem, carItem, rightItem, 'leftItemleft')
//将其他几条边都延长
let leftLineNeiPoint2 = that.getExtendPoint(leftItem2[1], leftItem2[0], 1000)
let carLeftPoint2 = that.getExtendPoint(carItem2[2], carItem2[3], 1000)
let carRightPoint2 = that.getExtendPoint(carItem2[1], carItem2[0], 1000)
let rightLineNeiPoint2 = that.getExtendPoint(rightItem2[2], rightItem2[3], 1000)
// let leftLineNei2 = that.getIntersects(leftLine, rightItem2[1], leftItem2[0], leftItem2[3])
// let carLeft2 = that.getIntersects(leftLine, rightItem2[1], carItem2[3], carItem2[2])
// let carRight2 = that.getIntersects(leftLine, rightItem2[1], carItem2[0], carItem2[1])
// let rightLineNei2 = that.getIntersects(leftLine, rightItem2[1], rightItem2[0], rightItem2[3])
let leftLineNei2 = that.getIntersects(leftLine, rightIntersection, leftItem2[1], leftLineNeiPoint2)
let carLeft2 = that.getIntersects(leftLine, rightIntersection, carItem2[2], carLeftPoint2)
let carRight2 = that.getIntersects(leftLine, rightIntersection, carItem2[1], carRightPoint2)
let rightLineNei2 = that.getIntersects(leftLine, rightIntersection, rightItem2[2], rightLineNeiPoint2)
// let arr = [leftLine, rightIntersection, leftItem2[3], leftLineNeiPoint2]
// arr.forEach((item, index) => {
// that.sdk.viewer.entities.add({
// name: 'node-secondary-edit-point',
// index: i,
// position: item,
// billboard: {
// image: that.getSourceRootPath() + '/img/point.png',
// width: 15,
// height: 15,
// disableDepthTestDistance: Number.POSITIVE_INFINITY,
// color: Cesium.Color.WHITE.withAlpha(0.99)
// },
// label: {
// text: '' + index,
// pixelOffset: { x: 0, y: -20 },
// },
// })
// })
// let leftLineNei2 = that.getIntersects(leftLine, intersection, leftItem2[0], leftItem2[3])
// //跟车道左侧相交点
// let carLeft2 = that.getIntersects(leftLine, intersection, carItem2[3], carItem2[2])
// //跟车道右侧相交点
// let carRight2 = that.getIntersects(leftLine, intersection, carItem2[0], carItem2[1])
// let rightLineNei2 = that.getIntersects(leftLine, intersection, rightItem2[0], rightItem2[3])
leftItem2[3] = leftLine
leftItem2[0] = leftLineNei
carItem2[3] = carLeft
carItem2[0] = carRight
rightItem2[3] = rightLineNei
rightItem2[0] = rightIntersection
console.log(leftItem2, carItem2, rightItem2, 'leftItem2left')
} else if (rightLine) {//右侧相交
//获取左侧延长交点
let point1 = that.getExtendPoint(leftItem[3], leftItem[2], 1000)
let point2 = that.getExtendPoint(leftItem2[2], leftItem2[3], 1000)
let rightIntersection = that.getIntersects(leftItem[3], point1, leftItem2[2], point2)
if (!rightIntersection) {
return
}
//将其他几条边都延长
let leftLineNeiPoint = that.getExtendPoint(leftItem[0], leftItem[1], 1000)
let carLeftPoint = that.getExtendPoint(carItem[3], carItem[2], 1000)
let carRightPoint = that.getExtendPoint(carItem[0], carItem[1], 1000)
let rightLineNeiPoint = that.getExtendPoint(rightItem[3], rightItem[2], 1000)
// //跟左侧里相交点
let leftLineNei = that.getIntersects(rightLine, rightIntersection, leftItem[0], leftLineNeiPoint)
//跟车道左侧相交点
let carLeft = that.getIntersects(rightLine, rightIntersection, carItem[3], carLeftPoint)
//跟车道右侧相交点
let carRight = that.getIntersects(rightLine, rightIntersection, carItem[0], carRightPoint)
let rightLineNei = that.getIntersects(rightLine, rightIntersection, rightItem[3], rightLineNeiPoint)
// //跟左侧里相交点
// let leftLineNei = that.getIntersects(rightLine, leftItem[2], leftItem[0], leftItem[3])
// //跟车道左侧相交点
// let carLeft = that.getIntersects(rightLine, leftItem[2], carItem[3], carItem[2])
// //跟车道右侧相交点
// let carRight = that.getIntersects(rightLine, leftItem[2], carItem[0], carItem[1])
// let rightLineNei = that.getIntersects(rightLine, leftItem[2], rightItem[0], rightItem[3])
leftItem[2] = rightIntersection
leftItem[1] = leftLineNei
carItem[2] = carLeft
carItem[1] = carRight
rightItem[2] = rightLineNei
rightItem[1] = rightLine
console.log(leftItem, carItem, rightItem, 'leftItemright')
//将其他几条边都延长
let leftLineNeiPoint2 = that.getExtendPoint(leftItem2[2], leftItem2[3], 1000)
let carLeftPoint2 = that.getExtendPoint(carItem2[2], carItem2[3], 1000)
let carRightPoint2 = that.getExtendPoint(carItem2[1], carItem2[0], 1000)
let rightLineNeiPoint2 = that.getExtendPoint(rightItem2[2], rightItem2[3], 1000)
let leftLineNei2 = that.getIntersects(rightLine, rightIntersection, leftItem2[1], leftLineNeiPoint2)
//跟车道左侧相交点
let carLeft2 = that.getIntersects(rightLine, rightIntersection, carItem2[2], carLeftPoint2)
//跟车道右侧相交点
let carRight2 = that.getIntersects(rightLine, rightIntersection, carItem2[1], carRightPoint2)
let rightLineNei2 = that.getIntersects(rightLine, rightIntersection, rightItem2[2], rightLineNeiPoint2)
// let leftLineNei2 = that.getIntersects(rightLine, leftItem2[1], leftItem2[0], leftItem2[3])
// //跟车道左侧相交点
// let carLeft2 = that.getIntersects(rightLine, leftItem2[1], carItem2[3], carItem2[2])
// //跟车道右侧相交点
// let carRight2 = that.getIntersects(rightLine, leftItem2[1], carItem2[0], carItem2[1])
// let rightLineNei2 = that.getIntersects(rightLine, leftItem2[1], rightItem2[0], rightItem2[3])
leftItem2[3] = rightIntersection
leftItem2[0] = leftLineNei
carItem2[3] = carLeft
carItem2[0] = carRight
rightItem2[3] = rightLineNei
rightItem2[0] = rightLine
console.log(leftItem2, carItem2, rightItem2, 'leftItem2right')
}
}
if (that.viewer.entities.getById(that.options.id)) {
that.viewer.entities.getById(that.options.id)._children.forEach((item) => {
that.viewer.entities.remove(item);
});
that.viewer.entities.remove(that.viewer.entities.getById(that.options.id))
}
that.lineEntity = that.viewer.entities.add(new Cesium.Entity({ id: that.options.id, show: that.options.show }))
const myImg = new Image()
myImg.src = that.options.roadImage
myImg.onload = function () {
console.log(area[1][0], that.options.roadImage, 'llll')
area[1][0].forEach((item, index) => {
that.viewer.entities.add({
// id: that.options.id,
parent: that.lineEntity,
polygon: {
hierarchy: new Cesium.PolygonHierarchy(item),
material: new Cesium.ImageMaterialProperty({
image: that.options.roadImage,
transparent: true,// 如果图片有透明部分,需要设置为 true
repeat: that.calculateTextureRepeat(item, myImg)
}),
stRotation: that.calculateRoadAngle(positions[index], positions[index + 1])
}
});
})
}
const myImg2 = new Image()
myImg2.src = that.options.sideImage
myImg2.onload = function () {
// area[0].forEach((item, index) => {
area[0].forEach((item, index) => {
that.viewer.entities.add({
parent: that.lineEntity,
polygon: {
hierarchy: new Cesium.PolygonHierarchy(item),
material: new Cesium.ImageMaterialProperty({
image: that.options.sideImage,
transparent: true,// 如果图片有透明部分,需要设置为 true
repeat: that.calculateTextureRepeat(item, myImg2)
}),
stRotation: that.calculateRoadAngle(positions[index], positions[index + 1])
}
});
})
// area[2].forEach((item, index) => {
area[2].forEach((item, index) => {
that.viewer.entities.add({
polygon: {
hierarchy: new Cesium.PolygonHierarchy(item),
material: new Cesium.ImageMaterialProperty({
image: that.options.sideImage,
transparent: true,// 如果图片有透明部分,需要设置为 true
repeat: that.calculateTextureRepeat(item, myImg2)
}),
stRotation: that.calculateRoadAngle(positions[index], positions[index + 1])
}
});
})
}
}
getSideRectangle(positions, width) {
let right = []
let left = []
let that = this
positions.forEach(item => {
right.push([item[0], item[1]])
left.push([item[2], item[3]])
})
let rightPosi = that.getRectangle(right, width, 'side')
let leftPosi = this.getRectangle(left, width, 'side')
return { left: leftPosi, right: rightPosi }
}
getRectangle(positions, width, type) {
let areaArr = []
let newPositions = []
let that = this
// for (let i = 0; i < positions.length - 1; i++) {
for (let i = 0; i < positions.length; i++) {
const start = positions[i][0];
const end = positions[i][1];
areaArr[i] = []
let posi = []
let Outlinegeometry = new Cesium.CorridorGeometry({
positions: [start, end],
width: width,
cornerType: Cesium.CornerType.MITERED,
vertexFormat: Cesium.MaterialAppearance.MaterialSupport.ALL.vertexFormat
})
let geometry = Cesium.CorridorGeometry.createGeometry(Outlinegeometry)
for (let j = 0; j < geometry.attributes.position.values.length; j += 3) {
let val = that.cartesian3Towgs84(new Cesium.Cartesian3(geometry.attributes.position.values[j], geometry.attributes.position.values[j + 1], geometry.attributes.position.values[j + 2]), that.sdk.viewer)
posi.push([val.lng, val.lat])
}
for (let x = 0; x < geometry.indices.length; x += 3) {
areaArr[i].push(turf.polygon([[posi[geometry.indices[x]], posi[geometry.indices[x + 1]], posi[geometry.indices[x + 2]], posi[geometry.indices[x]]]]))
}
let geojson = turf.union(areaArr[i][0], areaArr[i][1]);
let arr = []
geojson.geometry.coordinates[0].pop()
geojson.geometry.coordinates[0].forEach(item => {
arr.push(new Cesium.Cartesian3.fromDegrees(item[0], item[1]))
})
let dotResult, angle
const tempVec = new Cesium.Cartesian3();
// 计算并归一化第一个向量
const vector1 = Cesium.Cartesian3.normalize(
Cesium.Cartesian3.subtract(that.pointArr[i][1], that.pointArr[i][0], tempVec),
tempVec
);
// 计算并归一化第二个向量
const vector2 = Cesium.Cartesian3.normalize(
Cesium.Cartesian3.subtract(arr[1], arr[0], new Cesium.Cartesian3()),
new Cesium.Cartesian3()
);
dotResult = Cesium.Cartesian3.dot(vector1, vector2);
if ((0.999 < dotResult && dotResult < 1.001) || (-0.999 > dotResult && dotResult > -1.001)) {//调整方向
newPositions.push(arr)
} else {
let newArr = []
newArr[0] = arr[1]
newArr[1] = arr[2]
newArr[2] = arr[3]
newArr[3] = arr[0]
newPositions.push(newArr)
}
// }
// if (!type) {
// // if (cross > 0 && !type) {//调整方向
// if ((0.999 < dotResult && dotResult < 1.001) || (-0.999 > dotResult && dotResult > -1.001)) {//调整方向
// newPositions.push(arr)
// } else {
// let newArr = []
// newArr[0] = arr[1]
// newArr[1] = arr[2]
// newArr[2] = arr[3]
// newArr[3] = arr[0]
// newPositions.push(newArr)
// }
// } else {
// newPositions.push(arr)
// }
}
return newPositions
}
getExtendPoint(position1, position2, distance) {
// let position1 = Cesium.Cartesian3.fromDegrees(p1[0], p1[1], 0);
// let position2 = Cesium.Cartesian3.fromDegrees(p2[0], p2[1], 0);
let pot = Cesium.Cartesian3.subtract(position2, position1, new Cesium.Cartesian3());//方向
var dir = Cesium.Cartesian3.normalize(pot, new Cesium.Cartesian3());//向量归一化
var ray = new Cesium.Ray(position1, dir);
let np = Cesium.Ray.getPoint(ray, distance * 10);//计算延长点
return np
}
getArr(arr1, arr2) {
arr2 = arr2.reverse()
let polygon = []
for (let index = 0; index < arr1.length - 1; index++) {
polygon.push([arr1[index], arr1[index + 1], arr2[index + 1], arr2[index]])
}
return polygon
}
calculateRoadAngle2(startPoint, endPoint) {
// 1. 获取地表法向量
const normal = this.sdk.viewer.scene.globe.ellipsoid.geodeticSurfaceNormal(
startPoint, new Cesium.Cartesian3());
// 2. 构建带椭球参数的ENU矩阵
const enuMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(
startPoint, this.sdk.viewer.scene.globe.ellipsoid, normal);
const inverseMatrix = Cesium.Matrix4.inverse(
enuMatrix, new Cesium.Matrix4());
// 3. 转换坐标并计算相对向量
const localEnd = Cesium.Matrix4.multiplyByPoint(
inverseMatrix, endPoint, new Cesium.Cartesian3());
const heightFactor = Math.abs(localEnd.z) / 1000; // 高度差补偿
// 4. 使用四象限反正切计算角度
const angle = Math.atan2(localEnd.y, localEnd.x);
const adjustedAngle = angle - (heightFactor * 0.01); // 高度补偿
let result = Cesium.Math.toDegrees(adjustedAngle)
console.log(result, 'result')
return result;
}
calculateRoadAngle(startPoint, endPoint) {
// 1. 获取地表法向量
const normal = Cesium.Ellipsoid.WGS84.geodeticSurfaceNormal(startPoint);
// 2. 构建精确ENU坐标系
const enuMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(startPoint, undefined, normal);
const inverseMatrix = Cesium.Matrix4.inverse(enuMatrix, new Cesium.Matrix4());
// 3. 转换终点并计算水平向量
const localEnd = Cesium.Matrix4.multiplyByPoint(inverseMatrix, endPoint, new Cesium.Cartesian3());
const horizontalVec = new Cesium.Cartesian2(localEnd.x, localEnd.y);
Cesium.Cartesian2.normalize(horizontalVec, horizontalVec);
const north = new Cesium.Cartesian2(1, 0);
const angle = Cesium.Cartesian2.angleBetween(north, horizontalVec);
const cross = Cesium.Cartesian2.cross(north, horizontalVec, new Cesium.Cartesian2());
return cross < 0 ? angle : -angle;
}
calculatePolygonOrientation(positions) {
// 假设 position 是 Cesium.Cartesian3 对象,表示地球上的某个点
var position = positions[0]
// 获取东、北、上坐标系
var eastNorthUp = Cesium.Transforms.eastNorthUpToFixedFrame(position);
// northAxis 是北方向向量
var northAxis = eastNorthUp.getColumn(1, new Cesium.Cartesian3());
Cesium.Cartesian3.normalize(northAxis, northAxis);
const direction = Cesium.Cartesian3.subtract(positions[0], positions[1], new Cesium.Cartesian3());
Cesium.Cartesian3.normalize(direction, direction);
const dot = Cesium.Cartesian3.dot(northAxis, direction);
const magA = Cesium.Cartesian3.magnitude(northAxis);
const magB = Cesium.Cartesian3.magnitude(direction);
return Math.acos(dot / (magA * magB));
}
calculateTextureRepeat(polygonPositions, textureSize, meterPerPixel = 0.01) {
// 验证纹理尺寸
if (!textureSize.width || !textureSize.height) {
throw new Error('Texture size must contain width and height in pixels');
}
// 创建多边形几何体
const geometry = Cesium.PolygonGeometry.createGeometry(
new Cesium.PolygonGeometry({
polygonHierarchy: new Cesium.PolygonHierarchy(polygonPositions),
vertexFormat: Cesium.VertexFormat.POSITION_ONLY
})
);
// 计算多边形面积(平方米)
let area = 0;
const indices = geometry.indices;
const positions = geometry.attributes.position.values;
for (let i = 0; i < indices.length; i += 3) {
const i0 = indices[i] * 3;
const i1 = indices[i + 1] * 3;
const i2 = indices[i + 2] * 3;
const p0 = new Cesium.Cartesian3(positions[i0], positions[i0 + 1], positions[i0 + 2]);
const p1 = new Cesium.Cartesian3(positions[i1], positions[i1 + 1], positions[i1 + 2]);
const p2 = new Cesium.Cartesian3(positions[i2], positions[i2 + 1], positions[i2 + 2]);
const cross = Cesium.Cartesian3.cross(
Cesium.Cartesian3.subtract(p1, p0, new Cesium.Cartesian3()),
Cesium.Cartesian3.subtract(p2, p0, new Cesium.Cartesian3()),
new Cesium.Cartesian3()
);
area += Cesium.Cartesian3.magnitude(cross) * 0.5;
}
// 将像素尺寸转换为实际尺寸(平方米)
const textureWidthMeters = textureSize.width * meterPerPixel;
const textureHeightMeters = textureSize.height * meterPerPixel;
const textureArea = textureWidthMeters * textureHeightMeters;
// 计算各轴向重复次数
const repeatX = Math.sqrt(area) / textureWidthMeters;
const repeatY = Math.sqrt(area) / textureHeightMeters;
return new Cesium.Cartesian2(Math.max(1, Math.ceil(repeatX)), 1.0);
}
swapLastElements(arr1, arr2) {
const last = arr1[arr1.length - 1]
const first = arr2[0]
arr1[arr1.length - 1] = first
arr2[0] = last
return [arr1, arr2];
}
createLineBufferPolygonSide(positions, width) {
let area = []
for (let i = 0; i < positions.length; i++) {
const posi = positions[i];
const dir = Cesium.Cartesian3.subtract(posi[1], posi[0], new Cesium.Cartesian3());
Cesium.Cartesian3.normalize(dir, dir);
// 获取垂直向量基于Z轴
const perp = Cesium.Cartesian3.cross(dir, Cesium.Cartesian3.UNIT_Z, new Cesium.Cartesian3());
Cesium.Cartesian3.normalize(perp, perp);
// 生成偏移向量
const offset = Cesium.Cartesian3.multiplyByScalar(perp, width, new Cesium.Cartesian3());
let point1 = Cesium.Cartesian3.add(posi[0], offset, new Cesium.Cartesian3())
let point3 = Cesium.Cartesian3.add(posi[1], offset, new Cesium.Cartesian3())
// i == positions.length - 2 ? area.push(start, point1, end, point3) : area.push(start, point1)
area.push([posi[0], point1, point3, posi[1]])
}
// let arr = []
// for (let i = 0; i < area.length - 2; i += 2) {
// arr.push([area[i], area[i + 1], area[i + 3], area[i + 2]])
// }
return area
}
createLineBufferPolygon2(positions, width) {
let area = []
let leftPositions = [];
let rightPositions = [];
for (let i = 0; i < positions.length - 1; i++) {
const start = positions[i];
// const end = positions[i + 1] || positions[i - 1];
const end = positions[i + 1];
const dir = Cesium.Cartesian3.subtract(end, start, new Cesium.Cartesian3());
Cesium.Cartesian3.normalize(dir, dir);
// 获取垂直向量基于Z轴
const perp = Cesium.Cartesian3.cross(dir, Cesium.Cartesian3.UNIT_Z, new Cesium.Cartesian3());
Cesium.Cartesian3.normalize(perp, perp);
const dir2 = Cesium.Cartesian3.subtract(start, end, new Cesium.Cartesian3());
Cesium.Cartesian3.normalize(dir2, dir2);
// 获取垂直向量基于Z轴
const perp2 = Cesium.Cartesian3.cross(dir2, Cesium.Cartesian3.UNIT_Z, new Cesium.Cartesian3());
Cesium.Cartesian3.normalize(perp2, perp2);
// 生成偏移向量
const offset = Cesium.Cartesian3.multiplyByScalar(perp, width, new Cesium.Cartesian3());
const offset2 = Cesium.Cartesian3.multiplyByScalar(perp, -width, new Cesium.Cartesian3());
const offsetEnd = Cesium.Cartesian3.multiplyByScalar(perp2, -width, new Cesium.Cartesian3());
const offsetEnd2 = Cesium.Cartesian3.multiplyByScalar(perp2, width, new Cesium.Cartesian3());
let point1 = Cesium.Cartesian3.add(start, offset, new Cesium.Cartesian3())
let point2 = Cesium.Cartesian3.add(start, offset2, new Cesium.Cartesian3())
let point3 = Cesium.Cartesian3.add(end, offsetEnd, new Cesium.Cartesian3())
let point4 = Cesium.Cartesian3.add(end, offsetEnd2, new Cesium.Cartesian3())
area.push([point1, point3, point4, point2])
rightPositions.push([point1, point3])
leftPositions.push([point2, point4])
// if (i == positions.length - 2) {
// area.push(point1, point2, point3, point4)
// rightPositions.push(point1)
// leftPositions.push(point2)
// leftPositions.push(point4)
// rightPositions.push(point3)
// } else {
// area.push(point1, point2)
// rightPositions.push(point1)
// leftPositions.push(point2)
// }
}
// let arr = []
// for (let i = 0; i < area.length - 2; i += 2) {
// arr.push([area[i], area[i + 1], area[i + 3], area[i + 2]])
// }
console.log(area, rightPositions, 'rightPositions')
let that = this
// return [arr, rightPositions, leftPositions]
return [area, rightPositions, leftPositions]
}
getIntersects(point1, point2, point3, point4) {
let carPoint1 = this.getLonLat(point1)
let carPoint2 = this.getLonLat(point2)
let carPoint3 = this.getLonLat(point3)
let carPoint4 = this.getLonLat(point4)
var line1 = turf.lineString([
[carPoint1.lon, carPoint1.lat],
[carPoint2.lon, carPoint2.lat]
]);
var line2 = turf.lineString([
[carPoint3.lon, carPoint3.lat],
[carPoint4.lon, carPoint4.lat]
]);
var intersects = turf.lineIntersect(line1, line2);
if (intersects.features.length > 0) {
return Cesium.Cartesian3.fromDegrees(intersects.features[0].geometry.coordinates[0], intersects.features[0].geometry.coordinates[1])
}
}
getLonLat(point) {
let pointDe = Cesium.Cartographic.fromCartesian(point)
const longitude = Cesium.Math.toDegrees(pointDe.longitude);
const latitude = Cesium.Math.toDegrees(pointDe.latitude);
return { lon: longitude, lat: latitude }
}
createLineBufferPolygon(viewer, positions, width) {
// 计算每个线段的左右偏移点
const leftPositions = [];
const rightPositions = [];
for (let i = 0; i < positions.length; i++) {
const start = positions[i];
const end = positions[i + 1] || positions[i - 1];
// 计算线段方向向量
const direction = Cesium.Cartesian3.subtract(end, start, new Cesium.Cartesian3());
// const direction = Cesium.Cartesian3.subtract(start, end, new Cesium.Cartesian3());
Cesium.Cartesian3.normalize(direction, direction);
// 计算垂直向量(使用上向量叉积)
const up = Cesium.Cartesian3.UNIT_Z;
const perpendicular = Cesium.Cartesian3.cross(direction, up, new Cesium.Cartesian3());
Cesium.Cartesian3.normalize(perpendicular, perpendicular);
// 计算左右偏移点
const leftOffset = Cesium.Cartesian3.multiplyByScalar(
perpendicular,
width,
new Cesium.Cartesian3()
);
if (width > 0) {
rightPositions.unshift(Cesium.Cartesian3.add(start, leftOffset, new Cesium.Cartesian3()));
} else if (width < 0) {
rightPositions.push(Cesium.Cartesian3.add(start, leftOffset, new Cesium.Cartesian3()));
}
}
return rightPositions
}
//计算角度
calculateAangle(arr) {
// let fromDegreesArray = that.calSector(that.options.center, that.options.radius, that.options.startAngle, that.options.endAngle, 360, true)
function getAangle(start, end) {
let rad = Math.PI / 180,
lat1 = start.y * rad,
lat2 = end.y * rad,
lon1 = start.x * rad,
lon2 = end.x * rad;
const a = Math.sin(lon2 - lon1) * Math.cos(lat2);
const b =
Math.cos(lat1) * Math.sin(lat2) -
Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1);
const radians = Math.atan2(a, b)
const degrees = radians % (2 * Math.PI);
let bearing = 450 - ((degrees * 180) / Math.PI < 0
? 360 + (degrees * 180) / Math.PI
: (degrees * 180) / Math.PI) - 90;
return 360 - (bearing % 360)
}
let center = arr[0]
let pos84_1 = arr[1]
let pos84_2 = arr[2]
let start = { x: center.lng, y: center.lat }
let end1 = { x: pos84_1.lng, y: pos84_1.lat }
let end2 = { x: pos84_2.lng, y: pos84_2.lat }
let angle1 = getAangle(start, end1)
let angle2 = getAangle(start, end2)
return {
angle1,
angle2
}
}
get carRoadWidth() {
return this.options.carRoadWidth
}
set carRoadWidth(v) {
this.options.carRoadWidth = v
Road.create(this)
}
get sideWidth() {
return this.options.sideWidth
}
set sideWidth(v) {
this.options.sideWidth = v
Road.create(this)
}
/**
* @description 编辑框
* @param state=false {boolean} 状态: true打开, false关闭
*/
async edit(state = false) {
let _this = this
this.originalOptions = this.deepCopyObj(this.options)
if (this._DialogObject && this._DialogObject.close) {
this._DialogObject.close()
this._DialogObject = null
}
if (state) {
this._DialogObject = await new Dialog(this.sdk, this.originalOptions, {
title: '道路属性', left: '180px', top: '100px',
confirmCallBack: (options) => {
this.name = this.name.trim()
if (!this.name) {
this.name = '道路'
}
this.originalOptions = this.deepCopyObj(this.options)
this._DialogObject.close()
this.Dialog.confirmCallBack && this.Dialog.confirmCallBack(this.originalOptions)
syncData(this.sdk, this.options.id)
syncSplitData(this.sdk, this.options.id)
},
resetCallBack: () => {
this.reset()
this.Dialog.resetCallBack && this.Dialog.resetCallBack()
},
closeCallBack: () => {
this.reset()
this.Dialog.closeCallBack && this.Dialog.closeCallBack()
},
showCallBack: (show) => {
this.show = show
this.Dialog.showCallBack && this.Dialog.showCallBack()
}
}, true)
this._DialogObject._element.body.className = this._DialogObject._element.body.className + ' road-surface'
let contentElm = document.createElement('div');
contentElm.innerHTML = html()
this._DialogObject.contentAppChild(contentElm)
// 下拉选项
// let heightModeData = [
// {
// name: '海拔高度',
// value: '海拔高度',
// key: '0',
// },
// {
// name: '相对地表',
// value: '相对地表',
// key: '1',
// },
// {
// name: '依附模型',
// value: '依附模型',
// key: '2',
// }
// ]
// let heightModeObject = legp(
// this._DialogObject._element.content.getElementsByClassName(
// 'road-box'
// )[0],
// '.road-type'
// )
// if (heightModeObject) {
// heightModeObject.legp_search(heightModeData)
// let heightModeDataLegpElm = this._DialogObject._element.content
// .getElementsByClassName('road-type')[0]
// .getElementsByTagName('input')[0]
// for (let i = 0; i < heightModeData.length; i++) {
// if (heightModeData[i].key == this.heightMode) {
// heightModeDataLegpElm.value = heightModeData[i].value
// heightModeObject.legp_searchActive(
// heightModeData[i].value
// )
// break
// }
// }
// heightModeDataLegpElm.addEventListener('input', () => {
// for (let i = 0; i < heightModeData.length; i++) {
// if (heightModeData[i].value === heightModeDataLegpElm.value) {
// this.heightMode = heightModeData[i].key
// break
// }
// }
// })
// this._elms.height = heightElm
// this._elms.heightBox = heightBoxElm
// this._elms.heightMode = heightModeDataLegpElm
// this._elms.heightConfirm = heightConfirmElm
// this._elms.heightModeObject = heightModeObject
// heightConfirmElm.addEventListener('click', () => {
// this.positionEditing = false
// for (let i = 0; i < this.options.positions.length; i++) {
// this.options.positions[i].alt = Number((this.options.positions[i].alt + Number(heightElm.value)).toFixed(2))
// this._elms.alt[i].innerHTML = this.options.positions[i].alt
// }
// let fromDegreesArray = this.renewPositions(this.options.positions)
// this.entity.polyline.positions = Cesium.Cartesian3.fromDegreesArrayHeights(
// fromDegreesArray
// )
// this.positionEditing = false
// PolylineObject.closeNodeEdit(this)
// })
// }
let all_elm = contentElm.getElementsByTagName("*")
this._EventBinding.on(this, all_elm)
this._elms = this._EventBinding.element
} else {
// if (this._element_style) {
// document.getElementsByTagName('head')[0].removeChild(this._element_style)
// this._element_style = null
// }
// if (this._DialogObject && this._DialogObject.remove) {
// this._DialogObject.remove()
// this._DialogObject = null
// }
}
}
reset() {
if (!this.viewer.entities.getById(this.options.id)) {
return
}
this.name = this.originalOptions.name
this.carRoadWidth = this.originalOptions.carRoadWidth
this.sideWidth = this.originalOptions.sideWidth
this.positions = this.originalOptions.positions
this.roadImage = this.originalOptions.roadImage
this.sideImage = this.originalOptions.sideImage
}
/**
* 飞到对应实体
*/
async flyTo(options = {}) {
setActiveViewer(0)
closeRotateAround(this.sdk)
closeViewFollow(this.sdk)
if (this.options.customView && this.options.customView.relativePosition && this.options.customView.orientation) {
let orientation = {
heading: Cesium.Math.toRadians(this.options.customView.orientation.heading || 0.0),
pitch: Cesium.Math.toRadians(this.options.customView.orientation.pitch || -60.0),
roll: Cesium.Math.toRadians(this.options.customView.orientation.roll || 0.0)
}
let lng = this.options.customView.relativePosition.lng
let lat = this.options.customView.relativePosition.lat
let alt = this.options.customView.relativePosition.alt
let destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt)
let position = { lng: 0, lat: 0 }
if (this.options.position) {
position = { ...this.options.position }
}
else if (this.options.positions) {
position = { ...this.options.positions[0] }
}
else if (this.options.center) {
position = { ...this.options.center }
}
else if (this.options.start) {
position = { ...this.options.start }
}
else {
if (this.options.hasOwnProperty('lng')) {
position.lng = this.options.lng
}
if (this.options.hasOwnProperty('lat')) {
position.lat = this.options.lat
}
if (this.options.hasOwnProperty('alt')) {
position.alt = this.options.alt
}
}
// 如果没有高度值,则获取紧贴高度计算
// if (!position.hasOwnProperty('alt')) {
// position.alt = await this.getClampToHeight(position)
// }
lng = this.options.customView.relativePosition.lng + position.lng
lat = this.options.customView.relativePosition.lat + position.lat
alt = this.options.customView.relativePosition.alt + position.alt
destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt)
this.sdk.viewer.camera.flyTo({
destination: destination,
orientation: orientation
})
}
else {
let positionArray = []
for (let i = 0; i < this.positions.length; i++) {
let a = Cesium.Cartesian3.fromDegrees(
this.positions[i][0],
this.positions[i][1],
this.options.height + this.options.heightDifference / 2
)
positionArray.push(a.x, a.y, a.z)
}
let BoundingSphere = Cesium.BoundingSphere.fromVertices(positionArray)
this.viewer.camera.flyToBoundingSphere(BoundingSphere, {
offset: {
heading: Cesium.Math.toRadians(0.0),
pitch: Cesium.Math.toRadians(-20.0),
roll: Cesium.Math.toRadians(0.0)
}
})
}
}
getSphere() {
return new Promise((resolve) => {
// entity没有加载完成时 state 不会等于0 所以设置定时器直到获取到为止
const interval = setInterval(() => {
const sphere = new Cesium.BoundingSphere()
const state = this.sdk.viewer._dataSourceDisplay.getBoundingSphere(
this.viewer.entities.getById(this.options.id),
false,
sphere
)
if (state === Cesium.BoundingSphereState.DONE) {
clearInterval(interval)
}
}, 1000)
})
}
/**
* 删除
*/
async remove() {
this.positions = []
this.lineEntity = null
if (this.viewer.entities.getById(this.options.id)) {
this.viewer.entities.getById(this.options.id)._children.forEach((item) => {
this.viewer.entities.remove(item);
});
this.viewer.entities.remove(this.viewer.entities.getById(this.options.id))
}
if (this._DialogObject && !this._DialogObject.isDestroy) {
this._DialogObject.close()
this._DialogObject = null
}
await this.sdk.removeIncetance(this.options.id)
await syncData(this.sdk, this.options.id)
}
flicker() { }
}
export default Road