mapview_addLayer.mjs

/**
## /mapview/addLayer

The module exports the addLayer method which is bound to the mapview.

@module /mapview/addLayer
*/

/**
@function addLayer

@description
A single or an array of JSON layer can be added to the mapview with the addLayer method.

A default zIndex is assigned to layer without an implicit zIndex.

A structuredClone of the JSON layer will be merged into a clone of the locale.layer template to be decorated and assigned to the mapview [this] layers.

The mapview [this] to which the addLayer method is bound will be assigned to the layer object.

A layer with a valid format property will be decorated and added to the mapview.layers{} object.

Layer with a display flag will shown in the mapview.

A renderComplete event will be assigned to the Openlayers mapview.Map{}. This promise will resolve once after all layer to be shown in the addLayer method have completed their render.

@param {object} layers A single JSON layer or an array of JSON layer to be added to the mapview.

@returns {array} The array of decorated layers is returned.
*/
export default async function addLayer(layers) {
  // A single JSON layer is provided.
  if (layers instanceof Object && !Array.isArray(layers)) {
    // Create array of layers with single JSON layer.
    layers = [layers];
  }

  // A set of the layers is required in order to control the display based on URL params [hooks]
  const layersSet = this.hooks && new Set(mapp.hooks.current.layers);

  const decoratedLayers = [];

  for (let i = 0; i < layers.length; i++) {
    // The JSON layer is merged into the locale.layer
    const layer = mapp.utils.merge(
      {},
      structuredClone(this.locale.layer || {}),
      structuredClone(layers[i]),
    );

    // The layer.err is an array of errors from failing to retrieve templates asscoiated with a layer.
    layer.err && console.error(layer.err);

    // A default zIndex is assigned from the loop index to ensure layers are drawn in the order without an implicit zIndex.
    layer.zIndex ??= i;

    layer.mapview = this;

    // Only the layers in the layerset should be displayed.
    // Will override the layer.display setting from the workspace
    if (layersSet?.size) {
      layer.display = layersSet.has(layer.key);
    }

    // Layer without format should not be decorated.
    if (!layer.format) continue;

    // Assign default key if not explicit in layer JSON.
    layer.key ??= `${layer.format}-${i}`;

    // Check the layer format.
    if (!mapp.layer.formats[layer.format]) {
      console.error(`Layer: ${layer.key}; Format: ${layer.format} is unknown.`);
      continue;
    }

    await mapp.layer.decorate(layer);

    if (!layer.L) continue;

    // Assign layer to array returned from method.
    decoratedLayers.push(layer);

    this.layers[layer.key] = layer;

    layer.display && layer.show();
  }

  // Will resolve once the map has completed render.
  this.renderComplete = new Promise((resolve) => {
    this.Map.once('rendercomplete', resolve);
  });

  return decoratedLayers;
}