diff --git a/src/ol/graticule.js b/src/ol/graticule.js index 8fbcad521f..03ce26d3b2 100644 --- a/src/ol/graticule.js +++ b/src/ol/graticule.js @@ -422,6 +422,23 @@ ol.Graticule.prototype.handlePostCompose_ = function(e) { this.updateProjectionInfo_(projection); } + //Fix the extent if wrapped. + //(note: this is the same extent as vectorContext.extent_) + var offsetX = 0; + if (projection.canWrapX()) { + var projectionExtent = projection.getExtent(); + var worldWidth = ol.extent.getWidth(projectionExtent); + var x = frameState.focus[0]; + if (x < projectionExtent[0] || x > projectionExtent[2]) { + var worldsAway = Math.ceil((projectionExtent[0] - x) / worldWidth); + offsetX = worldWidth * worldsAway; + extent = [ + extent[0] + offsetX, extent[1], + extent[2] + offsetX, extent[3] + ]; + } + } + this.createGraticule_(extent, center, resolution, squaredTolerance); // Draw the lines diff --git a/src/ol/interaction/selectinteraction.js b/src/ol/interaction/selectinteraction.js index 6a84a8b477..447c18634e 100644 --- a/src/ol/interaction/selectinteraction.js +++ b/src/ol/interaction/selectinteraction.js @@ -8,6 +8,7 @@ goog.require('goog.asserts'); goog.require('goog.events'); goog.require('goog.events.Event'); goog.require('goog.functions'); +goog.require('goog.object'); goog.require('ol.CollectionEventType'); goog.require('ol.Feature'); goog.require('ol.array'); @@ -174,6 +175,14 @@ ol.interaction.Select = function(opt_options) { */ this.layerFilter_ = layerFilter; + /** + * An association between selected feature (key) + * and layer (value) + * @private + * @type {Object.} + */ + this.featureLayerAssociation_ = {}; + /** * @private * @type {ol.layer.Vector} @@ -200,6 +209,18 @@ ol.interaction.Select = function(opt_options) { goog.inherits(ol.interaction.Select, ol.interaction.Interaction); +/** + * @param {ol.Feature} feature Feature. + * @param {ol.layer.Layer} layer Layer. + * @private + */ +ol.interaction.Select.prototype.addFeatureLayerAssociation_ = + function(feature, layer) { + var key = goog.getUid(feature); + this.featureLayerAssociation_[key] = layer; +}; + + /** * Get the selected features. * @return {ol.Collection.} Features collection. @@ -210,6 +231,21 @@ ol.interaction.Select.prototype.getFeatures = function() { }; +/** + * Returns the associated {@link ol.layer.Vector vectorlayer} of + * the (last) selected feature. + * @param {ol.Feature} feature Feature + * @return {ol.layer.Vector} Layer. + * @api + */ +ol.interaction.Select.prototype.getLayer = function(feature) { + goog.asserts.assertInstanceof(feature, ol.Feature, + 'feature should be an ol.Feature'); + var key = goog.getUid(feature); + return /** @type {ol.layer.Vector} */ (this.featureLayerAssociation_[key]); +}; + + /** * Handles the {@link ol.MapBrowserEvent map browser event} and may change the * selected state of features. @@ -243,6 +279,7 @@ ol.interaction.Select.handleEvent = function(mapBrowserEvent) { function(feature, layer) { if (this.filter_(feature, layer)) { selected.push(feature); + this.addFeatureLayerAssociation_(feature, layer); return !this.multi_; } }, this, this.layerFilter_); @@ -256,6 +293,16 @@ ol.interaction.Select.handleEvent = function(mapBrowserEvent) { features.clear(); } features.extend(selected); + // Modify object this.featureLayerAssociation_ + if (selected.length === 0) { + goog.object.clear(this.featureLayerAssociation_); + } else { + if (deselected.length > 0) { + deselected.forEach(function(feature) { + this.removeFeatureLayerAssociation_(feature); + }, this); + } + } } } else { // Modify the currently selected feature(s). @@ -269,11 +316,13 @@ ol.interaction.Select.handleEvent = function(mapBrowserEvent) { if (add || toggle) { if (this.filter_(feature, layer)) { selected.push(feature); + this.addFeatureLayerAssociation_(feature, layer); } } } else { if (remove || toggle) { deselected.push(feature); + this.removeFeatureLayerAssociation_(feature); } } }, this, this.layerFilter_); @@ -360,3 +409,14 @@ ol.interaction.Select.prototype.removeFeature_ = function(evt) { map.unskipFeature(feature); } }; + + +/** + * @param {ol.Feature} feature Feature. + * @private + */ +ol.interaction.Select.prototype.removeFeatureLayerAssociation_ = + function(feature) { + var key = goog.getUid(feature); + delete this.featureLayerAssociation_[key]; +}; diff --git a/test/spec/ol/interaction/selectinteraction.test.js b/test/spec/ol/interaction/selectinteraction.test.js index 6e8e331e16..f1a0beb8b8 100644 --- a/test/spec/ol/interaction/selectinteraction.test.js +++ b/test/spec/ol/interaction/selectinteraction.test.js @@ -1,7 +1,7 @@ goog.provide('ol.test.interaction.Select'); describe('ol.interaction.Select', function() { - var target, map, source; + var target, map, layer, source; var width = 360; var height = 180; @@ -45,7 +45,7 @@ describe('ol.interaction.Select', function() { features: features }); - var layer = new ol.layer.Vector({source: source}); + layer = new ol.layer.Vector({source: source}); map = new ol.Map({ target: target, @@ -199,6 +199,32 @@ describe('ol.interaction.Select', function() { }); + describe('#getLayer(feature)', function() { + var interaction; + + beforeEach(function() { + interaction = new ol.interaction.Select(); + map.addInteraction(interaction); + }); + afterEach(function() { + map.removeInteraction(interaction); + }); + + it('returns a layer from a selected feature', function() { + var listenerSpy = sinon.spy(function(e) { + var feature = e.selected[0]; + var layer_ = interaction.getLayer(feature); + expect(e.selected).to.have.length(1); + expect(feature).to.be.a(ol.Feature); + expect(layer_).to.be.a(ol.layer.Vector); + expect(layer_).to.equal(layer); + }); + interaction.on('select', listenerSpy); + + simulateEvent(ol.MapBrowserEvent.EventType.SINGLECLICK, 10, -20); + }); + }); + describe('#setActive()', function() { var interaction;