Skip to content

Commit

Permalink
[ERD-69] Fix encoding Erdblick state parameters in the URL.
Browse files Browse the repository at this point in the history
[ERD-77] Add local persistence for the parameters.
  • Loading branch information
Vagram Airiian committed Feb 15, 2024
1 parent e1547be commit a342e4f
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 119 deletions.
195 changes: 99 additions & 96 deletions erdblick_app/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,19 +110,13 @@ export class AppComponent {
this.version = data.toString();
});

// this.parametersService.parameters.subscribe(parameters => {
// const entries = [...Object.entries(parameters)];
// entries.forEach(entry => entry[1] = JSON.stringify(entry[1]));
// this.updateQueryParams(Object.fromEntries(entries));
// });

libErdblickCore().then((coreLib: any) => {
console.log(" ...done.")
this.mapService.coreLib = coreLib;

let erdblickModel = new ErdblickModel(coreLib, styleService);
this.mapService.mapModel.next(erdblickModel);
this.mapService.mapView = new ErdblickView(erdblickModel, 'mapViewContainer');
this.mapService.mapView = new ErdblickView(erdblickModel, 'mapViewContainer', parametersService);

this.mapService.reloadStyle();

Expand Down Expand Up @@ -176,88 +170,97 @@ export class AppComponent {
this.mapService.mapModel.getValue()!.availableMapItems.next(mapItems);
});

// this.activatedRoute.queryParams.subscribe((params: Params) => {
// let currentParameters = this.parametersService.parameters.getValue();
// let newPosition = {
// x: params["x"] ? Number(params["x"]) : currentParameters.x,
// y: params["y"] ? Number(params["y"]) : currentParameters.y,
// z: params["z"] ? Number(params["z"]) : currentParameters.z
// }
// let newOrientation = {
// heading: params["heading"] ? Number(params["heading"]) : currentParameters.heading,
// pitch: params["pitch"] ? Number(params["pitch"]) : currentParameters.pitch,
// roll: params["roll"] ? Number(params["roll"]) : currentParameters.roll
// }
// if (this.mapService.mapView !== undefined) {
// this.mapService.mapView.viewer.camera.setView({
// destination: Cartesian3.fromElements(newPosition.x, newPosition.y, newPosition.z),
// orientation: newOrientation
// });
// }
// currentParameters.x = newPosition.x;
// currentParameters.y = newPosition.y;
// currentParameters.z = newPosition.z;
// currentParameters.heading = newOrientation.heading;
// currentParameters.roll = newOrientation.roll;
// currentParameters.pitch = newOrientation.pitch;
//
// let osmOpacity = currentParameters.osmOpacity;
// if (params["osm"]) {
// osmOpacity = Number(params["osm"]);
// }
// this.mapService.osmEnabled = currentParameters.osmEnabled;
// this.mapService.osmOpacityValue = osmOpacity;
// this.mapService.mapView?.updateOpenStreetMapLayer(osmOpacity / 100);
// currentParameters.osmOpacity = osmOpacity;
//
// let layerNamesLevels = currentParameters.layers;
// let currentLayers = new Array<Array<string>>;
// if (params["layers"]) {
// layerNamesLevels = JSON.parse(params["layers"]);
// }
// layerNamesLevels.forEach((nameLevel: Array<string>) => {
// const name = nameLevel[0];
// const level = Number(nameLevel[1]);
// if (mapService.mapModel.getValue()) {
// if (this.mapService.mapModel.getValue()!.layerIdToLevel.has(name)) {
// this.mapService.mapModel.getValue()!.layerIdToLevel.set(name, level);
// }
// const [mapName, layerName] = name.split('/');
// this.mapService.mapModel.getValue()!.availableMapItems.getValue().forEach(
// (mapItem: ErdblickMap, name: string) => {
// if (name == mapName) {
// mapItem.visible = true;
// mapItem.mapLayers.forEach((mapLayer: ErdblickLayer) => {
// if (mapLayer.name == layerName) {
// mapLayer.visible = true;
// currentLayers.push([`${mapName}/${layerName}`, level.toString()])
// }
// });
// }
// });
// }
// });
// if (currentLayers) {
// currentParameters.layers = currentLayers;
// }
//
// let styles = currentParameters.styles;
// if (params["styles"]) {
// styles = JSON.parse(params["styles"]);
// }
// let currentStyles = new Array<string>();
// [...this.styleService.activatedStyles.keys()].forEach(id => {
// const toActivate = styles.includes(id);
// this.styleService.activatedStyles.set(id, toActivate);
// if (toActivate) {
// currentStyles.push(id);
// }
// })
// if (currentStyles) {
// currentParameters.styles = currentStyles;
// }
// this.parametersService.parameters.next(currentParameters);
// });
this.activatedRoute.queryParams.subscribe((params: Params) => {
let currentParameters = this.parametersService.parameters.getValue();
const newPosition = {
x: params["x"] ? Number(params["x"]) : currentParameters.x,
y: params["y"] ? Number(params["y"]) : currentParameters.y,
z: params["z"] ? Number(params["z"]) : currentParameters.z
}
const newOrientation = {
heading: params["heading"] ? Number(params["heading"]) : currentParameters.heading,
pitch: params["pitch"] ? Number(params["pitch"]) : currentParameters.pitch,
roll: params["roll"] ? Number(params["roll"]) : currentParameters.roll
}
if (this.mapService.mapView !== undefined) {
this.mapService.mapView.viewer.camera.setView({
destination: Cartesian3.fromElements(newPosition.x, newPosition.y, newPosition.z),
orientation: newOrientation
});
}
currentParameters.x = newPosition.x;
currentParameters.y = newPosition.y;
currentParameters.z = newPosition.z;
currentParameters.heading = newOrientation.heading;
currentParameters.roll = newOrientation.roll;
currentParameters.pitch = newOrientation.pitch;

const osmEnabled = params["osmEnabled"] ? params["osmEnabled"] == "true" : currentParameters.osmEnabled;
const osmOpacity = params["osmOpacity"] ? Number(params["osmOpacity"]) : currentParameters.osmOpacity;
this.mapService.osmEnabled = osmEnabled;
this.mapService.osmOpacityValue = osmOpacity;
if (osmEnabled) {
this.mapService.mapView?.updateOpenStreetMapLayer(osmOpacity / 100);
} else {
this.mapService.mapView?.updateOpenStreetMapLayer(0);
}
currentParameters.osmEnabled = osmEnabled;
currentParameters.osmOpacity = osmOpacity;

let layerNamesLevels = currentParameters.layers;
let currentLayers = new Array<Array<string>>;
if (params["layers"]) {
layerNamesLevels = JSON.parse(params["layers"]);
}
layerNamesLevels.forEach((nameLevel: Array<string>) => {
const name = nameLevel[0];
const level = Number(nameLevel[1]);
if (mapService.mapModel.getValue()) {
if (this.mapService.mapModel.getValue()!.layerIdToLevel.has(name)) {
this.mapService.mapModel.getValue()!.layerIdToLevel.set(name, level);
}
const [mapName, layerName] = name.split('/');
this.mapService.mapModel.getValue()!.availableMapItems.getValue().forEach(
(mapItem: ErdblickMap, name: string) => {
if (name == mapName) {
mapItem.visible = true;
mapItem.mapLayers.forEach((mapLayer: ErdblickLayer) => {
if (mapLayer.name == layerName) {
mapLayer.visible = true;
currentLayers.push([`${mapName}/${layerName}`, level.toString()])
}
});
}
});
}
});
if (currentLayers) {
currentParameters.layers = currentLayers;
}

let styles = currentParameters.styles;
if (params["styles"]) {
styles = JSON.parse(params["styles"]);
}
let currentStyles = new Array<string>();
[...this.styleService.activatedStyles.keys()].forEach(id => {
const isActivated = styles.includes(id);
this.styleService.activatedStyles.set(id, isActivated);
if (isActivated) {
currentStyles.push(id);
}
})
if (currentStyles) {
currentParameters.styles = currentStyles;
}
this.parametersService.parameters.next(currentParameters);
});

this.parametersService.parameters.subscribe(parameters => {
const entries = [...Object.entries(parameters)];
entries.forEach(entry => entry[1] = JSON.stringify(entry[1]));
this.updateQueryParams(Object.fromEntries(entries));
});
});
}

