Skip to content

Commit

Permalink
* Move validateMapgetTileId and parseMapgetTileId helper functions to…
Browse files Browse the repository at this point in the history
… JumpTargetService.

* Implement tile source data inspection target in JumpTargetService.
* Modify RightClickMenuService to use BehaviorSubject for menuItems management.
* Update SourceDataLayerSelectionDialogComponent with map/tile ID custom loading and tile outlining.
* Adjust ErdblickViewComponent to manage tile outlines and bind menu items.
* Increase width of context menu in styles.scss and add .red background style.
  • Loading branch information
Waguramu committed Oct 29, 2024
1 parent be25272 commit 34d6225
Show file tree
Hide file tree
Showing 9 changed files with 284 additions and 81 deletions.
130 changes: 129 additions & 1 deletion erdblick_app/app/jump.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {coreLib} from "./wasm";
import {FeatureSearchService} from "./feature.search.service";
import {SidePanelService, SidePanelState} from "./sidepanel.service";
import {HighlightMode} from "build/libs/core/erdblick-core";
import {InspectionService} from "./inspection.service";
import {RightClickMenuService} from "./rightclickmenu.service";

export interface SearchTarget {
icon: string;
Expand Down Expand Up @@ -46,6 +48,8 @@ export class JumpTargetService {
private mapService: MapService,
private messageService: InfoMessageService,
private sidePanelService: SidePanelService,
private inspectionService: InspectionService,
private menuService: RightClickMenuService,
private searchService: FeatureSearchService) {
this.httpClient.get("/config.json", {responseType: 'json'}).subscribe({
next: (data: any) => {
Expand Down Expand Up @@ -108,6 +112,124 @@ export class JumpTargetService {
}
}

validateMapgetTileId(value: string) {
return value.length > 0 && !/\s/g.test(value.trim()) && !isNaN(+value.trim());
}

parseMapgetTileId(value: string): number[] | undefined {
if (!value) {
this.messageService.showError("No value provided!");
return;
}
try {
let wgs84TileId = BigInt(value);
let position = coreLib.getTilePosition(wgs84TileId);
return [position.x, position.y, position.z]
} catch (e) {
this.messageService.showError("Possibly malformed TileId: " + (e as Error).message.toString());
}
return undefined;
}

getInspectTileSourceDataTarget() {
const searchString = this.targetValueSubject.getValue();
let label = "tileId = ? | (mapId = ?) | (sourceLayerId = ?)";

const matchSourceDataElements = (value: string) => {
const regex = /^\s*(\d+)\s*(?:[,\s;]+)?\s*([^\s,;]*)\s*(?:[,\s;]+)?\s*([^\s,;]*)?\s*$/;
const match = value.match(regex);
let tileId: bigint | null = null;
let mapId = null;
let sourceLayerId = null;
let valid = true;

if (match) {
const [_, bigintStr, str1, str2] = match;
try {
tileId = BigInt(bigintStr);
valid = this.validateMapgetTileId(tileId.toString());
} catch {
valid = false;
}

// TODO: check whether the mapId and layerId are valid
if (str1) {
mapId = str1;
}
if (str2) {
sourceLayerId = str2;
}
} else {
valid = false;
}

if (!tileId || !valid) {
return null;
}



return [tileId, mapId, sourceLayerId]
}

const matches = matchSourceDataElements(searchString);
if (matches) {
const [tileId, mapId, sourceLayerId] = matches;
if (tileId) {
label = `tileId = ${tileId}`;
if (mapId) {
label = `${label} | mapId = ${mapId}`;
if (sourceLayerId) {
label = `${label} | sourceLayerId = ${sourceLayerId}`;
} else {
label = `${label} | (sourceLayerId = ?)`;
}
} else {
label = `${label} | (mapId = ?) | (sourceLayerId = ?)`
}
} else {
label += `<br><span class="search-option-warning">Insufficient parameters</span>`;
}
}

return {
icon: "pi-database",
color: "red",
name: "Inspect Mapget Tile",
label: label,
enabled: false,
execute: (value: string) => {
const matches = matchSourceDataElements(value);
if (matches) {
const [tileId, mapId, sourceLayerId] = matches;
try {
if (tileId) {
if (mapId) {
if (sourceLayerId) {
this.inspectionService.loadSourceDataInspection(
Number(tileId),
String(mapId),
String(sourceLayerId)
)
} else {
this.menuService.customTileAndMapId.next([String(tileId), String(mapId)]);
}
} else {
this.menuService.customTileAndMapId.next([String(tileId), ""]);
}
}
} catch (e) {
this.messageService.showError(String(e));
}
}
},
validate: (value: string) => {
const matches = matchSourceDataElements(value);
return matches && matches.length && matches[0];
}
}
}

update() {
let featureJumpTargets = this.mapService.tileParser?.filterFeatureJumpTargets(this.targetValueSubject.getValue());
let featureJumpTargetsConverted = [];
Expand All @@ -123,14 +245,20 @@ export class JumpTargetService {
name: `Jump to ${fjt.name}`,
label: label,
enabled: !fjt.error,
execute: (_: string) => { this.highlightByJumpTarget(fjt).then(); },
execute: (_: string) => {
if (fjt.name.toLowerCase().includes("tileid")) {

Check failure on line 249 in erdblick_app/app/jump.service.ts

View workflow job for this annotation

GitHub Actions / build-release

Empty block statement

}
this.highlightByJumpTarget(fjt).then();
},
validate: (_: string) => { return !fjt.error; },
}
});
}

this.jumpTargets.next([
this.getFeatureMatchTarget(),
this.getInspectTileSourceDataTarget(),
...featureJumpTargetsConverted,
...this.extJumpTargets
]);
Expand Down
10 changes: 0 additions & 10 deletions erdblick_app/app/map.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ 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 @@ -428,10 +427,6 @@ 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 @@ -810,9 +805,4 @@ export class MapService {
}
}
}

