control/heightRuler/HeightRulerScene.tstypescript
import { Entity } from "../../entity/Entity";
import { LonLat } from "../../LonLat";
import { Object3d } from "../../Object3d";
import { RulerScene, type IRulerSceneParams } from "../ruler/RulerScene";
import { Vector } from "../../layer/Vector";
import { Vec3 } from "../../math/Vec3";
import type { ILabelParams } from "../../entity/label/Label";
import type { IRayParams } from "../../entity/ray/Ray";
let obj3d = Object3d.createCylinder(0.33, 0, 1.0, 20, 1, true, false, 0, 0, 0);
const RAYS_OPTIONS: IRayParams = {
startColor: "rgb(255,131,0)",
endColor: "rgb(255,131,0)",
thickness: 5
};
const LABEL_OPTIONS: ILabelParams = {
text: "",
size: 11,
color: "rgba(255,255,255,1.0)",
outlineColor: "rgba(0,0,0,1)",
outline: 2,
align: "left",
offset: [10, 18]
};
const RULER_CORNER_OPTIONS = {
scale: 1,
instanced: true,
tag: "height-ruler",
color: "rgb(0,205,0)",
object3d: obj3d
};
interface IHeightRulerSceneParams extends IRulerSceneParams {}
class HeightRulerScene extends RulerScene {
protected _geoRulerLayer: Vector;
protected _heightLabels: Entity[];
protected _rayH: Entity;
protected _rayV: Entity;
constructor(options: IHeightRulerSceneParams = {}) {
super(options);
this._geoRulerLayer = new Vector("rayHeightRuler", {
entities: [],
pickingEnabled: false,
depthOffset: -5.0,
relativeToGround: false,
hideInLayerSwitcher: true
});
this._rayV = new Entity({
name: "verticalRay",
ray: RAYS_OPTIONS
});
this._rayH = new Entity({
name: "heightRay",
ray: RAYS_OPTIONS
});
this._heightLabels = [
new Entity({
name: "startCornerLabel",
label: {
...LABEL_OPTIONS
}
}),
new Entity({
name: "endCornerLabel",
label: {
...LABEL_OPTIONS
}
}),
new Entity({
name: "deltaLabel",
label: {
...LABEL_OPTIONS
}
})
];
}
public override setVisibility(visibility: boolean) {
super.setVisibility(visibility);
this._geoRulerLayer.setVisibility(visibility);
}
public get deltaLabel(): Entity {
return this._heightLabels[2];
}
public get startLabel(): Entity {
return this._heightLabels[0];
}
public get endLabel(): Entity {
return this._heightLabels[1];
}
public get corners(): Entity[] {
return this._cornerEntity;
}
public get startCorner(): Entity {
return this.corners[0];
}
public get endCorner(): Entity {
return this.corners[1];
}
public get startCornerLonLat(): LonLat {
return this.startCorner.getLonLat();
}
public get startCornerHeight(): number {
return this.startCornerLonLat.height;
}
public get endCornerLonLat(): LonLat {
return this.endCorner.getLonLat();
}
public get endCornerHeight(): number {
return this.endCornerLonLat.height;
}
public get maxHeightCornerLonLat(): LonLat {
if (this.startCornerHeight <= this.endCornerHeight) {
return this.endCornerLonLat;
} else {
return this.startCornerLonLat;
}
}
public get minHeightCornerLonLat(): LonLat {
if (this.startCornerHeight > this.endCornerHeight) {
return this.endCornerLonLat;
} else {
return this.startCornerLonLat;
}
}
public get deltaHeight(): number {
return Math.abs(this.startCornerHeight - this.endCornerHeight);
}
public override _drawLine(startLonLat: LonLat, endLonLat: LonLat, startPos?: Vec3) {
super._drawLine(startLonLat, endLonLat, startPos);
this._updateHeightRaysAndLabels();
}
protected async _updateHeightRaysAndLabels() {
const middleLonLat = this.minHeightCornerLonLat.clone();
middleLonLat.height = this.maxHeightCornerLonLat.height;
this._rayH.ray!.setStartPosition3v(this._planet!.ellipsoid.lonLatToCartesian(this.maxHeightCornerLonLat));
this._rayH.ray!.setEndPosition3v(this._planet!.ellipsoid.lonLatToCartesian(middleLonLat));
this._rayV.ray!.setStartPosition3v(this._planet!.ellipsoid.lonLatToCartesian(this.minHeightCornerLonLat));
this._rayV.ray!.setEndPosition3v(this._planet!.ellipsoid.lonLatToCartesian(middleLonLat));
middleLonLat.height = this.minHeightCornerLonLat.height + this.deltaHeight / 2;
this.deltaLabel.setLonLat(middleLonLat);
this.startLabel.setLonLat(this.startCornerLonLat);
this.endLabel.setLonLat(this.endCornerLonLat);
const startHeight = await this._planet!.getHeightDefault(this.startCornerLonLat),
endHeight = await this._planet!.getHeightDefault(this.endCornerLonLat);
this.deltaLabel.label!.setText(`\u0394 ${Math.abs(startHeight - endHeight).toFixed(1)} m`);
this.startLabel.label!.setText(`P1 ${startHeight.toFixed(1)} m`);
this.endLabel.label!.setText(`P2 ${endHeight.toFixed(1)} m`);
}
public override clear() {
this._rayH.remove();
this._rayV.remove();
this.startCorner.remove();
this.endCorner.remove();
this.startLabel.remove();
this.endLabel.remove();
this.deltaLabel.remove();
super.clear();
// this._rayH = null;
// this._rayV = null;
this._planet!.removeLayer(this._geoRulerLayer);
}
public override _createCorners() {
this._cornerEntity = [
new Entity({
geoObject: RULER_CORNER_OPTIONS,
properties: {
name: "start"
}
}),
new Entity({
geoObject: RULER_CORNER_OPTIONS,
properties: {
name: "end"
}
})
];
this._cornersLayer.setEntities(this._cornerEntity);
}
public override init() {
super.init();
this._createCorners();
this._labelLayer.addEntities(this._heightLabels);
this._geoRulerLayer.addEntities([this._rayH, this._rayV]);
this._planet!.addLayer(this._geoRulerLayer);
this.renderer!.events.on("forwardpass", this._onForwardpassHeight, this);
}
public override onremove() {
this.renderer?.events.off("forwardpass", this._onForwardpassHeight);
super.onremove();
}
protected _onForwardpassHeight = () => {
this._updateHeightRaysAndLabels();
};
}
export { HeightRulerScene };