Skip to content

Commit

Permalink
Refactor layer operations (#224)
Browse files Browse the repository at this point in the history
* Add layer as constructor parameter
* Refactor get/has layer
* Refactor remove layer
* Refactor visibility property
* Rename visibility layer 

Signed-off-by: Vijayan Balasubramanian <balasvij@amazon.com>
  • Loading branch information
VijayanB authored Feb 1, 2023
1 parent 538628c commit ab56667
Show file tree
Hide file tree
Showing 8 changed files with 265 additions and 165 deletions.
8 changes: 5 additions & 3 deletions public/components/layer_control_panel/layer_control_panel.tsx
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, removeLayers, updateLayerVisibility} 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 Expand Up @@ -288,7 +290,7 @@ export const LayerControlPanel = memo(
layer.visibility = LAYER_VISIBILITY.VISIBLE;
setLayerVisibility(new Map(layerVisibility.set(layer.id, true)));
}
layersFunctionMap[layer.type]?.hide(maplibreRef, layer);
updateLayerVisibility(maplibreRef.current!, layer.id, layer.visibility);
};

const onDeleteLayerIconClick = (layer: MapLayerSpecification) => {
Expand All @@ -298,7 +300,7 @@ export const LayerControlPanel = memo(

const onDeleteLayerConfirm = () => {
if (selectedDeleteLayer) {
layersFunctionMap[selectedDeleteLayer.type]?.remove(maplibreRef, selectedDeleteLayer);
removeLayers(maplibreRef.current!, selectedDeleteLayer.id, true);
removeLayer(selectedDeleteLayer.id);
setIsDeleteLayerModalVisible(false);
setSelectedDeleteLayer(undefined);
Expand Down
74 changes: 24 additions & 50 deletions public/model/OSMLayerFunctions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Map as Maplibre, LayerSpecification } from 'maplibre-gl';
import { OSMLayerSpecification } from './mapLayerType';
import { getMaplibreBeforeLayerId, layerExistInMbSource } from './layersFunctions';
import { getMaplibreBeforeLayerId } from './layersFunctions';
import { getLayers, hasLayer } from './map/layer_operations';

interface MaplibreRef {
current: Maplibre | null;
Expand All @@ -17,36 +18,27 @@ const fetchStyleLayers = (url: string) => {
});
};

const getCurrentStyleLayers = (maplibreRef: MaplibreRef) => {
return maplibreRef.current?.getStyle().layers || [];
};

const handleStyleLayers = (layerConfig: OSMLayerSpecification, maplibreRef: MaplibreRef) => {
const layers = getCurrentStyleLayers(maplibreRef);
layers.forEach((mbLayer) => {
if (mbLayer.id.includes(layerConfig.id)) {
maplibreRef.current?.setLayerZoomRange(
mbLayer.id,
layerConfig.zoomRange[0],
layerConfig.zoomRange[1]
);
// TODO: figure out error reason
if (mbLayer.type === 'symbol') {
return;
}
maplibreRef.current?.setPaintProperty(
mbLayer.id,
`${mbLayer.type}-opacity`,
layerConfig.opacity / 100
);
getLayers(maplibreRef.current!, layerConfig.id).forEach((mbLayer) => {
maplibreRef.current?.setLayerZoomRange(
mbLayer.id,
layerConfig.zoomRange[0],
layerConfig.zoomRange[1]
);
// TODO: figure out error reason
if (mbLayer.type === 'symbol') {
return;
}
maplibreRef.current?.setPaintProperty(
mbLayer.id,
`${mbLayer.type}-opacity`,
layerConfig.opacity / 100
);
});
};

const updateLayerConfig = (layerConfig: OSMLayerSpecification, maplibreRef: MaplibreRef) => {
if (maplibreRef.current) {
handleStyleLayers(layerConfig, maplibreRef);
}
handleStyleLayers(layerConfig, maplibreRef);
};

const addNewLayer = (
Expand All @@ -55,16 +47,16 @@ const addNewLayer = (
beforeLayerId: string | undefined
) => {
if (maplibreRef.current) {
const layerSource = layerConfig?.source;
const layerStyle = layerConfig?.style;
const { source, style } = layerConfig;
maplibreRef.current.addSource(layerConfig.id, {
type: 'vector',
url: layerSource?.dataURL,
url: source?.dataURL,
});
fetchStyleLayers(layerStyle?.styleURL).then((styleLayers: LayerSpecification[]) => {
fetchStyleLayers(style?.styleURL).then((styleLayers: LayerSpecification[]) => {
const beforeMbLayerId = getMaplibreBeforeLayerId(layerConfig, maplibreRef, beforeLayerId);
styleLayers.forEach((styleLayer) => {
styleLayer.id = styleLayer.id + '_' + layerConfig.id;
// TODO: Add comments on why we skip background type
if (styleLayer.type !== 'background') {
styleLayer.source = layerConfig.id;
}
Expand Down Expand Up @@ -98,26 +90,8 @@ export const OSMLayerFunctions = {
) => {
// If layer already exist in maplibre source, update layer config
// else add new layer.
if (layerExistInMbSource(layerConfig.id, maplibreRef)) {
updateLayerConfig(layerConfig, maplibreRef);
} else {
addNewLayer(layerConfig, maplibreRef, beforeLayerId);
}
},
remove: (maplibreRef: MaplibreRef, layerConfig: OSMLayerSpecification) => {
const layers = getCurrentStyleLayers(maplibreRef);
layers.forEach((mbLayer: { id: any }) => {
if (mbLayer.id.includes(layerConfig.id)) {
maplibreRef.current?.removeLayer(mbLayer.id);
}
});
},
hide: (maplibreRef: MaplibreRef, layerConfig: OSMLayerSpecification) => {
const layers = getCurrentStyleLayers(maplibreRef);
layers.forEach((mbLayer: { id: any }) => {
if (mbLayer.id.includes(layerConfig.id)) {
maplibreRef.current?.setLayoutProperty(mbLayer.id, 'visibility', layerConfig.visibility);
}
});
return hasLayer(maplibreRef.current!, layerConfig.id)
? updateLayerConfig(layerConfig, maplibreRef)
: addNewLayer(layerConfig, maplibreRef, beforeLayerId);
},
};
26 changes: 6 additions & 20 deletions public/model/customLayerFunctions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Map as Maplibre, AttributionControl, RasterSourceSpecification } from 'maplibre-gl';
import { CustomLayerSpecification, OSMLayerSpecification } from './mapLayerType';
import { getMaplibreBeforeLayerId, layerExistInMbSource } from './layersFunctions';
import { getMaplibreBeforeLayerId } from './layersFunctions';
import { hasLayer, removeLayers } from './map/layer_operations';

interface MaplibreRef {
current: Maplibre | null;
Expand Down Expand Up @@ -97,26 +98,11 @@ export const CustomLayerFunctions = {
layerConfig: CustomLayerSpecification,
beforeLayerId: string | undefined
) => {
if (layerExistInMbSource(layerConfig.id, maplibreRef)) {
updateLayerConfig(layerConfig, maplibreRef);
} else {
addNewLayer(layerConfig, maplibreRef, beforeLayerId);
}
return hasLayer(maplibreRef.current!, layerConfig.id)
? updateLayerConfig(layerConfig, maplibreRef)
: addNewLayer(layerConfig, maplibreRef, beforeLayerId);
},
remove: (maplibreRef: MaplibreRef, layerConfig: OSMLayerSpecification) => {
const layers = getCurrentStyleLayers(maplibreRef);
layers.forEach((mbLayer: { id: any }) => {
if (mbLayer.id.includes(layerConfig.id)) {
maplibreRef.current?.removeLayer(mbLayer.id);
}
});
},
hide: (maplibreRef: MaplibreRef, layerConfig: OSMLayerSpecification) => {
const layers = getCurrentStyleLayers(maplibreRef);
layers.forEach((mbLayer: { id: any }) => {
if (mbLayer.id.includes(layerConfig.id)) {
maplibreRef.current?.setLayoutProperty(mbLayer.id, 'visibility', layerConfig.visibility);
}
});
removeLayers(maplibreRef.current!, layerConfig.id, true);
},
};
47 changes: 16 additions & 31 deletions public/model/documentLayerFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ import { Map as Maplibre } from 'maplibre-gl';
import { parse } from 'wellknown';
import { DocumentLayerSpecification } from './mapLayerType';
import { convertGeoPointToGeoJSON, isGeoJSON } from '../utils/geo_formater';
import { getMaplibreBeforeLayerId, layerExistInMbSource } from './layersFunctions';
import { getMaplibreBeforeLayerId } from './layersFunctions';
import {
addCircleLayer,
addLineLayer,
addPolygonLayer,
hasLayer,
removeLayers,
updateCircleLayer,
updateLineLayer,
updatePolygonLayer,
updateLayerVisibility,
} from './map/layer_operations';

interface MaplibreRef {
Expand Down Expand Up @@ -175,7 +178,7 @@ const addNewLayer = (
}
};

const updateLayerConfig = (
const updateLayer = (
layerConfig: DocumentLayerSpecification,
maplibreRef: MaplibreRef,
data: any
Expand All @@ -188,35 +191,35 @@ const updateLayerConfig = (
dataSource.setData(getLayerSource(data, layerConfig));
}
updateCircleLayer(maplibreInstance, {
fillColor: layerConfig.style?.fillColor,
fillColor: layerConfig.style.fillColor,
maxZoom: layerConfig.zoomRange[1],
minZoom: layerConfig.zoomRange[0],
opacity: layerConfig.opacity,
outlineColor: layerConfig.style?.borderColor,
outlineColor: layerConfig.style.borderColor,
radius: layerConfig.style?.markerSize,
sourceId: layerConfig.id,
visibility: layerConfig.visibility,
width: layerConfig.style?.borderThickness,
width: layerConfig.style.borderThickness,
});
const geoFieldType = getGeoFieldType(layerConfig);
if (geoFieldType === 'geo_shape') {
updateLineLayer(maplibreInstance, {
width: layerConfig.style?.borderThickness,
color: layerConfig.style?.fillColor,
width: layerConfig.style.borderThickness,
color: layerConfig.style.fillColor,
maxZoom: layerConfig.zoomRange[1],
minZoom: layerConfig.zoomRange[0],
opacity: layerConfig.opacity,
sourceId: layerConfig.id,
visibility: layerConfig.visibility,
});
updatePolygonLayer(maplibreInstance, {
width: layerConfig.style?.borderThickness,
fillColor: layerConfig.style?.fillColor,
width: layerConfig.style.borderThickness,
fillColor: layerConfig.style.fillColor,
maxZoom: layerConfig.zoomRange[1],
minZoom: layerConfig.zoomRange[0],
opacity: layerConfig.opacity,
sourceId: layerConfig.id,
outlineColor: layerConfig.style?.borderColor,
outlineColor: layerConfig.style.borderColor,
visibility: layerConfig.visibility,
});
}
Expand All @@ -230,26 +233,8 @@ export const DocumentLayerFunctions = {
data: any,
beforeLayerId: string | undefined
) => {
if (layerExistInMbSource(layerConfig.id, maplibreRef)) {
updateLayerConfig(layerConfig, maplibreRef, data);
} else {
addNewLayer(layerConfig, maplibreRef, data, beforeLayerId);
}
},
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);
}
});
},
hide: (maplibreRef: MaplibreRef, layerConfig: DocumentLayerSpecification) => {
const layers = getCurrentStyleLayers(maplibreRef);
layers.forEach((layer) => {
if (layer.id.includes(layerConfig.id)) {
maplibreRef.current?.setLayoutProperty(layer.id, 'visibility', layerConfig.visibility);
}
});
return hasLayer(maplibreRef.current!, layerConfig.id)
? updateLayer(layerConfig, maplibreRef, data)
: addNewLayer(layerConfig, maplibreRef, data, beforeLayerId);
},
};
48 changes: 2 additions & 46 deletions public/model/layersFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { OSMLayerFunctions } from './OSMLayerFunctions';
import { DocumentLayerFunctions } from './documentLayerFunctions';
import { MapLayerSpecification } from './mapLayerType';
import { CustomLayerFunctions } from './customLayerFunctions';
import { getLayers } from './map/layer_operations';

interface MaplibreRef {
current: Maplibre | null;
Expand All @@ -22,37 +23,6 @@ interface MaplibreRef {
current: Maplibre | null;
}

const getAllMaplibreLayersIncludesId = (maplibreRef: MaplibreRef, layerId?: string) => {
if (!layerId && !maplibreRef) {
return [];
}
return (
maplibreRef.current
?.getStyle()
.layers.filter((layer) => layer.id?.includes(String(layerId)) === true) || []
);
};

export const LayerActions = {
move: (maplibreRef: MaplibreRef, sourceId: string, beforeId?: string) => {
const sourceMaplibreLayers = getAllMaplibreLayersIncludesId(maplibreRef, sourceId);
if (!sourceMaplibreLayers) {
return;
}
const beforeMaplibreLayers = getAllMaplibreLayersIncludesId(maplibreRef, 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 All @@ -65,16 +35,12 @@ export const layersTypeNameMap: { [key: string]: string } = {
[DASHBOARDS_MAPS_LAYER_TYPE.CUSTOM_MAP]: DASHBOARDS_MAPS_LAYER_NAME.CUSTOM_MAP,
};

const getCurrentStyleLayers = (maplibreRef: MaplibreRef) => {
return maplibreRef.current?.getStyle().layers || [];
};

export const getMaplibreBeforeLayerId = (
selectedLayer: MapLayerSpecification,
maplibreRef: MaplibreRef,
beforeLayerId: string | undefined
): string | undefined => {
const currentLoadedMbLayers = getCurrentStyleLayers(maplibreRef);
const currentLoadedMbLayers = getLayers(maplibreRef.current!);
if (beforeLayerId) {
const beforeMbLayer = currentLoadedMbLayers.find((mbLayer) =>
mbLayer.id.includes(beforeLayerId)
Expand All @@ -84,16 +50,6 @@ export const getMaplibreBeforeLayerId = (
return undefined;
};

export const layerExistInMbSource = (layerConfigId: string, maplibreRef: MaplibreRef) => {
const layers = getCurrentStyleLayers(maplibreRef);
for (const layer in layers) {
if (layers[layer].id.includes(layerConfigId)) {
return true;
}
}
return false;
};

export const layersTypeIconMap: { [key: string]: string } = {
[DASHBOARDS_MAPS_LAYER_TYPE.OPENSEARCH_MAP]: DASHBOARDS_MAPS_LAYER_ICON.OPENSEARCH_MAP,
[DASHBOARDS_MAPS_LAYER_TYPE.DOCUMENTS]: DASHBOARDS_MAPS_LAYER_ICON.DOCUMENTS,
Expand Down
Loading

0 comments on commit ab56667

Please sign in to comment.