我必须制作大量(数百种)物种分布图。我有一个shapefile,其中包含每个物种的分布,对于每个物种,我都希望获得一张地图,作为图像(jpg,png或其他格式),其中包含有关物种的名称,图例(以区分不同物种的区域)。年度分布,繁殖,非繁殖等...)。
我想使用QGIS来做到这一点。
我必须制作大量(数百种)物种分布图。我有一个shapefile,其中包含每个物种的分布,对于每个物种,我都希望获得一张地图,作为图像(jpg,png或其他格式),其中包含有关物种的名称,图例(以区分不同物种的区域)。年度分布,繁殖,非繁殖等...)。
我想使用QGIS来做到这一点。
Answers:
我有一个类似的要求,并基于一个Shapefile文件,将其放置在所有物种的点位置上,从而将QGIS插件组合在一起以生成地图(它假定属性表中的唯一分类名称为公共标识符)。我的要求并不那么复杂-我不需要季节性信息,标题或传说,但这可能对您有用。对于更复杂的方面,您将需要使用地图编辑器。有关更多信息,请参见PyQGIS食谱。
插入
该插件可自动创建地图,并允许您配置范围,分辨率和其他方面。它将与网格覆盖相同的样式应用于输出。当前,它仅在QGIS的开发版本(1.9或更高版本)上运行。
Sextante脚本
在制作插件之前,我先使用SEXTANTE确定了逻辑。此用户脚本也应在1.8中运行(尚未测试)。分发样式文件(.qml)是输出分发的样式(它忽略分发覆盖的样式)。当前,它根据您的操作系统默认值(Linux中的/ tmp,以及Windows中的各个位置-由TEMP环境变量定义)将输出映射放置在temp目录中。您可以在代码中轻松定义自己。您还需要在代码中编辑范围和输出分辨率(如果要为大海使用其他颜色,则需要编辑背景颜色)。
#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)
selectbylocation
步骤,并为每个季节添加一个额外的selectbyattribute
和saveselectedfeatures
步骤(更改grid_layer
为all_localities
)。然后加载更多.qml文件并添加附加您的季节性shapefile(最前面附加的顶层)。如果您不确定如何操作,我可能可以尝试编辑上面的脚本以进行或多或少的工作。
我今天花了一些时间来做这个。因此,我对您的脚本进行了一些更改。我不需要添加其他selectbyattribute和saveselectedfeatures步骤,因为我使用的是.qml文件,并且Seasonal字段位于同一shapefile中。在下面,您可以看到我做了什么:
#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)
如果您有任何意见或建议来改进它,请不要犹豫。
为了对其进行改进,最好是在选择范围时(例如欧洲),它使用此范围仅选择此范围内包括的物种。这是因为我获得了所有物种的地图,甚至包括欧洲以外的物种(因此我有很多空的地图)。您认为这可能吗?
干杯,
奥尼西姆