[Qgis-developer] Unloading a layer in Sextante script crashes QGIS

Victor Olaya volayaf at gmail.com
Thu Feb 21 04:58:10 PST 2013


Rudi,

Thanks for pushing the limits of SEXTANTE a bit further :-) This is a
good example, and if I have time I will try to investigate on that
line, since it can open the field for other similar "unusual"
algorithms

Thanks again



2013/2/21 Rudi von Staden <rudivs at gmail.com>:
> I got the script to work using
> QgsMapLayerRegistry.instance().addMapLayer(taxon_layer) to load and
>
> QgsMapLayerRegistry.instance().removeMapLayers([taxon_layer.id()]) to remove
> the layer. The main error was that the remove command needs the layer id in
> a list.
>
>
> I also made a plugin out of it, so if anyone would find it useful it's at
> https://github.com/rudivs/DistroMap. I must say that writing it first as a
> Sextante script was a great help in working out the logic. I could then look
> at the code from the algorithms and adapt it to my purposes.
>
>
> Regards,
> Rudi
>
>
> On Tue, Feb 19, 2013 at 2:10 PM, Rudi von Staden <rudivs at gmail.com> wrote:
>>
>> Thanks Victor... I tried a few other ways to load the layer, but none of
>> them seem to work.
>>
>>
>>
>> On Tue, Feb 19, 2013 at 1:13 PM, Victor Olaya <volayaf at gmail.com> wrote:
>>>
>>> ...
>>>
>>> Ideally, a SEXTANTE algorithm should just take data and produce new
>>> data, and then, if it is declared correctly as algorithm output, it
>>> will be loaded automatically by SEXTANTE. I am afraid that your
>>> algorithm might go beyond what SEXTANTE expects....
>>>
>>> Anyway, the problem might be that you are trying to remove the layer
>>> and maybe it is not there since the load method in SEXTANTE does not
>>> add the layer to the canvas, but just open it so SEXTANTE algorithms
>>> can use it if it is not loaded.
>>> ...
>>>
>>>
>>> 2013/2/19 Rudi von Staden <rudivs at gmail.com>:
>>> > I've put together a Sextante script to automate the production of
>>> > grid-based
>>> > species distribution maps (png image output) by modifying [1] and [2].
>>> > It
>>> > takes a vector layer of point localities (with species name as a field)
>>> > and
>>> > a grid layer as input, and produces output maps by selecting grids
>>> > based on
>>> > point localities.
>>> >
>>> > For each species it creates a distribution shapefile, which consists of
>>> > the
>>> > grid polygons where the species occurs. As far as I could tell, this
>>> > layer
>>> > needs to be loaded to the canvas before it can be included in the
>>> > layerset
>>> > to be rendered for the output images (is there a better way?). Sextante
>>> > includes a function for loading layers, but not removing them. From
>>> > what I
>>> > could find,
>>> > "QgsMapLayerRegistry.instance().removeMapLayers(taxon_layer.id())"
>>> > should
>>> > remove the layer, but it crashes QGIS when I try (current git version).
>>> > If I
>>> > comment out the line, my canvas gets clogged. Any idea where the
>>> > problem
>>> > lies? Script below.
>>> >
>>> > Thanks,
>>> > Rudi
>>> >
>>> > [1] http://www.qgis.org/pyqgis-cookbook/composer.html#simple-rendering
>>> > [2]
>>> > http://qgissextante.blogspot.com/2013/01/using-selection-algorithms.html
>>> >
>>> >
>>> > #Definition of inputs and outputs
>>> > #==================================
>>> > ##[Scratch]=group
>>> > ##all_localities=vector
>>> > ##taxon_field=field all_localities
>>> > ##africa_map=vector
>>> > ##sa_map=vector
>>> > ##grid_layer=vector
>>> > ##distribution_style_file=file
>>> > ##output=output file
>>> >
>>> > #Algorithm body
>>> > #==================================
>>> > from qgis.core import *
>>> > from PyQt4.QtCore import *
>>> > from PyQt4.QtGui import *
>>> > from sextante.core.QGisLayers import QGisLayers
>>> > from sextante.core.SextanteVectorWriter import SextanteVectorWriter
>>> > import tempfile
>>> > import os
>>> >
>>> > def print_map(taxon,taxon_shp):
>>> >     #load taxon layer (necessary?)
>>> >     QGisLayers.load(taxon_shp,name = "taxon",style =
>>> > distribution_style_file)
>>> >
>>> >     # create image (dimensions 325x299)
>>> >     img = QImage(QSize(325,299), QImage.Format_ARGB32_Premultiplied)
>>> >
>>> >     # set image's background color
>>> >     color = QColor(192,192,255)   # blue sea
>>> >     img.fill(color.rgb())
>>> >
>>> >     # create painter
>>> >     p = QPainter()
>>> >     p.begin(img)
>>> >     p.setRenderHint(QPainter.Antialiasing)
>>> >
>>> >     render = QgsMapRenderer()
>>> >
>>> >     # create layer set
>>> >     africa_layer = QGisLayers.getObjectFromUri(africa_map)
>>> >     sa_layer = QGisLayers.getObjectFromUri(sa_map)
>>> >     taxon_layer = QGisLayers.getObjectFromUri(taxon_shp)
>>> >
>>> >     lst = []
>>> >     lst.append(taxon_layer.id())
>>> >     lst.append(sa_layer.id())
>>> >     lst.append(africa_layer.id())
>>> >
>>> >     render.setLayerSet(lst)
>>> >
>>> >     # set extent (xmin,ymin,xmax,ymax)
>>> >     rect = QgsRectangle(14.75,-36.00,34.00,-21.00)
>>> >     render.setExtent(rect)
>>> >
>>> >     # set output size
>>> >     render.setOutputSize(img.size(), img.logicalDpiX())
>>> >
>>> >     # do the rendering
>>> >     render.render(p)
>>> >     p.end()
>>> >
>>> >     # save image
>>> >     outdir = os.path.dirname(os.path.abspath(output))
>>> >     img.save(os.path.join(outdir,taxon+".png"),"png")
>>> >
>>> >     # remove taxon layer from project
>>> >     QgsMapLayerRegistry.instance().removeMapLayers(taxon_layer.id())
>>> > #crashes QGIS
>>> >
>>> > tempdir = tempfile.gettempdir()
>>> > taxa = sextante.runalg('qgis:listuniquevalues', all_localities,
>>> > taxon_field,
>>> > None)['UNIQUE_VALUES'].split(";")
>>> > counter = 0   # limit for testing
>>> > for taxon in taxa:
>>> >     if counter < 10:
>>> >         sextante.runalg('qgis:selectbyattribute', all_localities,
>>> > taxon_field, 0, taxon)
>>> >         sextante.runalg('qgis:selectbylocation', grid_layer,
>>> > all_localities,
>>> > 0)
>>> >         filename = os.path.join(tempdir,"taxon.shp")    #memory file
>>> > better?
>>> >         sextante.runalg('qgis:saveselectedfeatures', grid_layer,
>>> > filename)
>>> >         print_map(taxon,filename)
>>> >         counter+=1
>>> >
>>>
>


More information about the Qgis-developer mailing list