Skip to content

Commit

Permalink
refinements
Browse files Browse the repository at this point in the history
  • Loading branch information
vladyslav-tk committed Jan 13, 2025
1 parent d66c779 commit ecca57b
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 108 deletions.
6 changes: 4 additions & 2 deletions src/apps/permits/demoPermitConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,10 @@ export const config: IPermitsConfig = {
[6.62566, 46.50648],
],
height: 5,
elevation: 0,
elevation: 374,
flyDuration: 2,
title: 'Building',
fovAngle: 45,
},
{
positions: [
Expand All @@ -63,9 +64,10 @@ export const config: IPermitsConfig = {
[6.62587, 46.50648],
],
height: 2,
elevation: 0,
elevation: 374,
flyDuration: 2,
title: 'Building 2',
fovAngle: 45,
},
],
layerOptions: {},
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/cesium/ingv-cesium-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export interface IngvCesiumContext {
elevation: number;
title: string;
flyDuration?: number;
fovAngle?: number; // default 45 degrees
fovAngle: number;
highlightColor?: string; // css string, default red
}[];
widgetOptions?: ConstructorParameters<typeof CesiumWidget>[1];
Expand Down
17 changes: 8 additions & 9 deletions src/plugins/cesium/interactionHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ export function calculateViewOnRectangle(
bottomRight: Cartesian3,
topLeft: Cartesian3,
topRight: Cartesian3,
fovAngle = 45,
fovAngle: number,
): {
destination: Cartesian3;
orientation: DirectionUp;
Expand All @@ -662,12 +662,14 @@ export function calculateViewOnRectangle(
new Cartesian3(),
);

const verticalExtent = Cartesian3.distance(topLeft, bottomLeft);
const horizontalExtent = Cartesian3.distance(bottomLeft, bottomRight);
const diagonalExtent = Math.sqrt(verticalExtent ** 2 + horizontalExtent ** 2);
const verticalDistance = Cartesian3.distance(topLeft, bottomLeft);
const horizontalDistance = Cartesian3.distance(bottomLeft, bottomRight);
const diagonalDistance = Math.sqrt(
verticalDistance ** 2 + horizontalDistance ** 2,
);

const fov = CMath.toRadians(fovAngle);
const cameraDistance = diagonalExtent / (2 * Math.tan(fov / 2));
const cameraDistance = diagonalDistance / (2 * Math.tan(fov / 2));

// Calculate the normal vector of the rectangle plane
const horizontalVector = Cartesian3.subtract(
Expand All @@ -693,10 +695,7 @@ export function calculateViewOnRectangle(
new Cartesian3(),
);

const cameraDirection = Cartesian3.normalize(
Cartesian3.subtract(midpoint, cameraPosition, new Cartesian3()),
new Cartesian3(),
);
const cameraDirection = Cartesian3.negate(normalVector, new Cartesian3());

return {
destination: cameraPosition,
Expand Down
172 changes: 76 additions & 96 deletions src/plugins/cesium/ngv-plugin-cesium-navigation.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import {customElement, property, state} from 'lit/decorators.js';
import {
css,
html,
type HTMLTemplateResult,
LitElement,
type PropertyValues,
} from 'lit';
import {css, html, type HTMLTemplateResult, LitElement} from 'lit';
import {Task} from '@lit/task';
import type {
CesiumWidget,
DataSourceCollection,
Expand Down Expand Up @@ -46,15 +41,13 @@ type NavViews = {
@customElement('ngv-plugin-cesium-navigation')
export class NgvPluginCesiumNavigation extends LitElement {
@property({type: Object})
private viewer: CesiumWidget;
public viewer: CesiumWidget;
@property({type: Object})
private dataSourceCollection: DataSourceCollection;
public dataSourceCollection: DataSourceCollection;
@property({type: Array})
private viewsConfig: IngvCesiumContext['views'];
@state()
private views: NavViews[] = [];
public viewsConfig: IngvCesiumContext['views'];
@state()
private tilesToLoad = Number.POSITIVE_INFINITY;
private tilesToLoad = 0;
@state()
private currentViewIndex: number;
private currentView: NavViews;
Expand Down Expand Up @@ -130,113 +123,100 @@ export class NgvPluginCesiumNavigation extends LitElement {
}
`;

parseViews(): void {
this.views = this.viewsConfig.map((v) => {
const positions: Cartographic[] = v.positions.map((p) =>
Cartographic.fromDegrees(p[0], p[1]),
);

const baseRect = Rectangle.fromCartographicArray(positions);
updateView(): void {
const v = this.viewsConfig[this.currentViewIndex];
const positions: Cartographic[] = v.positions.map((p) =>
Cartographic.fromDegrees(p[0], p[1]),
);

const nw = Cartographic.toCartesian(Rectangle.northwest(baseRect));
const ne = Cartographic.toCartesian(Rectangle.northeast(baseRect));
const sw = Cartographic.toCartesian(Rectangle.southwest(baseRect));
const se = Cartographic.toCartesian(Rectangle.southeast(baseRect));
const bottomPositions = [nw, ne, se, sw];
updateHeightForCartesianPositions(
bottomPositions,
v.elevation,
this.viewer.scene,
true,
);
const [nwt, net, set, swt] = updateHeightForCartesianPositions(
bottomPositions,
v.elevation + v.height,
this.viewer.scene,
);
const baseRect = Rectangle.fromCartographicArray(positions);

const highlightEntity = this.dataSource.entities.add(
new Entity({
show: false,
polygon: {
hierarchy: bottomPositions,
heightReference: HeightReference.RELATIVE_TO_GROUND,
extrudedHeightReference: HeightReference.RELATIVE_TO_GROUND,
material: v.highlightColor
? Color.fromCssColorString(v.highlightColor)
: Color.RED.withAlpha(0.6),
extrudedHeight: v.height,
},
}),
);
const nw = Cartographic.toCartesian(Rectangle.northwest(baseRect));
const ne = Cartographic.toCartesian(Rectangle.northeast(baseRect));
const sw = Cartographic.toCartesian(Rectangle.southwest(baseRect));
const se = Cartographic.toCartesian(Rectangle.southeast(baseRect));
const bottomPositions = [nw, ne, se, sw];
updateHeightForCartesianPositions(bottomPositions, v.elevation, null, true);
const [nwt, net, set, swt] = updateHeightForCartesianPositions(
bottomPositions,
v.elevation + v.height,
);

return {
top: {
...calculateViewOnRectangle(swt, set, nwt, net, v.fovAngle),
duration: v.flyDuration,
},
north: {
...calculateViewOnRectangle(ne, nw, net, nwt, v.fovAngle),
duration: v.flyDuration,
},
east: {
...calculateViewOnRectangle(se, ne, set, net, v.fovAngle),
duration: v.flyDuration,
},
west: {
...calculateViewOnRectangle(nw, sw, nwt, swt, v.fovAngle),
duration: v.flyDuration,
const highlightEntity = this.dataSource.entities.add(
new Entity({
show: false,
polygon: {
hierarchy: bottomPositions,
heightReference: HeightReference.RELATIVE_TO_GROUND,
extrudedHeightReference: HeightReference.RELATIVE_TO_GROUND,
material: v.highlightColor
? Color.fromCssColorString(v.highlightColor)
: Color.RED.withAlpha(0.6),
extrudedHeight: v.height,
},
south: {
...calculateViewOnRectangle(sw, se, swt, set, v.fovAngle),
duration: v.flyDuration,
},
title: v.title,
highlightEntity,
};
});
}),
);

this.currentView = {
top: {
...calculateViewOnRectangle(swt, set, nwt, net, v.fovAngle),
duration: v.flyDuration,
},
north: {
...calculateViewOnRectangle(ne, nw, net, nwt, v.fovAngle),
duration: v.flyDuration,
},
east: {
...calculateViewOnRectangle(se, ne, set, net, v.fovAngle),
duration: v.flyDuration,
},
west: {
...calculateViewOnRectangle(nw, sw, nwt, swt, v.fovAngle),
duration: v.flyDuration,
},
south: {
...calculateViewOnRectangle(sw, se, swt, set, v.fovAngle),
duration: v.flyDuration,
},
title: v.title,
highlightEntity,
};
}

willUpdate(changedProperties: PropertyValues): void {
if (changedProperties.has('currentViewIndex')) {
this.currentView = this.views[this.currentViewIndex];
// @ts-expect-error TS6133
private _changeViewTask = new Task(this, {
args: (): [number] => [this.currentViewIndex],
task: ([_currentViewIndex]) => {
this.updateView();
this.viewer.camera.flyTo(this.currentView.south);
}
}
},
});

firstUpdated(): void {
this.dataSourceCollection
.add(this.dataSource)
.then(() => {
this.currentViewIndex = 0;
this.updateView();
})
.catch((err) => console.error(err));
// todo make general loading?
const removeCallback =
this.viewer.scene.globe.tileLoadProgressEvent.addEventListener(
(tilesLoading: number) => {
this.tilesToLoad = tilesLoading;
if (tilesLoading === 0) {
this.parseViews();
this.currentViewIndex = 0;
removeCallback();
}
},
);
}

toNextView(): void {
if (!this.views) return;
if (!this.viewsConfig) return;
const nextIndx = this.currentViewIndex + 1;
if (nextIndx >= this.views.length) {
if (nextIndx >= this.viewsConfig.length) {
this.currentViewIndex = 0;
return;
}
this.currentViewIndex = nextIndx;
}

toPrevView(): void {
if (!this.views) return;
if (!this.viewsConfig) return;
const prevIndx = this.currentViewIndex - 1;
if (prevIndx < 0) {
this.currentViewIndex = this.views.length - 1;
this.currentViewIndex = this.viewsConfig.length - 1;
return;
}
this.currentViewIndex = prevIndx;
Expand All @@ -249,7 +229,7 @@ export class NgvPluginCesiumNavigation extends LitElement {
`Please wait for tiles loading. ${this.tilesToLoad} tiles to load`,
)
: html`
${this.views.length > 1
${this.viewsConfig.length > 1
? html`<div class="nav-container">
<button @click=${() => this.toPrevView()}>
${msg('Previous')}
Expand Down

0 comments on commit ecca57b

Please sign in to comment.