Expand Down Expand Up @@ -298,11 +301,11 @@ export class AppComponent {
this.jumpToTargetService.targetValueSubject.next(value);
}

// updateQueryParams(params: Params): void {
// this.router.navigate([], {
// queryParams: params,
// queryParamsHandling: 'merge',
// replaceUrl: true
// });
// }
updateQueryParams(params: Params): void {
this.router.navigate([], {
queryParams: params,
queryParamsHandling: 'merge',
replaceUrl: true
});
}
}
15 changes: 14 additions & 1 deletion erdblick_app/app/erdblick.view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
UrlTemplateImageryProvider,
Viewer
} from "cesium";
import {ParametersService} from "./parameters.service";

export class ErdblickView {
viewer: Viewer;
Expand All @@ -35,7 +36,9 @@ export class ErdblickView {
* @param {ErdblickModel} model
* @param containerDomElementId Div which hosts the Cesium view.
*/
constructor(model: ErdblickModel, containerDomElementId: string) {
constructor(model: ErdblickModel,
containerDomElementId: string,
public parameterService: ParametersService) {
this.model = model;
this.viewer = new Viewer(containerDomElementId,
{
Expand Down Expand Up @@ -85,6 +88,16 @@ export class ErdblickView {
// Add a handler for camera movement.
this.viewer.camera.percentageChanged = 0.1;
this.viewer.camera.changed.addEventListener(() => {
const parameters = this.parameterService.parameters.getValue();
if (parameters) {
parameters.x = this.viewer.camera.position.x;
parameters.y = this.viewer.camera.position.y;
parameters.z = this.viewer.camera.position.z;
parameters.heading = this.viewer.camera.heading;
parameters.pitch = this.viewer.camera.pitch;
parameters.roll = this.viewer.camera.roll;
this.parameterService.parameters.next(parameters);
}
this.updateViewport();
});

Expand Down
68 changes: 58 additions & 10 deletions erdblick_app/app/map.panel.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import {InfoMessageService} from "./info.service";
import {ErdblickLayer, ErdblickMap, MapService} from "./map.service";
import {StyleService} from "./style.service";
import {ErdblickModel} from "./erdblick.model";
import {ParametersService} from "./parameters.service";
import {map} from "rxjs";


@Component({
Expand All @@ -24,7 +26,7 @@ import {ErdblickModel} from "./erdblick.model";
</div>
</div>
<p-divider></p-divider>
<div *ngIf="!mapItems.size">No maps loaded.</div>
<div *ngIf="!mapItems.size" style="margin-top: 0.75em">No maps loaded.</div>
<div *ngIf="mapItems.size" class="maps-container">
<div *ngFor="let mapItem of mapItems | keyvalue" class="map-container">
<span class="font-bold white-space-nowrap map-header">
Expand All @@ -35,7 +37,7 @@ import {ErdblickModel} from "./erdblick.model";
{{ mapLayer.name }}
</span>
<div class="layer-controls">
<p-button (click)="toggleLayer(mapLayer)"
<p-button (click)="toggleLayer(mapItem.key, mapLayer)"
icon="{{mapLayer.visible ? 'pi pi-eye' : 'pi pi-eye-slash'}}"
label="" pTooltip="Toggle layer" tooltipPosition="bottom">
</p-button>
Expand All @@ -44,7 +46,7 @@ import {ErdblickModel} from "./erdblick.model";
label="" pTooltip="Focus on layer" tooltipPosition="bottom">
</p-button>
<p-inputNumber [(ngModel)]="mapLayer.level"
(ngModelChange)="onLayerLevelChanged($event, mapItem.key + '/' + mapLayer.name)"
(ngModelChange)="onLayerLevelChanged($event, mapItem.key, mapLayer.name)"
[showButtons]="true" [min]="0" [max]="15"
buttonLayout="horizontal" spinnerMode="horizontal" inputId="horizontal"
decrementButtonClass="p-button-secondary"
Expand Down Expand Up @@ -94,7 +96,8 @@ export class MapPanelComponent {

constructor(public mapService: MapService,
private messageService: InfoMessageService,
public styleService: StyleService) {
public styleService: StyleService,
public parameterService: ParametersService) {
this.mapService.mapModel.subscribe(mapModel => {
if (mapModel) {
mapModel.availableMapItems.subscribe(mapItems => this.mapItems = mapItems);
Expand All @@ -115,10 +118,28 @@ export class MapPanelComponent {
}
}

onLayerLevelChanged(event: Event, layerName: string) {
let level = Number(event.toString());
onLayerLevelChanged(event: Event, mapName: string, layerName: string) {
const mapLayerName = `${mapName}/${layerName}`;
const level = Number(event.toString());
if (this.mapService.mapModel.getValue()) {
this.mapService.mapModel.getValue()!.layerIdToLevel.set(layerName, level);
this.mapService.mapModel.getValue()!.layerIdToLevel.set(mapLayerName, level);
const parameters = this.parameterService.parameters.getValue();
if (parameters) {
const mapItem = this.mapItems.get(mapName);
if (mapItem !== undefined) {
mapItem.mapLayers.forEach(mapLayer => {
if (mapLayer.name == layerName && mapLayer.visible) {
let includes = false;
parameters.layers.forEach(layer => {
includes = layer[0] == mapLayerName;
if (includes) layer[1] = level.toString();
})
if (!includes) parameters.layers.push([mapLayerName, level.toString()]);
this.parameterService.parameters.next(parameters);
}
});
}
}
this.mapService.mapModel.getValue()!.update();
} else {
this.messageService.showError("Cannot access the map model. The model is not available.");
Expand All @@ -136,20 +157,47 @@ export class MapPanelComponent {
} else {
this.mapService.mapView?.updateOpenStreetMapLayer(0);
}
const parameters = this.parameterService.parameters.getValue();
if (parameters) {
parameters.osmEnabled = this.mapService.osmEnabled;
parameters.osmOpacity = this.mapService.osmOpacityValue;
this.parameterService.parameters.next(parameters);
}
}

toggleLayer(mapLayer: ErdblickLayer) {
toggleLayer(mapName: string, mapLayer: ErdblickLayer) {
const mapLayerName =`${mapName}/${mapLayer.name}`;
mapLayer.visible = !mapLayer.visible;
if (this.mapService.mapModel.getValue()) {
const parameters = this.parameterService.parameters.getValue();
if (parameters) {
if (mapLayer.visible) {
parameters.layers.push([mapLayerName, mapLayer.level.toString()]);
} else {
parameters.layers = parameters.layers.filter(layer => layer[0] != mapLayerName);
}
this.parameterService.parameters.next(parameters);
}
this.mapService.mapModel.getValue()!.update();
} else {
this.messageService.showError("Cannot access the map model. The model is not available.");
}
}

toggleStyle(styleId: string) {
const isAvailable = this.styleService.activatedStyles.get(styleId);
this.styleService.activatedStyles.set(styleId, !isAvailable);
const isAvailable = !this.styleService.activatedStyles.get(styleId);
this.styleService.activatedStyles.set(styleId, isAvailable);
const parameters = this.parameterService.parameters.getValue();
console.log(styleId, isAvailable);
if (parameters) {
if (isAvailable) {
parameters.styles.push(styleId);
} else {
parameters.styles = parameters.styles.filter(style => style != styleId);
console.log(parameters.styles);
}
this.parameterService.parameters.next(parameters);
}
this.mapService.reloadStyle();
}

Expand Down
Loading

0 comments on commit a342e4f

Please sign in to comment.