Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I'd like to get geometries from a local file (e.g. GML) displayed as rubber bands (QgsRubberBands) in QGIS. However, I wouldn't like to load the layer into the map because in the real scenario there could be a large number of files to get geometries from.

I've been attempting it with the following code (you can copy it directly to the QGIS Python Console), but the problem is that only the last feature is displayed:

from qgis.core import QgsFeature, QgsVectorLayer
from qgis.gui import QgsRubberBand
def loadGMLAsRubberBands(fileName):
    featList = []   
    rb = QgsRubberBand(qgis.utils.iface.mapCanvas(), True)
    vlayer = QgsVectorLayer(fileName, "layer", "ogr")
    allAttrs = vlayer.dataProvider().attributeIndexes()
    vlayer.select(allAttrs)        
    f = QgsFeature()
    while vlayer.dataProvider().nextFeature(f):
        featList.append(f)          
        rb.addGeometry(featList[-1].geometry(), None)   

loadGMLAsRubberBands("/tmp/gml/sample_three_features.gml")

A sample GML file can be found here.

I've already attempted several things with no success, namely to store layers (vlayer), features, geometries and/or rubber bands in a list (as suggested in some QGIS mailing-list threads).

I'm using QGIS 1.8.0-Lisboa (rev. a1255fc), Python v.2.7.2, GDAL/OGR v.1.7.3 on Ubuntu/Linux.

Any help would be appreciated.

share|improve this question
1  
Just be aware that you might hit more performance issue with lots of QgsRubberBands. –  Nathan W Jun 7 '12 at 9:56
    
Sure. However, I haven't even been able to compare performance because of this problem. –  tuxman Jun 7 '12 at 14:24
    
Very strange. I have done this before and it normally works well –  Nathan W Jun 7 '12 at 15:01
    
regarding performance I just tried on a using the code on a layer with 20000+ features and lets just say it wasn't a code experience. It's just not what QGIS is designed for. –  Nathan W Jun 8 '12 at 6:21
    
Also the reason it doesn't work for you is because there is a bug in the code with multipolygons when calling addGeometry(). The code works fine for normal polygons. –  Nathan W Jun 8 '12 at 6:22

1 Answer 1

up vote 0 down vote accepted

Since there is a bug with multi-polygons (thanks to @Nathan W), I added more code to the script and now it works. Basically, I adapted the code from the QGIS fTools plugin to convert multi-polygons into polygons as a workaround.

Now all features are displayed!

from qgis.core import QgsFeature, QgsVectorLayer
from qgis.gui import QgsRubberBand
def loadGMLAsRubberBands(fileName):
    featureList = []   
    rb = QgsRubberBand(qgis.utils.iface.mapCanvas(), True)
    vlayer = QgsVectorLayer(fileName, "layer", "ogr")
    vprovider = vlayer.dataProvider()
    allAttrs = vprovider.attributeIndexes()
    vlayer.select(allAttrs)       
    # Next code is adapted from fTools plugin 
    inFeat = QgsFeature()
    outFeat = QgsFeature()
    inGeom = QgsGeometry()
    while vprovider.nextFeature( inFeat ):
        inGeom = inFeat.geometry()
        featList = extractAsSingle( inGeom )
        for i in featList:
          outFeat.setGeometry( i )
          featureList.append( outFeat )
          rb.addGeometry(featureList[-1].geometry(), None)  

def extractAsSingle( geom ):
    # Code from QGIS fTools plugin
    multi_geom = QgsGeometry()
    temp_geom = []
    if geom.type() == 0:
      if geom.isMultipart():
        multi_geom = geom.asMultiPoint()
        for i in multi_geom:
          temp_geom.append( QgsGeometry().fromPoint ( i ) )
      else:
        temp_geom.append( geom )
    elif geom.type() == 1:
      if geom.isMultipart():
        multi_geom = geom.asMultiPolyline()
        for i in multi_geom:
          temp_geom.append( QgsGeometry().fromPolyline( i ) )
      else:
        temp_geom.append( geom )
    elif geom.type() == 2:
      if geom.isMultipart():
        multi_geom = geom.asMultiPolygon()
        for i in multi_geom:
          temp_geom.append( QgsGeometry().fromPolygon( i ) )
      else:
        temp_geom.append( geom )
    return temp_geom


loadGMLAsRubberBands("/tmp/gml/sample_three_features.gml")
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.