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

1705 lines
63 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.positionChangeIndex = []
this.sdk.addIncetance(this.options.id, this)
// Road.create(this)
const myImg = new Image()
myImg.src = this.options.roadImage
myImg.onload = () => {
console.log('加载完成')
this.createCorridor(myImg, this.options.positions)
}
}
// 创建走廊几何体
createCorridor(myImg, posis) {
let posiArr = []
posis.forEach(item => {
posiArr.push(item.lng, item.lat)
})
console.log(posiArr, 'posiArr')
const positions = Cesium.Cartesian3.fromDegreesArray(posiArr);
const corridorInstance = new Cesium.GeometryInstance({
geometry: new Cesium.CorridorGeometry({
positions: positions,
width: this.options.carRoadWidth,
vertexFormat: Cesium.VertexFormat.POSITION_AND_ST,
cornerType: Cesium.CornerType.MITERED,
extrudedHeight: 10.0
}),
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.WHITE)
}
});
const primitive = new Cesium.Primitive({
geometryInstances: corridorInstance,
appearance: new Cesium.MaterialAppearance({
material: new Cesium.Material({
fabric: {
type: 'Image',
uniforms: {
image: myImg
}
}
}),
translucent: false
}),
asynchronous: false
});
this.sdk.viewer.scene.primitives.add(primitive);
// 定位到走廊
// this.sdk.viewer.camera.flyTo({
// destination: Cesium.Cartesian3.fromDegrees(103.70271877620554, 41.95279346036913, 100),
// // orientation: {
// // heading: Cesium.Math.toRadians(0),
// // pitch: Cesium.Math.toRadians(-30),
// // roll: 0.0
// // }
// });
return primitive;
}
// 横断面计算函数
computeCrossSection(width, slope) {
const halfWidth = width / 2;
return [
new Cesium.Cartesian2(-halfWidth, 0),
new Cesium.Cartesian2(-halfWidth, -slope * 10),
new Cesium.Cartesian2(halfWidth, -slope * 10),
new Cesium.Cartesian2(halfWidth, 0)
];
}
computeST(geometry) {
// 安全校验:确保几何体包含位置属性
if (!geometry.attributes.position) {
throw new Error('Geometry must contain position attribute');
}
const positions = geometry.attributes.position.values;
const vertexCount = positions.length / 3;
const st = new Float32Array(vertexCount * 2);
// 计算UV坐标改进版
for (let i = 0; i < vertexCount; i++) {
const vertexIndex = i * 3;
const uvIndex = i * 2;
// 根据顶点在横截面中的位置计算V坐标
const isTopVertex = positions[vertexIndex + 2] > 0; // Z坐标判断顶面/底面
st[uvIndex + 1] = isTopVertex ? 1 : 0;
// 根据路径比例计算U坐标自动适应不同路段长度
const pathProgress = i % 4; // 每4个顶点为一个横截面
st[uvIndex] = (Math.floor(i / 4) + pathProgress / 4) / (vertexCount / 4) * 10;
}
return st;
}
// 创建道路
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
// 1. 定义道路中心线路径WGS84坐标
const roadPath = [start, end];
// 3. 计算纹理坐标(确保贴图沿道路方向连续)
console.log(roadPath, 'roadPath')
// 4. 创建道路几何体
const roadGeometry = new Cesium.PolylineVolumeGeometry({
polylinePositions: roadPath,
shapePositions: that.computeCrossSection(20, 0.5),
vertexFormat: Cesium.VertexFormat.POSITION_AND_ST,
cornerType: Cesium.CornerType.ROUNDED
});
console.log('kkkkk')
// 5. 使用Primitive渲染带贴图的道路
const roadPrimitive = that.viewer.scene.primitives.add(
new Cesium.Primitive({
geometryInstances: new Cesium.GeometryInstance({
geometry: roadGeometry,
attributes: {
st: new Cesium.GeometryAttribute({
componentDatatype: Cesium.ComponentDatatype.FLOAT,
componentsPerAttribute: 2,
values: (function () {
if (!roadGeometry.attributes.position) {
console.error('Road geometry lacks position data');
return new Float32Array(0);
}
return that.computeST(roadGeometry);
})()
})
}
}),
appearance: new Cesium.MaterialAppearance({
material: new Cesium.Material({
fabric: {
type: 'Image',
uniforms: {
image: that.options.roadImage, // 沥青纹理示例
repeat: new Cesium.Cartesian2(1, 1)
}
},
translucent: false
}),
faceForward: false // 确保双面渲染
})
})
);
}
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])
// // that.sdk.viewer.entities.add({
// // polyline: {
// // positions: [leftItem[2], leftItem[3]],
// // width: 2.0,
// // clampToGround: true,
// // material: new Cesium.PolylineGlowMaterialProperty({
// // color: Cesium.Color.YELLOW,
// // }),
// // },
// // });
// // that.sdk.viewer.entities.add({
// // polyline: {
// // positions: [leftItem2[2], leftItem2[3]],
// // width: 2.0,
// // clampToGround: true,
// // material: new Cesium.PolylineGlowMaterialProperty({
// // color: Cesium.Color.YELLOW,
// // }),
// // },
// // });
// let rightLine = that.getIntersects(rightItem[0], rightItem[1], rightItem2[0], rightItem2[1])
// // if (!leftLine && !rightLine) {
// // for (let index = 0; index < 4; index++) {
// // let positions = []
// // index === 0 ? positions.push(leftItem[2], leftItem[3]) : index === 1 ? positions.push(leftItem2[2], leftItem2[3]) : index === 2 ? positions.push(rightItem[0], rightItem[1]) : positions.push(rightItem2[0], rightItem2[1])
// // that.sdk.viewer.entities.add({
// // polyline: {
// // positions: positions,
// // width: 2.0,
// // clampToGround: true,
// // material: new Cesium.PolylineGlowMaterialProperty({
// // color: index === 0 ? Cesium.Color.RED : index === 1 ? Cesium.Color.BLUE : index === 2 ? Cesium.Color.YELLOW : Cesium.Color.GREEN,
// // }),
// // },
// // });
// // }
// // }
// for (let index = 0; index < 4; index++) {
// // that.sdk.viewer.entities.add({
// // name: 'node-secondary-edit-point',
// // index: index,
// // position: area[0][i][index],
// // 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 },
// // },
// // })
// // that.sdk.viewer.entities.add({
// // name: 'node-secondary-edit-point',
// // index: index,
// // position: area[2][i][index],
// // 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 },
// // },
// // })
// }
// if (leftLine) {//左侧相交
// // that.sdk.viewer.entities.add({
// // name: 'node-secondary-edit-point',
// // index: 1,
// // position: leftLine,
// // billboard: {
// // image: that.getSourceRootPath() + '/img/locate2.png',
// // width: 15,
// // height: 15,
// // disableDepthTestDistance: Number.POSITIVE_INFINITY,
// // color: Cesium.Color.WHITE.withAlpha(0.99)
// // },
// // label: {
// // text: '',
// // pixelOffset: { x: 0, y: -20 },
// // },
// // })
// //获取右侧延长交点
// let point1 = that.getExtendPoint(rightItem[0], rightItem[1], 1000)
// let point2 = that.getExtendPoint(rightItem2[1], rightItem2[0], 1000)
// that.sdk.viewer.entities.add({
// polyline: {
// positions: [rightItem[0], point1],
// width: 2.0,
// clampToGround: true,
// material: new Cesium.PolylineGlowMaterialProperty({
// color: Cesium.Color.AQUA,
// }),
// },
// });
// that.sdk.viewer.entities.add({
// polyline: {
// positions: [rightItem2[1], point2],
// width: 2.0,
// clampToGround: true,
// material: new Cesium.PolylineGlowMaterialProperty({
// color: Cesium.Color.AQUA,
// }),
// },
// });
// that.sdk.viewer.entities.add({
// name: 'node-secondary-edit-point',
// index: i,
// position: point1,
// billboard: {
// image: that.getSourceRootPath() + '/img/point.png',
// width: 15,
// height: 15,
// disableDepthTestDistance: Number.POSITIVE_INFINITY,
// color: Cesium.Color.WHITE.withAlpha(0.99)
// },
// label: {
// text: '' + 7 + "",
// pixelOffset: { x: 0, y: -20 },
// },
// })
// that.sdk.viewer.entities.add({
// name: 'node-secondary-edit-point',
// index: i,
// position: point2,
// billboard: {
// image: that.getSourceRootPath() + '/img/end.png',
// width: 15,
// height: 15,
// disableDepthTestDistance: Number.POSITIVE_INFINITY,
// color: Cesium.Color.WHITE.withAlpha(0.99)
// },
// label: {
// text: '' + 7 + "",
// pixelOffset: { x: 0, y: -20 },
// },
// })
// let rightIntersection = that.getIntersects(rightItem[0], point1, rightItem2[1], 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(leftLine, rightIntersection, leftItem[0], leftLineNeiPoint)
// //跟车道左侧相交点
// 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)
// // 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[2] = leftLineNei
// // carItem[1] = carRight
// carItem[1] = rightLineNei
// rightItem[2] = rightLineNei
// rightItem[1] = rightIntersection
// // that.sdk.viewer.entities.add({
// // name: 'node-secondary-edit-point',
// // index: 1,
// // position: leftLineNei,
// // billboard: {
// // image: that.getSourceRootPath() + '/img/locate2.png',
// // width: 15,
// // height: 15,
// // disableDepthTestDistance: Number.POSITIVE_INFINITY,
// // color: Cesium.Color.WHITE.withAlpha(0.99)
// // },
// // label: {
// // text: '',
// // pixelOffset: { x: 0, y: -20 },
// // },
// // })
// that.sdk.viewer.entities.add({
// name: 'node-secondary-edit-point',
// index: 1,
// position: rightIntersection,
// billboard: {
// image: that.getSourceRootPath() + '/img/locate2.png',
// width: 15,
// height: 15,
// disableDepthTestDistance: Number.POSITIVE_INFINITY,
// color: Cesium.Color.WHITE.withAlpha(0.99)
// },
// label: {
// text: '',
// pixelOffset: { x: 0, y: -20 },
// },
// })
// //将其他几条边都延长
// 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[3] = leftLineNei
// // carItem2[0] = carRight
// carItem2[0] = rightLineNei
// rightItem2[3] = rightLineNei
// rightItem2[0] = rightIntersection
// } else if (rightLine) {//右侧相交
// //获取左侧延长交点
// let point1 = that.getExtendPoint(leftItem[3], leftItem[2], 1000)
// let point2 = that.getExtendPoint(leftItem2[2], leftItem2[3], 1000)
// that.sdk.viewer.entities.add({
// polyline: {
// positions: [leftItem[3], point1],
// width: 2.0,
// clampToGround: true,
// material: new Cesium.PolylineGlowMaterialProperty({
// color: Cesium.Color.AQUA,
// }),
// },
// });
// that.sdk.viewer.entities.add({
// polyline: {
// positions: [leftItem2[2], point2],
// width: 2.0,
// clampToGround: true,
// material: new Cesium.PolylineGlowMaterialProperty({
// color: Cesium.Color.AQUA,
// }),
// },
// });
// 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[2] = leftLineNei
// // carItem[1] = carRight
// carItem[1] = rightLineNei
// rightItem[2] = rightLineNei
// rightItem[1] = rightLine
// //将其他几条边都延长
// 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[3] = leftLineNei
// // carItem2[0] = carRight
// carItem2[0] = rightLineNei
// rightItem2[3] = rightLineNei
// rightItem2[0] = rightLine
// // leftItem[2] = rightIntersection
// // leftItem[1] = leftLineNei
// // // carItem[2] = carLeft
// // carItem[2] = leftLineNei
// // // carItem[1] = carRight
// // carItem[1] = rightLineNei
// // rightItem[2] = rightLineNei
// // rightItem[1] = rightLine
// }
// // area[0][i] = leftItem
// // area[0][i + 1] = leftItem2
// // area[2][i] = rightItem
// // area[2][i + 1] = rightItem2
// // area[1][0][i] = carItem
// // area[1][0][i + 1] = carItem2
// }
// 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 () {
// area[1][0].forEach((item, index) => {
// // that.viewer.entities.add({
// // // id: that.options.id,
// // parent: that.lineEntity,
// // polygon: {
// // hierarchy: new Cesium.PolygonHierarchy(item),
// // heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
// // classificationType: Cesium.ClassificationType.BOTH,
// // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 10000),
// // material: new Cesium.ImageMaterialProperty({
// // image: that.options.roadImage,
// // transparent: true,// 如果图片有透明部分,需要设置为 true
// // repeat: that.calculateTextureRepeat(item, myImg)
// // }),
// // // stRotation: that.calculateRoadAngle(positions[index], positions[index + 1])
// // stRotation: that.calculateRoadAngle(item[0], item[1])
// // // material: Cesium.Color.fromRandom({ alpha: 0.5 }),
// // }
// // });
// })
// }
// const myImg2 = new Image()
// myImg2.src = that.options.sideImage
// myImg2.onload = function () {
// 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])
// // material: Cesium.Color.fromRandom({ alpha: 0.5 }),
// }
// });
// })
// area[2].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])
// // material: Cesium.Color.fromRandom({ alpha: 0.5 }),
// }
// });
// })
// }
}
getSideRectangle(positions, width) {
let right = []
let left = []
let that = this
positions.forEach((item, i) => {
// console.log(that.positionChangeIndex, 'positionChangeIndex')
// if (that.positionChangeIndex[i + '']) {
// console.log('1111')
// right.push([item[2], item[3]])
// left.push([item[0], item[1]])
// } else {
right.push([item[0], item[1]])
// left.push([item[2], item[3]])
left.push([item[3], item[2]])
// }
for (let index = 0; index < 2; index++) {
let ArrArr = []
index === 0 ? ArrArr.push(item[0], item[1]) : ArrArr.push(item[2], item[3]);
// that.sdk.viewer.entities.add({
// polyline: {
// positions: ArrArr,
// width: 2.0,
// clampToGround: true,
// material: new Cesium.PolylineGlowMaterialProperty({
// color: index === 0 ? Cesium.Color.RED : Cesium.Color.BLUE,
// }),
// },
// });
}
})
let rightPosi = that.getRectangle(right, width, 'side')
let newRightPosi = []
right.forEach((item, index) => {
newRightPosi.push([rightPosi[index][0], rightPosi[index][1], item[1], item[0]])
})
let leftPosi = this.getRectangle(left, width, 'side')
let newLeftPosi = []
left.forEach((item, index) => {
// newLeftPosi.push([item[0], item[1], leftPosi[index][2]], leftPosi[index][3])
newLeftPosi.push([item[0], item[1], leftPosi[index][2], leftPosi[index][3]])
})
return { left: newLeftPosi, right: newRightPosi }
}
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)) {//调整方向
// let newArr = []
// newArr[0] = arr[2]
// newArr[1] = arr[3]
// newArr[2] = arr[0]
// newArr[3] = arr[1]
// newPositions.push(newArr)
//判断方向是否正确
const vec1 = Cesium.Cartesian3.normalize(
Cesium.Cartesian3.subtract(start, arr[0], new Cesium.Cartesian3()),
new Cesium.Cartesian3()
);
// 计算并归一化第二个向量
const vec2 = Cesium.Cartesian3.normalize(
Cesium.Cartesian3.subtract(arr[1], arr[0], new Cesium.Cartesian3()),
new Cesium.Cartesian3()
);
let dRst = Cesium.Cartesian3.dot(vec1, vec2);
if (0 < dRst && dRst < 0.0001) {
newPositions.push(arr)
} else {
let dis1 = that.distancePointToLine(start, arr[0], arr[1])
let dis2 = that.distancePointToLine(start, arr[2], arr[3])
let newArr = []
if (dis1 > dis2) {//
newArr[0] = arr[3]
newArr[1] = arr[0]
newArr[2] = arr[1]
newArr[3] = arr[2]
} else {
newArr[0] = arr[2]
newArr[1] = arr[3]
newArr[2] = arr[0]
newArr[3] = arr[1]
}
newPositions.push(newArr)
// let newArr = []
// newArr[0] = arr[2]
// newArr[1] = arr[3]
// newArr[2] = arr[0]
// newArr[3] = arr[1]
// newPositions.push(newArr)
}
// newPositions.push(arr)
if (!type) {
for (let index = 0; index < 4; index++) {
that.sdk.viewer.entities.add({
name: 'node-secondary-edit-point',
index: index,
position: arr[index],
billboard: {
image: this.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 },
},
})
}
}
} else {
let dis1 = that.distancePointToLine(that.pointArr[i][0], arr[0], arr[1])
let dis2 = that.distancePointToLine(that.pointArr[i][0], arr[2], arr[3])
let newArr = []
if (dis1 > dis2) {
newArr[0] = arr[3]
newArr[1] = arr[0]
newArr[2] = arr[1]
newArr[3] = arr[2]
} else {
newArr[0] = arr[1]
newArr[1] = arr[2]
newArr[2] = arr[3]
newArr[3] = arr[0]
}
newPositions.push(newArr)
if (!type) {
for (let index = 0; index < 4; index++) {
that.sdk.viewer.entities.add({
name: 'node-secondary-edit-point',
index: index,
// position: newArr[index],
position: newArr[index],
billboard: {
image: this.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 },
},
})
}
}
// !type && that.positionChangeIndex.push(i + "")
}
// }
// 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
}
distancePointToLine(p, a, b) {
let ab = new Cesium.Cartesian3();
Cesium.Cartesian3.subtract(b, a, ab);
let ap = new Cesium.Cartesian3();
Cesium.Cartesian3.subtract(p, a, ap);
let abNormalized = new Cesium.Cartesian3();
Cesium.Cartesian3.normalize(ab, abNormalized);
let apProjectionMagnitude = Cesium.Cartesian3.dot(ap, abNormalized);
let apProjection = Cesium.Cartesian3.multiplyByScalar(abNormalized, apProjectionMagnitude, new Cesium.Cartesian3());
let footPoint = new Cesium.Cartesian3();
Cesium.Cartesian3.add(a, apProjection, footPoint);
return Cesium.Cartesian3.distance(p, footPoint);
}
getExtendPoint2(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
}
getExtendPoint3(pos1, pos2, distance) {
const geodesic = new Cesium.EllipsoidGeodesic();
geodesic.setEndPoints(pos1, pos2);
// 关键步骤:获取实际测地距离
const actualDist = geodesic.surfaceDistance;
const ratio = Math.max(1.1, distance / actualDist); // 强制外延比例
// 基于地理坐标的弧度插值
const carto1 = Cesium.Cartographic.fromCartesian(pos1);
const carto2 = Cesium.Cartographic.fromCartesian(pos2);
const resultCarto = new Cesium.Cartographic(
carto1.longitude + (carto2.longitude - carto1.longitude) * ratio,
carto1.latitude + (carto2.latitude - carto1.latitude) * ratio,
0
);
return Cesium.Cartesian3.fromRadians(
resultCarto.longitude,
resultCarto.latitude
);
}
getExtendPoint(position1, position2, distance) {
// 1. 向量计算与归一化
const direction = Cesium.Cartesian3.subtract(
position2,
position1,
new Cesium.Cartesian3()
);
Cesium.Cartesian3.normalize(direction, direction);
// 2. 使用Ellipsoid修正地球曲率影响
const ellipsoid = Cesium.Ellipsoid.WGS84;
const geodesic = new Cesium.EllipsoidGeodesic();
geodesic.setEndPoints(position1, position2);
const actualDistance = geodesic.surfaceDistance; // 获取实际测地距离
if (distance <= actualDistance) distance = actualDistance * 100; // 强制向外延伸
// 3. 考虑椭球面曲率的精确延长
const surfaceNormal = ellipsoid.geodeticSurfaceNormal(position1);
const projection = Cesium.Cartesian3.multiplyByScalar(
surfaceNormal,
Cesium.Cartesian3.dot(direction, surfaceNormal),
new Cesium.Cartesian3()
);
Cesium.Cartesian3.subtract(direction, projection, direction);
Cesium.Cartesian3.normalize(direction, direction);
// 4. 最终坐标计算
return Cesium.Cartesian3.add(
position2,
Cesium.Cartesian3.multiplyByScalar(direction, distance, new Cesium.Cartesian3()),
new Cesium.Cartesian3()
);
}
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)
return result;
}
calculateRoadAngle3(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;
}
calculateRoadAngle(startPoint, endPoint) {
// 1. 获取精确地形法向量(需配合地形服务使用)
const normal = Cesium.Ellipsoid.WGS84.geodeticSurfaceNormal(startPoint);
// 2. 构建ENU坐标系增加异常处理
if (!Cesium.defined(startPoint) || !Cesium.defined(endPoint)) {
return 0;
}
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());
// 4. 使用三维向量计算角度(保留高程信息)
const north3D = new Cesium.Cartesian3(1, 0, 0);
const direction3D = new Cesium.Cartesian3(
localEnd.x, localEnd.y, localEnd.z);
Cesium.Cartesian3.normalize(direction3D, direction3D);
// 5. 计算带符号角度(考虑三维空间关系)
const angle = Cesium.Cartesian3.angleBetween(
north3D, direction3D);
const cross = Cesium.Cartesian3.cross(
north3D, direction3D, new Cesium.Cartesian3());
// 6. 返回带符号角度Z轴分量为负则取反
return cross.z < 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');
}
let widthDis = Cesium.Cartesian3.distance(polygonPositions[0], polygonPositions[1])
let heightDis = Cesium.Cartesian3.distance(polygonPositions[0], polygonPositions[3])
// 计算纹理实际尺寸(米)
// const textureWidthMeters = textureSize.width * meterPerPixel;
// const textureHeightMeters = textureSize.height * meterPerPixel;
const textureWidthMeters = textureSize.width;
const textureHeightMeters = textureSize.height;
console.log(textureWidthMeters, textureHeightMeters, widthDis, heightDis, '宽度')
// 保持宽高比计算重复次数
const repeatX = widthDis / textureWidthMeters;
const repeatY = heightDis / textureHeightMeters;
const aspectRatio = textureWidthMeters / textureHeightMeters;
console.log(aspectRatio, 'aspectRatio')
// 选择主导轴并保持比例
const dominantRepeat = Math.max(repeatX, repeatY);
let x = Math.max(1, Math.ceil(widthDis / (aspectRatio * heightDis)))
console.log(x, '10')
return new Cesium.Cartesian2(
x,
1
);
}
calculateTextureRepeat2(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]])
// }
let that = this
// return [arr, rightPositions, leftPositions]
return [area, rightPositions, leftPositions]
}
getIntersects2(segment1Start, segment1End, segment2Start, segment2End) {
// 构造平面使用线段2的起点和方向向量
let direction = Cesium.Cartesian3.subtract(segment2End, segment2Start, new Cesium.Cartesian3());
let plane = Cesium.Plane.fromPointNormal(segment2Start, direction);
// 计算线段1与平面的交点增加容差参数
let intersection = Cesium.IntersectionTests.lineSegmentPlane(
segment1Start, segment1End, plane, 1e-10
);
if (!intersection) return null;
// 使用参数方程验证交点有效性
let vecToIntersect = Cesium.Cartesian3.subtract(intersection, segment2Start, new Cesium.Cartesian3());
let t = Cesium.Cartesian3.dot(vecToIntersect, direction) /
Cesium.Cartesian3.magnitudeSquared(direction);
let result = (t >= -1e-10 && t <= 1.0 + 1e-10) ? intersection : null;
return result;
}
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