[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