중요

번역은 여러분이 참여할 수 있는 커뮤니티 활동입니다. 이 페이지는 현재 100.00% 번역되었습니다.

3. 레이어 불러오기

힌트

이 페이지에 있는 코드 조각들을 다음과 같이 가져와야 합니다:

import os # This is is needed in the pyqgis console also
from qgis.core import (
    QgsVectorLayer
)

데이터를 담고 있는 레이어를 열어봅시다. QGIS는 벡터 및 래스터 레이어를 인식합니다. 추가적으로 사용자 정의 레이어 유형도 사용할 수 있지만, 이 문서에서는 다루지 않을 것입니다.

3.1. 벡터 레이어

프로젝트에 벡터 레이어 인스턴스를 생성하고 추가하려면, 레이어의 데이터 소스 식별자, 레이어 이름, 그리고 제공자의 이름을 지정하십시오:

 1# get the path to the shapefile e.g. /home/project/data/ports.shp
 2path_to_airports_layer = "testdata/airports.shp"
 3
 4# The format is:
 5# vlayer = QgsVectorLayer(data_source, layer_name, provider_name)
 6
 7vlayer = QgsVectorLayer(path_to_airports_layer, "Airports layer", "ogr")
 8if not vlayer.isValid():
 9    print("Layer failed to load!")
10else:
11    QgsProject.instance().addMapLayer(vlayer)

data_source 식별자는 문자열로, 각 벡터 데이터 제공자에 특화되어 있습니다. layer_name은 레이어 목록 위젯에서 사용합니다. 레이어를 성공적으로 불러왔는지 확인하는 일이 중요합니다. 성공적이 아니라면, 무결하지 않은 레이어 인스턴스를 반환합니다.

GeoPackage 벡터 레이어의 경우:

 1# get the path to a geopackage  e.g. /usr/share/qgis/resources/data/world_map.gpkg
 2path_to_gpkg = os.path.join(QgsApplication.pkgDataPath(), "resources", "data", "world_map.gpkg")
 3# append the layername part
 4gpkg_countries_layer = path_to_gpkg + "|layername=countries"
 5# e.g. gpkg_places_layer = "/usr/share/qgis/resources/data/world_map.gpkg|layername=countries"
 6vlayer = QgsVectorLayer(gpkg_countries_layer, "Countries layer", "ogr")
 7if not vlayer.isValid():
 8    print("Layer failed to load!")
 9else:
10    QgsProject.instance().addMapLayer(vlayer)

QGIS에서 벡터 레이어를 가장 빨리 열어서 보이게 하는 방법은 QgisInterface 클래스의 addVectorLayer() 메소드를 사용하는 것입니다:

vlayer = iface.addVectorLayer(path_to_airports_layer, "Airports layer", "ogr")
if not vlayer:
  print("Layer failed to load!")

이렇게 하면 한번에 새 레이어를 생성해서 현재 QGIS 프로젝트에 추가합니다. (레이어 목록에 새 레이어를 나타나게 합니다.) 이 함수는 레이어 인스턴스를 반환하거나 레이어를 불러올 수 없는 경우 None 을 반환합니다.

다음 목록은 벡터 데이터 제공자들을 통해 여러 데이터 소스에 접근하는 방법을 보여줍니다:

  • GDAL 라이브러리 (셰이프파일 및 다른 수많은 파일 포맷들) — 데이터 소스는 파일을 가리키는 경로입니다:

    • 셰이프파일의 경우:

      vlayer = QgsVectorLayer("testdata/airports.shp", "layer_name_you_like", "ogr")
      QgsProject.instance().addMapLayer(vlayer)
      
    • DXF 파일의 경우 (데이터 소스 URI에 있는 내부 옵션들을 주목하십시오):

      uri = "testdata/sample.dxf|layername=entities|geometrytype=Polygon"
      vlayer = QgsVectorLayer(uri, "layer_name_you_like", "ogr")
      QgsProject.instance().addMapLayer(vlayer)
      
  • PostGIS 데이터베이스 — 데이터 소스는 PostgreSQL 데이터베이스와의 연결을 생성하는 데 필요한 모든 정보를 가진 문자열입니다.

    QgsDataSourceUri 클래스가 이 문자열을 생성할 수 있습니다. QGIS가 PostgreSQL를 지원하도록 QGIS를 컴파일해야 한다는 점을 기억하십시오. 그렇지 않으면 이 제공자를 사용할 수 없습니다:

    1uri = QgsDataSourceUri()
    2# set host name, port, database name, username and password
    3uri.setConnection("localhost", "5432", "dbname", "johny", "xxx")
    4# set database schema, table name, geometry column and optionally
    5# subset (WHERE clause)
    6uri.setDataSource("public", "roads", "the_geom", "cityid = 2643", "primary_key_field")
    7
    8vlayer = QgsVectorLayer(uri.uri(False), "layer name you like", "postgres")
    

    참고

    uri.uri(False) 에 전달된 False 인자가 인증 환경설정 파라미터들이 확장되지 못하게 막습니다. 사용자가 어떤 인증 환경설정도 사용하지 않는 경우, 이 인자는 어떤 영향도 미치지 않습니다.

  • CSV 파일 또는 기타 구분된 텍스트 파일들 — 쌍반점(;)을 구분자로 사용하고 “x” 필드에 X 좌표를 그리고 “y” 필드에 Y 좌표를 가진 파일을 열려면 다음과 같은 코드를 사용해야 할 것입니다:

    uri = "file://{}/testdata/delimited_xy.csv?delimiter={}&xField={}&yField={}".format(os.getcwd(), ";", "x", "y")
    vlayer = QgsVectorLayer(uri, "layer name you like", "delimitedtext")
    QgsProject.instance().addMapLayer(vlayer)
    

    참고

    제공자 문자열은 URL로써 구성되어 있기 때문에, 경로 앞에 반드시 file:// 을 붙여야만 합니다. 또 xy 필드의 대체물로써 WKT(Well Known Text) 서식 도형을 사용할 수 있으며, 좌표계도 지정할 수 있습니다. 다음은 그 예시입니다:

    uri = "file:///some/path/file.csv?delimiter={}&crs=epsg:4723&wktField={}".format(";", "shape")
    
  • GPX 파일 — “gpx” 데이터 제공자는 GPX 파일에서 트랙, 루트, 웨이포인트를 읽어옵니다. GPX 파일을 열려면, 데이터 유형(트랙/루트/웨이포인트)을 URL의 일부분으로 지정해줘야 합니다:

    uri = "testdata/layers.gpx?type=track"
    vlayer = QgsVectorLayer(uri, "layer name you like", "gpx")
    QgsProject.instance().addMapLayer(vlayer)
    
  • SpatiaLite 데이터베이스 — PostGIS 데이터베이스와 유사하게, QgsDataSourceUri 클래스를 사용해서 데이터 소스 식별자를 생성할 수 있습니다:

     1uri = QgsDataSourceUri()
     2uri.setDatabase('/home/martin/test-2.3.sqlite')
     3schema = ''
     4table = 'Towns'
     5geom_column = 'Geometry'
     6uri.setDataSource(schema, table, geom_column)
     7
     8display_name = 'Towns'
     9vlayer = QgsVectorLayer(uri.uri(), display_name, 'spatialite')
    10QgsProject.instance().addMapLayer(vlayer)
    
  • GDAL을 통한 MySQL WKB 기반 도형 — 데이터 소스는 테이블과의 연결 문자열입니다:

    uri = "MySQL:dbname,host=localhost,port=3306,user=root,password=xxx|layername=my_table"
    vlayer = QgsVectorLayer( uri, "my table", "ogr" )
    QgsProject.instance().addMapLayer(vlayer)
    
  • WFS 연결 — URI와 WFS 제공자를 사용해서 연결을 정의합니다:

    uri = "https://demo.mapserver.org/cgi-bin/wfs?service=WFS&version=2.0.0&request=GetFeature&typename=ms:cities"
    vlayer = QgsVectorLayer(uri, "my wfs layer", "WFS")
    

    표준 urllib 라이브러리를 사용해서 URI를 생성할 수 있습니다:

     1import urllib
     2
     3params = {
     4    'service': 'WFS',
     5    'version': '2.0.0',
     6    'request': 'GetFeature',
     7    'typename': 'ms:cities',
     8    'srsname': "EPSG:4326"
     9}
    10uri2 = 'https://demo.mapserver.org/cgi-bin/wfs?' + urllib.parse.unquote(urllib.parse.urlencode(params))
    

참고

다음 예시처럼 QgsVectorLayer 클래스 인스턴스에 대해 setDataSource() 메소드를 호출하면 기존 레이어의 데이터 소스를 변경할 수 있습니다:

1uri = "https://demo.mapserver.org/cgi-bin/wfs?service=WFS&version=2.0.0&request=GetFeature&typename=ms:cities"
2provider_options = QgsDataProvider.ProviderOptions()
3# Use project's transform context
4provider_options.transformContext = QgsProject.instance().transformContext()
5vlayer.setDataSource(uri, "layer name you like", "WFS", provider_options)
6
7del(vlayer)

3.2. 래스터 레이어

래스터 파일에 접근하기 위해 GDAL 라이브러리를 사용합니다. GDAL 라이브러리는 광범위한 파일 포맷들을 지원합니다. 어떤 파일을 여는 데 문제가 있는 경우, 사용자의 GDAL 라이브러리가 그 특정 포맷을 지원하고 있는지 확인하십시오. (기본적으로 모든 포맷을 지원하지는 않습니다.) 파일로부터 래스터를 불러오려면, 래스터의 파일 이름과 표시 이름을 지정하십시오:

1# get the path to a tif file  e.g. /home/project/data/srtm.tif
2path_to_tif = "qgis-projects/python_cookbook/data/srtm.tif"
3rlayer = QgsRasterLayer(path_to_tif, "SRTM layer name")
4if not rlayer.isValid():
5    print("Layer failed to load!")

GeoPackage에서 래스터를 불러오려면:

1# get the path to a geopackage  e.g. /home/project/data/data.gpkg
2path_to_gpkg = os.path.join(os.getcwd(), "testdata", "sublayers.gpkg")
3# gpkg_raster_layer = "GPKG:/home/project/data/data.gpkg:srtm"
4gpkg_raster_layer = "GPKG:" + path_to_gpkg + ":srtm"
5
6rlayer = QgsRasterLayer(gpkg_raster_layer, "layer name you like", "gdal")
7
8if not rlayer.isValid():
9    print("Layer failed to load!")

벡터 레이어와 비슷하게, QgisInterface 클래스 객체의 addRasterLayer 함수를 사용해서 래스터 레이어를 불러올 수 있습니다:

iface.addRasterLayer(path_to_tif, "layer name you like")

이렇게 하면 한번에 새 레이어를 생성해서 현재 프로젝트에 추가합니다. (레이어 목록에 새 레이어를 나타나게 합니다.)

PostGIS 래스터를 불러오려면:

PostGIS 벡터와 비슷하게, URI 문자열을 사용해서 프로젝트에 PostGIS 래스터를 추가할 수 있습니다. 데이터베이스 연결 파라미터에 대해 재사용 가능한 문자열 목록(dictionary)을 유지하는 편이 효율적입니다. 이렇게 하면 적용 가능한 연결에 대한 목록을 쉽게 편집할 수 있습니다. 그 다음 ‘postgresraster’ 제공자 메타데이터 객체를 사용해서 목록을 URI로 인코딩합니다. 그러면 프로젝트에 래스터를 추가할 수 있습니다.

 1uri_config = {
 2    # database parameters
 3    'dbname':'gis_db',      # The PostgreSQL database to connect to.
 4    'host':'localhost',     # The host IP address or localhost.
 5    'port':'5432',          # The port to connect on.
 6    'sslmode':QgsDataSourceUri.SslDisable, # SslAllow, SslPrefer, SslRequire, SslVerifyCa, SslVerifyFull
 7    # user and password are not needed if stored in the authcfg or service
 8    'authcfg':'QconfigId',  # The QGIS athentication database ID holding connection details.
 9    'service': None,         # The PostgreSQL service to be used for connection to the database.
10    'username':None,        # The PostgreSQL user name.
11    'password':None,        # The PostgreSQL password for the user.
12    # table and raster column details
13    'schema':'public',      # The database schema that the table is located in.
14    'table':'my_rasters',   # The database table to be loaded.
15    'geometrycolumn':'rast',# raster column in PostGIS table
16    'sql':None,             # An SQL WHERE clause. It should be placed at the end of the string.
17    'key':None,             # A key column from the table.
18    'srid':None,            # A string designating the SRID of the coordinate reference system.
19    'estimatedmetadata':'False', # A boolean value telling if the metadata is estimated.
20    'type':None,            # A WKT string designating the WKB Type.
21    'selectatid':None,      # Set to True to disable selection by feature ID.
22    'options':None,         # other PostgreSQL connection options not in this list.
23    'enableTime': None,
24    'temporalDefaultTime': None,
25    'temporalFieldIndex': None,
26    'mode':'2',             # GDAL 'mode' parameter, 2 unions raster tiles, 1 adds tiles separately (may require user input)
27}
28# remove any NULL parameters
29uri_config = {key:val for key, val in uri_config.items() if val is not None}
30# get the metadata for the raster provider and configure the URI
31md = QgsProviderRegistry.instance().providerMetadata('postgresraster')
32uri = QgsDataSourceUri(md.encodeUri(uri_config))
33
34# the raster can then be loaded into the project
35rlayer = iface.addRasterLayer(uri.uri(False), "raster layer name", "postgresraster")

WCS 서비스로부터도 래스터 레이어를 생성할 수 있습니다:

layer_name = 'modis'
url = "https://demo.mapserver.org/cgi-bin/wcs?identifier={}".format(layer_name)
rlayer = QgsRasterLayer(uri, 'my wcs layer', 'wcs')

다음에서는 WCS URI가 담을 수 있는 파라미터들을 설명합니다:

WCS URI는 & 문자로 구분된 키=값 쌍으로 이루어집니다. 이는 URL에 있는 동일한 방식으로 인코딩된 쿼리 문자열과 동일한 서식입니다. 특수 문자들이 제대로 인코딩되도록 보장하려면 QgsDataSourceUri 클래스를 사용해서 URI를 작성해야 할 것입니다.

  • url (필수): WCS 서버 URL입니다. WCS 각 버전이 GetCapabilities 버전에 대해 서로 다른 파라미터 이름을 사용하고 있기 때문에, URL에 VERSION을 사용하면 안 됩니다. 파라미터 버전을 참조하세요.

  • identifier (필수): 커버리지 이름

  • time (선택적): 시점(time position) 또는 기간(time period) (beginPosition/endPosition[/timeResolution])

  • format (선택적): 지원하는 포맷 이름입니다. 기본값은 이름에 tif 가 있는 경우 첫 번째로 지원하는 포맷 또는 그렇지 않은 경우 첫 번째로 지원하는 포맷입니다.

  • crs (선택적) : 기관:ID 형식의, 예를 들면 EPSG:4326 같은 좌표계입니다. 기본값은 지원하는 경우 EPSG:4326, 지원하지 않는 경우 첫 번째로 지원하는 좌표계입니다.

  • username (선택적): 기본 인증을 위한 사용자 이름입니다.

  • password (선택적): 기본 인증을 위한 비밀번호입니다.

  • IgnoreGetMapUrl (선택적, 꼼수): 지정한 (1로 설정한) 경우, GetCapabilities가 노출하는 GetCoverage URL을 무시합니다. 서버를 제대로 환경설정하지 않은 경우 필요할 수도 있습니다.

  • InvertAxisOrientation (선택적, 꼼수): 지정한 (1로 설정한) 경우, GetCoverage 요청에 있는 축의 순서를 바꿉니다. 서버가 사용하는 축 순서가 틀린 경우 지리 좌표계에 대해 필요할 수도 있습니다.

  • IgnoreAxisOrientation (선택적, 꼼수): 지정한 (1로 설정한) 경우, 지리 좌표계에 대해 WCS 표준을 준수하는 축 순서로 바꾸지 않습니다.

  • cache (선택적): QNetworkRequest::CacheLoadControl에서 설명하는 대로 캐시 불러오기를 제어하지만, AlwaysCache로 실패한 경우 요청을 PreferCache로 다시 보냅니다. 다음 값들 가운데 하나로 설정할 수 있습니다: AlwaysCache, PreferCache, PreferNetwork, AlwaysNetwork. 기본값은 AlwaysCache입니다.

아니면 WMS 서버에서 래스터 레이어를 불러올 수도 있습니다. 하지만 현재 API에서 GetCapabilities 응답에 접근할 수가 없습니다 — 사용자가 원하는 레이어가 어떤 레이어인지 알고 있어야 합니다:

urlWithParams = "crs=EPSG:4326&format=image/png&layers=continents&styles&url=https://demo.mapserver.org/cgi-bin/wms"
rlayer = QgsRasterLayer(urlWithParams, 'some layer name', 'wms')
if not rlayer.isValid():
  print("Layer failed to load!")

3.3. QgsProject 인스턴스

렌더링 작업에 열려져 있는 레이어를 사용하고 싶다면, QgsProject 클래스 인스턴스에 해당 레이어를 추가해야 한다는 사실을 기억하십시오. QgsProject 클래스 인스턴스는 레이어의 소유권을 가지며, 이후 응용 프로그램의 어느 부분에서든 레이어의 유일 ID를 통해 해당 레이어에 접근할 수 있습니다. 프로젝트에서 레이어를 제거하는 경우, 유일 ID도 삭제됩니다. 사용자는 QGIS 인터페이스에서 또는 removeMapLayer() 메소드를 사용하는 파이썬 코드를 통해 레이어를 제거할 수 있습니다.

addMapLayer() 메소드를 사용하면 현재 프로젝트에 레이어를 추가할 수 있습니다:

QgsProject.instance().addMapLayer(rlayer)

절대 위치에 레이어를 추가하려면:

1# first add the layer without showing it
2QgsProject.instance().addMapLayer(rlayer, False)
3# obtain the layer tree of the top-level group in the project
4layerTree = iface.layerTreeCanvasBridge().rootGroup()
5# the position is a number starting from 0, with -1 an alias for the end
6layerTree.insertChildNode(-1, QgsLayerTreeLayer(rlayer))

removeMapLayer() 메소드를 사용해서 레이어를 삭제하고 싶다면:

# QgsProject.instance().removeMapLayer(layer_id)
QgsProject.instance().removeMapLayer(rlayer.id())

앞의 코드에서는 (레이어의 id() 메소드를 호출해서 얻을 수 있는) 레이어 ID를 전달했지만, 레이어 객체 자체도 전달할 수 있습니다.

불러온 레이어와 레이어 ID의 목록을 원한다면, mapLayers() 메소드를 사용하십시오:

QgsProject.instance().mapLayers()