Робота з геометрією

Точки, лінії та полігони, які представляють просторові об’єкти, зазвичай називають геометрією. В QGIS вони описуються класом QgsGeometry. З усіма можливими типами геометрій можна ознайомитися на сторінці обговорення JTS.

Іноді одна геометрія насправді є колекцією простих (single-part) геометрій. Такі геометрії називаються складеними (multi-part). Якщо складена геометрія містить прості геометрії одного типу, то її називають мульти-точка, мульти-лінія або мульти-полігон. Наприклад, країна, що складається з декількох островів може бути представлена як мульти-полігон.

Координати, що описують геометрії, можуть бути в будь-якій системі координат (CRS). Коли виконується доступ до об’єктів шару, асоційовані геометрії будуть мати систему координат шару.

Створення геометрії

Існує декілька способів створити геометрію:

  • from coordinates

    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.

    Полілінія описується масивом точок. Полігон в свою чергу описується як список лінійних кілець (тобто замкнених ліній). Перше кільце — зовнішнє (межа), всі наступні необов’язкові кільця описують дірки в полігоні.

    Складені геометрії мають ще один рівень вкладеності: мульти-точка це список точок, мульти-лінія — список ліній, а мульти-полігон, відповідно, список полігонів.

  • from well-known text (WKT)

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

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

Доступ до геометрії

First, you should find out geometry type, wkbType() method is the one to use — it returns a value from QGis.WkbType enumeration

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

As an alternative, one can use type() method which returns a value from QGis.GeometryType enumeration. There is also a helper function isMultipart() to find out whether a geometry is multipart or not.

Для витягнення інформації з геометрії передбачено спеціальні функції доступу для кожного типу геометрії. Нижче показано як їх використовувати

>>> 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 використовує бібліотеку GEOS для виконання різноманітних операцій з геометріями, таких як геометричні предикати (contains(), intersects(), ...) та операції (union(), difference(), ...). Також вона може обчислювати геометричні характеристики, такі як площа (для полігонів) або довжина (для полігонів та ліній).

Нижче наведено маленький приклад, де показаний обхід всіх геометрій шару та обчислення деяких геометричних характеристик відповідних об’єктів.

# 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. Якщо перепроектування вимкнене, розрахунки відбуваються на площині, інакше — на еліпсоїді. Якщо еліпсоїд не задано явно, використовуються параметри WGS 84.

d = QgsDistanceArea()
d.setProjectionsEnabled(True)

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

Багато прикладів використання методів аналізу та перетворення векторних даних можна знайти в коді алгоритмів QGIS. Ось декілька посилань для початку:

Additional information can be found in following sources: