Skip to content

Commit

Permalink
Add __nonzero__ and __bool__ methods to QgsGeometry
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Aug 1, 2016
1 parent d075b12 commit b7ca001
Show file tree
Hide file tree
Showing 8 changed files with 34 additions and 14 deletions.
8 changes: 5 additions & 3 deletions doc/api_break.dox
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -220,8 +220,8 @@ attributeIndexes(), pkAttributeIndexes(), isSaveAndLoadStyleToDBSupported()</li>
<li>The setGeometry( QgsGeometry* ) method has been removed, use setGeometry( const QgsGeometry& ) instead.</li> <li>The setGeometry( QgsGeometry* ) method has been removed, use setGeometry( const QgsGeometry& ) instead.</li>
<li>The geometry() method now returns a copy of the geometry, not a pointer. Since QgsGeometry objects are <li>The geometry() method now returns a copy of the geometry, not a pointer. Since QgsGeometry objects are
implicitly shared this is a low-cost copy, and avoids ownership and dangling pointer issues. <b>Very important: Testing that implicitly shared this is a low-cost copy, and avoids ownership and dangling pointer issues. <b>Very important: Testing that
a feature has a geometry is now done using the new hasGeometry() method. QgsFeature::geometry() will ALWAYS return a feature has a geometry is now done using the new hasGeometry() method. Any code which compares QgsFeature::geometry() to
true, as the method will return an empty geometry if the feature has no geometry.</b></li> None will need to be modified, as the method will return an empty geometry if the feature has no geometry.</b></li>
<li>The temporary constGeometry() method has been removed. Use geometry() instead.</li> <li>The temporary constGeometry() method has been removed. Use geometry() instead.</li>
<li>setFields( const QgsFields*, bool ) has been removed, use setFields( const QgsFields&, bool ) instead.</li> <li>setFields( const QgsFields*, bool ) has been removed, use setFields( const QgsFields&, bool ) instead.</li>
</ul> </ul>
Expand All @@ -230,7 +230,9 @@ true, as the method will return an empty geometry if the feature has no geometry


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


\subsection qgis_api_break_3_0_QgsGeometryAnalyzer QgsGeometryAnalyzer \subsection qgis_api_break_3_0_QgsGeometryAnalyzer QgsGeometryAnalyzer
Expand Down
8 changes: 8 additions & 0 deletions python/core/__init__.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@
import string import string
from qgis._core import * from qgis._core import *


# Boolean evaluation of QgsGeometry


def _geometryNonZero(self):
return not self.isEmpty()
QgsGeometry.__nonzero__ = _geometryNonZero
QgsGeometry.__bool__ = _geometryNonZero



def register_function(function, arg_count, group, usesgeometry=False, referenced_columns=[QgsFeatureRequest.AllAttributes], **kwargs): def register_function(function, arg_count, group, usesgeometry=False, referenced_columns=[QgsFeatureRequest.AllAttributes], **kwargs):
""" """
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/Eliminate.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ def processAlgorithm(self, progress):
# We have a candidate # We have a candidate
iGeom = geom2Eliminate.intersection(selGeom) iGeom = geom2Eliminate.intersection(selGeom)


if iGeom is None: if not iGeom:
continue continue


if boundary: if boundary:
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def processAlgorithm(self, progress):
outGeom = None outGeom = None
if not inGeom.isEmpty(): if not inGeom.isEmpty():
reversedLine = inGeom.geometry().reversed() reversedLine = inGeom.geometry().reversed()
if reversedLine is None: if not reversedLine:
raise GeoAlgorithmExecutionException( raise GeoAlgorithmExecutionException(
self.tr('Error reversing line')) self.tr('Error reversing line'))
outGeom = QgsGeometry(reversedLine) outGeom = QgsGeometry(reversedLine)
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/Smooth.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def processAlgorithm(self, progress):
attrs = inFeat.attributes() attrs = inFeat.attributes()


outGeom = inGeom.smooth(iterations, offset) outGeom = inGeom.smooth(iterations, offset)
if outGeom is None: if not outGeom:
raise GeoAlgorithmExecutionException( raise GeoAlgorithmExecutionException(
self.tr('Error smoothing geometry')) self.tr('Error smoothing geometry'))


Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/Union.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def processAlgorithm(self, progress):
int_geom = geom.intersection(tmpGeom) int_geom = geom.intersection(tmpGeom)
lstIntersectingB.append(tmpGeom) lstIntersectingB.append(tmpGeom)


if int_geom is None: if not int_geom:
# There was a problem creating the intersection # There was a problem creating the intersection
ProcessingLog.addToLog(ProcessingLog.LOG_INFO, ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
self.tr('GEOS geoprocessing error: One or more input features have invalid geometry.')) self.tr('GEOS geoprocessing error: One or more input features have invalid geometry.'))
Expand Down
8 changes: 4 additions & 4 deletions tests/src/gui/testqgsrubberband.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ void TestQgsRubberband::testBoundingRect()


