2

I have experienced a very bizarre issue with my PyQgis code. I simply want to load a raster and a vector layer to do zonal statistics, the first part works perfectly but for the zonal statistic I have got an error with this command:

raster file = qgis.utils.iface.mapCanvas().layer(1).source()

(AttributeError: 'NoneType' object has no attribute 'source')

The strange thing is that if I rerun only the second part of the code (ie. my layers are already loaded) the extension .source() does not report any errors. This is still annoying since I am not able to write a loop with the full code and then use it for different layers.

Did anyone already experience this kind of issue?

Here is the code,

os.chdir("C:\Projet")
###          Part I
##           load vector layer
vbaselayer = QgsVectorLayer("county_save_as_lamhert_onlyUS.shp", "basemap", "ogr")
##           load and project the raster layer

os.system('gdalwarp -overwrite -t_srs EPSG:102004 -of GTiff NETCDF:"rhum.2m.2000.nc":rhum rhum_projection.tif')
humidity = "rhum_projection.tif"
fileInfo = QFileInfo(humidity)
rlayer = QgsRasterLayer(humidity,"hum2000")
rlayer.isValid()
QgsMapLayerRegistry.instance().addMapLayer(rlayer)
QgsVectorFileWriter.writeAsVectorFormat(vbaselayer,"2000.shp","utf-8",None,"ESRI Shapefile")
year = 2000
vlayer = QgsVectorLayer("{}.shp".format(year), "county", "ogr")
vlayer.isValid()
QgsMapLayerRegistry.instance().addMapLayer(vlayer)
###          Part II
##           zonal statistics
id = 1
while id < 365:
    vectorlayer=qgis.utils.iface.mapCanvas().layer(0)
    rasterfile = qgis.utils.iface.mapCanvas().layer(1).source()
    zonalstats = qgis.analysis.QgsZonalStatistics(vectorlayer,rasterfile,str(id),id)
    zonalstats.calculateStatistics(None)
    id += 1
12
  • I guess you meant raster_file = qgis.utils.iface.mapCanvas().layers()[1].source(), didn't you? Feb 20, 2015 at 20:33
  • Not really, is there any difference? The full code for zonal stat is : vectorlayer=qgis.utils.iface.mapCanvas().layer(0) rasterfile = qgis.utils.iface.mapCanvas().layer(1).source() zonalstats = qgis.analysis.QgsZonalStatistics(vectorlayer,rasterfile,str(1),1) zonalstats.calculateStatistics(None)
    – Sébastien
    Feb 20, 2015 at 20:39
  • Didn't know about that way to access layers, but it works. So, how many layers are loaded when you run the line of code you posted in the question? Feb 20, 2015 at 20:42
  • Only two, the first one is the vector layer and the second is the raster one. So the code stop after having load the 2 layers, but if i rerun only the second part it will work...
    – Sébastien
    Feb 20, 2015 at 20:43
  • 1
    Weird. You should then be able to access the second layer in the ToC via layer(1). Could you post how are you loading your layers, i.e., provide a reproducible code snippet? Feb 20, 2015 at 20:45

1 Answer 1

2

The following script works for me in the QGIS Python console:

vLayer = QgsVectorLayer("/path/to/vector.shp","my vector","ogr")
rasterPath = "/path/to/raster.tif"
rLayer = QgsRasterLayer(rasterPath,"my raster")
if not ( vLayer.isValid() and rLayer.isValid() ):
    print "Error loading layers..."

band=1
from qgis.analysis import QgsZonalStatistics
zonalstats = QgsZonalStatistics( vLayer, rasterPath, str(band), band )
zonalstats.calculateStatistics( None )

I would suggest you to try this very simple script and then extend it with your own logic.


By the way, there are strange things in your script.

You don't need to put these lines inside a while loop:

vectorlayer=qgis.utils.iface.mapCanvas().layer(0)
rasterfile = qgis.utils.iface.mapCanvas().layer(1).source()

You already have the vector layer in vlayer and the raster source in rlayer.source(). Even more, you also don't need to add the layers to the registry before using them.

Your while loop could be simply:

id = 1
rsource = rlayer.source()
while id < 365:
    zonalstats = qgis.analysis.QgsZonalStatistics(vlayer,rsource,str(id),id)
    zonalstats.calculateStatistics(None)
    id += 1
0

Your Answer

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

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