import ol_Collection from 'ol/Collection.js' import ol_interaction_CurrentMap from './CurrentMap.js'; /** An interaction to copy/paste features on a map. * It will fire a 'focus' event on the map when map is focused (use mapCondition option to handle the condition when the map is focused). * @constructor * @fires focus * @fires copy * @fires paste * @extends {ol_interaction_Interaction} * @param {Object} options Options * @param {function} options.condition a function that takes a mapBrowserEvent and return the action to perform: 'copy', 'cut' or 'paste', default Ctrl+C / Ctrl+V * @param {function} options.mapCondition a function that takes a mapBrowserEvent and return true if the map is the active map, default always returns true * @param {ol.Collection} options.features list of features to copy * @param {ol.source.Vector | Array} options.sources the source to copy from (used for cut), if not defined, it will use the destination * @param {ol.source.Vector} options.destination the source to copy to */ var ol_interaction_CopyPaste = class olinteractionCopyPaste extends ol_interaction_CurrentMap { constructor(options) { options = options || {}; var condition = options.condition; if (typeof (condition) !== 'function') { condition = function (e) { if (e.originalEvent.ctrlKey) { if (/^c$/i.test(e.originalEvent.key)) return 'copy'; if (/^x$/i.test(e.originalEvent.key)) return 'cut'; if (/^v$/i.test(e.originalEvent.key)) return 'paste'; } return false; }; } // Create interaction super({ condition: options.mapCondition, onKeyDown: function (e) { switch (condition(e)) { case 'copy': { self.copy({ silent: false }); break; } case 'cut': { self.copy({ cut: true, silent: false }); break; } case 'paste': { self.paste({ silent: false }); break; } default: break; } } }); var self = this; // Features to copy this.features = []; this._cloneFeature = true; this._featuresSource = options.features || new ol_Collection(); this.setSources(options.sources); this.setDestination(options.destination); } /** * Remove the interaction from its current map and attach it to the new map. * @param {ol_Map} map The map instance. */ setMap(map) { super.setMap(map); this.features = []; } /** Sources to cut feature from * @param { ol.source.Vector | Array } sources */ setSources(sources) { if (sources) { this._source = []; this._source = sources instanceof Array ? sources : [sources]; } else { this._source = null; } } /** Get sources to cut feature from * @return { Array } */ getSources() { return this._source; } /** Source to paste features * @param { ol.source.Vector } source */ setDestination(destination) { this._destination = destination; } /** Get source to paste features * @param { ol.source.Vector } */ getDestination() { return this._destination; } /** Get current feature to copy * @return {Array} */ getFeatures() { return this.features; } /** Set current feature to copy * @param {Object} options * @param {Array | ol.Collection} options.features feature to copy, default get in the provided collection * @param {boolean} options.cut try to cut feature from the sources, default false * @param {boolean} options.silent true to send an event, default true */ copy(options) { options = options || {}; var features = options.features || this._featuresSource.getArray(); // Try to remove feature from sources if (options.cut) { var sources = this._source || [this._destination]; // Remove feature from sources features.forEach(function (f) { sources.forEach(function (source) { try { source.removeFeature(f); } catch (e) { /*ok*/ } }); }); } if (this._cloneFeature) { this.features = []; features.forEach(function (f) { this.features.push(f.clone()); }.bind(this)); } else { this.features = features; } // Send an event if (options.silent === false) this.dispatchEvent({ type: options.cut ? 'cut' : 'copy', time: (new Date).getTime() }); } /** Paste features * @param {Object} options * @param {Array | ol.Collection} features feature to copy, default get current features * @param {ol.source.Vector} options.destination Source to paste to, default the current source * @param {boolean} options.silent true to send an event, default true */ paste(options) { options = options || {}; var features = options.features || this.features; if (features) { var destination = options.destination || this._destination; if (destination) { destination.addFeatures(this.features); if (this._cloneFeature) this.copy({ features: this.features }); } } // Send an event if (options.silent === false) this.dispatchEvent({ type: 'paste', features: features, time: (new Date).getTime() }); } } export default ol_interaction_CopyPaste