The code snippets on this page need the following imports if you’re outside the pyqgis console:

``` 1from qgis.core import (
2  QgsGeometry,
3  QgsPoint,
4  QgsPointXY,
5  QgsWkbTypes,
6  QgsProject,
7  QgsFeatureRequest,
8  QgsVectorLayer,
9  QgsDistanceArea,
10  QgsUnitTypes,
11  QgsCoordinateTransform,
12  QgsCoordinateReferenceSystem
13)
```

# 7. 도형 다루기

Points, linestrings and polygons that represent a spatial feature are commonly referred to as geometries. In QGIS they are represented with the `QgsGeometry` class.

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

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

Description and specifications of all possible geometries construction and relationships are available in the OGC Simple Feature Access Standards for advanced details.

## 7.1. 도형 작성

PyQGIS provides several options for creating a geometry:

• 좌표로부터

```1gPnt = QgsGeometry.fromPointXY(QgsPointXY(1,1))
2print(gPnt)
3gLine = QgsGeometry.fromPolyline([QgsPoint(1, 1), QgsPoint(2, 2)])
4print(gLine)
5gPolygon = QgsGeometry.fromPolygonXY([[QgsPointXY(1, 1),
6    QgsPointXY(2, 2), QgsPointXY(2, 1)]])
7print(gPolygon)
```

Coordinates are given using `QgsPoint` class or `QgsPointXY` class. The difference between these classes is that `QgsPoint` supports M and Z dimensions.

A Polyline (Linestring) is represented by a list of points.

A Polygon is represented by a list of linear rings (i.e. closed linestrings). The first ring is the outer ring (boundary), optional subsequent rings are holes in the polygon. Note that unlike some programs, QGIS will close the ring for you so there is no need to duplicate the first point as the last.

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

• WKT(well-known text)로부터

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

```1g = QgsGeometry()
2wkb = bytes.fromhex("010100000000000000000045400000000000001440")
3g.fromWkb(wkb)
4
5# print WKT representation of the geometry
6print(g.asWkt())
```

## 7.2. 도형에 접근

First, you should find out the geometry type. The `wkbType()` method is the one to use. It returns a value from the `QgsWkbTypes.Type` enumeration.

```1if gPnt.wkbType() == QgsWkbTypes.Point:
2  print(gPnt.wkbType())
3  # output: 1 for Point
4if gLine.wkbType() == QgsWkbTypes.LineString:
5  print(gLine.wkbType())
6  # output: 2 for LineString
7if gPolygon.wkbType() == QgsWkbTypes.Polygon:
8  print(gPolygon.wkbType())
9  # output: 3 for Polygon
```

As an alternative, one can use the `type()` method which returns a value from the `QgsWkbTypes.GeometryType` enumeration.

You can use the `displayString()` function to get a human readable geometry type.

```1print(QgsWkbTypes.displayString(gPnt.wkbType()))
2# output: 'Point'
3print(QgsWkbTypes.displayString(gLine.wkbType()))
4# output: 'LineString'
5print(QgsWkbTypes.displayString(gPolygon.wkbType()))
6# output: 'Polygon'
```
```Point
LineString
Polygon
```

There is also a helper function `isMultipart()` to find out whether a geometry is multipart or not.

To extract information from a geometry there are accessor functions for every vector type. Here’s an example on how to use these accessors:

```1print(gPnt.asPoint())
2# output: <QgsPointXY: POINT(1 1)>
3print(gLine.asPolyline())
4# output: [<QgsPointXY: POINT(1 1)>, <QgsPointXY: POINT(2 2)>]
5print(gPolygon.asPolygon())
6# output: [[<QgsPointXY: POINT(1 1)>, <QgsPointXY: POINT(2 2)>, <QgsPointXY: POINT(2 1)>, <QgsPointXY: POINT(1 1)>]]
```

참고

The tuples (x,y) are not real tuples, they are `QgsPoint` objects, the values are accessible with `x()` and `y()` methods.

For multipart geometries there are similar accessor functions: `asMultiPoint()`, `asMultiPolyline()` and `asMultiPolygon()`.

It is possible to iterate over all the parts of a geometry, regardless of the geometry’s type. E.g.

