Skip to content

Commit

Permalink
fix(layers): fixes geocore layers not appearing in service order (#2685)
Browse files Browse the repository at this point in the history
Closes #2644
  • Loading branch information
DamonU2 authored Jan 14, 2025
1 parent 22ac39a commit 0030f48
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -353,12 +353,12 @@ export class LegendEventProcessor extends AbstractEventProcessor {

// Update the legend layers with the updated array, triggering the subscribe
// Reorder the array so legend tab is in synch
const sortedLayers = layers.sort((a, b) =>
MapEventProcessor.getMapIndexFromOrderedLayerInfo(mapId, a.layerPath) >
MapEventProcessor.getMapIndexFromOrderedLayerInfo(mapId, b.layerPath)
? 1
: -1
const sortedLayers = layers.sort(
(a, b) =>
MapEventProcessor.getMapIndexFromOrderedLayerInfo(mapId, a.layerPath) -
MapEventProcessor.getMapIndexFromOrderedLayerInfo(mapId, b.layerPath)
);
this.sortLegendLayersChildren(mapId, sortedLayers);

this.getLayerState(mapId).setterActions.setLegendLayers(sortedLayers);
}
Expand Down Expand Up @@ -397,7 +397,7 @@ export class LegendEventProcessor extends AbstractEventProcessor {
foundLayer = layer;
}

if (layerPath?.startsWith(layer.layerPath) && layer.children?.length > 0) {
if (layerPath.startsWith(`${layer.layerPath}/`) && layer.children?.length > 0) {
const result: TypeLegendLayer | undefined = LegendEventProcessor.findLayerByPath(layer.children, layerPath);
if (result) {
foundLayer = result;
Expand Down Expand Up @@ -742,4 +742,21 @@ export class LegendEventProcessor extends AbstractEventProcessor {
return matchingBreak ? matchingBreak.visible : classBreakStyle.info[classBreakStyle.info.length - 1].visible;
});
}

/**
* Sorts legend layers children recursively in given legend layers list.
* @param {string} mapId - The ID of the map.
* @param {TypeLegendLayer[]} legendLayerList - The list to sort.
*/
static sortLegendLayersChildren = (mapId: string, legendLayerList: TypeLegendLayer[]): void => {
legendLayerList.forEach((legendLayer) => {
if (legendLayer.children.length)
legendLayer.children.sort(
(a, b) =>
MapEventProcessor.getMapIndexFromOrderedLayerInfo(mapId, a.layerPath) -
MapEventProcessor.getMapIndexFromOrderedLayerInfo(mapId, b.layerPath)
);
this.sortLegendLayersChildren(mapId, legendLayer.children);
});
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,23 @@ export class MapEventProcessor extends AbstractEventProcessor {
return this.getMapStateProtected(mapId).orderedLayerInfo.find((orderedLayerInfo) => orderedLayerInfo.layerPath === layerPath);
}

/**
* Gets the ordered layer info for one layer and its children.
* @param {string} mapId - The map id.
* @param {string} layerPath - The path of the layer to get.
* @param {TypeOrderedLayerInfo[]} orderedLayerInfo - The array of ordered layer info to search, default is current ordered layer info.
* @returns {TypeOrderedLayerInfo[] | undefined} The ordered layer info of the layer and its children.
*/
static getMapLayerAndChildrenOrderedInfo(
mapId: string,
layerPath: string,
orderedLayerInfo: TypeOrderedLayerInfo[] = this.getMapStateProtected(mapId).orderedLayerInfo
): TypeOrderedLayerInfo[] {
return orderedLayerInfo.filter(
(info: TypeOrderedLayerInfo) => info.layerPath.startsWith(`${layerPath}/`) || info.layerPath === layerPath
);
}

static getMapIndexFromOrderedLayerInfo(mapId: string, layerPath: string): number {
// Get index of a layer
const info = this.getMapStateProtected(mapId).orderedLayerInfo;
Expand Down Expand Up @@ -749,8 +766,9 @@ export class MapEventProcessor extends AbstractEventProcessor {
const layerPath = (geoviewLayerConfig as TypeGeoviewLayerConfig).geoviewLayerId
? `${(geoviewLayerConfig as TypeGeoviewLayerConfig).geoviewLayerId}/${(geoviewLayerConfig as TypeGeoviewLayerConfig).geoviewLayerId}`
: (geoviewLayerConfig as TypeLayerEntryConfig).layerPath;
const index = this.getMapIndexFromOrderedLayerInfo(mapId, layerPathToReplace || layerPath);
const replacedLayers = orderedLayerInfo.filter((layerInfo) => layerInfo.layerPath.startsWith(layerPathToReplace || layerPath));
const pathToSearch = layerPathToReplace || layerPath;
const index = this.getMapIndexFromOrderedLayerInfo(mapId, pathToSearch);
const replacedLayers = this.getMapLayerAndChildrenOrderedInfo(mapId, pathToSearch);
const newOrderedLayerInfo = LayerApi.generateArrayOfLayerOrderInfo(geoviewLayerConfig);
orderedLayerInfo.splice(index, replacedLayers.length, ...newOrderedLayerInfo);

Expand Down Expand Up @@ -803,7 +821,9 @@ export class MapEventProcessor extends AbstractEventProcessor {
*/
static removeOrderedLayerInfo(mapId: string, layerPath: string): void {
const { orderedLayerInfo } = this.getMapStateProtected(mapId);
const newOrderedLayerInfo = orderedLayerInfo.filter((layerInfo) => !layerInfo.layerPath.startsWith(layerPath));
const newOrderedLayerInfo = orderedLayerInfo.filter(
(layerInfo) => !layerInfo.layerPath.startsWith(`${layerPath}/`) || !(layerInfo.layerPath === layerPath)
);

// Redirect
this.setMapOrderedLayerInfo(mapId, newOrderedLayerInfo);
Expand Down Expand Up @@ -1087,7 +1107,8 @@ export class MapEventProcessor extends AbstractEventProcessor {
const listOfLayerEntryConfig: TypeLayerEntryConfig[] = [];
if (layerEntryConfig!.entryType === 'group') {
const sublayerPaths = MapEventProcessor.getMapLayerOrder(mapId).filter(
(entryLayerPath) => entryLayerPath.startsWith(layerPath) && entryLayerPath.split('/').length === layerPath.split('/').length + 1
(entryLayerPath) =>
entryLayerPath.startsWith(`${layerPath}/`) && entryLayerPath.split('/').length === layerPath.split('/').length + 1
);
sublayerPaths.forEach((sublayerPath) => listOfLayerEntryConfig.push(MapEventProcessor.createLayerEntryConfig(mapId, sublayerPath)));
}
Expand Down Expand Up @@ -1134,7 +1155,7 @@ export class MapEventProcessor extends AbstractEventProcessor {
// Check for sublayers
const sublayerPaths = MapEventProcessor.getMapLayerOrder(mapId).filter(
// We only want the immediate child layers, group sublayers will handle their own sublayers
(entryLayerPath) => entryLayerPath.startsWith(layerPath) && entryLayerPath.split('/').length === layerPath.split('/').length + 1
(entryLayerPath) => entryLayerPath.startsWith(`${layerPath}/`) && entryLayerPath.split('/').length === layerPath.split('/').length + 1
);

// Build list of sublayer entry configs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useTheme } from '@mui/material/styles';
import { SingleLayer } from './single-layer';
import { getSxClasses } from './left-panel-styles';
import { Box } from '@/ui';
import { useGeoViewMapId, useMapStoreActions } from '@/core/stores';
import { useGeoViewMapId, useLayerStoreActions, useMapStoreActions } from '@/core/stores';
import { logger } from '@/core/utils/logger';
import { TypeLegendLayer } from '@/core/components/layers/types';
import { TABS } from '@/core/utils/constant';
Expand All @@ -23,10 +23,12 @@ export function LayersList({ layersList, showLayerDetailsPanel, isLayoutEnlarged

const mapId = useGeoViewMapId();
const { getIndexFromOrderedLayerInfo } = useMapStoreActions();
const { sortLegendLayersChildren } = useLayerStoreActions();

const sortedLayers = layersList.sort((a, b) =>
getIndexFromOrderedLayerInfo(a.layerPath) > getIndexFromOrderedLayerInfo(b.layerPath) ? 1 : -1
);
sortLegendLayersChildren(sortedLayers);

const textToSlug = (text: string): string => {
return text
Expand Down
2 changes: 1 addition & 1 deletion packages/geoview-core/src/core/stores/state-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export class StateApi {
let startingIndex = -1;
for (let i = 0; i < orderedLayers.length; i++) if (orderedLayers[i].layerPath === layerPath) startingIndex = i;
const layerInfo = orderedLayers[startingIndex];
const movedLayers = orderedLayers.filter((layer) => layer.layerPath.startsWith(layerPath));
const movedLayers = MapEventProcessor.getMapLayerAndChildrenOrderedInfo(mapId, layerPath, orderedLayers);
orderedLayers.splice(startingIndex, movedLayers.length);
let nextIndex = startingIndex;
const pathLength = layerInfo.layerPath.split('/').length;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export interface ILayerState {
setLayerDeleteInProgress: (newVal: boolean) => void;
setLayerOpacity: (layerPath: string, opacity: number) => void;
setSelectedLayerPath: (layerPath: string) => void;
sortLegendLayersChildren: (legendLayerList: TypeLegendLayer[]) => void;
toggleItemVisibility: (layerPath: string, item: TypeLegendItem) => void;
zoomToLayerExtent: (layerPath: string) => Promise<void>;
setSelectedLayerSortingArrowId: (layerId: string) => void;
Expand Down Expand Up @@ -236,6 +237,14 @@ export function initializeLayerState(set: TypeSetStore, get: TypeGetStore): ILay
LegendEventProcessor.setSelectedLayersTabLayer(get().mapId, layerPath);
},

/**
* Sorts legend layers children recursively in given legend layers list.
* @param {TypeLegendLayer[]} legendLayerList - The list to sort.
*/
sortLegendLayersChildren: (legendLayerList: TypeLegendLayer[]): void => {
LegendEventProcessor.sortLegendLayersChildren(get().mapId, legendLayerList);
},

/**
* Toggle visibility of an item.
* @param {string} layerPath - The layer path of the layer to change.
Expand Down
27 changes: 16 additions & 11 deletions packages/geoview-core/src/geo/layer/layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1004,14 +1004,11 @@ export class LayerApi {
MapEventProcessor.replaceOrderedLayerInfo(this.getMapId(), layerConfig, parentLayerPath);
} else if (layerConfig.parentLayerConfig) {
// Here the map index of a sub layer path hasn't been set and there's a parent layer config for the current layer config

// Get the map index of the parent layer path
const parentLayerIndex = MapEventProcessor.getMapIndexFromOrderedLayerInfo(this.getMapId(), parentLayerPath);

// Get the number of child layers
const numberOfLayers = MapEventProcessor.getMapOrderedLayerInfo(this.getMapId()).filter((layerInfo) =>
layerInfo.layerPath.startsWith(parentLayerPath)
).length;
// Get the number of layers
const numberOfLayers = MapEventProcessor.getMapLayerAndChildrenOrderedInfo(this.getMapId(), parentLayerPath).length;

// If the map index of the parent has been set
if (parentLayerIndex !== -1) {
Expand Down Expand Up @@ -1201,7 +1198,7 @@ export class LayerApi {

// Remove layer info from registered layers
this.getLayerEntryConfigIds().forEach((registeredLayerPath) => {
if (registeredLayerPath.startsWith(layerPath)) {
if (registeredLayerPath.startsWith(`${layerPath}/`) || registeredLayerPath === layerPath) {
// Remove ol layer
if (this.getOLLayer(registeredLayerPath)) this.mapViewer.map.removeLayer(this.getOLLayer(registeredLayerPath) as BaseLayer);
// Unregister layer
Expand Down Expand Up @@ -1280,7 +1277,10 @@ export class LayerApi {
// Trying to get the layer associated with the layer path, can be undefined because the layer might be in error
const theLayer = this.getGeoviewLayer(registeredLayerPath);
if (theLayer) {
if (!registeredLayerPath.startsWith(layerPath) && !layerEntryIsGroupLayer(this.#layerEntryConfigs[registeredLayerPath])) {
if (
!(registeredLayerPath.startsWith(`${layerPath}/`) || registeredLayerPath === layerPath) &&
!layerEntryIsGroupLayer(this.#layerEntryConfigs[registeredLayerPath])
) {
const otherOpacity = theLayer.getOpacity();
theLayer.setOpacity((otherOpacity || 1) * 0.25);
} else this.getOLLayer(registeredLayerPath)!.setZIndex(999);
Expand Down Expand Up @@ -1313,7 +1313,10 @@ export class LayerApi {
// Trying to get the layer associated with the layer path, can be undefined because the layer might be in error
const theLayer = this.getGeoviewLayer(registeredLayerPath);
if (theLayer) {
if (!registeredLayerPath.startsWith(layerPath) && !layerEntryIsGroupLayer(this.#layerEntryConfigs[registeredLayerPath])) {
if (
!(registeredLayerPath.startsWith(`${layerPath}/`) || registeredLayerPath === layerPath) &&
!layerEntryIsGroupLayer(this.#layerEntryConfigs[registeredLayerPath])
) {
const otherOpacity = theLayer.getOpacity();
theLayer.setOpacity(otherOpacity ? otherOpacity * 4 : 1);
} else theLayer.setOpacity(originalOpacity || 1);
Expand Down Expand Up @@ -1348,7 +1351,9 @@ export class LayerApi {

layerIds.forEach((layerId) => {
// Get sublayerpaths and layerpaths from layer IDs.
const subLayerPaths = Object.keys(this.#layerEntryConfigs).filter((layerPath) => layerPath.startsWith(layerId));
const subLayerPaths = Object.keys(this.#layerEntryConfigs).filter(
(layerPath) => layerPath.startsWith(`${layerId}/`) || layerPath === layerId
);

if (subLayerPaths.length) {
// Get max extents from all selected layers.
Expand Down Expand Up @@ -1457,7 +1462,7 @@ export class LayerApi {
const layerVisibility = MapEventProcessor.getMapVisibilityFromOrderedLayerInfo(this.getMapId(), layerPath);
// Determine the outcome of the new visibility based on parameters
const newVisibility = newValue !== undefined ? newValue : !layerVisibility;
const layerInfos = curOrderedLayerInfo.filter((info: TypeOrderedLayerInfo) => info.layerPath.startsWith(layerPath));
const layerInfos = MapEventProcessor.getMapLayerAndChildrenOrderedInfo(this.getMapId(), layerPath, curOrderedLayerInfo);

layerInfos.forEach((layerInfo: TypeOrderedLayerInfo) => {
if (layerInfo) {
Expand Down Expand Up @@ -1491,7 +1496,7 @@ export class LayerApi {
}
const children = curOrderedLayerInfo.filter(
// eslint-disable-next-line no-loop-func
(info: TypeOrderedLayerInfo) => info.layerPath.startsWith(parentLayerPath) && info.layerPath !== parentLayerPath
(info: TypeOrderedLayerInfo) => info.layerPath.startsWith(`${parentLayerPath}/`) && info.layerPath !== parentLayerPath
);
if (!children.some((child: TypeOrderedLayerInfo) => child.visible === true)) {
this.setOrToggleLayerVisibility(parentLayerPath, false);
Expand Down

0 comments on commit 0030f48

Please sign in to comment.