pyQGIS를 이용한 벡터 데이터 처리 2 : 레이어 추가 및 삭제

SHP 파일 등과 같은 벡터 데이터를 레이어로 추가하는 코드는 다음과 같습니다.

layer = QgsVectorLayer("D:/__Data__/세종특별자치시_36000/TL_SPRD_MANAGE.shp", "TL_SPRD_MANAGE")
QgsProject.instance().addMapLayers([layer])

실행 결과는 다음과 같습니다. 레이어를 추가할 때 추가된 레이어가 바로 지도뷰에 꽉 차게 표시하기 위한 코드는 다음과 같습니다.

canvas = iface.mapCanvas()
extent = layer.extent()
canvas.setExtent(extent)

추가한 레이어에 대한 객체를 얻는 코드는 다음과 같습니다.

layers = QgsProject.instance().mapLayersByName("TL_SPRD_MANAGE")
print(len(layers), layers[0].name())

레이어의 이름으로 객체를 얻는 것인데, 레이어의 이름은 중복될 수 있으므로 동일한 이름이라도 여러개의 레이어 객체가 참조 될 수 있습니다.

추가한 레이어를 삭제하는 코드는 다음과 같습니다.

layers = QgsProject.instance().mapLayersByName("TL_SPRD_MANAGE")
QgsProject.instance().removeMapLayer(layers[0].id())

레이어의 이름은 중복될 수 있으므로 실제 삭제 시에는 레이어의 ID 값을 지정하여 삭제해야 합니다.

추가된 모든 레이어를 삭제하는 코드는 다음과 같습니다.

QgsProject.instance().removeAllMapLayers()

pyQGIS를 이용한 벡터 데이터 처리 1 : Message, Progress 출력

QGIS 프로그램 안에서 사용자에게 어떤 메세지를 전달하고자 할 때의 코드의 예는 다음과 같습니다.

iface.messageBar().pushMessage("안녕하세요, pyQGIS")

실행 결과는 QGIS의 맵영역 상단에 표시되며 다음과 같습니다.

iface의 messageBar를 통한 pushMessage 매서드는 더 많은 인자를 받을 수 있습니다. 다음 코드를 보면요.

iface.messageBar().pushMessage(
    "환영", 
    "안녕하세요, pyQGIS",
    level=Qgis.Success,
    duration=5
)

아래의 실행 결과를 통해 각 인자의 의미를 유추할 수 있습니다.

세번째와 네번째 인자에 대해 언급하면 먼저 level 인자는 4가지 값을 가질 수 있습니다. Qgis.Critical, Qgis.Warning, Qgis.Info, Qgis.Success이며 각각 에러 메세지, 경고 메세지, 정보 메세지, 성공 메세지에 대한 아이콘을 표시해 줍니다. 그리고 duration은 메세지를 몇초간 표시하고 사라지게 할지 지정할 수 있습니다.

QGIS에서는 시간이 오래 걸리는 연산이 많이 수행됩니다. 이때 수행되는 연산의 진행율을 사용자에게 알려주는 코드는 다음과 같습니다.

import time

progressMessageBar = iface.messageBar().createMessage("처리 메세지")

progress = QProgressBar()
progress.setMaximum(100)
progressMessageBar.layout().addWidget(progress)

iface.messageBar().pushWidget(progressMessageBar, Qgis.Info)

for i in range(100):
    time.sleep(0.01)
    progress.setValue(i + 1)

time.sleep(0.01)을 100번 호출하므로 1초에 걸쳐 최대 100까지 값을 증가시켜 진행율을 표시합니다. 실행결과는 다음과 같습니다.

pyQGIS Tip

특정 Feature를 확대하기

아래의 코드는 선택된 Feature를 확대합니다.

canvas = iface.mapCanvas()
id = 0
#canvas.setSelectionColor(QColor("red"))
layer.select(id)
canvas.zoomToSelected(layer)

아래의 코드는 Feature를 선택하지 않고 FID가 0인 Feature를 확대합니다.

