PyQGIS를 사용하여 많은 수의 맵을 생성하십니까?


10

종의 분포지도를 수백 개 만들어야합니다. 각 종에 대한 분포를 포함하는 shapefile이 있으며 각 종에 대한 분포를 포함하고 있으며 관련 종의 이름, 범례 (영역을 구별하기 위해)를 포함하는 이미지 (jpg, png 또는 기타)로 맵을 얻고 싶습니다. 연간 분포, 번식, 비 사육 등 ...).

QGIS를 사용하여이 작업을 수행하고 싶습니다.


1
지도의 특성에 대해 좀 더 자세히 설명해 주시겠습니까? 예를 들어,이 모든지도가 특정 대륙이나 국가와 같은 동일한 영역을 표시하도록 하시겠습니까, 아니면지도 범위를 동적으로 변경 하시겠습니까? 또한 하나의 맵에서 모든 범위 하위 유형을 원합니까 아니면 여러 맵에 있습니까? 이러한 답변에 따라 문제가 상당히 단순하거나 좀 더 복잡한 접근 방식이 필요할 수 있습니다. GIS 용 Atlas 플러그인을 살펴 보거나 ArcGIS 10 이상을 사용할 수 있다면 ESRI의지도 책도 도움이 될 것입니다.
Jay Guarneri

1
세부 정보가 부족하여 죄송합니다. 예, 모든지도에서 같은 지역 (유럽)이됩니다. 모든 종과 속성에 해당 분포가있는 하나의 shapefile이 있습니다. 이 shapefile은 다른 shapefile (각 종마다 하나씩)로 쉽게 분리 할 수 ​​있습니다. 마지막으로, 나는 매번 정확히 같은 지역 (유럽), 같은 색 (예를 들어 짙은 녹색의 연간 분포, 연한 녹색의 번식, 번식이없는)으로 각 종마다 하나의 그림을 갖고 싶습니다. blue 등 ...), 동일한 범례 및 제목의 이름으로 지정됩니다.
Onesime

나는 당신이해야 할 일은 각지도를 만들기 위해해야 ​​할 각 단계를 계획 한 다음 선택과지도 내보내기를 파이썬으로 코딩하는 것입니다. ArcGIS Python에서이 작업을 쉽게 수행 할 수 있다는 것을 알고 있지만 QGIS Python 인터페이스에 대해 많은 지침을 제공 할만큼 충분한 지식이 없습니다. 그러나 하나의 shapefile 로이 작업을 수행 할 수 있다고 확신합니다.
Jay Guarneri

Python 플러그인을 사용하여 QGIS와 비슷한 작업을 수행했습니다. 필자의 경우 레이어는 PostGIS에 저장되었지만 shapefile을 사용하여 비슷한 작업을 수행 할 수 있다고 생각합니다. 코드를 공유하게되어 기쁩니다. 메세지 보내주세요.
브라이언 에드먼드

1
우리가 가지고 놀 데이터의 샘플을 업로드 할 수 있습니까?
Nathan W

답변:


4

비슷한 요구 사항이 있었고 QGIS 플러그인을 조합하여 모든 종에 대한 점 위치가있는 shapefile을 기반으로 맵을 생성했습니다 (속성 테이블의 공통 분류 이름을 공통 식별자로 가정). 요구 사항이 복잡하지 않았습니다. 계절 정보, 제목 또는 범례가 필요하지 않았지만 유용한 출발점이 될 수 있습니다. 더 복잡한 측면을 위해서는 맵 작성기를 사용해야합니다. 자세한 내용은 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)

안녕하십니까, 모든 답장을 보내 주셔서 감사합니다. 더 많은 요소를 제공하기 위해 BirdLife에서 가져온 데이터입니다 (예 : birdlife.org/datazone/speciesfactsheet.php?id=2794 ). 간단히 말해서, 모든 종에 대해 모든 다각형을 가진 하나의 shapefile이 있으며 (따라서 일부 종은 단일 종에 대해 많은 선이 있음) 계절 분포에 해당하는 속성이 있습니다 (1에서 5까지의 값은 다른 용도에 해당) ), 원산지 등을 위해 서로. 전설 및 제목은 필수 불가결하지 않습니다.
Onesime

-쉬운 위치를 위해 백그라운드에서 국가 계층을 사용합니다. - "계절"속성과 다른 값에 대해 다른 색상을 사용하려면 .qml 파일을 사용하는 것이 적합하다고 생각합니다. -제목과 범례의 경우 작곡가의 파일을 사용해야한다고 생각합니다. 너무 어렵다면 다른 소프트웨어로 추가 할 수 있습니다. -모든 종에 대해 작업을 반복해야하므로 이는 속성 별 선택에 해당하며 최종 그림의 이름을 지정하는 데 사용됩니다.
Onesime

플러그인 "Atlas"를 사용해 보았지만 다양한 위치에 더 적합한 것 같습니다. 제 경우에는 항상 같은 지역 인 유럽에 해당합니다. 커버리지 영역을 고칠 수 있기 때문에이 지점에 해당하는 플러그인 "배포 맵 관리자"를 사용해 보았지만 이미 다각형 레이어가 있으므로 그리드 레이어와 포인트를 교차시키는 프로세스는 필요하지 않습니다. ArcGis에서 시도했지만 QGis Atlas 플러그인의 경우와 동일합니다. 해결책은 파이썬 스크립트를 작성하는 것 같습니다.
Onesime

그래서 저는 "rudivonstaden"스크립트 (고마워요!)를 기반으로 Sextante를 사용하여 제 사건에 맞게 사용할 것이라고 생각합니다. 마지막으로, 이러한 다른 의견에 대해 죄송하지만 문자 수 제한이 있습니다 ...
Onesime

제목과 범례를 제외하고 @Onesime은 위의 sextante 스크립트를 필요에 맞게 조정할 수 있다고 생각합니다. 당신은 아마 제거해야합니다 selectbylocation단계, 그리고 추가로 추가 selectbyattribute하고 saveselectedfeatures각 시즌 (변경 단계 grid_layerall_localities). 그런 다음 더 많은 .qml 파일을로드하고 계절별 모양 파일을 추가하십시오 (맨 위 레이어가 먼저 추가됨). 잘 모르겠다면 위의 스크립트를 편집하여 더 많은 작업을 할 수 있습니다.
rudivonstaden

2

오늘이 일을하는 데 시간이 조금 걸렸습니다. 그래서 나는 당신의 스크립트를 약간 변경했습니다. .qml 파일을 사용하고 계절 필드가 동일한 쉐이프 파일에 있으므로 추가 selectbytribute 및 saveselected 기능 단계를 추가 할 필요가 없습니다. 아래에서 내가 한 일을 볼 수 있습니다.

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

개선을위한 언급이나 조언이 있으시면 망설이지 마십시오.

그것을 개선하기 위해, 우리가 범위를 선택할 때 (예를 들어 유럽의 경우) 가장 좋을 것입니다.이 범위를 사용 하여이 범위 안에 포함 된 종만 선택합니다. 예를 들어 유럽 이외의 지역에서도 모든 종에 대한지도를 얻을 수 있기 때문에 (빈지도가 많이 있습니다). 가능하다고 생각하십니까?

건배,

오네 심

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.