wegue-oss / wegue

Template and components for webmapping applications with OpenLayers and Vue.js
BSD 2-Clause "Simplified" License
97 stars 42 forks source link

Manage TileGrids in LayerFactory instead of MapComponent #309

Open chrismayer opened 1 year ago

chrismayer commented 1 year ago

Currently the TileGrids, which are defined in the app-conf.json are managed withing the MapComponent: the OL TileGrids are instanciated in the created hook of the MapComponent (see here) and are stored in the tileGrids member variable. This works quite well in case you have only static map layers defined in the app-conf.json.

In case you want to create dynamic layers with a custom TileGrid by the LayerFactory this won't work. The TileGrid instance is set within the createLayers function of the MapComponent and not by the LayerFactory. Therefore a layer created in the app code with the LayerFactory is not aware of the TileGrid. In a project / app we used the following overwrite, which works quite well (here for Tile WMS):

// ==========================
// Overwrite LayerFactory with custom changes not (yet) in Wegue master
// ==========================
LayerFactory.tileGrids = {};
LayerFactory.createTileWmsLayer = (lConf) => {
  // apply additional HTTP params
  const params = { 'LAYERS': lConf.layers };
  ObjectUtil.mergeDeep(params, lConf.params);

  // manage TileGrid instances from app config
  const tileGridDefs = Vue.prototype.$appConfig.tileGridDefs || {};
  // Optional TileGrid definitions by name, for ref in Layers
  Object.keys(tileGridDefs).map(name => {
    LayerFactory.tileGrids[name] = new TileGrid(tileGridDefs[name]);
  });
  const tileGrid = lConf.tileGridRef ? LayerFactory.tileGrids[lConf.tileGridRef] : undefined;

  const layer = new TileLayer({
    ...LayerFactory.getCommonLayerOptions(lConf),
    // ...this.getCommonLayerOptions(lConf),
    source: new TileWmsSource({
      url: lConf.url,
      params: params,
      serverType: lConf.serverType,
      tileGrid: tileGrid,
      projection: lConf.projection,
      crossOrigin: lConf.crossOrigin,
      hoverable: lConf.hoverable,
      hoverAttribute: lConf.hoverAttribute,
      hoverOverlay: lConf.hoverOverlay
    })
  });

  return layer;
};
// ==========================
// END Overwrite LayerFactory  
// ==========================

Should I come up with a PR for that or are there any objections for this approach?

/cc @fschmenger @JakobMiksch @justb4 (and anybody else welcome of course)

fschmenger commented 1 year ago

I think the scope of the question should be enhanced. As far as I can see, we have a wrapper on top of the LayerFactory, which currently manages the following config attributes:

All of those won't work as expected, if we instantiate layers by passing in a config object directly into the LayerFactory.

Currently I don`t regard this as a major problem, as the LayerFactory is an internal component and not part of a publicly document API. However, if we think about exposing it as part of the Wegue API, then this requires a structural cleanup.