canvas = iface.mapCanvas()
id = 0
feat = layer.getFeature(id)
geom = feat.geometry()
bbox = geom.boundingBox()
canvas.setExtent(bbox)
canvas.refresh()

특정 Feature를 깜박이게 하기

canvas = iface.mapCanvas()
id = 0
canvas.flashFeatureIds(layer, [id])

화면 좌표와 지도 좌표 간의 변환

아래의 코드는 화면 좌표 (100, 20)을 지도 좌표로 변환하고 다시 변환된 지도 좌표를 화면 좌표로 변환하는 코드입니다.

ptView = QPoint(100, 20)
ptMap = canvas.getCoordinateTransform().toMapCoordinates(ptView)
print(ptMap.x(), ptMap.y())

ptMap2 = QgsMapTool(canvas).toCanvasCoordinates(ptMap)
print(ptMap2.x(), ptMap2.y())

다양한 형태의 지오메트리 생성

좌표를 지정해서 다양한 형태의 지오메트리를 생성하는 코드입니다.

geomPoint = QgsGeometry.fromPointXY(QgsPointXY(10000, 15000))

geomMultiPoint = QgsGeometry.fromMultiPointXY(
    [
        QgsPointXY(10000, 15000),
        QgsPointXY(11000, 16000),
    ]
)

geomPolyline = QgsGeometry.fromPolylineXY(
    [
        QgsPointXY(10000, 15000),
        QgsPointXY(11000, 16000),
        QgsPointXY(12000, 17000),
        QgsPointXY(13000, 18000),
    ]
)

geomPolyline = QgsGeometry.fromMultiPolylineXY(
    [
        [
            QgsPointXY(10000, 15000),
            QgsPointXY(11000, 16000),
            QgsPointXY(12000, 17000),
            QgsPointXY(13000, 18000),
        ]
    ]
)

pX = 971195
pY = 1841488

geomPolygon = QgsGeometry.fromPolygonXY(
    [
        [
            QgsPointXY(pX, pY),
            QgsPointXY(pX+1000, pY),
            QgsPointXY(pX+1000, pY+1000),
            QgsPointXY(pX, pY+1000),
        ],
        [
            QgsPointXY(pX+100, pY+100),
            QgsPointXY(pX+900, pY+100),
            QgsPointXY(pX+900, pY+900),
            QgsPointXY(pX+100, pY+900),
        ]
    ]
)

geomPolygon = QgsGeometry.fromMultiPolygonXY(
    [
        [
            [
                QgsPointXY(pX, pY),
                QgsPointXY(pX+1000, pY),
                QgsPointXY(pX+1000, pY+1000),
                QgsPointXY(pX, pY+1000),
            ],
            [
                QgsPointXY(pX+100, pY+100),
                QgsPointXY(pX+900, pY+100),
                QgsPointXY(pX+900, pY+900),
                QgsPointXY(pX+100, pY+900),
            ]
        ]
    ]
)

아래는 Python 언어의 특징을 이용한 효율적인 코드 작성입니다.

pts = [
    (583899.8, 8177297.19), 
    (583900.23, 8177262.52), 
    (583896.49, 8177262.47), 
    (583895.96, 8177297.29), 
    (583899.8, 8177297.19)
]

geomPolygon = QgsGeometry.fromPolygonXY( [[ QgsPointXY( xy[0], xy[1] ) for xy in pts ]] ) 

HDRI 제작하기

먼저 원하는 장면을 아래의 예시처럼 구성합니다.

카메라를 장면의 중심(대부분 원점)에 배치하고 회전 값을 다음처럼 설정합니다.

카메라의 속성을 다음처럼 지정합니다. 아래의 속성 구성(Panorama Type)을 위해서 렌더링은 Cycles로 지정되어 있어야 합니다.

출력(Output) 속성은 다음과 같습니다. Resolution을 변경했으며 File Format 역시 변경했습니다.