openlayersopenlayers-3openlayers-5

Move vector features by dragging


If I have a polygon, line, text, and point on a layer I want to be able to select 1 feature, right click to select "Move" and then be able to drag the feature to another location on the map and when I release the mouse button save the new location to my database.

Where I'm at, I can...

Select the feature to move

Right click and select a "Move" action that is used to call code that adds the Translate and Select ol objects. This does NOT select the feature that I pass to Translate though...I still need to click the feature and then I'm able to drag it. Even though I added only 1 feature to Translate I can click and drag any of the features (something I didn't think doing this would allow.

Once in the mode of selecting features to drag there is no way out other than reloading the map...I don't know how and haven't seen in documentation how to catch the "drag complete"

My Code

moveObject(){ 
//first get the selected object
const selectedObject = new Array<number>();

  const selectedFeatures: Array<olFeature> = myFeatureLayer.getSource().getFeatures();
  selectedFeatures.forEach((feature: olFeature) => {
    selectedObject.push(feature.getId());
  });

  //get the feature
  let selectedFeatures = this.myFeatureService.getFeature(selectedObject);

  let select = new Select();
  let translate = new Translate({
  features: selectedFeatures,  (this should restrict the move to just the feature passed in,but it 
                                doesn't)    
  });
  MapValues.map.addInteraction(translate);
  MapValues.map.addInteraction(select); 
  //Here I want to automatically select the feature given and put it into "Move" mode.

 // Here once move is done I want to catch "Dropping" the feature and add to the data base and 
    remove the Interactions.

}

UPDATE: I've found 'translateend'

 translate.on('translateend', evt => {
    evt.features.forEach(feat => {
      // process every feature
    })
 })

...but this doesn't just fire at the end, it fires with the clickdown and the upclick? I'm so confused as to why it was done like this and what seems like a ridged framework to this functionality?...I could be wrong but the limited documentation and examples make it hard to understand that capabilities of translate.

Any help is greatly appreciated


Solution

  • To my understanding, once the Translate interaction has features it can interact with (i.e. the collection of features has features in it) then even clicking on it is enough to trigger the "translatestart" and "translateend" events.

    One thing you could do is watch for the feature's collection "add" and "remove" event. On "add", register a "change" event on the geometry object itself to detect if the geometry has changed when the "translateend" event fires (in the handler method of the "translateend" event you would mark the feature as changed). On "remove", undo the marking thingy the feature.

    That way, you would ignore simple "clicks" on the selected feature and only care about if its geometry has changed.

    Live demo

    I've created a small demo of what I meant out of the OpenLayers Translate example. See:

    https://codesandbox.io/s/translate-features-forked-p7kum?file=/index.html