7 几何处理 
此页面上的代码片段需要导入以下模块:
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 from   qgis.core   import  ( 
  QgsGeometry , 
  QgsGeometryCollection 
  QgsPoint , 
  QgsPointXY , 
  QgsWkbTypes , 
  QgsProject , 
  QgsFeatureRequest , 
  QgsVectorLayer , 
  QgsDistanceArea , 
  QgsUnitTypes , 
  QgsCoordinateTransform , 
  QgsCoordinateReferenceSystem 
) 
表示空间要素的点、线和多边形通常称为几何。在QGIS中,它们用QgsGeometry
有时,一种几何实际上是简单(单部件)几何的集合。另一种几何形状称为多部件几何。如果它只包含一种类型的简单几何,我们称之为多点、多线或多多边形。例如,由多个岛组成的国家可以表示为多多边形。
几何的坐标可以在任何坐标参考系统(CRS)中。从图层中提取要素时,关联的几何图形将在图层的CRS中具有坐标。
有关所有可访问的几何结构和关系说明,请参阅OGC简单要素访问标准 ,以获取更详细的信息。
7.1 几何构造 
PyQGIS提供了几种创建几何的选项:
gPnt  =  QgsGeometry . fromPointXY ( QgsPointXY ( 1 , 1 )) 
print ( gPnt ) 
gLine  =  QgsGeometry . fromPolyline ([ QgsPoint ( 1 ,  1 ),  QgsPoint ( 2 ,  2 )]) 
print ( gLine ) 
gPolygon  =  QgsGeometry . fromPolygonXY ([[ QgsPointXY ( 1 ,  1 ), 
    QgsPointXY ( 2 ,  2 ),  QgsPointXY ( 2 ,  1 )]]) 
print ( gPolygon ) 
使用QgsPointQgsPointXYQgsPoint
折线(Linestring)由一系列点表示。
多边形由线环列表(即闭合的线段)表示。第一个环是外环(边界),第二个可选项线环是多边形中的孔。请注意,与某些程序不同,QGIS会为你闭合环,因此无需将第一个点复制为最后一个。
多部件几何图形更进一步:多点是一个点列表,多线是一个线列表,多多边形是一个多边形列表。
gem  =  QgsGeometry . fromWkt ( "POINT(3 4)" ) 
print ( geom ) 
g  =  QgsGeometry () 
wkb  =  bytes . fromhex ( "010100000000000000000045400000000000001440" ) 
g . fromWkb ( wkb ) 
#使用WKT打印几何 
print ( g . asWkt ()) 
7.2 访问几何 
首先,你应该找出几何类型。wkbType()QgsWkbTypes.Type
if  gPnt . wkbType ()  ==  QgsWkbTypes . Point : 
  print ( gPnt . wkbType ()) 
  # output: 1 for Point 
if  gLine . wkbType ()  ==  QgsWkbTypes . LineString : 
  print ( gLine . wkbType ()) 
  # output: 2 for LineString 
if  gPolygon . wkbType ()  ==  QgsWkbTypes . Polygon : 
  print ( gPolygon . wkbType ()) 
  # output: 3 for Polygon 
作为替代方案,可以使用type()QgsWkbTypes.GeometryType
你可以使用displayString()
print ( QgsWkbTypes . displayString ( gPnt . wkbType ())) 
# output: 'Point' 
print ( QgsWkbTypes . displayString ( gLine . wkbType ())) 
# output: 'LineString' 
print ( QgsWkbTypes . displayString ( gPolygon . wkbType ())) 
# output: 'Polygon' 
还有一个辅助函数 isMultipart()
从几何中提取信息,每种矢量类型都有访问器函数。以下是如何使用这些访问器的示例:
gPnt . asPoint () 
# output: <QgsPointXY: POINT(1 1)> 
gLine . asPolyline () 
# output: [<QgsPointXY: POINT(1 1)>, <QgsPointXY: POINT(2 2)>] 
gPolygon . asPolygon () 
# output: [[<QgsPointXY: POINT(1 1)>, <QgsPointXY: POINT(2 2)>, <QgsPointXY: POINT(2 1)>, <QgsPointXY: POINT(1 1)>]] 
对于多部件几何也有类似的访问函数: asMultiPoint()asMultiPolyline()asMultiPolygon()
不用管几何的类型,直接遍历所有几何是可以的,例如:
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) 
gc  =  QgsGeometryCollection () 
gc . fromWkt ( 'GeometryCollection( Point(1 2), Point(11 12), LineString(33 34, 44 45))' ) 
print ( gc [ 1 ] . asWkt ()) 
# Point (11 12) 
使用 QgsGeometry.parts()
geom  =  QgsGeometry . fromWkt (  'MultiPoint( 0 0, 1 1, 2 2)'  ) 
for  part  in  geom . parts (): 
  part . transform ( QgsCoordinateTransform ( 
    QgsCoordinateReferenceSystem ( "EPSG:4326" ), 
    QgsCoordinateReferenceSystem ( "EPSG:3111" ), 
    QgsProject . instance ()) 
  ) 
