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

fix(layers): fixes geocore layers not appearing in service order #2685

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading