PyQGISを使用して多数のマップを生成しますか?


10

種の分布図を多数(数百)作成する必要があります。各種の分布を含むシェープファイルがあり、各種について、関係する種の名前、凡例(領域を区別するため)を含む画像(jpg、pngなど)としてマップを取得したい年間分布、繁殖、非繁殖など...)。

これを行うためにQGISを使用したいと思います。


1
マップの詳細についてもう少し詳しく教えてもらえますか?たとえば、これらのすべてのマップに特定の大陸や国などの同じエリアを表示したいですか、それともマップの範囲を動的に変更したいですか?また、1つのマップにすべての範囲サブタイプが必要ですか、それとも複数のマップにありますか?これらの回答に応じて、問題はかなり単純になることもあれば、もう少し高度なアプローチが必要になることもあります。探し始めるのに適した場所は、GIS用のAtlasプラグインです。または、ArcGIS 10以降が利用可能な場合は、ESRIのマップブックも役立ちます。
Jay Guarneri

1
詳細の欠如でごめんなさい。はい、すべてのマップで同じエリアになります(ヨーロッパ)。私は、すべての種と属性で対応する分布を含む1つのシェープファイルを持っています。このシェープファイルは、さまざまなシェープファイル(種ごとに1つ)に簡単に分割できます。最後に、種ごとに1枚の写真を用意します。常に同じエリア(ヨーロッパ)、同じ色(たとえば、濃い緑の年間分布、明るい緑の繁殖、非繁殖)を使用します青など...)、同じ伝説、そしてタイトルとして正体の名前。
Onesime 2013

あなたがする必要があるのは、各マップを作成するために実行する必要がある各ステップを計画し、Pythonで選択とマップのエクスポートをコーディングすることだと思います。これはArcGIS Pythonで簡単に実行できることはわかっていますが、QGIS Pythonインターフェイスについて十分な知識がないため、多くのガイダンスを提供できません。ただし、1つのシェープファイルでこれを機能させることができると私は確信しています。
Jay Guarneri

Pythonプラグインを使用してQGISで同様のことを行いました。私の場合、私のレイヤーはPostGISに保存されていましたが、シェープファイルを使用して同様のことを実行できると思います。コードを共有できてうれしいです。私の首相。
ブライアンエドモンド

1
データのサンプルをアップロードして、試していただけますか。
Nathan W

回答:


4

同様の要件があり、すべての種の点の局所性を含むシェープファイルに基づいてマップを生成するQGISプラグインをまとめました(共通の識別子として属性テーブルの一意の分類名を想定しています)。私の要件はそれほど複雑ではありませんでした-私は季節的な情報、タイトル、または伝説を必要としませんでしたが、それはあなたにとって有用な出発点かもしれません。より複雑な側面については、マップコンポーザーを使用する必要があります。詳細については、PyQGISクックブックを参照してください。

プラグイン

プラグインは、マップの作成を自動化し、範囲、解像度、その他の側面を構成できます。グリッドオーバーレイと同じスタイルを出力に適用します。現在、QGISの開発バージョン(1.9以降)でのみ動作します。

Sextanteスクリプト

プラグインを作成する前に、SEXTANTEを使用してロジックを作成しました。このユーザースクリプトは1.8でも動作するはずです(テストしていません)。配布スタイルファイル(.qml)は、出力配布のスタイルです(配布オーバーレイのスタイルは無視されます)。現在、オペレーティングシステムのデフォルト(Linuxでは/ tmp、Windowsではさまざまな場所-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)

こんにちは、すべての返信ありがとうございます。さらにいくつかの要素を提供するために、それはBirdLifeからのデータです(specieの例:birdlife.org/datazone/speciesfactsheet.php?id=2794)。簡単に言うと、すべての種のすべてのポリゴンを含む1つのシェープファイルがあり(一部の種では、単一の種の多くの線)、季節の分布に対応する属性があります(1から5までの値がさまざまな用途に対応しています) )、もう一方は起源などです。凡例とタイトルは必須ではありません。
Onesime 2013年

-バックグラウンドでカントリーレイヤーを使用しています。-「季節」属性とは異なる値の異なる色については、.qmlファイルの使用が適していると思います。-オプションで、タイトルと凡例については、作曲家のファイルを使用する必要があると思います。難しい場合は、他のソフトウェアで追加できます。-すべての種について操作を繰り返す必要があるため、これは属性による選択に対応し、最終的な写真の名前を付けるために使用されます。
Onesime 2013年

プラグイン「Atlas」を試しましたが、さまざまな場所に適しているようです。私の場合は、同じ地域であるヨーロッパです。カバレッジエリアを修正できるため、この時点で対応していると思われるプラグイン「分布図マネージャー」を試してみましたが、すでにポリゴンレイヤーがあるため、グリッドレイヤーとポイントを交差させる処理は必要ありません。ArcGisで試しましたが、QGis Atlasプラグインでもまったく同じです。解決策は、Pythonスクリプトを記述することです...
Onesime

それで、私は「rudivonstaden」スクリプトに基づいてSextanteを使用し(ありがとうございます!)、それを私のケースに適応させると思います。最後に、これらの異なるコメントについては申し訳ありませんが、文字数の制限があります...
Onesime

@Onesime、タイトルと凡例を除いて、私はあなたが必要なことをするために上記の六分儀スクリプトを適応させることができると思います。あなたは、おそらく削除する必要がありますselectbylocationステップを、そして追加の追加selectbyattributesaveselectedfeatures各季節(変更のためのステップをgrid_layerしますall_localities)。次に、さらに.qmlファイルをロードし、季節的なシェープファイルを追加します(最初に追加される最上層)。方法がわからない場合は、上記のスクリプトを編集して、多かれ少なかれ作業を行うことができます。
rudivonstaden 2013年

2

今日は少し時間をかけてこれに取り組みました。だから私はあなたのスクリプトにいくつかの変更を加えました。.qmlファイルを使用し、Seasonalフィールドが同じシェープファイルにあるため、selectbyattributeおよびsaveselectedfeaturesステップを追加する必要はありません。以下に、私が行ったことを示します。

#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)

あなたがそれを改善するための発言やアドバイスがあれば、躊躇しないでください。

これを改善するには、範囲を選択する(たとえば、ヨーロッパの場合)ことが最善です。この範囲を使用して、この範囲内に含まれる種のみを選択します。これは、すべての種のマップを取得しているためです。たとえば、ヨーロッパ以外の種も含まれています(そのため、空のマップがたくさんあります)。それは可能だと思いますか?

乾杯、

Onesime

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.