Layer Config

Now that we have a parser, we can hook that up to a layer. OpenSphere automatically configures layers through registered classes dubbed “layer configs”. Given a JSON object like:

{
  "type": "georss"
}

OpenSphere looks up the registered layer config class for the type georss, instantiates it, and passes it that JSON object to create the layer.

Let’s create that class.

src/plugin/georss/georsslayerconfig.js
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
goog.declareModuleId('plugin.georss.GeoRSSLayerConfig');

import AbstractDataSourceLayerConfig from 'opensphere/src/os/layer/config/abstractdatasourcelayerconfig.js';
import GeoRSSParser from './georssparser.js';

/**
 * GeoRSS layer config.
 */
export default class GeoRSSLayerConfig extends AbstractDataSourceLayerConfig {
  /**
   * Constructor.
   */
  constructor() {
    super();
  }

  /**
   * @inheritDoc
   */
  getParser(options) {
    return new GeoRSSParser();
  }
}

The parent class, os.layer.config.AbstractDataSourceLayerConfig handles most of the heavy lifting and common key/value pairs like title, url, description, etc. All we have to do is pass it a parser.

And, since we are good developers, here is a test for it.

test/plugin/georss/georsslayerconfig.test.js
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
goog.require('plugin.georss.GeoRSSLayerConfig');
goog.require('plugin.georss.GeoRSSParser');

describe('plugin.georss.GeoRSSLayerConfig', function() {
  const {default: GeoRSSLayerConfig} = goog.module.get('plugin.georss.GeoRSSLayerConfig');
  const {default: GeoRSSParser} = goog.module.get('plugin.georss.GeoRSSParser');

  it('should return a GeoRSS parser', function() {
    var config = new GeoRSSLayerConfig();
    expect(config.getParser() instanceof GeoRSSParser).toBe(true);
  });
});

Now that we have that tested, we need to modify our plugin and register the layer config:

src/plugin/georss/georssplugin.js
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
goog.declareModuleId('plugin.georss.GeoRSSPlugin');

import LayerConfigManager from 'opensphere/src/os/layer/config/layerconfigmanager.js';
import AbstractPlugin from 'opensphere/src/os/plugin/abstractplugin.js';
import PluginManager from 'opensphere/src/os/plugin/pluginmanager.js';

import {ID} from './georss.js';
import GeoRSSLayerConfig from './georsslayerconfig.js';

/**
 * Provides support for the GeoRSS format.
 */
export default class GeoRSSPlugin extends AbstractPlugin {
  /**
   * Constructor.
   */
  constructor() {
    super();

    this.id = ID;
    this.errorMessage = null;
  }

  /**
   * @inheritDoc
   */
  init() {
    const lcm = LayerConfigManager.getInstance();
    lcm.registerLayerConfig(ID, GeoRSSLayerConfig);
  }
}

// add the plugin to the application
PluginManager.getInstance().addPlugin(new GeoRSSPlugin());

Running yarn build and viewing the debug instance of the application should allow you to drop this in the console and have a GeoRSS layer:

const {default: CommandProcessor} = goog.module.get('os.command.CommandProcessor');
const {default: LayerAdd} = goog.module.get('os.command.LayerAdd');
CommandProcessor.getInstance().addCommand(
  new LayerAdd({
    type: 'georss',
    id: 'georss-test',
    title: 'Test GeoRSS Layer',
    url: 'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.atom',
    color: 'FFFF00'
  })
);

Cool! But unfortunately this layer is not saved across sessions and it does not support the OpenSphere file/URL import flow. We will do that next!