PyQGIS kullanarak çok sayıda harita mı oluşturuyorsunuz?


10

Çok sayıda (yüzlerce) tür dağıtım haritası yapmam gerekiyor. Her tür için dağılımları içeren bir şekil dosyası var ve her biri için, ilgili türlerin adını, efsaneyi (alanları ayırt etmek için) içeren bir görüntü (jpg, png veya başka bir) olarak bir harita almak istiyorum yıllık dağılımlar, üreme, üreme, vb ...).

Bunu yapmak için QGIS kullanmak istiyorum.


1
Haritaların özellikleri hakkında biraz daha bilgi verebilir misiniz? Örneğin, tüm bu haritaların belirli bir kıta veya ülke gibi aynı alanı göstermesini mi istiyorsunuz, yoksa harita boyutunun dinamik olarak değişmesini mi istiyorsunuz? Ayrıca, tüm aralık alt türlerini bir haritada mı yoksa birden çok haritada mı istiyorsunuz? Bu cevaplara bağlı olarak, sorununuz oldukça basit olabilir veya biraz daha karmaşık bir yaklaşım gerektirebilir. Bakmaya başlamak için iyi bir yer, GIS için Atlas eklentisidir veya ArcGIS 10 veya daha üst sürümünüz varsa, ESRI'nin harita kitapları da yardımcı olacaktır.
Jay Guarneri

1
Ayrıntıların olmaması için üzgünüm. Tüm haritalar için evet, aynı bölge (Avrupa) olacaktır. Tüm türler ve niteliklerde karşılık gelen dağılım ile bir şekil dosyası var. Bu şekil dosyası, kolayca farklı şekil dosyalarına bölebilirim (her tür için bir tane). Sonunda, her bir tür için, her seferinde, tam olarak aynı alan (Avrupa), aynı renklerle (örneğin koyu yeşil, yıllık yeşil, açık yeşil üreme, mavi, vb ...), aynı efsane ve başlık olarak türün adı.
Onesime

Yapmanız gereken şey, her haritayı yapmak için atmanız gereken her adımı planlamak, ardından seçimleri kodlamak ve Python'da harita dışa aktarmalarını planlamaktır. Bunun ArcGIS Python'da kolayca yapılabileceğini biliyorum, ancak QGIS Python arayüzü hakkında çok fazla rehberlik sağlayacak kadar bilgim yok. Ancak, bu işi bir şekil dosyasıyla yapabileceğinizden eminim.
Jay Guarneri

Bir Python eklentisi kullanarak QGIS ile benzer bir şey yaptım. Benim durumumda, katmanlarım PostGIS'te saklanmıştı, ancak sanırım şekil dosyası kullanarak benzer bir şey yapabilirsiniz. Kodumu paylaşmaktan mutluluk duyuyorum. Bana özel mesaj at.
Brian Edmond

1
Oynamamız için verilerinizin bir örneğini yükleyebilir misiniz?
Nathan W

Yanıtlar:


4

Ben benzer bir gereksinim vardı ve tüm türler için nokta yerelliği olan bir şekil dosyasına dayalı haritalar oluşturmak için bir QGIS eklentisi koymak (ortak tanımlayıcı olarak öznitelik tablosunda benzersiz bir takson adı varsayar). Gereksinimlerim o kadar karmaşık değildi - mevsimsel bilgilere, başlıklara veya efsaneye ihtiyacım yoktu, ama sizin için yararlı bir başlangıç ​​noktası olabilir. Daha karmaşık yönler için, harita oluşturucuyu kullanmanız gerekir. Bununla ilgili daha fazla bilgi için PyQGIS yemek kitabına bakınız .

Eklenti

Eklenti, haritaların oluşturulmasını otomatikleştirir ve uzantıları, çözünürlüğü ve diğer yönleri yapılandırmanıza olanak tanır. Izgara katmanınızla çıktıya aynı stili uygular. Şu anda sadece QGIS'in (1.9 veya üzeri) geliştirme sürümünde çalışıyor.

Sextante alfabesi

Eklentiyi yapmadan önce SEXTANTE kullanarak mantığı çalıştım. Bu kullanıcı betiği de 1.8 olarak çalışmalıdır (test etmedi). Dağıtım stili dosyası (.qml), çıktı dağıtımlarının stilidir (dağıtım katmanının stilini yoksayar). Şu anda çıktı haritalarını işletim sisteminizin varsayılanlarına (Linux'ta / tmp ve Windows'daki çeşitli yerlerde - TEMP çevresel değişkeni tarafından tanımlanan) geçici dizine yerleştirir. Yine de kolayca kodu kendiniz tanımlayabilirsiniz. Ayrıca koddaki kapsamı ve çıktı çözünürlüğünü (ve deniz için farklı bir renk istiyorsanız arka plan rengini) düzenlemeniz gerekir.

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

Merhabalar, Tüm yanıtlarınız için teşekkürler. Size daha fazla öğe vermek için BirdLife'tan gelen verilerdir (tür için bir örnek: birdlife.org/datazone/speciesfactsheet.php?id=2794 ). Kısaca, tüm türler için tüm çokgenleri olan bir şekil dosyası vardır (bu nedenle, bazıları için, tek bir tür için birçok çizgi) ve mevsimsel dağılıma karşılık gelen bir özellik vardır (farklı kullanımlara karşılık gelen 1'den 5'e kadar değerlerle) ), menşei vb. için bir diğeri. Efsane ve unvan vazgeçilmez değildir.
Onesime

- Arka planda bir ülke katmanı kullanıyorum, sadece kolay bir konum için. - "mevsimsel" özelliğinden farklı değer için farklı renk için, bunun için bir kullanım .qml dosyası uygun olduğunu düşünüyorum. - İsteğe bağlı olarak, başlık ve efsane için, besteciden bir dosya kullanmam gerektiğini düşünüyorum, eğer çok zorsa, başka bir yazılımla ekleyebilirim. - İşlem tüm türler için tekrarlanmalıdır, bu nedenle bu, son resmin ismini vermek için kullanılacak olan özniteliğe göre bir seçime karşılık gelir.
Onesime

"Atlas" eklentisini denedim, ancak çeşitli yerler için daha uygun gibi görünüyor, benim durumumda, aynı alan için her zaman: Avrupa. Kapsama alanını düzeltmek mümkün olduğu için bu noktada karşılık gelen "Dağıtım harita yöneticisi" eklentisini denedim, ancak zaten çokgen bir katmanım olduğu için bir ızgara katmanı ile noktaları kesen işleme gerek yok. ArcGis'te denedim, ancak QGis Atlas eklentisi için de aynı, çözüm bir python betiği yazmak gibi görünüyor ...
Onesime

Bence "rudivonstaden" senaryosuna (bunun için teşekkürler!) Dayanarak ve benim durumuma uyarlamak için Sextante kullanacağım. Son olarak, bu farklı yorumlar için özür dilerim, ama bir karakter sayısı sınırı var ...
Onesime

@Onesime, başlık ve efsane hariç, yukarıdaki sekstan betiğini ihtiyacınız olanı yapmak için uyarlayabileceğinizi düşünüyorum. Muhtemelen kaldırmak gerekir selectbylocationadımı ve ek eklemek selectbyattributeve saveselectedfeaturesher mevsim (değişim için adım grid_layeriçin all_localities). Ardından daha fazla .qml dosyası yükleyin ve mevsimsel şekil dosyalarınızı ekleyin (önce üst katman eklenir). Nasıl yapılacağından emin değilseniz, yukarıdaki komut dosyasını daha fazla veya daha az çalışmak için düzenlemeyi deneyebilirim.
rudivonstaden

2

Bugün bunun üzerinde çalışmak için birkaç zamanımı aldım. Bu yüzden senaryonuzda bazı değişiklikler yaptım. Bir .qml dosyaları kullandığım ve Mevsimsel alan aynı shapefile olduğu gibi ek bir selectbyattribute ve saveselectedfeatures adım eklemek gerekmez. Aşağıda ne yaptığımı görebilirsiniz:

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

Geliştirmek için herhangi bir yorumunuz veya tavsiyeniz varsa, tereddüt etmeyin.

Bunu geliştirmek için en iyisi, kapsamı seçtiğimizde (örnek Avrupa için), bu kapsamı yalnızca bu kapsamda yer alan türleri seçmek için kullanır. Bu, çünkü tüm türler için haritalar elde ediyorum, örneğin Avrupa dışındakilar için bile (bu yüzden birçok boş haritam var). Bunun mümkün olduğunu düşünüyor musunuz?

Alkış,

Onesime

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.