goog.provide('ol.Feature'); goog.provide('ol.FeatureEvent'); goog.provide('ol.FeatureEventType'); goog.provide('ol.FeatureRenderIntent'); goog.require('goog.events'); goog.require('goog.events.Event'); goog.require('goog.events.EventType'); goog.require('ol.Object'); goog.require('ol.geom.Geometry'); /** * Create a new feature. A feature is the base entity for vectors and has * attributes, including normally a geometry attribute. * * Example: * * var feature = new ol.Feature({'foo': 'bar'}); * feature.setGeometry(new ol.geom.Point([100, 500])); * * @constructor * @extends {ol.Object} * @param {Object.=} opt_values Attributes. * @todo stability experimental */ ol.Feature = function(opt_values) { /** * @type {ol.Extent} * @private */ this.geometryExtent_ = null; goog.base(this, opt_values); /** * @type {string|undefined} * @private */ this.featureId_; /** * @type {string|undefined} * @private */ this.geometryName_; /** * The render intent for this feature. * @type {ol.FeatureRenderIntent|string} * @private */ this.renderIntent_ = ol.FeatureRenderIntent.DEFAULT; /** * @type {Array.} * @private */ this.symbolizers_ = null; }; goog.inherits(ol.Feature, ol.Object); /** * Gets a copy of the attributes of this feature. * @param {boolean=} opt_nonGeometry Don't include any geometry attributes * (by default geometry attributes are returned). * @return {Object.} Attributes object. * @todo stability experimental */ ol.Feature.prototype.getAttributes = function(opt_nonGeometry) { var keys = this.getKeys(), includeGeometry = !opt_nonGeometry, len = keys.length, attributes = {}, i, value, key; for (i = 0; i < len; ++ i) { key = keys[i]; value = this.get(key); if (includeGeometry || !(value instanceof ol.geom.Geometry)) { attributes[key] = value; } } return attributes; }; /** * Returns the feature's commonly used identifier. This identifier is usually * the unique id in the source store. * * @return {string|undefined} The feature's identifier. * @todo stability experimental */ ol.Feature.prototype.getId = function() { return this.featureId_; }; /** * Get the geometry associated with this feature. * @return {ol.geom.Geometry} The geometry (or null if none). * @todo stability experimental */ ol.Feature.prototype.getGeometry = function() { return goog.isDef(this.geometryName_) ? /** @type {ol.geom.Geometry} */ (this.get(this.geometryName_)) : null; }; /** * Get any symbolizers set directly on the feature. * @return {Array.} Symbolizers (or null if none). */ ol.Feature.prototype.getSymbolizers = function() { return this.symbolizers_; }; /** * Listener for geometry change events. * @param {goog.events.Event} evt Change event. * @private */ ol.Feature.prototype.handleGeometryChange_ = function(evt) { var oldExtent = this.geometryExtent_; this.geometryExtent_ = this.getGeometry().getBounds(); this.dispatchEvent(new ol.FeatureEvent( ol.FeatureEventType.CHANGE, this, oldExtent)); }; /** * @inheritDoc * @param {string} key Key. * @param {*} value Value. * @todo stability experimental */ ol.Feature.prototype.set = function(key, value) { var geometry = this.getGeometry(); var oldExtent = this.geometryExtent_; if (goog.isDefAndNotNull(geometry)) { if (key === this.geometryName_) { this.geometryExtent_ = null; goog.events.unlisten(geometry, goog.events.EventType.CHANGE, this.handleGeometryChange_, false, this); } } if (value instanceof ol.geom.Geometry) { if (!goog.isDef(this.geometryName_)) { this.geometryName_ = key; } if (key === this.geometryName_) { this.geometryExtent_ = value.getBounds(); goog.events.listen(value, goog.events.EventType.CHANGE, this.handleGeometryChange_, false, this); } } goog.base(this, 'set', key, value); this.dispatchEvent(new ol.FeatureEvent( ol.FeatureEventType.CHANGE, this, oldExtent)); }; /** * Set the feature's commonly used identifier. This identifier is usually the * unique id in the source store. * * @param {string|undefined} featureId The feature's identifier. */ ol.Feature.prototype.setId = function(featureId) { this.featureId_ = featureId; }; /** * Set the geometry to be associated with this feature after its creation. * @param {ol.geom.Geometry} geometry The geometry. * @todo stability experimental */ ol.Feature.prototype.setGeometry = function(geometry) { if (!goog.isDef(this.geometryName_)) { this.geometryName_ = ol.Feature.DEFAULT_GEOMETRY; } this.set(this.geometryName_, geometry); }; /** * Gets the renderIntent for this feature. * @return {string} Render intent. */ ol.Feature.prototype.getRenderIntent = function() { return this.renderIntent_; }; /** * Changes the renderIntent for this feature. * @param {string} renderIntent Render intent. */ ol.Feature.prototype.setRenderIntent = function(renderIntent) { this.renderIntent_ = renderIntent; var geometry = this.getGeometry(); if (!goog.isNull(geometry)) { this.dispatchEvent(new ol.FeatureEvent( ol.FeatureEventType.INTENTCHANGE, this, geometry.getBounds())); } }; /** * Set the symbolizers to be used for this feature. * @param {Array.} symbolizers Symbolizers for this * feature. If set, these take precedence over layer style. */ ol.Feature.prototype.setSymbolizers = function(symbolizers) { this.symbolizers_ = symbolizers; }; /** * @const * @type {string} */ ol.Feature.DEFAULT_GEOMETRY = 'geometry'; /** * @enum {string} */ ol.FeatureRenderIntent = { DEFAULT: 'default', FUTURE: 'future', HIDDEN: 'hidden', SELECTED: 'selected', TEMPORARY: 'temporary' }; /** * @enum {string} */ ol.FeatureEventType = { CHANGE: 'featurechange', INTENTCHANGE: 'featureintentchange' }; /** * Constructor for feature events. * @constructor * @extends {goog.events.Event} * @param {string} type Event type. * @param {ol.Feature} target The target feature. * @param {ol.Extent} oldExtent The previous geometry extent. */ ol.FeatureEvent = function(type, target, oldExtent) { goog.base(this, type, target); this.oldExtent = oldExtent; }; goog.inherits(ol.FeatureEvent, goog.events.Event);