// Polygon extent is 10,10 to 30,30 // Polygon extent is 10,10 to 30,30
QgsGeometry geom( QgsGeometry::fromWkt( QgsGeometry geom( QgsGeometry::fromWkt(
"POLYGON((10 10,10 30,30 30,30 10,10 10))" "POLYGON((10 10,10 30,30 30,30 10,10 10))"
) ); ) );
mRubberband = new QgsRubberBand( mCanvas, mPolygonLayer->geometryType() ); mRubberband = new QgsRubberBand( mCanvas, mPolygonLayer->geometryType() );
mRubberband->setIconSize( 5 ); // default, but better be explicit mRubberband->setIconSize( 5 ); // default, but better be explicit
mRubberband->setWidth( 1 ); // default, but better be explicit mRubberband->setWidth( 1 ); // default, but better be explicit
Expand Down Expand Up @@ -173,8 +173,8 @@ void TestQgsRubberband::testVisibility()


// Check visibility after setting to valid geometry // Check visibility after setting to valid geometry
QgsGeometry geom( QgsGeometry::fromWkt( QgsGeometry geom( QgsGeometry::fromWkt(
"POLYGON((10 10,10 30,30 30,30 10,10 10))" "POLYGON((10 10,10 30,30 30,30 10,10 10))"
) ); ) );
mRubberband->setToGeometry( geom, mPolygonLayer ); mRubberband->setToGeometry( geom, mPolygonLayer );
QCOMPARE( mRubberband->isVisible(), true ); QCOMPARE( mRubberband->isVisible(), true );


Expand Down
16 changes: 13 additions & 3 deletions tests/src/python/test_qgsgeometry.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@


class TestQgsGeometry(unittest.TestCase): class TestQgsGeometry(unittest.TestCase):


def testBool(self):
""" Test boolean evaluation of QgsGeometry """
g = QgsGeometry()
self.assertFalse(g)
myWKT = 'Point (10 10)'
g = QgsGeometry.fromWkt(myWKT)
self.assertTrue(g)
g.setGeometry(None)
self.assertFalse(g)

def testWktPointLoading(self): def testWktPointLoading(self):
myWKT = 'Point (10 10)' myWKT = 'Point (10 10)'
myGeometry = QgsGeometry.fromWkt(myWKT) myGeometry = QgsGeometry.fromWkt(myWKT)
Expand Down Expand Up @@ -1516,7 +1526,7 @@ def testConvertToType(self):
######## TO LINE ######## ######## TO LINE ########
# POINT TO LINE # POINT TO LINE
point = QgsGeometry.fromPoint(QgsPoint(1, 1)) point = QgsGeometry.fromPoint(QgsPoint(1, 1))
assert point.convertToType(Qgis.Line, False) is None, "convertToType with a point should return a null geometry" self.assertFalse(point.convertToType(Qgis.Line, False)), "convertToType with a point should return a null geometry"
# MultiPoint TO LINE # MultiPoint TO LINE
multipoint = QgsGeometry.fromMultiPoint(points[0][0]) multipoint = QgsGeometry.fromMultiPoint(points[0][0])
wkt = multipoint.convertToType(Qgis.Line, False).exportToWkt() wkt = multipoint.convertToType(Qgis.Line, False).exportToWkt()
Expand Down Expand Up @@ -1581,10 +1591,10 @@ def testConvertToType(self):
assert compareWkt(expWkt, wkt), "convertToType failed: from line to polygon. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt) assert compareWkt(expWkt, wkt), "convertToType failed: from line to polygon. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt)
# LINE ( 3 vertices, with first = last ) TO Polygon # LINE ( 3 vertices, with first = last ) TO Polygon
line = QgsGeometry.fromPolyline([QgsPoint(1, 1), QgsPoint(0, 0), QgsPoint(1, 1)]) line = QgsGeometry.fromPolyline([QgsPoint(1, 1), QgsPoint(0, 0), QgsPoint(1, 1)])
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" 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")
# MULTILINE ( with a part of 3 vertices, with first = last ) TO MultiPolygon # MULTILINE ( with a part of 3 vertices, with first = last ) TO MultiPolygon
multiline = QgsGeometry.fromMultiPolyline([points[0][0], [QgsPoint(1, 1), QgsPoint(0, 0), QgsPoint(1, 1)]]) multiline = QgsGeometry.fromMultiPolyline([points[0][0], [QgsPoint(1, 1), QgsPoint(0, 0), QgsPoint(1, 1)]])
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" 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")
# LINE TO MultiPolygon # LINE TO MultiPolygon
line = QgsGeometry.fromPolyline(points[0][0]) line = QgsGeometry.fromPolyline(points[0][0])
wkt = line.convertToType(Qgis.Polygon, True).exportToWkt() wkt = line.convertToType(Qgis.Polygon, True).exportToWkt()
Expand Down

0 comments on commit b7ca001

Please sign in to comment.