print ( geom . asWkt ()) 
# MultiPoint ((-10334728.12541878595948219 -5360106.25905461423099041),(-10462135.16126426123082638 -5217485.4735023295506835),(-10589399.84444035589694977 -5072021.45942386891692877)) 
7.3 几何谓词与操作 
QGIS使用GEOS库进行高级几何操作,如几何谓词(contains()intersects()combine()difference()
让我们看一个结合遍历指定图层要素,并基于它们的几何执行一些几何计算的示例。下面的代码计算并打印countries 图层中每个国家的面积和周长。
以下代码假定layer是具有多边形要素类型的QgsVectorLayer
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 # 访问'countries'图层 
layer  =  QgsProject . instance () . mapLayersByName ( 'countries' )[ 0 ] 
# 过滤以Z开头的国家,然后获取其要素 
query  =  '"name" LIKE  \' Z% \' ' 
features  =  layer . getFeatures ( QgsFeatureRequest () . setFilterExpression ( query )) 
# 现在遍历要素,执行几何计算并打印结果 
for  f  in  features : 
  geom  =  f . geometry () 
  name  =  f . attribute ( 'NAME' ) 
  print ( name ) 
  print ( 'Area: ' ,  geom . area ()) 
  print ( 'Perimeter: ' ,  geom . length ()) 
# Zambia 
# Area:  62.822790653431205 
# Perimeter:  50.65232014052552 
# Zimbabwe 
# Area:  33.41113559136521 
# Perimeter:  26.608288555013935 
现在,你已经计算并打印了几何图形的面积和周长。但是,你可能会很快注意到这些值很奇怪。这是因为当使用 QgsGeometryarea()length()QgsDistanceArea
以下代码假定layer是具有多边形要素类型的QgsVectorLayer
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 d  =  QgsDistanceArea () 
d . setEllipsoid ( 'WGS84' ) 
layer  =  QgsProject . instance () . mapLayersByName ( 'countries' )[ 0 ] 
# 过滤以Z开头的国家,然后获取其要素 
query  =  '"name" LIKE  \' Z% \' ' 
features  =  layer . getFeatures ( QgsFeatureRequest () . setFilterExpression ( query )) 
for  f  in  features : 
  geom  =  f . geometry () 
  name  =  f . attribute ( 'NAME' ) 
  print ( name ) 
  print ( "Perimeter (m):" ,  d . measurePerimeter ( geom )) 
  print ( "Area (m2):" ,  d . measureArea ( geom ))  )) 
  # 打印(“面积(m2):” , d 。measureArea (GEOM )) 
  # 计算并重新打印面积,单位为平方公里 
  print ( "Area (km2):" ,  d . convertAreaMeasurement ( d . measureArea ( geom ),  QgsUnitTypes . AreaSquareKilometers )) 
# Zambia 
# Perimeter (m): 5539361.250294601 
# Area (m2): 751989035032.9031 
# Area (km2): 751989.0350329031 
# Zimbabwe 
# Perimeter (m): 2865021.3325076113 
# Area (m2): 389267821381.6008 
# Area (km2): 389267.8213816008 
或者,你可能想知道两点之间的距离。
d  =  QgsDistanceArea () 
d . setEllipsoid ( 'WGS84' ) 
# 让我们创造两个点 
# 圣诞老人是一个工作狂,他需要放个暑假,让我们看一下他家离特内里费有多远 
santa  =  QgsPointXY ( 25.847899 ,  66.543456 ) 
tenerife  =  QgsPointXY ( - 16.5735 ,  28.0443 ) 
print ( "Distance in meters: " ,  d . measureLine ( santa ,  tenerife )) 
你可以在QGIS中找到许多算法示例,并使用这些方法来分析和转换矢量数据。以下是一些代码的链接。