Skip to content

Commit

Permalink
* Rename and refactor
Browse files Browse the repository at this point in the history
* Fix Subject usage
* Introduce better filtering for maps amd layers
* Make dropdowns and context menu larger
* Optimise entries in dropdowns
  • Loading branch information
Waguramu committed Oct 24, 2024
1 parent d8a8f6f commit 2cace90
Show file tree
Hide file tree
Showing 12 changed files with 305 additions and 183 deletions.
4 changes: 2 additions & 2 deletions erdblick_app/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ import {ReactiveFormsModule} from '@angular/forms';
import {FormlyPrimeNGModule} from "@ngx-formly/primeng";
import {DataSourcesService} from "./datasources.service";
import {ProgressSpinnerModule} from "primeng/progressspinner";
import {TileSourceDataComponent} from "./tilesources.component";
import {SourceDataLayerSelectionDialogComponent} from "./sourcedataselection.dialog.component";
import {ContextMenuModule} from "primeng/contextmenu";
import {RightClickMenuService} from "./rightclickmenu.service";

Expand Down Expand Up @@ -150,7 +150,7 @@ export function typeValidationMessage({ schemaType }: any) {
MultiSchemaTypeComponent,
HighlightSearch,
TreeTableFilterPatchDirective,
TileSourceDataComponent
SourceDataLayerSelectionDialogComponent
],
bootstrap: [
AppComponent
Expand Down
2 changes: 1 addition & 1 deletion erdblick_app/app/inspection.panel.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export interface InspectionContainerSize {
<i class="pi {{ tabs[activeIndex].icon || '' }}"></i>{{ tabs[activeIndex].title || '' }}
<p-dropdown class="source-layer-dropdown" *ngIf="activeIndex > 0" [options]="layerMenuItems"
[(ngModel)]="selectedLayerItem" (click)="onDropdownClick($event)"
[(ngModel)]="selectedLayerItem" (click)="onDropdownClick($event)" scrollHeight="20em"
(ngModelChange)="onSelectedLayerItem()" optionLabel="label" optionDisabled="disabled" />
</span>
</ng-template>
Expand Down
9 changes: 9 additions & 0 deletions erdblick_app/app/inspection.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,15 @@ export class InspectionService {
return `{"type": "FeatureCollection", "features": [${this.selectedFeatureGeoJsonTexts.join(", ")}]}`;
}

loadSourceDataInspection(tileId: number, mapId: string, layerId: string) {
this.isInspectionPanelVisible = true;
this.selectedSourceData.next({
tileId: tileId,
layerId: layerId,
mapId: mapId
});
}

protected readonly InspectionValueType = coreLib.ValueType;
protected readonly GeometryType = coreLib.GeomType;
}
11 changes: 11 additions & 0 deletions erdblick_app/app/map.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {SidePanelService, SidePanelState} from "./sidepanel.service";
import {InfoMessageService} from "./info.service";
import {MAX_ZOOM_LEVEL} from "./feature.search.service";
import {PointMergeService} from "./pointmerge.service";
import {Color} from "./cesium";

/** Expected structure of a LayerInfoItem's coverage entry. */
export interface CoverageRectItem extends Record<string, any> {
Expand Down Expand Up @@ -91,6 +92,7 @@ export class MapService {
private tileVisualizationQueue: [string, TileVisualization][];
private selectionVisualizations: TileVisualization[];
private hoverVisualizations: TileVisualization[];
private specialTileBorderColourForTiles: [bigint, Color] = [-1n, Color.TRANSPARENT];

tileParser: TileLayerParser|null = null;
tileVisualizationTopic: Subject<any>;
Expand Down Expand Up @@ -426,6 +428,10 @@ export class MapService {
return false;
}
tileVisu.showTileBorder = this.getMapLayerBorderState(mapName, layerName);
if (this.specialTileBorderColourForTiles[0] == tileVisu.tile.tileId) {
tileVisu.showTileBorder = true;
tileVisu.specialBorderColour = this.specialTileBorderColourForTiles[1];
}
tileVisu.isHighDetail = this.currentHighDetailTileIds.has(tileVisu.tile.tileId) || tileVisu.tile.preventCulling;
return true;
});
Expand Down Expand Up @@ -804,4 +810,9 @@ export class MapService {
}
}
}

