2014-11-12 82 views
5

ho bisogno di implementare undo/redo funzionalità utilizzando OpenLayers 3 di editing (come dimostrato nella http://dev.openlayers.org/examples/modify-feature.html per OpenLayers 2).OpenLayers 3 Come registrare Caratteristica evento modificato come "featuremodified" in openlayers 2

per tenere traccia di geometria cambiamenti di caratteristiche, devo gestire uno stack di memoria che conterrà le definizioni geometriche mutate caratteristiche su di interazioni degli utenti. So che OpenLayers 3 fornisce oggetti osservabili. Così ol.Feature o ol.Feature.getGeometry() può essere osservato per le modifiche, ma cerco di eventi espliciti emessi da ol.interaction.Modify, che mi dovrebbe notificare quando i interazione inizia o finisce l'operazione di editing (proprio come "beforefeaturemodified" e "featuremodified" eventi in OpenLayers 2).

Un gestore di ascolto per osservata geometria o caratteristica modifiche possono essere utilizzati per lo scopo, ma è troppo costoso perché geometria della funzione in fase di modifica viene cambiato ad ogni movimento pixel.

Ho passato con il funzionario documentation di OpenLayers 3 ma non ho trovato vari eventi che vengono forniti da OpenLayers 2. Nella maggior parte dei casi la documentazione menziona cambiamento solo evento. Mi chiedo se tali eventi non siano una considerazione per l'architettura di Openlayer 3. Se è così, qualche suggerimento come posso estendere il ol.interaction.Modify esistente per incorporare eventi personalizzati? Grazie.

+0

Attualmente non vi sono eventi simili. Quindi mi piacerebbe solo consigliare di creare problemi in Ol3 GitHub per questo. – erilem

+0

Sia OL2 che OL3 sono open source. Hai guardato il codice sorgente? Ho trovato soluzioni a problemi specifici in OL3 copiando funzioni e modificandole ai miei scopi. –

+0

Grazie a @erilem e @ anders-finn. Ho creato il problema su [github] (https://github.com/openlayers/ol3/issues/2946) e inoltre ho ereditato con successo il 'ol.interaction.Modify' per incorporare l'evento necessario usando' goog.EventTarget 'ecc. La nostra azienda sta cercando due risposte per decidere se utilizzare openlayers-3 o meno in un progetto imminente. 1- È sicuro ottenere un comportamento personalizzato estendendo le classi 'ol' usando' goog.base' e ​​'goog.inherits' in termini di futuri aggiornamenti di OL3? 2- Ci saranno conflitti di licenza se queste estensioni vengono spedite con prodotti commerciali? Grazie. –

risposta

2

A partire da OpenLayers 3.7.0, ol.interaction.Modify emette modifystart e modifyend. Documentazione: http://openlayers.org/en/v3.7.0/apidoc/ol.ModifyEvent.html

Esempio che decide casualmente dopo ogni modifica se deve essere mantenuta o invertita (http://jsfiddle.net/rbha7f83/1/):

var select = new ol.interaction.Select({ 
    style: overlayStyle 
}); 

// The modify interaction does not listen to geometry change events. 
// Changing the feature coordinates will make the modify interaction 
// unaware of the actual feature coordinates. 
// A possible fix: Maintain a collection used by Modify, so we can reload 
// the features manually. This collection will always contain the same 
// features as the select interaction. 
var selectSource = new ol.Collection(); 
select.on('select', function (evt) { 
    evt.selected.forEach(function (feature) { 
     selectSource.push(feature); 
    }); 
    evt.deselected.forEach(function (feature) { 
     selectSource.remove(feature); 
    }); 
}); 

var modify = new ol.interaction.Modify({ 
    features: selectSource, // use our custom collection 
    style: overlayStyle 
}); 

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

var originalCoordinates = {}; 
modify.on('modifystart', function (evt) { 
    evt.features.forEach(function (feature) { 
     originalCoordinates[feature] = feature.getGeometry().getCoordinates(); 
    }); 
}); 
modify.on('modifyend', function (evt) { 
    evt.features.forEach(function (feature) { 
     if (feature in originalCoordinates && Math.random() > 0.5) { 
      feature.getGeometry().setCoordinates(
      originalCoordinates[feature]); 
      delete originalCoordinates[feature]; 

      // remove and re-add the feature to make Modify reload it's geometry 
      selectSource.remove(feature); 
      selectSource.push(feature); 
     } 
    }); 
}) 

nota che gli eventi sono emessi prima e dopo ogni interazione. Trascinando un vertice e facendo clic su un vertice per rimuoverlo (entrambi sulla stessa funzione) verranno attivati ​​due eventi modifystart e modifyend.