diff --git a/examples/select-features.html b/examples/select-features.html new file mode 100644 index 0000000000..8e34f3422b --- /dev/null +++ b/examples/select-features.html @@ -0,0 +1,56 @@ + + + + + + + + + + + Select featuers example + + + + + +
+ +
+
+
+
+
+ +
+ +
+

Select features example

+

Example of using the Select control.

+
+

See the select-features.js source to see how this is done.

+
+
SelectFeature, vector
+
+ +
+ +
+ + + + + + diff --git a/examples/select-features.js b/examples/select-features.js new file mode 100644 index 0000000000..cb13f361e6 --- /dev/null +++ b/examples/select-features.js @@ -0,0 +1,48 @@ +goog.require('ol.Map'); +goog.require('ol.RendererHint'); +goog.require('ol.View2D'); +goog.require('ol.control.Select'); +goog.require('ol.control.defaults'); +goog.require('ol.layer.TileLayer'); +goog.require('ol.layer.Vector'); +goog.require('ol.parser.ogc.GML_v3'); +goog.require('ol.source.MapQuestOpenAerial'); +goog.require('ol.source.Vector'); +goog.require('ol.style.Polygon'); +goog.require('ol.style.Rule'); +goog.require('ol.style.Style'); + +var raster = new ol.layer.TileLayer({ + source: new ol.source.MapQuestOpenAerial() +}); + +var vector = new ol.layer.Vector({ + source: new ol.source.Vector({ + parser: new ol.parser.ogc.GML_v3(), + url: 'data/gml/topp-states-wfs.xml' + }), + style: new ol.style.Style({rules: [ + new ol.style.Rule({ + symbolizers: [ + new ol.style.Polygon({ + strokeColor: '#bada55' + }) + ] + }) + ]}) +}); + +var selectControl = new ol.control.Select({layers: [vector]}); + +var map = new ol.Map({ + controls: ol.control.defaults({}, [selectControl]), + layers: [raster, vector], + renderer: ol.RendererHint.CANVAS, + target: 'map', + view: new ol.View2D({ + center: [-10997171.194994785, 5206335.565590534], + zoom: 4 + }) +}); + +selectControl.activate(); diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc index 973fd47471..04cda33390 100644 --- a/src/objectliterals.jsdoc +++ b/src/objectliterals.jsdoc @@ -201,6 +201,15 @@ * Default is '' (empty string). */ +/** + * @typedef {Object} ol.control.SelectOptions + * @property {string|undefined} className CSS class name. Default is 'ol-select'. + * @property {Element|undefined} element Element. + * @property {Array.|undefined} layers Layers to select features on. + * @property {ol.Map|undefined} map Map. + * @property {Element|undefined} target Target. + */ + /** * @typedef {Object} ol.control.ScaleLineOptions * @property {string|undefined} className CSS Class name. Default is 'ol-scale-line'. diff --git a/src/ol/control/selectcontrol.js b/src/ol/control/selectcontrol.js new file mode 100644 index 0000000000..20c5b34933 --- /dev/null +++ b/src/ol/control/selectcontrol.js @@ -0,0 +1,106 @@ +goog.provide('ol.control.Select'); + +goog.require('goog.array'); +goog.require('goog.dom'); +goog.require('goog.dom.TagName'); +goog.require('goog.dom.classes'); +goog.require('goog.events'); +goog.require('goog.events.EventType'); +goog.require('ol.MapBrowserEvent.EventType'); +goog.require('ol.control.Control'); +goog.require('ol.css'); + + + +/** + * @constructor + * @extends {ol.control.Control} + * @param {ol.control.SelectOptions=} opt_options Options. + */ +ol.control.Select = function(opt_options) { + var options = goog.isDef(opt_options) ? opt_options : {}; + + this.layers_ = options.layers; + + var className = goog.isDef(options.className) ? options.className : + 'ol-select'; + + var element = goog.dom.createDom(goog.dom.TagName.DIV, { + 'class': className + ' ' + ol.css.CLASS_UNSELECTABLE + }); + var button = goog.dom.createDom(goog.dom.TagName.A, { + 'href': '#Select' + }); + goog.dom.appendChild(element, button); + + goog.events.listen(element, [ + goog.events.EventType.TOUCHEND, + goog.events.EventType.CLICK + ], this.toggleActive_, false, this); + + goog.base(this, { + element: element, + map: options.map, + target: options.target + }); +}; +goog.inherits(ol.control.Select, ol.control.Control); + + +/** + * @param {goog.events.BrowserEvent} browserEvent Browser event. + * @private + */ +ol.control.Select.prototype.toggleActive_ = function(browserEvent) { + // prevent #Select anchor from getting appended to the url + browserEvent.preventDefault(); + if (this.active_) { + this.deactivate(); + } else { + this.activate(); + } +}; + + +/** + * Activate the control. + */ +ol.control.Select.prototype.activate = function() { + goog.dom.classes.add(this.element, 'active'); + // TODO: Add box selection + this.listenerKeys.push( + goog.events.listen(this.getMap(), ol.MapBrowserEvent.EventType.CLICK, + this.handleClick, true, this)); +}; + + +/** + * Dectivate the control. + */ +ol.control.Select.prototype.deactivate = function() { + if (!goog.array.isEmpty(this.listenerKeys)) { + goog.array.forEach(this.listenerKeys, goog.events.unlistenByKey); + this.listenerKeys.length = 0; + } + goog.dom.classes.remove(this.element, 'active'); +}; + + +/** + * @param {ol.MapBrowserEvent} evt Event. + */ +ol.control.Select.prototype.handleClick = function(evt) { + this.getMap().getFeatures({ + layers: this.layers_, + pixel: evt.getPixel(), + success: this.select + }); +}; + + +/** + * @param {Array.>} featuresByLayer Features by layer. + */ +ol.control.Select.prototype.select = function(featuresByLayer) { + // TODO: Do something with the features. +};