Source: temp/jsdocinputdirs/cercalia.interaction.dragfeatures.js

/**
 * @classdesc
 * Drag Features interaction. Internal for Cercalia API
 *
 * @constructor
 * @extends {ol.interaction.Pointer}
 */
cercalia.Interaction.DragFeatures = function() {

    this.handleEvent = function(mapBrowserEvent) {

        if (!(mapBrowserEvent instanceof ol.MapBrowserPointerEvent)) { return true; }

        var stopEvent = false;
        this.updateTrackedPointers_(mapBrowserEvent);
        if (this.handlingDownUpSequence) {
            if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.POINTERDRAG) {
                this.handleDragEvent(mapBrowserEvent);
            } else if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.POINTERUP) {
                this.handlingDownUpSequence = this.handleUpEvent(mapBrowserEvent);
            }
        }
        if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.POINTERDOWN) {
            var handled = this.handleDownEvent(mapBrowserEvent);
            this.handlingDownUpSequence = handled;
            stopEvent = this.shouldStopEvent(handled);
        } else if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.POINTERMOVE) {
            this.handleMoveEvent(mapBrowserEvent);
        }
        return !stopEvent;
    };

    ol.interaction.Pointer.call(this, {
        handleDownEvent: cercalia.Interaction.DragFeatures.prototype.handleDownEvent,
        handleDragEvent: cercalia.Interaction.DragFeatures.prototype.handleDragEvent,
        handleMoveEvent: cercalia.Interaction.DragFeatures.prototype.handleMoveEvent,
        handleUpEvent: cercalia.Interaction.DragFeatures.prototype.handleUpEvent
    });

    /**
     * @private
     * @type {ol.Pixel}
     */
    this.coordinate_ = null;

    /**
     * @private
     * @type {string|undefined}
     */
    this.cursor_ = 'pointer';

    /**
	 * @private
     * @type {ol.Feature}
     */
    this.feature_ = null;

    /**
	 * @private
     * @type {string|undefined}
     */
    this.previousCursor_ = undefined;

    /**
	 * @private
     * @type {string|undefined}
     */
    this.onStartDragFeature_ = null;
    
    this.layers_ = [ ];

};
ol.inherits(cercalia.Interaction.DragFeatures, ol.interaction.Pointer);

/**
 * Add drag layer
 * @param {cercalia.WMS|cercalia.KML} layer
 * @return {cercalia.Interaction.DragFeatures} this
 */
cercalia.Interaction.DragFeatures.prototype.addLayer = function(layer){
	if(layer){
		var index = this.layers_.indexOf(layer.getLayer());
		if (index <= -1) {
			this.layers_.push(layer.getLayer());
		}
	}
	
	return this;
};

/**
 * remove drag layer
 * @param {cercalia.WMS|cercalia.KML} layer
 * @return {cercalia.Interaction.DragFeatures} this
 */
cercalia.Interaction.DragFeatures.prototype.removeLayer = function(layer){
	var index = this.layers_.indexOf(layer.getLayer());
	if (index > -1) {
		this.layers_.splice(index, 1);
	}
	return this;
};

/**
 * remove drag layer
 * @private
 * @param {cercalia.WMS|cercalia.KML} layer
 * @return {boolean} boolean true if is drag
 */
cercalia.Interaction.DragFeatures.prototype.isDraggable_ = function(layer){
	return  layer != null && ("DragLayer" == layer.get('name') || (this.layers_.indexOf(layer)) > -1);
};

/**
 * @param {ol.MapBrowserEvent} evt Map browser event.
 * @return {boolean} `true` to start the drag sequence.
 */
