diff --git a/examples/vector-layer.js b/examples/vector-layer.js index f8103b0044..be99803e4c 100644 --- a/examples/vector-layer.js +++ b/examples/vector-layer.js @@ -48,7 +48,7 @@ map.on(['click', 'mousemove'], function(evt) { success: function(features) { var info = []; for (var i = 0, ii = features.length; i < ii; ++i) { - info.push(features[i].get('name')); + info.push(features[i].getFeatureId() + ': ' + features[i].get('name')); } document.getElementById('info').innerHTML = info.join(', ') || ' '; } diff --git a/src/ol/feature.exports b/src/ol/feature.exports index 67545ce3d5..77a493fac0 100644 --- a/src/ol/feature.exports +++ b/src/ol/feature.exports @@ -1,7 +1,9 @@ @exportSymbol ol.Feature @exportProperty ol.Feature.prototype.get @exportProperty ol.Feature.prototype.getAttributes +@exportProperty ol.Feature.prototype.getFeatureId @exportProperty ol.Feature.prototype.getGeometry @exportProperty ol.Feature.prototype.set +@exportProperty ol.Feature.prototype.setFeatureId @exportProperty ol.Feature.prototype.setGeometry @exportProperty ol.Feature.prototype.setSymbolizers diff --git a/src/ol/feature.js b/src/ol/feature.js index 199ddeb318..3430e109de 100644 --- a/src/ol/feature.js +++ b/src/ol/feature.js @@ -14,6 +14,12 @@ ol.Feature = function(opt_values) { goog.base(this, opt_values); + /** + * @type {string|undefined} + * @private + */ + this.featureId_; + /** * @type {string|undefined} * @private @@ -46,6 +52,17 @@ ol.Feature.prototype.getAttributes = function() { }; +/** + * 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. + */ +ol.Feature.prototype.getFeatureId = function() { + return this.featureId_; +}; + + /** * @return {ol.geom.Geometry} The geometry (or null if none). */ @@ -85,6 +102,17 @@ ol.Feature.prototype.set = function(key, value) { }; +/** + * Set the feature's commonly used identifier. This identifier is usually the + * unique id in the source store. + * + * @param {string} featureId The feature's identifier. + */ +ol.Feature.prototype.setFeatureId = function(featureId) { + this.featureId_ = featureId; +}; + + /** * @param {ol.geom.Geometry} geometry The geometry. */ diff --git a/src/ol/parser/geojson.js b/src/ol/parser/geojson.js index ca55c5b923..8630f4b2cb 100644 --- a/src/ol/parser/geojson.js +++ b/src/ol/parser/geojson.js @@ -144,6 +144,9 @@ ol.parser.GeoJSON.prototype.parseFeature_ = function(json, opt_options) { geometry = null, options = opt_options || {}; var feature = new ol.Feature(json.properties); + if (goog.isDef(json.id)) { + feature.setFeatureId(json.id); + } if (geomJson) { var type = geomJson.type; var callback = options.callback; diff --git a/src/ol/parser/kml.js b/src/ol/parser/kml.js index 1133f75d39..a64c05bb31 100644 --- a/src/ol/parser/kml.js +++ b/src/ol/parser/kml.js @@ -104,6 +104,7 @@ ol.parser.KML = function(opt_options) { 'Placemark': function(node, obj) { var container = {properties: {}}; var sharedVertices, callback; + var id = node.getAttribute('id'); this.readChildNodes(node, container); if (goog.isDef(container.track)) { var track = container.track, j, jj; @@ -125,6 +126,9 @@ ol.parser.KML = function(opt_options) { container.properties['altitude'] = track.points[i].coordinates[2]; } var feature = new ol.Feature(container.properties); + if (!goog.isNull(id)) { + feature.setFeatureId(id); + } var geom = track.points[i]; if (geom) { sharedVertices = undefined; @@ -150,6 +154,9 @@ ol.parser.KML = function(opt_options) { } } feature = new ol.Feature(container.properties); + if (!goog.isNull(id)) { + feature.setFeatureId(id); + } if (container.geometry) { sharedVertices = undefined; if (this.readFeaturesOptions_) { diff --git a/test/spec/ol/feature.test.js b/test/spec/ol/feature.test.js index 3cde6f08e9..12ae10ba37 100644 --- a/test/spec/ol/feature.test.js +++ b/test/spec/ol/feature.test.js @@ -16,6 +16,12 @@ describe('ol.Feature', function() { expect(feature.get('foo')).to.be('bar'); }); + it('can store the feature\'s commonly used id', function() { + var feature = new ol.Feature(); + feature.setFeatureId('foo'); + expect(feature.getFeatureId()).to.be('foo'); + }); + it('will set the default geometry', function() { var feature = new ol.Feature({ loc: new ol.geom.Point([10, 20]), diff --git a/test/spec/ol/parser/geojson.test.js b/test/spec/ol/parser/geojson.test.js index 0d08cbdbda..885a7a5266 100644 --- a/test/spec/ol/parser/geojson.test.js +++ b/test/spec/ol/parser/geojson.test.js @@ -198,6 +198,7 @@ describe('ol.parser.GeoJSON', function() { var first = result[0]; expect(first).to.be.a(ol.Feature); expect(first.get('name')).to.be('Afghanistan'); + expect(first.getFeatureId()).to.be('AFG'); var firstGeom = first.getGeometry(); expect(firstGeom).to.be.a(ol.geom.Polygon); expect(ol.extent.equals(firstGeom.getBounds(), @@ -207,6 +208,7 @@ describe('ol.parser.GeoJSON', function() { var last = result[178]; expect(last).to.be.a(ol.Feature); expect(last.get('name')).to.be('Zimbabwe'); + expect(last.getFeatureId()).to.be('ZWE'); var lastGeom = last.getGeometry(); expect(lastGeom).to.be.a(ol.geom.Polygon); expect(ol.extent.equals(lastGeom.getBounds(), diff --git a/test/spec/ol/parser/kml.test.js b/test/spec/ol/parser/kml.test.js index 0cf36ffec5..ece7ed1fb1 100644 --- a/test/spec/ol/parser/kml.test.js +++ b/test/spec/ol/parser/kml.test.js @@ -86,6 +86,7 @@ describe('ol.parser.kml', function() { 'itself \n at the height of the underlying terrain.'; expect(obj.features[0].get('description')).to.eql(description); expect(obj.features[0].get('foo')).to.eql('bar'); + expect(obj.features[0].getFeatureId()).to.eql('foobarbaz'); }); }); it('Extended data read correctly [2]', function() { diff --git a/test/spec/ol/parser/kml/extended_data.kml b/test/spec/ol/parser/kml/extended_data.kml index fb3a6d38a9..6b4bdd8651 100644 --- a/test/spec/ol/parser/kml/extended_data.kml +++ b/test/spec/ol/parser/kml/extended_data.kml @@ -1,6 +1,6 @@ - + Extended data placemark Attached to the ground. Intelligently places itself at the height of the underlying terrain.