Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2611 visibility refresh #2627

Original file line number Diff line number Diff line change
Expand Up @@ -1063,7 +1063,7 @@ export class MapEventProcessor extends AbstractEventProcessor {

let configLayerEntryConfig;
if (geoviewLayerConfig) {
configLayerEntryConfig = (geoviewLayerConfig as TypeGeoviewLayerConfig).listOfLayerEntryConfig.find(
configLayerEntryConfig = (geoviewLayerConfig as TypeGeoviewLayerConfig).listOfLayerEntryConfig?.find(
(nextEntryConfig: TypeLayerEntryConfig) => nextEntryConfig.layerId === pathArray[1]
);
for (let i = 2; i < pathArray.length; i++) {
Expand Down
113 changes: 74 additions & 39 deletions packages/geoview-core/src/geo/layer/layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -559,53 +559,88 @@ export class LayerApi {
logger.logError(`Duplicate use of geoview layer identifier ${mapConfigLayerEntry.geoviewLayerId} on map ${this.getMapId()}`);
}

/**
* TODO Add this function to utilties
* Gets all child paths from a parent path
* @param {string} parentPath - The parent path
* @returns {string[]} Child layer paths
*/
#getAllChildPaths(parentPath: string): string[] {
const parentLayerEntryConfig = this.getLayerEntryConfig(parentPath)?.geoviewLayerConfig.listOfLayerEntryConfig;

if (!parentLayerEntryConfig) return [];

function getChildPaths(listOfLayerEntryConfig: TypeLayerEntryConfig[]): string[] {
const layerPaths: string[] = [];
listOfLayerEntryConfig.forEach((entryConfig) => {
layerPaths.push(entryConfig.layerPath);
if (entryConfig.listOfLayerEntryConfig) {
layerPaths.push(...getChildPaths(entryConfig.listOfLayerEntryConfig));
}
});
return layerPaths;
}

const layerPaths = getChildPaths(parentLayerEntryConfig);
return layerPaths;
}

/**
* Refreshes GeoCore Layers
* @returns {Promise<void>} A promise which resolves when done refreshing
*/
reloadGeocoreLayers(): Promise<void> {
reloadGeocoreLayers(): void {
const configs = this.getLayerEntryConfigs();
const originalMapOrderedLayerInfo = MapEventProcessor.getMapOrderedLayerInfo(this.getMapId());
const promisesOfGeoCoreGeoviewLayers: Promise<TypeGeoviewLayerConfig[]>[] = [];

configs
.filter((config) => {
// Filter to just Geocore layers and not child layers
if (api.config.isValidUUID(config.geoviewLayerConfig.geoviewLayerId) && config.parentLayerConfig === undefined) {
return true;
}
return false;
})
.forEach((config) => {
// Remove and add back in GeoCore Layers and return their promises
this.removeLayerUsingPath(config.layerPath);
const geoCore = new GeoCore(this.getMapId(), this.mapViewer.getDisplayLanguage());
promisesOfGeoCoreGeoviewLayers.push(geoCore.createLayersFromUUID(config.geoviewLayerConfig.geoviewLayerId));
});

return Promise.allSettled(promisesOfGeoCoreGeoviewLayers)
.then((promisedLayers) => {
promisedLayers
.filter((promise) => promise.status === 'fulfilled')
.map((promise) => promise as PromiseFulfilledResult<TypeGeoviewLayerConfig[]>)
.forEach((promise) => {
promise.value.forEach((geoviewLayerConfig) => {
this.addGeoviewLayer(geoviewLayerConfig);
const parentPaths: string[] = [];

// Have to do the Promise allSettled so the new MapOrderedLayerInfo has all the children layerPaths
Promise.allSettled(
configs
.filter((config) => {
// Filter to just Geocore layers and not child layers
if (api.config.isValidUUID(config.geoviewLayerConfig.geoviewLayerId) && config.parentLayerConfig === undefined) {
return true;
}
return false;
})
.map((config) => {
// Remove and add back in GeoCore Layers and return their promises
parentPaths.push(config.layerPath);
this.removeLayerUsingPath(config.layerPath);
return this.addGeoviewLayerByGeoCoreUUID(config.geoviewLayerConfig.geoviewLayerId);
})
)
.then(() => {
const originalLayerPaths = originalMapOrderedLayerInfo.map((info) => info.layerPath);

// Prepare listeners for removing previously removed layers
parentPaths.forEach((parentPath) => {
function removeChildLayers(sender: LayerApi): void {
const childPaths = sender.#getAllChildPaths(parentPath);
childPaths.forEach((childPath) => {
if (!originalLayerPaths.includes(childPath)) {
sender.removeLayerUsingPath(childPath);
}
});
});
const newMapOrderedLayerInfo = MapEventProcessor.getMapOrderedLayerInfo(this.getMapId());
const originalLayerPaths = originalMapOrderedLayerInfo.map((layer) => layer.layerPath);
const childLayersToRemove = newMapOrderedLayerInfo
.map((layer) => layer.layerPath)
.filter((path) => !originalLayerPaths.includes(path));
if (childLayersToRemove) {
childLayersToRemove.forEach((childPath) => {
this.removeLayerUsingPath(childPath);
});
}
sender.offLayerAdded(removeChildLayers);
}
this.onLayerAdded(removeChildLayers);
});

// Prepare listeners for changing the visibility
MapEventProcessor.setMapOrderedLayerInfo(this.getMapId(), originalMapOrderedLayerInfo);
originalMapOrderedLayerInfo.forEach((layerInfo) => {
function setLayerVisibility(sender: LayerApi, event: LayerLoadedEvent): void {
if (layerInfo.layerPath === event.layerPath) {
const { visible } = originalMapOrderedLayerInfo.filter((info) => info.layerPath === event.layerPath)[0];
event.layer?.setVisible(visible, event.layerPath);
sender.offLayerLoaded(setLayerVisibility);
}
}
this.onLayerLoaded(setLayerVisibility);
});
})
.catch((error) => logger.logError(error));
.catch((err) => logger.logError(err));
}

/**
Expand Down
16 changes: 7 additions & 9 deletions packages/geoview-core/src/geo/map/map-viewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -918,28 +918,26 @@ export class MapViewer {
*
* @param {TypeDisplayLanguage} displayLanguage - The language to use (en, fr)
* @param {boolean} resetLayer - Optional flag to ask viewer to reload layers with the new localize language
* @returns {Promise<[void, void]>}
* @returns {Promise<void>}
*/
setLanguage(displayLanguage: TypeDisplayLanguage, reloadLayers?: boolean | false): Promise<[void, void]> {
async setLanguage(displayLanguage: TypeDisplayLanguage, reloadLayers?: boolean | false): Promise<void> {
// If the language hasn't changed don't do anything
if (AppEventProcessor.getDisplayLanguage(this.mapId) === displayLanguage) return Promise.resolve([undefined, undefined]);
if (AppEventProcessor.getDisplayLanguage(this.mapId) === displayLanguage) return;
if (VALID_DISPLAY_LANGUAGE.includes(displayLanguage)) {
const promise = AppEventProcessor.setDisplayLanguage(this.mapId, displayLanguage);
await AppEventProcessor.setDisplayLanguage(this.mapId, displayLanguage);

// if flag is true, reload GeoCore layers
// if flag is true, reload just the GeoCore layers instead of reloading the whole map with current state
if (reloadLayers) {
this.layer.reloadGeocoreLayers().catch((error) => logger.logError(error));
this.layer.reloadGeocoreLayers();
}

// Emit language changed event
this.#emitMapLanguageChanged({ language: displayLanguage });
// Return the promise
return promise;
return;
}

// Unsupported
this.notifications.addNotificationError(getLocalizedMessage('validation.changeDisplayLanguage', displayLanguage));
return Promise.resolve([undefined, undefined]);
}

/**
Expand Down
Loading