cercalia.Interaction.DragFeatures.prototype.handleDownEvent = function(evt) {

	var feature;
    var map = evt.map;
    var self = this;

    //case 1  : Left Mouse button pressed.
    //case 2  : Middle Mouse button pressed.
    //case 3  : Right Mouse button pressed.
    var whickHandle = evt.originalEvent.which;
    
    if(whickHandle == 1){
	    feature = map.forEachFeatureAtPixel(evt.pixel, function(feature, layer) {
	        return    feature && feature.getCercaliaObject() && feature.getCercaliaObject().isDraggable() ? feature // si es draggable la retornem
	        		: layer == null ? null // si el layer es null, no es draggable 
	    	        : feature; // draggable
	    }, undefined, function(layer) {
	        
	    	return self.isDraggable_(layer);
	    	//return "DragLayer" == layer.get('name'); // Filtramos solo para los layers que nos interese
	    });
	
	    if (feature) {
	        this.coordinate_ = evt.coordinate;
	        this.feature_ = feature;
	    }
    }

    return !!feature;
};

/**
 * @param {ol.MapBrowserEvent} evt Map browser event.
 */
cercalia.Interaction.DragFeatures.prototype.handleDragEvent = function(evt) {
    var map = evt.map;
    var self = this;
    
    var feature = map.forEachFeatureAtPixel(evt.pixel, function(feature, layer) {
    	return    feature && feature.getCercaliaObject() && feature.getCercaliaObject().isDraggable() ? feature // si es draggable la retornem
        		: layer == null ? null // si el layer es null, no es draggable 
    	        : feature; // draggable    
        }, undefined, function(layer) {
    	return self.isDraggable_(layer);
    	//return "DragLayer" == layer.get('name'); // Filtramos solo para los layers que nos interese
    });

    // si trobem una feature, la posem en onStarDragFeature per saber que hem començat a dragar.
    // Cridem el onStarDrag (si el te)
    if (feature) {

        if (!this.onStartDragFeature_) {

            this.onStartDragFeature_ = feature;
            switch (feature.featureType_) {
	            case "cercalia.Marker":
	                var marker = feature.marker_;
	            	var mapCercalia = marker.getMap();
	                if (marker.onDragStart) {
	                    var lonlat = new cercalia.LonLat(this.coordinate_[0], this.coordinate_[1], mapCercalia.getProjectionCode());
	                    marker.onDragStart(marker, lonlat, evt);
	                }
	                break;
	            case "cercalia.Feature":
	                var cercaliaFeature = feature.feature_;
	            	var mapCercalia = cercaliaFeature.getMap();
	                if (cercaliaFeature.onDragStart) {
	                    var lonlat = new cercalia.LonLat(this.coordinate_[0], this.coordinate_[1], mapCercalia.getProjectionCode());
	                    cercaliaFeature.onDragStart(cercaliaFeature, lonlat, evt);
	                }
	                break;
	            default:
	                break;
            }
        }
    }

    var deltaX = evt.coordinate[0] - this.coordinate_[0];
    var deltaY = evt.coordinate[1] - this.coordinate_[1];

    var geometry = /** @type {ol.geom.SimpleGeometry} */
    (this.feature_.getGeometry());
    geometry.translate(deltaX, deltaY);

    this.coordinate_[0] = evt.coordinate[0];
    this.coordinate_[1] = evt.coordinate[1];

    // si ja hem començat a fer el drag.. cridem el onDragMove
    if (this.onStartDragFeature_) {
        switch (this.onStartDragFeature_.featureType_) {
	        case "cercalia.Marker":
	            var marker = this.onStartDragFeature_.marker_;
	            var mapCercalia = marker.getMap();
	            if (marker.onDragMove) {
	            	var lonlat = new cercalia.LonLat(this.coordinate_[0], this.coordinate_[1], mapCercalia.getProjectionCode());
	                //var lonlat = new cercalia.LonLat(this.coordinate_[0], this.coordinate_[1]);
	                marker.onDragMove(marker, lonlat, evt);
	            }
	            break;
	        case "cercalia.Feature":
	            var cercaliaFeature = this.onStartDragFeature_.feature_;
	            var mapCercalia = cercaliaFeature.getMap();
	            if (cercaliaFeature.onDragMove) {
	            	var lonlat = new cercalia.LonLat(this.coordinate_[0], this.coordinate_[1], mapCercalia.getProjectionCode());
	                //var lonlat = new cercalia.LonLat(this.coordinate_[0], this.coordinate_[1]);
	                cercaliaFeature.onDragMove(cercaliaFeature, lonlat, evt);
	            }
	            break;
	        default:
	            break;
        }
    }
    
};

