diff --git a/src/ol/feature.exports b/src/ol/feature.exports index 69f6322038..08e79a2c8c 100644 --- a/src/ol/feature.exports +++ b/src/ol/feature.exports @@ -1,4 +1,5 @@ @exportSymbol ol.Feature -@exportProperty ol.Feature.prototype.getGeometry +@exportProperty ol.Feature.prototype.getGeometryName +@exportProperty ol.Feature.prototype.setGeometryName @exportProperty ol.Feature.prototype.getId @exportProperty ol.Feature.prototype.setId diff --git a/src/ol/feature.js b/src/ol/feature.js index 63127bb16b..f930fff6f8 100644 --- a/src/ol/feature.js +++ b/src/ol/feature.js @@ -12,7 +12,6 @@ goog.require('ol.style.Style'); * @enum {string} */ ol.FeatureProperty = { - GEOMETRY: 'geometry', STYLE_FUNCTION: 'styleFunction' }; @@ -40,6 +39,12 @@ ol.Feature = function(opt_geometryOrValues) { */ this.id_ = undefined; + /** + * @type {string} + * @private + */ + this.geometryName_ = 'geometry'; + /** * @private * @type {number} @@ -53,7 +58,7 @@ ol.Feature = function(opt_geometryOrValues) { this.geometryChangeKey_ = null; goog.events.listen( - this, ol.Object.getChangeEventType(ol.FeatureProperty.GEOMETRY), + this, ol.Object.getChangeEventType(this.geometryName_), this.handleGeometryChanged_, false, this); goog.events.listen( this, ol.Object.getChangeEventType(ol.FeatureProperty.STYLE_FUNCTION), @@ -89,7 +94,7 @@ ol.Feature.prototype.dispatchChangeEvent = function() { */ ol.Feature.prototype.getGeometry = function() { return /** @type {ol.geom.Geometry|undefined} */ ( - this.get(ol.FeatureProperty.GEOMETRY)); + this.get(this.geometryName_)); }; goog.exportProperty( ol.Feature.prototype, @@ -105,6 +110,14 @@ ol.Feature.prototype.getId = function() { }; +/** + * @return {string} Geometry property name. + */ +ol.Feature.prototype.getGeometryName = function() { + return this.geometryName_; +}; + + /** * @return {number} Revision. */ @@ -163,7 +176,7 @@ ol.Feature.prototype.handleStyleFunctionChange_ = function() { * @param {ol.geom.Geometry|undefined} geometry Geometry. */ ol.Feature.prototype.setGeometry = function(geometry) { - this.set(ol.FeatureProperty.GEOMETRY, geometry); + this.set(this.geometryName_, geometry); }; goog.exportProperty( ol.Feature.prototype, @@ -189,3 +202,18 @@ goog.exportProperty( ol.Feature.prototype.setId = function(id) { this.id_ = id; }; + + +/** + * @param {string} name Geometry property name. + */ +ol.Feature.prototype.setGeometryName = function(name) { + goog.events.unlisten( + this, ol.Object.getChangeEventType(this.geometryName_), + this.handleGeometryChanged_, false, this); + this.geometryName_ = name; + goog.events.listen( + this, ol.Object.getChangeEventType(this.geometryName_), + this.handleGeometryChanged_, false, this); + this.handleGeometryChanged_(); +}; diff --git a/test/spec/ol/feature.test.js b/test/spec/ol/feature.test.js new file mode 100644 index 0000000000..afbf896ed9 --- /dev/null +++ b/test/spec/ol/feature.test.js @@ -0,0 +1,216 @@ +goog.provide('ol.test.Feature'); + +describe('ol.Feature', function() { + + describe('constructor', function() { + + it('creates a new feature', function() { + var feature = new ol.Feature(); + expect(feature).to.be.a(ol.Feature); + }); + + it('takes attribute values', function() { + var feature = new ol.Feature({ + foo: 'bar' + }); + expect(feature.get('foo')).to.be('bar'); + }); + + it('can store the feature\'s commonly used id', function() { + var feature = new ol.Feature(); + feature.setId('foo'); + expect(feature.getId()).to.be('foo'); + }); + + it('will set the default geometry', function() { + var feature = new ol.Feature({ + geometry: new ol.geom.Point([10, 20]), + foo: 'bar' + }); + var geometry = feature.getGeometry(); + expect(geometry).to.be.a(ol.geom.Point); + expect(feature.get('geometry')).to.be(geometry); + }); + + }); + + describe('#get()', function() { + + it('returns values set at construction', function() { + var feature = new ol.Feature({ + a: 'first', + b: 'second' + }); + expect(feature.get('a')).to.be('first'); + expect(feature.get('b')).to.be('second'); + }); + + it('returns undefined for unset attributes', function() { + var feature = new ol.Feature(); + expect(feature.get('a')).to.be(undefined); + }); + + it('returns values set by set', function() { + var feature = new ol.Feature(); + feature.set('a', 'b'); + expect(feature.get('a')).to.be('b'); + }); + + }); + + describe('#getAttributes()', function() { + + it('returns an object with all attributes', function() { + var point = new ol.geom.Point([15, 30]); + var feature = new ol.Feature({ + foo: 'bar', + ten: 10, + geometry: point + }); + + var attributes = feature.getProperties(); + + var keys = goog.object.getKeys(attributes); + expect(keys.sort()).to.eql(['foo', 'geometry', 'ten']); + + expect(attributes.foo).to.be('bar'); + expect(attributes.geometry).to.be(point); + expect(attributes.ten).to.be(10); + }); + + }); + + + describe('#getGeometry()', function() { + + var point = new ol.geom.Point([15, 30]); + + it('returns null for no geometry', function() { + var feature = new ol.Feature(); + expect(feature.getGeometry()).to.be(null); + }); + + it('gets the geometry set at construction', function() { + var feature = new ol.Feature({ + geometry: point + }); + expect(feature.getGeometry()).to.be(point); + }); + + it('gets any geometry set by setGeometry', function() { + var feature = new ol.Feature(); + feature.setGeometry(point); + expect(feature.getGeometry()).to.be(point); + + var point2 = new ol.geom.Point([1, 2]); + feature.setGeometry(point2); + expect(feature.getGeometry()).to.be(point2); + }); + + }); + + describe('#set()', function() { + + it('sets values', function() { + var feature = new ol.Feature({ + a: 'first', + b: 'second' + }); + feature.set('a', 'new'); + expect(feature.get('a')).to.be('new'); + }); + + it('can be used to set the geometry', function() { + var point = new ol.geom.Point([3, 4]); + var feature = new ol.Feature({ + geometry: new ol.geom.Point([1, 2]) + }); + feature.set('geometry', point); + expect(feature.get('geometry')).to.be(point); + expect(feature.getGeometry()).to.be(point); + }); + + it('can be used to set attributes with arbitrary names', function() { + + var feature = new ol.Feature(); + + feature.set('toString', 'string'); + expect(feature.get('toString')).to.be('string'); + expect(typeof feature.toString).to.be('function'); + + feature.set('getGeometry', 'x'); + expect(feature.get('getGeometry')).to.be('x'); + + feature.set('geometry', new ol.geom.Point([1, 2])); + expect(feature.getGeometry()).to.be.a(ol.geom.Point); + + }); + + }); + + describe('#setGeometry()', function() { + + var point = new ol.geom.Point([15, 30]); + + it('sets the default geometry', function() { + var feature = new ol.Feature(); + feature.setGeometry(point); + expect(feature.get('geometry')).to.be(point); + }); + + it('replaces previous default geometry', function() { + var feature = new ol.Feature({ + geometry: point + }); + expect(feature.getGeometry()).to.be(point); + + var point2 = new ol.geom.Point([1, 2]); + feature.setGeometry(point2); + expect(feature.getGeometry()).to.be(point2); + }); + + }); + + describe('#setGeometryName()', function() { + + var point = new ol.geom.Point([15, 30]); + + it('sets property where to to look at geometry', function() { + var feature = new ol.Feature(); + feature.setGeometry(point); + expect(feature.getGeometry()).to.be(point); + + var point2 = new ol.geom.Point([1, 2]); + feature.set('altGeometry', point2); + expect(feature.getGeometry()).to.be(point); + feature.setGeometryName('altGeometry'); + expect(feature.getGeometry()).to.be(point2); + + feature.on('change', function() { + expect.fail(); + }); + point.setCoordinates([0, 2]); + }); + + it('changes property listener', function(done) { + var feature = new ol.Feature(); + feature.setGeometry(point); + var point2 = new ol.geom.Point([1, 2]); + feature.set('altGeometry', point2); + feature.setGeometryName('altGeometry'); + + feature.on('change', function() { + done(); + }); + point2.setCoordinates([0, 2]); + }); + + }); + +}); + + +goog.require('goog.events'); +goog.require('goog.object'); +goog.require('ol.Feature'); +goog.require('ol.geom.Point');