setSpecialTileBorder(tileId: bigint, color: Color) {
this.specialTileBorderColourForTiles = [tileId, color];
this.update();
}
}
2 changes: 0 additions & 2 deletions erdblick_app/app/parameters.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,6 @@ export class ParametersService {

lastSearchHistoryEntry: BehaviorSubject<[number, string] | null> = new BehaviorSubject<[number, string] | null>(null);

tileIdsForSourceData: Array<any> = [];

baseFontSize: number = 16;
inspectionContainerWidth: number = 40;
inspectionContainerHeight: number = (window.innerHeight - 10.5 * this.baseFontSize);
Expand Down
45 changes: 41 additions & 4 deletions erdblick_app/app/rightclickmenu.service.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,58 @@
import {Injectable} from "@angular/core";
import {MenuItem} from "primeng/api";
import {BehaviorSubject} from "rxjs";
import {BehaviorSubject, Subject} from "rxjs";
import {InspectionService} from "./inspection.service";

export interface SourceDataDropdownOption {
id: bigint | string,
name: string,
disabled?: boolean
}

@Injectable()
export class RightClickMenuService {

menuItems: MenuItem[];
tileIdsReady: BehaviorSubject<boolean> = new BehaviorSubject(false);
tileSourceDataDialogVisible: boolean = false;
lastInspectedTileSourceDataOption: BehaviorSubject<{tileId: number, mapId: string, layerId: string} | null> =
new BehaviorSubject<{tileId: number, mapId: string, layerId: string} | null>(null);
tileIdsForSourceData: Subject<SourceDataDropdownOption[]> = new Subject<SourceDataDropdownOption[]>();

constructor() {
constructor(private inspectionService: InspectionService) {
this.menuItems = [{
label: 'Tile Source Data',
label: 'Inspect Source Data for Tile',
icon: 'pi pi-database',
command: () => {
this.tileSourceDataDialogVisible = true;
}
}];

this.lastInspectedTileSourceDataOption.subscribe(lastInspectedTileSourceData => {
if (lastInspectedTileSourceData) {
this.updateMenuForLastInspectedSourceData(lastInspectedTileSourceData);
} else if (this.menuItems.length > 1) {
this.menuItems.shift();
}
});
}

private updateMenuForLastInspectedSourceData(sourceDataParams: {tileId: number, mapId: string, layerId: string}) {
const menuItem = {
label: 'Inspect Last Selected Source Data',
icon: 'pi pi-database',
command: () => {
this.inspectionService.loadSourceDataInspection(
sourceDataParams.tileId,
sourceDataParams.mapId,
sourceDataParams.layerId
);
}
};

if (this.menuItems.length > 1) {
this.menuItems[0] = menuItem;
} else {
this.menuItems.unshift(menuItem);
}
}
}
14 changes: 12 additions & 2 deletions erdblick_app/app/sourcedata.panel.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,8 @@ export class SourceDataPanelComponent implements OnInit, AfterViewInit, OnDestro
}

selectItemWithAddress(address?: bigint) {
let addressInRange: any;
if (address) {
let addressInRange: Function | undefined;
if (address !== undefined) {
if (this.addressFormat == coreLib.SourceDataAddressFormat.BIT_RANGE) {
const searchAddress = {
offset: address >> BigInt(32) & BigInt(0xFFFFFFFF),
Expand Down Expand Up @@ -282,6 +282,10 @@ export class SourceDataPanelComponent implements OnInit, AfterViewInit, OnDestro
});
}

if (address === undefined && node.children?.length == 1) {
node.expanded = true;
}

if (node.children) {
node.children.forEach((item: TreeTableNode, index) => { select(item, [...parents, node], highlight, 1 + virtualRowIndex + index) })
}
Expand All @@ -291,6 +295,12 @@ export class SourceDataPanelComponent implements OnInit, AfterViewInit, OnDestro
select(item, [], false, index);
});

if (address === undefined) {
for (const item of this.treeData) {
item.expanded = true;
}
}

setTimeout(() => {
this.table.scrollToVirtualIndex(firstHighlightedItemIndex || 0);
}, 0);
Expand Down
198 changes: 198 additions & 0 deletions erdblick_app/app/sourcedataselection.dialog.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
import {Component} from "@angular/core";
import {ParametersService} from "./parameters.service";
import {RightClickMenuService, SourceDataDropdownOption} from "./rightclickmenu.service";
import {MapService} from "./map.service";
import {SourceDataPanelComponent} from "./sourcedata.panel.component";
import {InspectionService} from "./inspection.service";
import {Color} from "./cesium";

@Component({
selector: 'sourcedatadialog',
template: `
<p-dialog header="Inspect Tile Source Data" [(visible)]="menuService.tileSourceDataDialogVisible" [modal]="false"
(onHide)="reset()" [style]="{'min-height': '14em', 'min-width': '36em'}">
<div *ngIf="loading" style="display:flex; justify-content: center">
<p-progressSpinner ariaLabel="loading"/>
</div>
<div *ngIf="!loading" class="tilesource-options">
<p *ngIf="errorString">{{ errorString }}</p>
<p-dropdown *ngIf="!errorString"
[options]="tileIds"
[(ngModel)]="selectedTileId"
optionLabel="name"
scrollHeight="20em"
placeholder="Select a TileId"
(ngModelChange)="onTileIdChange($event)"
appendTo="body"/>
<p-dropdown *ngIf="!errorString"
[options]="mapIds"
[(ngModel)]="selectedMapId"
[disabled]="!mapIds.length"
optionLabel="name"
scrollHeight="20em"
[placeholder]="mapIds.length ? 'Select a MapId' : 'No associated maps found'"
(ngModelChange)="onMapIdChange($event)"
appendTo="body" />
<p-dropdown *ngIf="!errorString"
[options]="sourceDataLayers"
[(ngModel)]="selectedSourceDataLayer"
[disabled]="!sourceDataLayers.length"
optionLabel="name"
scrollHeight="20em"
placeholder="Select a SourceDataLayer"
[placeholder]="mapIds.length ? 'Select a SourceDataLayer' : 'No associated source data layers found'"
(ngModelChange)="onLayerIdChange($event)"
appendTo="body" />
<div style="display: flex; flex-direction: row; gap: 0.5em">
<p-button *ngIf="!errorString" (click)="requestSourceData()" label="Ok" icon="pi pi-check"></p-button>
<p-button (click)="close()" label="Close" icon="pi pi-times"></p-button>
</div>
</div>
</p-dialog>
`,
styles: [``]
})
export class SourceDataLayerSelectionDialogComponent {
selectedTileId: SourceDataDropdownOption | undefined;
tileIds: SourceDataDropdownOption[] = [];
selectedSourceDataLayer: SourceDataDropdownOption | undefined;
sourceDataLayers: SourceDataDropdownOption[] = [];
sourceDataLayersMap: Map<string, SourceDataDropdownOption[]> = new Map<string, SourceDataDropdownOption[]>();
selectedMapId: SourceDataDropdownOption | undefined;
mapIdsMap: Map<bigint, SourceDataDropdownOption[]> = new Map<bigint, SourceDataDropdownOption[]>();
mapIds: SourceDataDropdownOption[] = [];
errorString: string = "";
loading: boolean = true;

constructor(private parameterService: ParametersService,
private mapService: MapService,
private inspectionService: InspectionService,
public menuService: RightClickMenuService) {
this.menuService.tileIdsForSourceData.subscribe(data => {
this.tileIds = data;
this.loading = !data.length;
this.load();
});
}

load() {
if (this.tileIds.length) {
for (let i = 0; i < this.tileIds.length; i++) {
const id = this.tileIds[i].id as bigint;
const maps = this.findMapsForTileId(id);
this.tileIds[i]["disabled"] = !maps.length;
this.mapIdsMap.set(id, maps);
}
} else {
this.selectedTileId = undefined;
this.loading = false;
this.errorString = "No tile IDs available for the clicked position!";
}
this.mapIds = [];
this.sourceDataLayers = [];
this.selectedTileId = this.tileIds.find(element => !element.disabled);
if (this.selectedTileId !== undefined) {
this.onTileIdChange(this.selectedTileId);
if (this.mapIds.length) {
this.selectedMapId = this.mapIds[0];
this.onMapIdChange(this.selectedMapId);
if (this.sourceDataLayers.length) {
this.selectedSourceDataLayer = this.sourceDataLayers[0];
this.onLayerIdChange(this.selectedSourceDataLayer);
}
}
}
}

findMapsForTileId(tileId: bigint) {
const maps = new Set<string>();
for (const featureTile of this.mapService.loadedTileLayers.values()) {
if (featureTile.tileId == tileId) {
maps.add(featureTile.mapName);
}
}
return [...maps].map(mapId => ({ id: mapId, name: mapId }));
}

onTileIdChange(tileId: SourceDataDropdownOption) {
this.selectedMapId = undefined;
this.selectedSourceDataLayer = undefined;
this.sourceDataLayers = [];
// TODO: Fix this.
// Consider just drawing a tile box rectangle without visualising the tile.
// for (const featureTile of this.mapService.loadedTileLayers.values()) {
// if (featureTile.tileId == tileId.id as bigint) {
// this.mapService.setSpecialTileBorder(tileId.id as bigint, Color.HOTPINK);
// }
// }
const mapIds = this.mapIdsMap.get(tileId.id as bigint);
if (mapIds !== undefined) {
this.mapIds = mapIds.sort((a, b) => a.name.localeCompare(b.name));
for (let i = 0; i < this.mapIds.length; i++) {
const id = this.mapIds[i].id as string;
const layers = this.findLayersForMapId(id);
this.mapIds[i]["disabled"] = !layers.length;
this.sourceDataLayersMap.set(id, layers);
}
}
}

findLayersForMapId(mapId: string) {
const map = this.mapService.maps.getValue().get(mapId);
if (map) {
const dataLayers = new Set<string>();
for (const layer of map.layers.values()) {
if (layer.type == "SourceData") {
dataLayers.add(layer.layerId);
}
}
return [...dataLayers].map(layerId => ({
id: layerId,
name: SourceDataPanelComponent.layerNameForLayerId(layerId)
}));
}
return [];
}

onMapIdChange(mapId: SourceDataDropdownOption) {
this.selectedSourceDataLayer = undefined;
const sourceDataLayers = this.sourceDataLayersMap.get(mapId.id as string);
if (sourceDataLayers !== undefined) {
this.sourceDataLayers = sourceDataLayers;
}
}

onLayerIdChange(layerId: SourceDataDropdownOption) {
if (this.selectedTileId === undefined ||
this.selectedMapId === undefined ||
this.selectedSourceDataLayer === undefined) {
return;
}
this.menuService.lastInspectedTileSourceDataOption.next({
tileId: Number(this.selectedTileId.id),
mapId: String(this.selectedMapId.id),
layerId: String(this.selectedSourceDataLayer.id)
});
}

requestSourceData() {
this.inspectionService.loadSourceDataInspection(
Number(this.selectedTileId?.id),
String(this.selectedMapId?.id),
String(this.selectedSourceDataLayer?.id)
);
this.close();
}

reset() {
this.loading = true;
this.errorString = "";
this.selectedTileId = undefined;
this.selectedMapId = undefined;
this.selectedSourceDataLayer = undefined;
}

close() {
this.menuService.tileSourceDataDialogVisible = false;
}
}
Loading

0 comments on commit 2cace90

Please sign in to comment.