5 votos

¿Cómo crear y eliminar múltiples QgsRubberBands en PyQGIS?

Actualmente el siguiente recorte de código funciona muy bien para resaltar una forma basada en el característica y capa variables:

    self.rubberHighlight = QgsRubberBand(self.iface.mapCanvas(),QGis.Polygon)
    self.rubberHighlight.setBorderColor(QtGui.QColor(0,0,255))
    self.rubberHighlight.setFillColor(QtGui.QColor(0,0,0,0))
    self.rubberHighlight.setLineStyle(Qt.PenStyle(Qt.DotLine))
    self.rubberHighlight.setWidth(3)
    self.rubberHighlight.setToGeometry(feature, layer)
    self.rubberHighlight.show()

Al crear un resalte, puedo eliminar instancias singulares con...

    self.iface.mapCanvas().scene().removeItem(self.rubberHighlight)
    del self.rubberHighlight

... sin embargo, esto no funciona para múltiples características resaltadas por la banda elástica simultáneamente.

¿Alguna pista sobre cómo añadir y eliminar muchas mechas a la vez?

SOLUCIÓN ACTUALIZADA (SUCIA):

def __init__(self, iface, ..., parent=None):
    ...
    self.rbDict = {}
    ...
    self.show()

def selectedRow(self):
    selectedIndexes = self.cellSelectionModel.selectedRows()
    if len(selectedIndexes)<=0:
        self.clearRubberBandHighlights()
        return
    else:
        for index in selectedIndexes:
            row = index.row()
            layerAndFeatureIDs = self.tableData.data(self.tableData.index(row,0),Qt.DisplayRole)
            if layerAndFeatureIDs==None:
                self.clearRubberBandHighlights()
                return
            else:
                self.clearRubberBandHighlights()
                if 'Layer' in self.editorType or 'Stress Period' in self.editorType:
                    single = None
                    try:
                        layerId,featureId = [layerAndFid for layerAndFid \
                                             in layerAndFeatureIDs.split('~:#>')]
                        single = True
                    except:
                        layerIds = []
                        featureIds = []
                        eachLayerFidPair = list(set([pair for pair \
                                                     in layerAndFeatureIDs.split('}${')]))
                        for pair in eachLayerFidPair:
                            layerId,featureId = [layerAndFid for layerAndFid \
                                                 in pair.split('~:#>')]
                            layerIds.append(layerId)
                            featureIds.append(featureId)
                        single = False
                    if single:
                        layerRef = ftools_utils.getMapLayerByName(unicode(layerId))
                        for feature in layerRef.getFeatures():
                            if int(feature.id())==int(featureId):
                                self.rubberBandHighlight(feature,layerRef)
                    elif not single:
                        for layIdx, layerId in enumerate(layerIds):
                            layerRef = ftools_utils.getMapLayerByName(unicode(layerId))
                            for feature in layerRef.getFeatures():
                                if int(feature.id())==int(featureIds[layIdx]):
                                    self.rubberBandHighlight(feature,layerRef)

def rubberBandHighlight(self,feature,layer):
    self.rbDict[feature.id()] = QgsRubberBand(self.iface.mapCanvas(),True)
    self.rbDict[feature.id()].setBorderColor(QtGui.QColor(0,0,255))
    self.rbDict[feature.id()].setFillColor(QtGui.QColor(0,0,0,0))
    self.rbDict[feature.id()].setLineStyle(Qt.PenStyle(Qt.DotLine))
    self.rbDict[feature.id()].setWidth(3)
    self.rbDict[feature.id()].addGeometry(feature.geometry(),None)

def clearRubberBandHighlights(self):
    for key in self.rbDict.keys():
        self.iface.mapCanvas().scene().removeItem(self.rbDict[key])
        del self.rbDict[key]

EJEMPLO DE DATOS DE ENTRADA (tal como aparecen en QtableView):

(donde cada sublista index[0] contiene una cadena delimitada especial de toda la información de la capa y feature.id())

[Aquitards~:#>1,Aquitard 2,1,2,,,,,,,,,,,],
[Aquitards~:#>0}${Aquitards~:#>0}${Aquitards~:#>2,Aquitard 1;Aquitard 8;Aquitard 3,1,3,,,,,,,,,,,],
[Aquitards~:#>2}${Aquitards~:#>1,Aquitard 7;Aquitard 9,1,4,,,,,,,,,,,]

6voto

Elliott Maynard Puntos 11

Esto debería funcionar para una capa poligonal (lo he probado en la consola Python de QGIS, QGIS v.2.8.1):

from qgis.gui import QgsRubberBand
from PyQt4.QtGui import QColor

rbDict = {} # We need this to store the rbs we'll create
layer = iface.activeLayer()

# Create rubber bands
for f in layer.getFeatures():
  fId=f.id()
  rbDict[fId] = QgsRubberBand(iface.mapCanvas(), True)
  rbDict[fId].setColor( QColor( 0,255,0,255 ) )
  rbDict[fId].setWidth( 2 )
  rbDict[fId].addGeometry(f.geometry(), None) 

# And then remove them
for f in layer.getFeatures():
  fId=f.id()
  iface.mapCanvas().scene().removeItem(rbDict[fId])
  del rbDict[fId]

Como ya sabrás, usarías casi el mismo código para las líneas (sólo cambiando el parámetro booleano a False en la instanciación de la goma elástica) y necesitarías usar QgsVertexMarker para los puntos.

Dime si algo no está claro.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X