/**
 * @param {ol.MapBrowserEvent} evt Event.
 */
cercalia.Interaction.DragFeatures.prototype.handleMoveEvent = function(evt) {

    if (this.cursor_) {

        var map = evt.map;
        var self = this;
        
        var feature = map.forEachFeatureAtPixel(evt.pixel, function(feature, layer) {
        	return    feature && feature.getCercaliaObject() && feature.getCercaliaObject().isDraggable() ? feature // si es draggable la retornem
	        		: layer == null ? null // si el layer es null, no es draggable 
	    	    	: feature; // draggable      
	       }, undefined, function(layer) {
        	return self.isDraggable_(layer);
	    	//return "DragLayer" == layer.get('name'); // Filtramos solo para los layers que nos interese
        });

        var element = evt.map.getTargetElement();
        if (feature) {
            if (element.style.cursor != this.cursor_) {
                this.previousCursor_ = element.style.cursor;
                element.style.cursor = this.cursor_;
            }
        } else if (this.previousCursor_ !== undefined) {
            element.style.cursor = this.previousCursor_;
            this.previousCursor_ = undefined;
        }
    }
};

/**
 * @param {ol.MapBrowserEvent} evt Map browser event.
 * @return {boolean} `false` to stop the drag sequence.
 */
cercalia.Interaction.DragFeatures.prototype.handleUpEvent = function(evt) {

    // si s'ha dragat amb el UpEvent notifiquem el onDragEnd.
    if (this.onStartDragFeature_) {
        switch (this.onStartDragFeature_.featureType_) {
	        case "cercalia.Marker":
	            //var map = evt.map;
	            var marker = this.onStartDragFeature_.marker_;
	            if (marker.onDragEnd) {
	            	var mapCercalia = marker.getMap();
	            	var lonlat = new cercalia.LonLat(this.coordinate_[0], this.coordinate_[1], mapCercalia.getProjectionCode());
	                //var lonlat = new cercalia.LonLat(this.coordinate_[0], this.coordinate_[1]);
	                marker.onDragEnd(marker, lonlat, evt);
	            }
	            break;
	        case "cercalia.Feature":
	            //var map = evt.map;
	            var cercaliaFeature = this.onStartDragFeature_.feature_;
	            var mapCercalia = cercaliaFeature.getMap();
	            if (cercaliaFeature.onDragEnd) {
	            	var lonlat = new cercalia.LonLat(this.coordinate_[0], this.coordinate_[1], mapCercalia.getProjectionCode());
	                //var lonlat = new cercalia.LonLat(this.coordinate_[0], this.coordinate_[1]);
	                cercaliaFeature.onDragEnd(cercaliaFeature, lonlat, evt);
	            }
	            break;
	        default:
	            break;
        }
    }

    this.coordinate_ = null;
    this.feature_ = null;
    this.onStartDragFeature_ = null
    return false;
};

/**
 * Stop dragging.
 * @param {ol.Feature|cercalia.Marker|cercalia.Feature} feature
 */
cercalia.Interaction.DragFeatures.prototype.stopDrag = function(feature) {
    
    if (feature != null && this.feature_ != null) {
        if (feature instanceof cercalia.Feature) {
            feature = feature.getFeature();
        }

        if (this.feature_ == feature) {
            this.coordinate_ = null;
            this.feature_ = null;
            this.onStartDragFeature_ = null;
            this.handlingDownUpSequence = false;
        }
    }
    
};