/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for * full list of contributors). Published under the 2-clause BSD license. * See license.txt in the OpenLayers distribution or repository for the * full text of the license. */ /** * @requires OpenLayers/Events.js */ /** * Class: OpenLayers.Events.featureclick * * Extension event type for handling feature click events, including overlapping * features. * * Event types provided by this extension: * - featureclick */ OpenLayers.Events.featureclick = OpenLayers.Class({ /** * Property: cache * {Object} A cache of features under the mouse. */ cache: null, /** * Property: map * {} The map to register browser events on. */ map: null, /** * Property: provides * {Array(String)} The event types provided by this extension. */ provides: ["featureclick", "nofeatureclick", "featureover", "featureout"], /** * Constructor: OpenLayers.Events.featureclick * Create a new featureclick event type. * * Parameters: * target - {} The events instance to create the events * for. */ initialize: function(target) { this.target = target; if (target.object instanceof OpenLayers.Map) { this.setMap(target.object); } else if (target.object instanceof OpenLayers.Layer.Vector) { if (target.object.map) { this.setMap(target.object.map); } else { target.object.events.register("added", this, function(evt) { this.setMap(target.object.map); }); } } else { throw("Listeners for '" + this.provides.join("', '") + "' events can only be registered for OpenLayers.Layer.Vector " + "or OpenLayers.Map instances"); } for (var i=this.provides.length-1; i>=0; --i) { target.extensions[this.provides[i]] = true; } }, /** * Method: setMap * * Parameters: * map - {} The map to register browser events on. */ setMap: function(map) { this.map = map; this.cache = {}; map.events.register("mousedown", this, this.start, {extension: true}); map.events.register("mouseup", this, this.onClick, {extension: true}); map.events.register("touchstart", this, this.start, {extension: true}); map.events.register("touchmove", this, this.cancel, {extension: true}); map.events.register("touchend", this, this.onClick, {extension: true}); map.events.register("mousemove", this, this.onMousemove, {extension: true}); }, /** * Method: start * Sets startEvt = evt. * * Parameters: * evt - {} */ start: function(evt) { this.startEvt = evt; }, /** * Method: cancel * Deletes the start event. * * Parameters: * evt - {} */ cancel: function(evt) { delete this.startEvt; }, /** * Method: onClick * Listener for the click event. * * Parameters: * evt - {} */ onClick: function(evt) { if (!this.startEvt || evt.type !== "touchend" && !OpenLayers.Event.isLeftClick(evt)) { return; } var features = this.getFeatures(this.startEvt); delete this.startEvt; // fire featureclick events var feature, layer, more, clicked = {}; for (var i=0, len=features.length; i} */ onMousemove: function(evt) { delete this.startEvt; var features = this.getFeatures(evt); var over = {}, newly = [], feature; for (var i=0, len=features.length; i)} List of features at the given point. */ getFeatures: function(evt) { var x = evt.clientX, y = evt.clientY, features = [], targets = [], layers = [], layer, target, feature, i, len; // go through all layers looking for targets for (i=this.map.layers.length-1; i>=0; --i) { layer = this.map.layers[i]; if (layer.div.style.display !== "none") { if (layer.renderer instanceof OpenLayers.Renderer.Elements) { if (layer instanceof OpenLayers.Layer.Vector) { target = document.elementFromPoint(x, y); while (target && target._featureId) { feature = layer.getFeatureById(target._featureId); if (feature) { features.push(feature); target.style.display = "none"; targets.push(target); target = document.elementFromPoint(x, y); } else { // sketch, all bets off target = false; } } } layers.push(layer); layer.div.style.display = "none"; } else if (layer.renderer instanceof OpenLayers.Renderer.Canvas) { feature = layer.renderer.getFeatureIdFromEvent(evt); if (feature) { features.push(feature); layers.push(layer); } } } } // restore feature visibility for (i=0, len=targets.length; i=0; --i) { layers[i].div.style.display = "block"; } return features; }, /** * APIMethod: destroy * Clean up. */ destroy: function() { for (var i=this.provides.length-1; i>=0; --i) { delete this.target.extensions[this.provides[i]]; } this.map.events.un({ mousemove: this.onMousemove, mousedown: this.start, mouseup: this.onClick, touchstart: this.start, touchmove: this.cancel, touchend: this.onClick, scope: this }); delete this.cache; delete this.map; delete this.target; } }); /** * Class: OpenLayers.Events.nofeatureclick * * Extension event type for handling click events that do not hit a feature. * * Event types provided by this extension: * - nofeatureclick */ OpenLayers.Events.nofeatureclick = OpenLayers.Events.featureclick; /** * Class: OpenLayers.Events.featureover * * Extension event type for handling hovering over a feature. * * Event types provided by this extension: * - featureover */ OpenLayers.Events.featureover = OpenLayers.Events.featureclick; /** * Class: OpenLayers.Events.featureout * * Extension event type for handling leaving a feature. * * Event types provided by this extension: * - featureout */ OpenLayers.Events.featureout = OpenLayers.Events.featureclick;