[GIS] Adding drag interaction breaks ability to move map location in OpenLayers 3

openlayers

I am working with a version of OpenLayers 3. I am attempting to add the ability to drag a feature on the map. The problem I am running into is when adding a drag interaction to the map, I break the base functionality of moving around the map location.

I created a jsfiddle to demonstrate. When opening, try changing location of the map.

http://jsfiddle.net/mcroteau/w8bj1htb/

Javascript

var mapTile = new ol.layer.Tile({
    source: new ol.source.OSM()
});


var lineStyle = new ol.style.Style({
    stroke: new ol.style.Stroke({
        color: 'blue',
        width: 3
    }),
    fill: new ol.style.Fill({
        color: 'rgba(0, 0, 255, 0.1)'
    })
})


var verticeStyle = new ol.style.Style({
    image: new ol.style.Circle({
        radius: 6,
        stroke: new ol.style.Stroke({
            color: 'rgba(0, 0, 255, 0.8)',
            width: 2
        }),
        fill: new ol.style.Fill({
            color: 'rgba(0, 0, 255, 0.5)'
        })
    }),
    geometry: function(feature) {
        var coordinates = feature.getGeometry().getCoordinates()[0];
        return new ol.geom.MultiPoint(coordinates);
    }
})





var mapView =  new ol.View({
    center: [-11000000, 4600000],
    zoom: 3
});

var map = new ol.Map({
    layers: [mapTile],
    target: 'map',
    view: mapView
});


/**
* TODO : Issue 1 Drag Interaction
*
* adding drag interaction to map breaks ability to move map location
*
**/

var dragInteraction = new ol.interaction.Pointer({
    handleDownEvent : function(event){
        var feature = map.forEachFeatureAtPixel(event.pixel,
            function(feature, layer) {
              return feature;
            });

        if (feature) {
          this.coordinate_ = event.coordinate;
          this.feature_ = feature;
        }

        return !!feature;
    },
    handleDragEvent : function(event){

        var feature = map.forEachFeatureAtPixel(event.pixel,
            function(feature, layer) {
              return feature;
            });

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

        if(feature){
            var geometry = feature.getGeometry();
            geometry.translate(deltaX, deltaY);


            this.coordinate_[0] = event.coordinate[0];
            this.coordinate_[1] = event.coordinate[1];
        }

    },
    handleMoveEvent : function(){
        //console.log('handle move')
    },
    handleUpEvent : function(event){
        //console.log('handle up event')
    }
})
map.addInteraction(dragInteraction);




var features = new ol.Collection();
var vector_source = new ol.source.Vector({
    features: features,
});

var featureOverlay = new ol.layer.Vector({
    source: vector_source,
    style: [ lineStyle, verticeStyle ]
})
featureOverlay.setMap(map);



var geometryFunction = function(coordinates, geometry) {

    var start = coordinates[0];
    var end = coordinates[1];

    if (!geometry) {
        geometry = new ol.geom.Polygon(null);
    }

    geometry.setCoordinates([
        [start, [start[0], end[1]], end, [end[0], start[1]], start]
    ]);

    return geometry;
}


var draw = new ol.interaction.Draw({
    condition: function(event) {
        return ol.events.condition.shiftKeyOnly(event)
    },
    features: features,
    type: 'LineString',
    geometryFunction: geometryFunction,
    maxPoints: 2
});


map.addInteraction(draw);

Best Answer

I figured out that the draw interaction adds a feature where the cursor is pointing. This was throwing off the ol.interaction.Pointer handleDownEvent logic.

Full working example : http://jsfiddle.net/mcroteau/p23x3jqn/

I added an event listener to the ol.Collection's 'add' event and set the id of the new feature that I later used in the handleDownEvent.

new event listener 'add' event :

var features = new ol.Collection();
features.on('add', function(event){
    var feature = event.element;
    feature.set('id', 'bounding-box');
});

updated 'handleDownEvent'

handleDownEvent : function(event){
    var feature = map.forEachFeatureAtPixel(event.pixel,    
        function(feature, layer) {
            return feature;
        }
    );

    if(feature && feature.get('id') === 'bounding-box'){
        dragCoordinate = event.coordinate;
        dragFeature = feature;
        return true;
    }

    return false;
}
Related Question