```geom = QgsGeometry.fromWkt( 'MultiPoint( 0 0, 1 1, 2 2)' )
for part in geom.parts():
print(part.asWkt())
```
```Point (0 0)
Point (1 1)
Point (2 2)
```
```geom = QgsGeometry.fromWkt( 'LineString( 0 0, 10 10 )' )
for part in geom.parts():
print(part.asWkt())
```
```LineString (0 0, 10 10)
```

It’s also possible to modify each part of the geometry using `QgsGeometry.parts()` method.

```1geom = QgsGeometry.fromWkt( 'MultiPoint( 0 0, 1 1, 2 2)' )
2for part in geom.parts():
3  part.transform(QgsCoordinateTransform(
4    QgsCoordinateReferenceSystem("EPSG:4326"),
5    QgsCoordinateReferenceSystem("EPSG:3111"),
6    QgsProject.instance())
7  )
8
9print(geom.asWkt())
```
```MultiPoint ((-10334726.79314761981368065 -5360105.10101188533008099),(-10462133.82917750626802444 -5217484.34365727473050356),(-10589398.51346865110099316 -5072020.358805269934237))
```

## 7.3. 도형 관계계산 및 연산

QGIS uses GEOS library for advanced geometry operations such as geometry predicates (`contains()`, `intersects()`, …) and set operations (`combine()`, `difference()`, …). It can also compute geometric properties of geometries, such as area (in the case of polygons) or lengths (for polygons and lines).

Let’s see an example that combines iterating over the features in a given layer and performing some geometric computations based on their geometries. The below code will compute and print the area and perimeter of each country in the `countries` layer within our tutorial QGIS project.

The following code assumes `layer` is a `QgsVectorLayer` object that has Polygon feature type.

``` 1# let's access the 'countries' layer
2layer = QgsProject.instance().mapLayersByName('countries')
3
4# let's filter for countries that begin with Z, then get their features
5query = '"name" LIKE \'Z%\''
6features = layer.getFeatures(QgsFeatureRequest().setFilterExpression(query))
7
8# now loop through the features, perform geometry computation and print the results
9for f in features:
10  geom = f.geometry()
11  name = f.attribute('NAME')
12  print(name)
13  print('Area: ', geom.area())
14  print('Perimeter: ', geom.length())
```
```1Zambia
2Area:  62.822790653431205
3Perimeter:  50.65232014052552
4Zimbabwe
5Area:  33.41113559136521
6Perimeter:  26.608288555013935
```

Now you have calculated and printed the areas and perimeters of the geometries. You may however quickly notice that the values are strange. That is because areas and perimeters don’t take CRS into account when computed using the `area()` and `length()` methods from the `QgsGeometry` class. For a more powerful area and distance calculation, the `QgsDistanceArea` class can be used, which can perform ellipsoid based calculations:

The following code assumes `layer` is a `QgsVectorLayer` object that has Polygon feature type.

``` 1d = QgsDistanceArea()
2d.setEllipsoid('WGS84')
3
4layer = QgsProject.instance().mapLayersByName('countries')
5
6# let's filter for countries that begin with Z, then get their features
7query = '"name" LIKE \'Z%\''
8features = layer.getFeatures(QgsFeatureRequest().setFilterExpression(query))
9
10for f in features:
11  geom = f.geometry()
12  name = f.attribute('NAME')
13  print(name)
14  print("Perimeter (m):", d.measurePerimeter(geom))
15  print("Area (m2):", d.measureArea(geom))
16
17  # let's calculate and print the area again, but this time in square kilometers
18  print("Area (km2):", d.convertAreaMeasurement(d.measureArea(geom), QgsUnitTypes.AreaSquareKilometers))
```
```1Zambia
2Perimeter (m): 5539361.250080013
3Area (m2): 752000605894.2937
4Area (km2): 752000.6058942936
5Zimbabwe
6Perimeter (m): 2865021.3323912495
7Area (m2): 389250992553.95465
8Area (km2): 389250.99255395465
```

Alternatively, you may want to know the distance and bearing between two points.

``` 1d = QgsDistanceArea()
2d.setEllipsoid('WGS84')
3
4# Let's create two points.
5# Santa claus is a workaholic and needs a summer break,
6# lets see how far is Tenerife from his home
7santa = QgsPointXY(25.847899, 66.543456)
8tenerife = QgsPointXY(-16.5735, 28.0443)
9
10print("Distance in meters: ", d.measureLine(santa, tenerife))
```

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