/** * Provides access to the JOSM layers. * * @module josm/layers */ /* global Java */ // -- imports const MainApplication = Java.type('org.openstreetmap.josm.gui.MainApplication') const OsmDataLayer = Java.type('org.openstreetmap.josm.gui.layer.OsmDataLayer') const DataSet = Java.type('org.openstreetmap.josm.data.osm.DataSet') const Layer = Java.type('org.openstreetmap.josm.gui.layer.Layer') import * as util from './util' /** * Provides access to JOSM layers. */ export class Layers { /** * Replies the number of currently open layers. * * @readOnly * @type {number} */ get length() { return MainApplication.getLayerManager().getLayers().size() } /** * Set or get the active layer. * * <dl> * <dt>get</dt> * <dd class="param-desc">Replies the active layer or undefined.</dd> * * <dt>set</dt> * <dd class="param-desc">Assign either an existing {@class org.openstreetmap.josm.gui.layer.Layer}, * the name of a layer as string, or a layer index as number.</dd> * </dl> * * @type {org.openstreetmap.josm.gui.layer.Layer} */ get activeLayer() { return MainApplication.getLayerManager().getActiveLayer() } set activeLayer(value) { util.assert(util.isSomething(value),'Value must not be null or undefined)') let layer = null if (value instanceof Layer) { layer = value } else if (util.isNumber(value) || util.isString(value)) { layer = layers.get(value) } else { util.assert(false, 'Unexpected type of value, got {0}', value) } util.assert(util.isSomething(layer), 'Layer \'\'{0}\'\' doesn\'\'t exist. It can\'\'t be set as active layer.', value) MainApplication.getLayerManager().setActiveLayer(layer) } #getLayerByName (key) { key = util.trim(key).toLowerCase() if (this.length === 0) return undefined const layers = MainApplication.getLayerManager().getLayers() for (let it = layers.iterator(); it.hasNext();) { const l = it.next() if (l.getName().trim().toLowerCase() === key) return l } return undefined } #getLayerByIndex (idx) { if (idx < 0 || idx >= this.length) return undefined const layers = MainApplication.getLayerManager().getLayers() return layers.get(idx) } /** * Replies one of the layers given a key. * * <ul> * <li>If <code>key</code> is a number, replies the layer with index key, or * undefined, if no layer for this index exists.</li> * <li>If <code>key</code> is a string, replies the first layer whose name * is identical to key (case insensitive, without leading/trailing * whitespace), or undefined, if no layer with such a name exists.</li> * </ul> * * @example * import layers from 'josm/layers' * * // get the first layer * const layer1 = layers.get(0) * * // get the first layer with name "data layer" * const layer2 = layers.get('data layer') * * @param {number|string} key the key to retrieve the layer * @returns {org.openstreetmap.josm.gui.layer.Layer} */ get(key) { if (util.isNothing(key)) return undefined if (util.isString(key)) return this.#getLayerByName(key) if (util.isNumber(key)) return this.#getLayerByIndex(key) return undefined } /** * Checks whether <code>layer</code> is a currently registered layer. * * @example * import layers from 'josm/layers' * * // is there a layer with name "my layer"? * let b = layers.has('my layer') * * // is there a layer at index position 2 * b = layers.has(2) * * // is there a specific layer? * let l = layers.get(0) * b = layers.has(l) * * @param {org.openstreetmap.josm.gui.layer.Layer|string|number} layer a layer, * a layer name, or a layer index * @returns {boolean } true, if the layer or at least one layer with the given name exists. * False, otherwise. */ has(layer) { if (util.isNothing(layer)) return false const layerManager = MainApplication.getLayerManager() if (layer instanceof Layer) { return layerManager.getLayers().contains(layer) } else if (util.isString(layer)) { return util.isSomething(layers.get(layer)) } else if (util.isNumber(layer)) { return layer >= 0 && layer < layers.length } else { return false } } /** * Adds a layer. * <p> * Either pass in a layer object or a data set. In the later case, an * {@class org.openstreetmap.josm.gui.layer.OsmDataLayer} is * automatically created. * * @example * import layers from 'josm/layers' * const OsmDataLayer = Java.type('org.openstreetmap.josm.gui.layer.OsmDataLayer') * const DataSet = Java.type('org.openstreetmap.josm.data.osm.DataSet') * * const dataLayer = new OsmDataLayer(new DataSet(), null, null); * // add a layer ... * layers.add(dataLayer) * * // or add a dataset, which will create a data layer * const ds = new DataSet() * layer.add(ds) * * @param {org.openstreetmap.josm.gui.layer.Layer * |org.openstreetmap.josm.data.osm.DataSet} obj a layer to add, * or a dataset. Ignored if null or undefined. * @returns {org.openstreetmap.josm.gui.layer.Layer} the added layer */ add(obj) { if (util.isNothing(obj)) return const layerManager = MainApplication.getLayerManager() if (obj instanceof Layer) { layerManager.addLayer(obj) } else if (obj instanceof DataSet) { layerManager.addLayer(new OsmDataLayer(obj, null, null)) } else { util.assert(false, 'Expected an instance of Layer or DataSet, got {0}', obj) } } #removeLayerByIndex (idx) { const layer = this.get(idx) if (util.isNothing(layer)) return MainApplication.getLayerManager().removeLayer(layer) } #removeLayerByName (name) { const layer = this.get(name) if (util.isNothing(layer)) return MainApplication.getLayerManager().removeLayer(layer) } /** * Removes a layer with the given key. * * <ul> * <li>If <code>key</code> is a <code>Number</code>, removes the layer with * the index key. If the index doesn't isn't a valid layer index, nothing * is removed.</li> * <li>If <code>key</code> is a <code>string</code>, removes the layer with * the name <code>key</code>. Leading and trailing white space is removed, * matching is a case-insensitive sub-string match.</li> * </ul> * @example * import josm from 'josm' * * // remove the first layer * josm.layers.remove(0) * * // remove the first layer matching with the supplied name * josm.layers.remove('myLayerName') * * @param {number|string} key indicates the layer to remove */ remove(key) { if (util.isNothing(key)) return if (util.isNumber(key)) { this.#removeLayerByIndex(key) } else if (util.isString(key)) { this.#removeLayerByName(key) } else { util.assert(false, 'Expected a number or a string, got {0}', key) } } /** * Creates and adds a new data layer. The new layer becomes the new edit * layer. * <p> * * <string>Signatures</string> * <dl> * <dt><code class="signature">addDataLayer()</code></dt> * <dd class="param-desc">create data layer with a new dataset and default name</dd> * <dt><code class="signature">addDataLayer(ds)</code></dt> * <dd class="param-desc">create data layer with dataset ds and default name</dd> * <dt><code class="signature">addDataLayer(name)</code></dt> * <dd class="param-desc">create data layer with a new dataset and name <code>name</code></dd> * <dt><code class="signature">addDataLayer({name: ..., ds: ...})</code></dt> * <dd class="param-desc">create data layer with a new dataset and name <code>name</code></dd> * </dl> * @example * import josm from 'josm' * const DataSet = Java.type('org.openstreetmap.josm.data.osm.DataSet') * * // creates a new data layer * const l1 = josm.layers.addDataLayer() * * // creates a new data layer with name 'test' * const l2 = josm.layers.addDataLayer('test') * * // creates a new data layer for the dataset ds * const ds = new DataSet() * const l3 = josm.layers.addDataLayer(ds) * * @returns {org.openstreetmap.josm.gui.layer.OsmDataLayer} the added layer * @param {string | org.openstreetmap.josm.data.osm.DataSet | object } args see description */ addDataLayer() { let name, ds switch (arguments.length) { case 0: break case 1: if (util.isString(arguments[0])) { name = util.trim(arguments[0]) } else if (arguments[0] instanceof DataSet) { ds = arguments[0] } else if (typeof arguments[0] === 'object') { if (util.isString(arguments[0].name)) { name = util.trim(arguments[0].name) } if (arguments[0].ds instanceof DataSet) { ds = arguments[0].ds } } else { util.assert(false, 'unsupported type of argument, got {0}', arguments[0]) } break default: util.assert(false, 'Unsupported number of arguments, got {0}', arguments.length) } ds = ds || new DataSet() name = name || OsmDataLayer.createNewName() const layer = new OsmDataLayer(ds, name, null /* no file */) layers.add(layer) return layer } } /** * the singleton instance of the layers class */ const layers = new Layers() export default layers