3

I'm trying to replicate something that was fairly easy in OpenLayers 2 in OpenLayers 3, which is: dragging an existing feature to a new location on the map.

In OpenLayers 2 I just added a DragFeature control to my map like this:

this.mapRasterDragFeature = new OpenLayers.Control.DragFeature(_self.rasterVectorSource,
     {'onComplete': function(e) { console.log(e);}});
this.mapRaster.addControl(_self.mapRasterDragFeature);
this.mapRasterDragFeature.activate();

But this control seems to have disappeared in OpenLayers 3. I've searched far and wide in the documentation for the new way to this, but I can't seem to find it. I hope I'm overlooking something.

I'm adding the feature through a click event on the map like this:

this.mapRaster.on('singleclick',function(e){
    var iconFeature = new ol.Feature({
        geometry: new ol.geom.Point(e.coordinate),
    });
    iconFeature.setStyle(_self.iconStyle);
    _self.rasterVectorSource.addFeatures([iconFeature]);
});

All I've found looking like a drag interaction is ol.interaction.DragAndDrop(), but I think it does something different than just dragging and dropping a feature...

Can someone help me out on this one?

  • Did you figure this out? I am also trying to figure this out. – user2268177 Jun 1 '14 at 8:16
  • This does not really answer the question. If you have a different question, you can ask it by clicking Ask Question. You can also add a bounty to draw more attention to this question once you have enough reputation. – PolyGeo Jun 1 '14 at 8:39
  • This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post - you can always comment on your own posts, and once you have sufficient reputation you will be able to comment on any post. – BradHards Jun 1 '14 at 9:35
  • Yeah I kind of did. I've added a select and modify interaction to my map, which enables selection and dragging of features. The problem is that I add markers on singleclick, which prevented me from selecting features, because a new feature was put on top of the feature I was trying to select. I now handle this by first checking if I'm clicking on an existing feature by utilizing the forEachFeatureAtPixel method of my map. If a feature is detected, no new feature is added and thus the feature I'm clicking on is selected after which it's draggable. – Danny Hoek Jun 8 '14 at 21:34
7

You will need to add a new interaction. Assuming that...

this.mapRaster = ol.Map

This should work

this.mapRaster.on('singleclick',function(e){
    var iconFeature = new ol.Feature({
        geometry: new ol.geom.Point(e.coordinate),
    });
    iconFeature.setStyle(_self.iconStyle);
    _self.rasterVectorSource.addFeatures([iconFeature]);

Make the feature moveable

    var modify = new ol.interaction.Modify({
        features: new ol.Collection([iconFeature])
    });

Let me know when the feature is moving

    iconFeature.on('change',function(){
        console.log('Feature Moved To:' + this.getGeometry().getCoordinates());
    },iconFeature);

Then add the Modify Interaction

    this.mapRaster.addInteraction(modify);

});
  • Excellent! One question though.. Is there any way to make the whole icon clickeable for drag? this code shows a dot – Alvaro Nov 16 '14 at 3:19
4

While looking to solve this problem in my application I stumbled upon a new interaction, which wasn't part of OpenLayers 3 when the above question was posted. Anyone having to move features around the map should, at this point, have a look at the Translate Interaction. The official example demonstrates how it works.

The code could not be simpler:

var translate = new ol.interaction.Translate({
    features: YOURFEATURES
});


You can then add the interaction:

map.addInteraction(translate);

And remove it, if need be:

map.removeInteraction(translate);
0

I hate untyped languages.

This is an extension to BritishSteel's answer to point out that where he says YOURFEATURES that means an ol.Collection of features, not a simple array of features, and notably not what myLayer.getSource().getFeatures() returns.

So to the complete code is:

var myCollection = new ol.Collection();
myCollection.extend( myLayer.getSource().getFeatures() );

var myTranslate = new ol.interaction.Translate({
    features: myCollection
});

map.addInteraction( myTranslate );

// ... and then to get the coordinates of the icon after it's dragged
myTranslate.on( "translateend", HandleMapIconDrag );

function HandleMapIconDrag( e )
{
    var p = e.features.getArray()[ 0 ].getGeometry().getCoordinates();
    p = ol.proj.transform( p, "EPSG:3857", "EPSG:4326" );
    // p now holds the [ lon, lat ] value of the dragged point icon
}

Note that the official example BritishSteel references skirts this issue because it uses a Select interaction, which returns a Collection of features. But in my case I did not want the user to have to click to select the feature and then click again to drag it. The code above does the what I needed: cursor changes to a hand when the mouse is over the feature, user clicks and drags to move the feature. (This also solves a problem I had with the Select approach where my point icon was changing to a blue dot when selected, and dragged, and only changed back to the correct icon image when the feature was deselected by clicking elsewhere on the map. I didn't look into a solution for that because I didn't want the Select behavior anyway.)

0

Piggybacking on BritishSteel's reference to the OL official example, if you want to avoid requiring your users to first click a feature to select it and THEN begin dragging to move it, you can just set your Select interaction to fire on pointerMove.

Here's my modified version of the interaction declarations from the OL example:

  var select = new Select({ 
     condition: pointerMove
  });

  var translate = new Translate({
    features: select.getFeatures()
  });

In the background, this will select whichever feature you are hovered over, so clicking and dragging will move only that feature.

You may need to add a filter function to the Select interaction to ensure you don't start moving them as you drag another object over it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.