Skip to content

Commit b7ca001

Browse files
committed
Add __nonzero__ and __bool__ methods to QgsGeometry
1 parent d075b12 commit b7ca001

File tree

8 files changed

+34
-14
lines changed

8 files changed

+34
-14
lines changed

doc/api_break.dox

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,8 @@ attributeIndexes(), pkAttributeIndexes(), isSaveAndLoadStyleToDBSupported()</li>
220220
<li>The setGeometry( QgsGeometry* ) method has been removed, use setGeometry( const QgsGeometry& ) instead.</li>
221221
<li>The geometry() method now returns a copy of the geometry, not a pointer. Since QgsGeometry objects are
222222
implicitly shared this is a low-cost copy, and avoids ownership and dangling pointer issues. <b>Very important: Testing that
223-
a feature has a geometry is now done using the new hasGeometry() method. QgsFeature::geometry() will ALWAYS return
224-
true, as the method will return an empty geometry if the feature has no geometry.</b></li>
223+
a feature has a geometry is now done using the new hasGeometry() method. Any code which compares QgsFeature::geometry() to
224+
None will need to be modified, as the method will return an empty geometry if the feature has no geometry.</b></li>
225225
<li>The temporary constGeometry() method has been removed. Use geometry() instead.</li>
226226
<li>setFields( const QgsFields*, bool ) has been removed, use setFields( const QgsFields&, bool ) instead.</li>
227227
</ul>
@@ -230,7 +230,9 @@ true, as the method will return an empty geometry if the feature has no geometry
230230

231231
<ul>
232232
<li>All QgsGeometry methods now accept geometry references instead of pointers, and return a QgsGeometry
233-
value instead of a pointer.</li>
233+
value instead of a pointer. The biggest impact with this change is that PyQGIS code should not compare a geometry
234+
result to None, but instead either use a boolean test (`if g.buffer(10):`) or explicitly use the isEmpty()
235+
method to determine if a geometry is valid.</li>
234236
</ul>
235237

236238
\subsection qgis_api_break_3_0_QgsGeometryAnalyzer QgsGeometryAnalyzer

python/core/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@
2929
import string
3030
from qgis._core import *
3131

32+
# Boolean evaluation of QgsGeometry
33+
34+
35+
def _geometryNonZero(self):
36+
return not self.isEmpty()
37+
QgsGeometry.__nonzero__ = _geometryNonZero
38+
QgsGeometry.__bool__ = _geometryNonZero
39+
3240

