Skip to content

Commit

Permalink
Refactor remove layer
Browse files Browse the repository at this point in the history
Signed-off-by: Vijayan Balasubramanian <balasvij@amazon.com>
  • Loading branch information
VijayanB committed Jan 31, 2023
1 parent 219c5dc commit ff5d859
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import {
} from '../../model/layerRenderController';
import { MapState } from '../../model/mapState';
import { ConfigSchema } from '../../../common/config';
import {moveLayers} from "../../model/map/layer_operations";

interface MaplibreRef {
current: Maplibre | null;
Expand Down Expand Up @@ -241,7 +242,8 @@ export const LayerControlPanel = memo(

const currentMaplibreLayerId = layers[prevIndex].id;
const beforeMaplibreLayerId = beforeMaplibreLayerID(prevIndex, newIndex);
LayerActions.move(maplibreRef, currentMaplibreLayerId, beforeMaplibreLayerId);

moveLayers(maplibreRef.current!, currentMaplibreLayerId, beforeMaplibreLayerId);

// update map layers
const layersClone = [...layers];
Expand Down
9 changes: 2 additions & 7 deletions public/model/documentLayerFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { getMaplibreBeforeLayerId} from './layersFunctions';
import {
addCircleLayer,
addLineLayer,
addPolygonLayer, hasLayer,
addPolygonLayer, hasLayer, removeLayers,
updateCircleLayer,
updateLineLayer,
updatePolygonLayer,
Expand Down Expand Up @@ -237,12 +237,7 @@ export const DocumentLayerFunctions = {
}
},
remove: (maplibreRef: MaplibreRef, layerConfig: DocumentLayerSpecification) => {
const layers = getCurrentStyleLayers(maplibreRef);
layers.forEach((layer: { id: any }) => {
if (layer.id.includes(layerConfig.id)) {
maplibreRef.current?.removeLayer(layer.id);
}
});
removeLayers(maplibreRef.current!, layerConfig.id, true);
},
hide: (maplibreRef: MaplibreRef, layerConfig: DocumentLayerSpecification) => {
const layers = getCurrentStyleLayers(maplibreRef);
Expand Down
20 changes: 0 additions & 20 deletions public/model/layersFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,6 @@ interface MaplibreRef {
current: Maplibre | null;
}

export const LayerActions = {
move: (maplibreRef: MaplibreRef, sourceId: string, beforeId?: string) => {
const sourceMaplibreLayers = getLayers(maplibreRef.current!, sourceId);
if (!sourceMaplibreLayers) {
return;
}
const beforeMaplibreLayers = getLayers(maplibreRef.current!, beforeId);
if (!beforeMaplibreLayers || beforeMaplibreLayers.length < 1) {
// move to top
sourceMaplibreLayers.forEach((layer) => maplibreRef.current?.moveLayer(layer.id));
return;
}
const topOfBeforeLayer = beforeMaplibreLayers[0];
sourceMaplibreLayers.forEach((layer) =>
maplibreRef.current?.moveLayer(layer.id, topOfBeforeLayer.id)
);
return;
},
};

export const layersFunctionMap: { [key: string]: any } = {
[DASHBOARDS_MAPS_LAYER_TYPE.OPENSEARCH_MAP]: OSMLayerFunctions,
[DASHBOARDS_MAPS_LAYER_TYPE.DOCUMENTS]: DocumentLayerFunctions,
Expand Down
43 changes: 43 additions & 0 deletions public/model/map/__mocks__/map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,37 @@
import { LayerSpecification } from 'maplibre-gl';
import { MockLayer } from './layer';

export type Source = any;

export class MockMaplibreMap {
private _styles: {
layers: MockLayer[];
sources: Map<string, Source>;
};

constructor(layers: MockLayer[]) {
this._styles = {
layers: new Array<MockLayer>(...layers),
sources: new Map<string, Source>(),
};
}

public addSource(sourceId: string, source: Source) {
this._styles.sources.set(sourceId, source);
}

public getSource(sourceId: string): string | undefined {
return this._styles.sources.get(sourceId);
}

public removeSource(sourceId: string) {
this._styles.sources.delete(sourceId);
}

public getLayers(): MockLayer[] {
return [...this._styles.layers];
}

getLayer(id: string): MockLayer[] {
return this._styles.layers.filter((layer) => (layer.getProperty('id') as string).includes(id));
}
Expand Down Expand Up @@ -66,4 +86,27 @@ export class MockMaplibreMap {
});
this._styles.layers.splice(beforeLayerIndex, 0, layer);
}

private move(fromIndex: number, toIndex: number) {
const element = this._styles.layers[fromIndex];
this._styles.layers.splice(fromIndex, 1);
this._styles.layers.splice(toIndex, 0, element);
}

moveLayer(layerId: string, beforeId?: string) {
if (layerId === beforeId) {
return;
}
const fromIndex: number = this._styles.layers.indexOf(this.getLayer(layerId)[0]);
const toIndex: number = beforeId
? this._styles.layers.indexOf(this.getLayer(beforeId)[0])
: this._styles.layers.length;
this.move(fromIndex, toIndex);
}

removeLayer(layerId: string) {
this._styles.layers = this.getLayers().filter(
(layer) => !(layer.getProperty('id') as string).includes(layerId)
);
}
}
60 changes: 59 additions & 1 deletion public/model/map/layer_operations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {
addCircleLayer,
addLineLayer,
addPolygonLayer,
getLayers, hasLayer,
getLayers,
hasLayer, moveLayers, removeLayers,
updateCircleLayer,
updateLineLayer,
updatePolygonLayer,
Expand Down Expand Up @@ -301,3 +302,60 @@ describe('get layer', () => {
expect(hasLayer((mockMap as unknown) as Maplibre, 'layer-1')).toBe(true);
});
});

describe('move layer', () => {
it('should move to top', function () {
const mockLayer1: MockLayer = new MockLayer('layer-1');
const mockLayer2: MockLayer = new MockLayer('layer-11');
const mockLayer3: MockLayer = new MockLayer('layer-2');
const mockMap: MockMaplibreMap = new MockMaplibreMap([mockLayer1, mockLayer2, mockLayer3]);
moveLayers((mockMap as unknown) as Maplibre, 'layer-1');
const reorderedLayer: string[] = mockMap.getLayers().map((layer) => layer.getProperty('id'));
expect(reorderedLayer).toEqual(['layer-2', 'layer-1', 'layer-11']);
});
it('should move before middle layer', function () {
const mockLayer1: MockLayer = new MockLayer('layer-1');
const mockLayer2: MockLayer = new MockLayer('layer-2');
const mockLayer3: MockLayer = new MockLayer('layer-3');
const mockMap: MockMaplibreMap = new MockMaplibreMap([mockLayer1, mockLayer2, mockLayer3]);
moveLayers((mockMap as unknown) as Maplibre, 'layer-1', 'layer-2');
const reorderedLayer: string[] = mockMap.getLayers().map((layer) => layer.getProperty('id'));
expect(reorderedLayer).toEqual(['layer-2', 'layer-1', 'layer-3']);
});
it('should not move if no layer is matched', function () {
const mockLayer1: MockLayer = new MockLayer('layer-1');
const mockLayer2: MockLayer = new MockLayer('layer-2');
const mockLayer3: MockLayer = new MockLayer('layer-3');
const mockMap: MockMaplibreMap = new MockMaplibreMap([mockLayer1, mockLayer2, mockLayer3]);
moveLayers((mockMap as unknown) as Maplibre, 'layer-4', 'layer-2');
const reorderedLayer: string[] = mockMap.getLayers().map((layer) => layer.getProperty('id'));
expect(reorderedLayer).toEqual(['layer-1', 'layer-2', 'layer-3']);
});
});

describe('delete layer', function () {
it('should delete layer without source', function () {
const mockLayer1: MockLayer = new MockLayer('layer-1');
const mockLayer2: MockLayer = new MockLayer('layer-11');
const mockLayer3: MockLayer = new MockLayer('layer-2');
const mockMap: MockMaplibreMap = new MockMaplibreMap([mockLayer1, mockLayer2, mockLayer3]);
mockMap.addSource('layer-1', 'geojson');
removeLayers((mockMap as unknown) as Maplibre, 'layer-1');
expect(mockMap.getLayers().length).toBe(1);
expect(mockMap.getSource('layer-1')).toBeDefined();
expect(mockMap.getLayers()[0].getProperty('id')).toBe('layer-2');
});
it('should delete layer with source', function () {
const mockLayer1: MockLayer = new MockLayer('layer-1');
const mockLayer2: MockLayer = new MockLayer('layer-11');
const mockLayer3: MockLayer = new MockLayer('layer-2');
const mockMap: MockMaplibreMap = new MockMaplibreMap([mockLayer1, mockLayer2, mockLayer3]);
mockMap.addSource('layer-2', 'geojson');
removeLayers((mockMap as unknown) as Maplibre, 'layer-2', true);
expect(mockMap.getLayers().length).toBe(2);
expect(mockMap.getSource('layer-2')).toBeUndefined();
expect(
mockMap.getLayers().filter((layer) => String(layer?.getProperty('id')) === 'layer-2')
).toEqual([]);
});
});
21 changes: 21 additions & 0 deletions public/model/map/layer_operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,27 @@ export const hasLayer = (map: Maplibre, dashboardMapsLayerId: string) => {
return false;
};

export const moveLayers = (map: Maplibre, sourceId: string, beforeId?: string) => {
const sourceLayers = getLayers(map, sourceId);
if (!sourceLayers.length) {
return;
}
const beforeLayers = beforeId ? getLayers(map, beforeId) : [];
const topOfBeforeLayer = beforeLayers.length ? beforeLayers[0].id : undefined;
sourceLayers.forEach((layer) => map?.moveLayer(layer.id, topOfBeforeLayer));
return;
};

export const removeLayers = (map: Maplibre, layerId: string, removeSource?: boolean) => {
getLayers(map, layerId).forEach((layer) => {
map.removeLayer(layer.id);
});
// client might remove source if it is used anymore.
if (removeSource && map.getSource(layerId)) {
map.removeSource(layerId);
}
};

export interface LineLayerSpecification {
sourceId: string;
visibility: string;
Expand Down

0 comments on commit ff5d859

Please sign in to comment.