setSpecialTileBorder(tileId: bigint, color: Color) {
this.specialTileBorderColourForTiles = [tileId, color];
this.update();
}
}
3 changes: 2 additions & 1 deletion erdblick_app/app/parameters.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -499,10 +499,11 @@ export class ParametersService {
this.saveHistoryStateValue(value);
}
}
console.log(value);
this.p().search = value ? value : [];
this._replaceUrl = false;
this.parameters.next(this.p())
this.lastSearchHistoryEntry.next(value);
this.parameters.next(this.p())
}

private saveHistoryStateValue(value: [number, string]) {
Expand Down
24 changes: 15 additions & 9 deletions erdblick_app/app/rightclickmenu.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {Injectable} from "@angular/core";
import {MenuItem} from "primeng/api";
import {BehaviorSubject, Subject} from "rxjs";
import {InspectionService} from "./inspection.service";
import {Entity} from "./cesium";

export interface SourceDataDropdownOption {
id: bigint | string,
Expand All @@ -12,26 +13,30 @@ export interface SourceDataDropdownOption {
@Injectable()
export class RightClickMenuService {

menuItems: MenuItem[];
menuItems: BehaviorSubject<MenuItem[]> = new BehaviorSubject<MenuItem[]>([]);
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[]>();
tileOutiline: Subject<Object | null> = new Subject<Object | null>();

Check failure on line 21 in erdblick_app/app/rightclickmenu.service.ts

View workflow job for this annotation

GitHub Actions / build-release

Prefer using the primitive `object` as a type name, rather than the upper-cased `Object`

Check failure on line 21 in erdblick_app/app/rightclickmenu.service.ts

View workflow job for this annotation

GitHub Actions / build-release

Prefer using the primitive `object` as a type name, rather than the upper-cased `Object`
customTileAndMapId: Subject<[string, string]> = new Subject<[string, string]>();

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

this.lastInspectedTileSourceDataOption.subscribe(lastInspectedTileSourceData => {
const items = this.menuItems.getValue();
if (lastInspectedTileSourceData) {
this.updateMenuForLastInspectedSourceData(lastInspectedTileSourceData);
} else if (this.menuItems.length > 1) {
this.menuItems.shift();
} else if (items.length > 1) {
items.shift();
this.menuItems.next(items);
}
});
}
Expand All @@ -48,11 +53,12 @@ export class RightClickMenuService {
);
}
};

if (this.menuItems.length > 1) {
this.menuItems[0] = menuItem;
const items = this.menuItems.getValue();
if (items.length > 1) {
items[0] = menuItem;
} else {
this.menuItems.unshift(menuItem);
items.unshift(menuItem);
}
this.menuItems.next(items);
}
}
48 changes: 25 additions & 23 deletions erdblick_app/app/search.panel.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {SidePanelService, SidePanelState} from "./sidepanel.service";
import {Dialog} from "primeng/dialog";
import {KeyboardService} from "./keyboard.service";
import {distinctUntilChanged} from "rxjs";
import {RightClickMenuService} from "./rightclickmenu.service";

interface ExtendedSearchTarget extends SearchTarget {
index: number;
Expand Down Expand Up @@ -116,7 +117,7 @@ export class SearchPanelComponent implements AfterViewInit {
const targetsArray: Array<SearchTarget> = [];
const value = this.searchInputValue.trim();
let label = "tileId = ?";
if (this.validateMapgetTileId(value)) {
if (this.jumpToTargetService.validateMapgetTileId(value)) {
label = `tileId = ${value}`;
} else {
label += `<br><span class="search-option-warning">Insufficient parameters</span>`;
Expand All @@ -127,8 +128,8 @@ export class SearchPanelComponent implements AfterViewInit {
name: "Mapget Tile ID",
label: label,
enabled: false,
jump: (value: string) => { return this.parseMapgetTileId(value) },
validate: (value: string) => { return this.validateMapgetTileId(value) }
jump: (value: string) => { return this.jumpToTargetService.parseMapgetTileId(value) },
validate: (value: string) => { return this.jumpToTargetService.validateMapgetTileId(value) }
});
label = "lon = ? | lat = ? | (level = ?)"
if (this.validateWGS84(value, true)) {
Expand Down Expand Up @@ -203,6 +204,7 @@ export class SearchPanelComponent implements AfterViewInit {
private keyboardService: KeyboardService,
private messageService: InfoMessageService,
private jumpToTargetService: JumpTargetService,
private menuService: RightClickMenuService,
private sidePanelService: SidePanelService) {
this.keyboardService.registerShortcuts(["Ctrl+k", "Ctrl+K"], this.clickOnSearchToStart.bind(this));
this.clickListener = this.renderer.listen('document', 'click', this.handleClickOut.bind(this));
Expand Down Expand Up @@ -233,7 +235,11 @@ export class SearchPanelComponent implements AfterViewInit {
this.parametersService.parameters.pipe(distinctUntilChanged()).subscribe(parameters => {
if (parameters.search.length) {
const lastEntry = this.parametersService.lastSearchHistoryEntry.getValue();
if (lastEntry && parameters.search[0] != lastEntry[0] && parameters.search[1] != lastEntry[1]) {
if (lastEntry) {
if (parameters.search[0] != lastEntry[0] && parameters.search[1] != lastEntry[1]) {
this.parametersService.lastSearchHistoryEntry.next(parameters.search);
}
} else {
this.parametersService.lastSearchHistoryEntry.next(parameters.search);
}
}
Expand All @@ -256,6 +262,21 @@ export class SearchPanelComponent implements AfterViewInit {
this.reloadSearchHistory();
});

this.menuService.lastInspectedTileSourceDataOption.subscribe(lastInspectedData => {
if (lastInspectedData && lastInspectedData.tileId && lastInspectedData.mapId && lastInspectedData.layerId) {
const value = `${lastInspectedData?.tileId} ${lastInspectedData?.mapId} ${lastInspectedData?.layerId}`;
for (let i = 0; i < this.searchItems.length; i++) {
if (!this.searchItems[i].name.toLowerCase().includes("features") &&
this.searchItems[i].validate(value)) {
console.log("VALIDATED")
console.log("SET HISTORY")
this.parametersService.setSearchHistoryState([i, value]);
break;
}
}
}
});

this.reloadSearchHistory();
}

Expand Down Expand Up @@ -298,21 +319,6 @@ export class SearchPanelComponent implements AfterViewInit {
}
}

parseMapgetTileId(value: string): number[] | undefined {
if (!value) {
this.messageService.showError("No value provided!");
return;
}
try {
let wgs84TileId = BigInt(value);
let position = coreLib.getTilePosition(wgs84TileId);
return [position.x, position.y, position.z]
} catch (e) {
this.messageService.showError("Possibly malformed TileId: " + (e as Error).message.toString());
}
return undefined;
}

parseWgs84Coordinates(coordinateString: string, isLonLat: boolean): number[] | undefined {
let lon = 0;
let lat = 0;
Expand Down Expand Up @@ -442,10 +448,6 @@ export class SearchPanelComponent implements AfterViewInit {
);
}

validateMapgetTileId(value: string) {
return value.length > 0 && !/\s/g.test(value.trim()) && !isNaN(+value.trim());
}

validateWGS84(value: string, isLonLat: boolean = false) {
const coords = this.parseWgs84Coordinates(value, isLonLat);
return coords !== undefined && coords[0] >= -90 && coords[0] <= 90 && coords[1] >= -180 && coords[1] <= 180;
Expand Down
Loading

0 comments on commit 34d6225

Please sign in to comment.