10 votos

¿Generar un gran número de mapas con PyQGIS?

Tengo que hacer un gran número (cientos) de mapas de distribución de especies. Tengo un shapefile que contiene las distribuciones para cada especie, y para cada uno, me gustaría obtener un mapa como una imagen (jpg, png o de otra manera) que contienen el nombre de la especie en cuestión, la leyenda (para distinguir las áreas de distribuciones anuales, cría, no cría, etc ...).

Me gustaría utilizar QGIS para ello.

4voto

rudivonstaden Puntos 1684

Yo tenía una necesidad similar y creé un plugin de QGIS para generar los mapas, basado en un shapefile con localidades puntuales para todas las especies (asume un nombre de taxón único en la tabla de atributos como identificador común). Mis requisitos no eran tan complejos - no necesitaba información estacional, títulos o leyenda, pero puede ser un punto de partida útil para usted. Para los aspectos más complejos, tendrá que utilizar el compositor de mapas. Consulte el Recetario PyQGIS para más información.

Plugin

El plugin automatiza la creación de los mapas, y permite configurar extensiones, resolución y otros aspectos. Aplica el mismo estilo a la salida que su superposición de cuadrícula. Actualmente sólo funciona en la versión de desarrollo de QGIS (1.9 o posterior).

Escritura sextante

Antes de hacer el plugin elaboré la lógica utilizando SEXTANTE. Este script de usuario también debería funcionar en 1.8 (no lo he probado). El archivo de estilo de distribución (.qml) es el estilo de las distribuciones de salida (ignora el estilo de la superposición de distribución). Actualmente coloca los mapas de salida en el directorio temp basado en los valores predeterminados de su sistema operativo (/tmp en Linux, y varios lugares en Windows - definidos por la variable ambiental TEMP). Sin embargo, puedes definirlo fácilmente en el código. También tendrá que editar la extensión y la resolución de salida en el código (y el color de fondo si desea un color diferente para el mar).

#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

#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)
    taxon_layer = QgsVectorLayer(taxon_shp,"taxon","ogr")
    QgsMapLayerRegistry.instance().addMapLayer(taxon_layer)
    taxon_layer.loadNamedStyle(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))
    tempdir = tempfile.gettempdir()
    img.save(os.path.join(tempdir,taxon+".png"),"png")

    # remove taxon layer from project
    QgsMapLayerRegistry.instance().removeMapLayers([taxon_layer.id()])

tempdir = tempfile.gettempdir()   
taxa = sextante.runalg('qgis:listuniquevalues', all_localities, taxon_field, None)['UNIQUE_VALUES'].split(";")
for taxon in taxa:
    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)

2voto

Joel Puntos 142

Hoy me he tomado poco tiempo para trabajar en esto. Así que hice algunos cambios a su guión. No necesito añadir un paso adicional selectbyattribute y saveselectedfeatures ya que utilizo un archivo .qml y el campo Seasonal está en el mismo shapefile. A continuación, puede ver lo que he hecho:

#Definition of inputs and outputs
#==================================
##[Scratch]=group
##all_localities=vector
##taxon_field=field all_localities
##seasonal_field=field all_localities
##countries_map=vector
##distribution_style_file=file
##output_folder=folder

#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)
taxon_layer = QgsVectorLayer(taxon_shp,"taxon","ogr")
QgsMapLayerRegistry.instance().addMapLayer(taxon_layer)
taxon_layer.loadNamedStyle(distribution_style_file)

# create image (dimensions 325x299)
img = QImage(QSize(325,299), QImage.Format_ARGB32_Premultiplied)

# set image's background color
color = QColor(221,249,254)   # blue sea
img.fill(color.rgb())

# create painter
p = QPainter()
p.begin(img)
p.setRenderHint(QPainter.Antialiasing)

render = QgsMapRenderer()

# create layer set
countries_layer = QGisLayers.getObjectFromUri(countries_map)
taxon_layer = QGisLayers.getObjectFromUri(taxon_shp)

lst = []
lst.append(taxon_layer.id())    
lst.append(countries_layer.id())
render.setLayerSet(lst)

# set extent (xmin,ymin,xmax,ymax)
rect = QgsRectangle(-11,32,39,71)
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))
tempdir = output_folder
img.save(os.path.join(tempdir,taxon+".png"),"png")

# remove taxon layer from project
QgsMapLayerRegistry.instance().removeMapLayers([taxon_layer.id()])

tempdir = tempfile.gettempdir()  

taxa = sextante.runalg('qgis:listuniquevalues', all_localities, taxon_field, None)        ['UNIQUE_VALUES'].split(";")

for taxon in taxa:
sextante.runalg('qgis:selectbyattribute', all_localities, taxon_field, 0, taxon)
filename = os.path.join(tempdir,"taxon.shp")    #memory file better?
sextante.runalg('qgis:saveselectedfeatures', all_localities, filename)
print_map(taxon,filename)

Si tienes algún comentario o consejo para mejorarlo, no lo dudes.

Para mejorarlo, lo mejor sería que cuando seleccionemos la extensión (por ejemplo Europa), utilice esta extensión para seleccionar sólo las especies incluidas dentro de esta extensión. Esto, porque obtengo mapas para todas las especies, incluso las que están fuera de Europa por ejemplo (por lo que tengo muchos mapas vacíos). ¿Crees que es posible?

Salud,

Onesime

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X