1
votes

I have a modify interaction enabled on a vector layer with multiple features. It work fine to move a feature to a new position. However if there are more features on the same coordinate, then all of then moved at the same time. See example on codepen.

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

var data = new ol.Collection();

  data.push(new ol.Feature({
    geometry: new ol.geom.Point([0, 0])
  }));

  var f = new ol.Feature({
    geometry: new ol.geom.Point([0, 0])
  });
  f.setStyle(new ol.style.Style({
                image: new ol.style.Circle({
                    radius: 10,
                    fill: new ol.style.Fill({
                        color: [255, 255, 255, 0.5]
                    }),
                    zIndex: Infinity
                }),
            }));

  data.push(f);

  var vector = new ol.layer.Vector({
    source: new ol.source.Vector({
      features: data
    })
  });


  var modify = new ol.interaction.Modify({
    features: data
  });

  var map = new ol.Map({
    interactions: ol.interaction.defaults().extend([modify]),
    layers: [raster, vector],
    target: 'map',
    view: new ol.View({
      center: [0, 0],
      zoom: 12
    })
  });

Are there any way to avoid that? The only solutions I have found are:

  1. I have a select interation to select the feature
  2. Use translate interaction to move one of the features

or

  1. At pointer move event and detect if one or more features are at the coordinate and then select one of then
  2. Add the selected feature to modify feature layer and move it

Any other way?

Regrads RM

1
You already have 2 solutions. Any particular reason why you are looking for another solution? - Sumanth Shastry
The first solution requires an extra click (the select click), which i want to avoid. The secound require bookeping, when moving the feature from one layer to another, which make the code more complicated and i hope i could keep the code simple. That is why I was looking for other solutions. - user7064696

1 Answers

0
votes

There is another way. You can register a 'pointermove' handler on the map, in which you get the topmost feature, and set it as the only feature on the source that the Modify interaction works on. See https://codepen.io/ahocevar/pen/YxjyRd for the full example.

Other than in your code, you'll connect the Modify interaction to a source instead of a collection, and that source (modifySource) is separate from the vector layer's source and initially empty. In the pointermove handler, you add just a single feature to that source:

function pointermove(e) {
  if (e.dragging) {
    return;
  }
  var features = map.getFeaturesAtPixel(e.pixel, {
    layerFilter: function(l) {
      return l == vector;
    }
  });
  if (features && features[0] != modifySource.getFeatures()[0]) {
    modifySource.clear();
    modifySource.addFeature(features[0]);
  }
}
map.on("pointermove", pointermove);

Also note that this handler must be registered before the Modify interaction is added to the map.