3341
def register_function(function, arg_count, group, usesgeometry=False, referenced_columns=[QgsFeatureRequest.AllAttributes], **kwargs):
3442
"""

python/plugins/processing/algs/qgis/Eliminate.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ def processAlgorithm(self, progress):
258258
# We have a candidate
259259
iGeom = geom2Eliminate.intersection(selGeom)
260260

261-
if iGeom is None:
261+
if not iGeom:
262262
continue
263263

264264
if boundary:

python/plugins/processing/algs/qgis/ReverseLineDirection.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def processAlgorithm(self, progress):
6868
outGeom = None
6969
if not inGeom.isEmpty():
7070
reversedLine = inGeom.geometry().reversed()
71-
if reversedLine is None:
71+
if not reversedLine:
7272
raise GeoAlgorithmExecutionException(
7373
self.tr('Error reversing line'))
7474
outGeom = QgsGeometry(reversedLine)

python/plugins/processing/algs/qgis/Smooth.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def processAlgorithm(self, progress):
7575
attrs = inFeat.attributes()
7676

7777
outGeom = inGeom.smooth(iterations, offset)
78-
if outGeom is None:
78+
if not outGeom:
7979
raise GeoAlgorithmExecutionException(
8080
self.tr('Error smoothing geometry'))
8181

python/plugins/processing/algs/qgis/Union.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ def processAlgorithm(self, progress):
117117
int_geom = geom.intersection(tmpGeom)
118118
lstIntersectingB.append(tmpGeom)
119119

120-
if int_geom is None:
120+
if not int_geom:
121121
# There was a problem creating the intersection
122122
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
123123
self.tr('GEOS geoprocessing error: One or more input features have invalid geometry.'))

tests/src/gui/testqgsrubberband.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ void TestQgsRubberband::testBoundingRect()
123123

124124
// Polygon extent is 10,10 to 30,30
125125
QgsGeometry geom( QgsGeometry::fromWkt(
126-
"POLYGON((10 10,10 30,30 30,30 10,10 10))"
127-
) );
126+
"POLYGON((10 10,10 30,30 30,30 10,10 10))"
127+
) );
128128
mRubberband = new QgsRubberBand( mCanvas, mPolygonLayer->geometryType() );
129129
mRubberband->setIconSize( 5 ); // default, but better be explicit
130130
mRubberband->setWidth( 1 ); // default, but better be explicit
@@ -173,8 +173,8 @@ void TestQgsRubberband::testVisibility()
173173

174174
// Check visibility after setting to valid geometry
175175
QgsGeometry geom( QgsGeometry::fromWkt(
176-
"POLYGON((10 10,10 30,30 30,30 10,10 10))"
177-
) );
176+
"POLYGON((10 10,10 30,30 30,30 10,10 10))"
177+
) );
178178
mRubberband->setToGeometry( geom, mPolygonLayer );
179179
QCOMPARE( mRubberband->isVisible(), true );
180180

tests/src/python/test_qgsgeometry.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@
5858

5959
class TestQgsGeometry(unittest.TestCase):
6060

61+
def testBool(self):
62+
""" Test boolean evaluation of QgsGeometry """
63+
g = QgsGeometry()
64+
self.assertFalse(g)
65+
myWKT = 'Point (10 10)'
66+
g = QgsGeometry.fromWkt(myWKT)
67+
self.assertTrue(g)
68+
g.setGeometry(None)
69+
self.assertFalse(g)
70+
6171
def testWktPointLoading(self):
6272
myWKT = 'Point (10 10)'
6373
myGeometry = QgsGeometry.fromWkt(myWKT)
@@ -1516,7 +1526,7 @@ def testConvertToType(self):
15161526
######## TO LINE ########
15171527
# POINT TO LINE
15181528
point = QgsGeometry.fromPoint(QgsPoint(1, 1))
1519-
assert point.convertToType(Qgis.Line, False) is None, "convertToType with a point should return a null geometry"
1529+
self.assertFalse(point.convertToType(Qgis.Line, False)), "convertToType with a point should return a null geometry"
15201530
# MultiPoint TO LINE
15211531
multipoint = QgsGeometry.fromMultiPoint(points[0][0])
15221532
wkt = multipoint.convertToType(Qgis.Line, False).exportToWkt()
@@ -1581,10 +1591,10 @@ def testConvertToType(self):
15811591
assert compareWkt(expWkt, wkt), "convertToType failed: from line to polygon. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt)
15821592
# LINE ( 3 vertices, with first = last ) TO Polygon
15831593
line = QgsGeometry.fromPolyline([QgsPoint(1, 1), QgsPoint(0, 0), QgsPoint(1, 1)])
1584-
assert line.convertToType(Qgis.Polygon, False) is None, "convertToType to polygon of a 3 vertices lines with first and last vertex identical should return a null geometry"
1594+
self.assertFalse(line.convertToType(Qgis.Polygon, False), "convertToType to polygon of a 3 vertices lines with first and last vertex identical should return a null geometry")
15851595
# MULTILINE ( with a part of 3 vertices, with first = last ) TO MultiPolygon
15861596
multiline = QgsGeometry.fromMultiPolyline([points[0][0], [QgsPoint(1, 1), QgsPoint(0, 0), QgsPoint(1, 1)]])
1587-
assert multiline.convertToType(Qgis.Polygon, True) is None, "convertToType to polygon of a 3 vertices lines with first and last vertex identical should return a null geometry"
1597+
self.assertFalse(multiline.convertToType(Qgis.Polygon, True), "convertToType to polygon of a 3 vertices lines with first and last vertex identical should return a null geometry")
15881598
# LINE TO MultiPolygon
15891599
line = QgsGeometry.fromPolyline(points[0][0])
15901600
wkt = line.convertToType(Qgis.Polygon, True).exportToWkt()

0 commit comments

Comments
 (0)