简体   繁体   中英

Drag/Move Multiple Selected Features - OpenLayers

I know that I can easily allow a user to select multiple Features/Geometries in OpenLayers but I then want enable the user to easily drag/move all of the selected features at the same time.

With the ModifyFeature control it only moves one feature at a time ... is there a way to easily extend this control (or whatever works) to move all of the selected features on that layer?

Okay, skip the ModifyFeature control and just hook into the SelectFeature control to keep track of the selected features and then use the DragControl to manipulate the selected points at the same time.

Example of the control instantiation:

var drag = new OpenLayers.Control.DragFeature(vectors, {
  onStart: startDrag,
  onDrag: doDrag,
  onComplete: endDrag
});
var select = new OpenLayers.Control.SelectFeature(vectors, {
  box: true,
  multiple: true,
  onSelect: addSelected,
  onUnselect: clearSelected
});

Example of the event handling functions:

/* Keep track of the selected features */
function addSelected(feature) {
    selectedFeatures.push(feature);
}

/* Clear the list of selected features */
function clearSelected(feature) {
    selectedFeatures = [];
}

/* Feature starting to move */
function startDrag(feature, pixel) {
    lastPixel = pixel;
}

/* Feature moving */
function doDrag(feature, pixel) {
    for (f in selectedFeatures) {
        if (feature != selectedFeatures[f]) {
            var res = map.getResolution();
            selectedFeatures[f].geometry.move(res * (pixel.x - lastPixel.x), res * (lastPixel.y - pixel.y));
            vectors.drawFeature(selectedFeatures[f]);
        }
    }
    lastPixel = pixel;
}

/* Featrue stopped moving */
function endDrag(feature, pixel) {
    for (f in selectedFeatures) {
        f.state = OpenLayers.State.UPDATE;
    }
}

Hmm...

I tried the code above, and couldn't make it work. Two issues: 1) To move each feature, you need to use the original position of that feature, and add the "drag vector" from whatever feature the DragControl is moving around by itself (ie the feature-parameter to doDrag). 2) Since DragFeatures own code sets lastPixel=pixel before calling onDrag, the line calling move() will move the feature to (0,0).

My code looks something like this:

var lastPixels;
function startDrag(feature, pixel) {
    // save hash with selected features start position
    lastPixels = [];
    for( var f=0; f<wfs.selectedFeatures.length; f++){
         lastPixels.push({ fid: layer.selectedFeatures[f].fid, 
                           lastPixel: map.getPixelFromLonLat( layer.selectedFeatures[f].geometry.getBounds().getCenterLonLat() )
                         });
    }
}

function doDrag(feature, pixel) {
    /* because DragFeatures own handler overwrites dragSelected.lastPixel with pixel before this is called, calculate drag vector from movement of "feature" */
    var g = 0;
    while( lastPixels[g].fid != feature.fid ){ g++; }
    var lastPixel = lastPixels[g].lastPixel;

    var currentCenter =  map.getPixelFromLonLat( feature.geometry.getBounds().getCenterLonLat() );
    var dragVector = { dx: currentCenter.x - lastPixel.x, dy: lastPixel.y - currentCenter.y };

    for( var f=0; f<layer.selectedFeatures.length; f++){
         if (feature != layer.selectedFeatures[f]) {
             // get lastpixel of this feature
             lastPixel = null;
             var h = 0;
             while( lastPixels[h].fid != layer.selectedFeatures[f].fid ){ h++; }
             lastPixel = lastPixels[h].lastPixel;

             var newPixel = new OpenLayers.Pixel( lastPixel.x + dragVector.dx, lastPixel.y - dragVector.dy );
             // move() moves polygon feature so that centre is at location given as parameter
             layer.selectedFeatures[f].move(newPixel);
         }
    }
}

I had a similar problem and solved it by overriding DragFeature's moveFeature function and putting this.lastPixel = pixel inside the for loop that applies the move to all features within my layer vector. Until I moved this.lastPixel = pixel inside the loop, all features except the one being dragged got crazily distorted.

 `OpenLayers.Control.DragFeature.prototype.moveFeature = function (pixel) {

        var res = this.map.getResolution();         
        for (var i = 0; i < vector.features.length; i++) {
            var feature = vector.features[i];
            feature .geometry.move(res * (pixel.x - this.lastPixel.x),
                res * (this.lastPixel.y - pixel.y));
            this.layer.drawFeature(feature );
            this.lastPixel = pixel;
        }
        this.onDrag(this.feature, pixel);
    };

`

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM