6

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.

7
  • 1
    Just be aware that you might hit more performance issue with lots of QgsRubberBands.
    – Nathan W
    Jun 7, 2012 at 9:56
  • Sure. However, I haven't even been able to compare performance because of this problem. Jun 7, 2012 at 14:24
  • Very strange. I have done this before and it normally works well
    – Nathan W
    Jun 7, 2012 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, 2012 at 6:21
  • 1
    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, 2012 at 6:22

1 Answer 1

3

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")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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