2010-12-08 47 views
6

Je sais que je peux facilement permettre à un utilisateur de sélectionner plusieurs fonctionnalités/géométries dans OpenLayers, mais je veux ensuite permettre à l'utilisateur de faire glisser/déplacer facilement toutes les fonctionnalités sélectionnées en même temps.Glisser/Déplacer plusieurs fonctionnalités sélectionnées - OpenLayers

Avec le contrôle ModifyFeature, il ne déplace qu'une fonction à la fois ... est-il possible d'étendre facilement ce contrôle (ou tout ce qui fonctionne) pour déplacer toutes les entités sélectionnées sur ce calque?

Répondre

12

Ok, passez le contrôle ModifyFeature et juste crochet dans le contrôle SelectFeature de garder une trace des fonctions sélectionnées, puis utilisez le DragControl pour manipuler les points sélectionnés en même temps.

Exemple de l'instanciation de commande:

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 
}); 

Exemple de fonctions de gestion d'événements:

/* 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; 
    } 
} 
+0

Merci pour cela - ça marche aussi pour moi, attendez-vous qu'une fois les caractéristiques ont été traînés, ils ne sont plus « sélectionnables » dans la zone de sélection, et ne peuvent pas être déplacés à nouveau. Avez-vous eu ce problème? –

+0

Merci pour l'exemple clair, il m'a fallu presque une journée pour trouver un exemple simple sur le glisser et les événements. Celui-ci est génial! Je ne l'utilise pas pour plusieurs fonctionnalités, mais pour 1. – Marco

+0

Trouvé, utilisé et cela fonctionne :). Donc, un grand MERCI! – elrado

0

Hmm ...

J'ai essayé le code ci-dessus, et ne pouvait pas faire ça marche. Deux problèmes: 1) Pour déplacer chaque entité, vous devez utiliser la position d'origine de cette entité et ajouter le "vecteur de déplacement" de n'importe quelle fonction du DragControl lui-même (c'est-à-dire le paramètre feature à doDrag). 2) Étant donné que DragFeatures possède son propre code lastPixel = pixel avant d'appeler onDrag, la ligne appelant move() déplace l'entité vers (0,0).

Mon code ressemble à ceci:

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); 
     } 
    } 
} 
+1

Bienvenue dans Stack Overflow! Si vous avez une NOUVELLE question, posez-la en cliquant sur le bouton [Poser une question] (http://stackoverflow.com/questions/ask). Si vous avez une réputation suffisante, [vous pouvez upvote] (http://stackoverflow.com/privileges/vote-up) la question. Alternativement, "star" en tant que favori et vous serez informé de toutes les nouvelles réponses. – jjnguy

0

J'ai eu un problème similaire et résolu en remplaçant la fonction moveFeature de DragFeature et de mettre this.lastPixel = pixel dans la boucle qui applique le mouvement à toutes les fonctions au sein de mon vecteur de couche. Jusqu'à ce que j'ai déplacé this.lastPixel = pixel à l'intérieur de la boucle, toutes les fonctionnalités, sauf celle qui a été déplacée, ont été faussement déformées.

`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); 
    }; 

`