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

Rudi von Staden rudivs at gmail.com
Thu Feb 21 02:14:03 PST 2013


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
>> >
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/qgis-developer/attachments/20130221/581b4e92/attachment-0001.html>


More information about the Qgis-developer mailing list