도형 다루기

공간 피처를 표현하는 포인트, 라인스트링, 폴리곤을 흔히 도형라고 합니다. QGIS는 이들을 QgsGeometry 클래스로 표현합니다. JTS discussion page 에 사용 가능한 모든 도형 유형이 잘 정리돼 있습니다.

도형 한 개가 실제로는 단순(단일 영역, single-part) 도형의 집합인 경우가 종종 있습니다. 이런 도형을 다중 영역(multi-part) 도형이라고 합니다. 다중 영역 도형이 한 가지 유형의 단순 도형으로만 이루어져 있을 경우 다중 포인트, 다중 라인스트링, 다중 폴리곤이라 부릅니다. 예를 들어 여러 개의 섬으로 이루어진 국가라면 다중 폴리곤으로 표현할 수 있습니다.

도형의 좌표는 어떤 좌표계(CRS)라도 될 수 있습니다. 레이어에서 피처를 불러올 때, 해당 도형은 레이어의 좌표계를 따르는 좌표를 가지게 될 겁니다.

도형 작성

도형을 생성하는 데에는 몇 가지 옵션이 있습니다.

  • 좌표로부터

    gPnt = QgsGeometry.fromPoint(QgsPoint(1,1))
    gLine = QgsGeometry.fromPolyline([QgsPoint(1, 1), QgsPoint(2, 2)])
    gPolygon = QgsGeometry.fromPolygon([[QgsPoint(1, 1), QgsPoint(2, 2), QgsPoint(2, 1)]])
    

    QgsPoint 클래스를 통해 좌표를 부여합니다.

    폴리라인(라인스트링)은 포인트 목록으로 표현됩니다. 폴리곤은 선형 폐곡선(예를 들면 닫힌 라인스트링) 목록으로 표현됩니다. 첫 번째 폐곡선은 외곽(경계선)이고, 있을 수도 없을 수도 있는 다음 폐곡선은 폴리곤 내부에 있는 구멍입니다.

    다중 영역 도형은 한 단계 심화됩니다. 다중 포인트는 포인트의 목록, 다중 라인스트링은 라인스트링의 목록, 다중 폴리곤은 폴리곤의 목록입니다.

  • WKT(well-known text)로부터

    gem = QgsGeometry.fromWkt("POINT(3 4)")
    
  • WKB(well-known binary)로부터

    g = QgsGeometry()
    g.setWkbAndOwnership(wkb, len(wkb))
    

도형에 접근

먼저 wkbType() 메소드 같은 방법을 써서 도형의 유형을 알아내야 합니다. 이 함수는 QGis.WkbType 열거 목록(enumeration) 값을 반환합니다.

>>> gPnt.wkbType() == QGis.WKBPoint
True
>>> gLine.wkbType() == QGis.WKBLineString
True
>>> gPolygon.wkbType() == QGis.WKBPolygon
True
>>> gPolygon.wkbType() == QGis.WKBMultiPolygon
False

다른 방법으로는 QGis.GeometryType 열거 목록 값을 반환하는 type() 함수 메소드를 사용할 수 있습니다. 도형이 다중 영역인지 아닌지 알아낼 수 있는 보조 함수인 isMultipart() 도 있습니다.

도형에서 정보를 추출하기 위해 모든 벡터 유형마다 사용가능한 접근자(accessor) 함수가 있습니다. 다음과 같이 사용하면 됩니다.

>>> gPnt.asPoint()
(1, 1)
>>> gLine.asPolyline()
[(1, 1), (2, 2)]
>>> gPolygon.asPolygon()
[[(1, 1), (2, 2), (2, 1), (1, 1)]]

주석: 튜플로 보이는 (x,y)는 진짜 튜플이 아니라 QgsPoint 클래스의 오브젝트이며, x()y() 메소드를 통해 좌표에 접근할 수 있습니다. 튜플은 파이썬에서 괄호로 묶여진 값을 이르는 용어입니다.

다중 영역 도형의 경우 비슷한 접근자 함수인 asMultiPoint(), asMultiPolyline(), asMultiPolygon() 이 있습니다.

도형 관계계산 및 연산

QGIS는 도형 관계계산(contains(), intersects() 등) 및 연산(union(), difference() 등)과 같은 고급 도형 작업에 GEOS 라이브러리를 이용합니다. 이 라이브러리는 면적(폴리곤의 경우) 또는 길이(폴리곤 및 라인의 경우)와 같은 도형의 기하학적 속성도 계산할 수 있습니다.

다음은 주어진 레이어 안에 있는 피처에 대해 반복 작업을 수행하고 도형을 기반으로 기하학적 계산을 하는 작업을 결합한 간단한 예시 코드입니다.

# we assume that 'layer' is a polygon layer
features = layer.getFeatures()
for f in features:
  geom = f.geometry()
  print "Area:", geom.area()
  print "Perimeter:", geom.length()

QgsGeometry 클래스가 이런 메소드로 면적 및 둘레를 계산할 때 좌표계를 고려하지는 않습니다. 더 강력한 면적 및 거리 계산을 원한다면 QgsDistanceArea 클래스를 사용할 수 있습니다. 투영이 비활성화되어 있다면 평면 상에서 계산이 이루어지고, 반대의 경우 타원체 상에서 이루어질 것입니다. 타원체를 명확히 설정하지 않는다면 계산에 WGS84 파라미터를 쓰게 됩니다.

d = QgsDistanceArea()
d.setEllipsoidalMode(True)

print "distance in meters: ", d.measureLine(QgsPoint(10,10),QgsPoint(11,11))

QGIS에 포함되어 있는, 벡터 데이터를 분석하고 변환하는 데 사용할 수 있는 알고리즘들의 수많은 예시가 있습니다. 다음은 링크들은 그 가운데 몇몇 코드를 보여줍니다.

다음 소스에서 추가적인 정보를 찾아볼 수 있습니다.