Skip to content

Commit

Permalink
Merge pull request #4078 from nyalldawson/geom_api
Browse files Browse the repository at this point in the history
API changes to QgsGeometry::isEmpty()/isNull()
  • Loading branch information
nyalldawson committed Jan 30, 2017
2 parents c4165e4 + afcb75a commit 8709e1f
Show file tree
Hide file tree
Showing 107 changed files with 368 additions and 290 deletions.
5 changes: 4 additions & 1 deletion doc/api_break.dox
Expand Up @@ -1044,8 +1044,10 @@ QgsGeometry {#qgis_api_break_3_0_QgsGeometry}

- All QgsGeometry methods now accept geometry references instead of pointers, and return a QgsGeometry
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()
result to None, but instead either use a boolean test (`if g.buffer(10):`) or explicitly use the isNull()
method to determine if a geometry is valid.
- isEmpty() was renamed to isNull() to differentiate a missing geometry from a geometry which is empty (eg an
empty geometry collection)
- wkbSize() and asWkb() has been replaced by exportToWkb(). WKB representation is no longer cached within QgsGeometry
- asGeos() has been replaced by exportToGeos(). GEOS representation is no longer cached within QgsGeometry
- int addPart( const QList<QgsPoint> &points, QgsWkbTypes::GeometryType geomType ) has been renamed to addPoints
Expand All @@ -1055,6 +1057,7 @@ method to determine if a geometry is valid.
- static bool compare( const QgsMultiPolygon& p1, const QgsMultiPolygon& p2, double epsilon ) has been renamed to compareMultiPolygons
- smoothLine and smoothPolygon are no longer public API (use smooth() instead)
- avoidIntersections() got an extra argument: list of layers to include in the operation (previously read from active QgsProject)
- isGeosEmpty() was removed. Use isEmpty() instead.


QgsGeometryAnalyzer {#qgis_api_break_3_0_QgsGeometryAnalyzer}
Expand Down
2 changes: 1 addition & 1 deletion python/core/geometry/qgsabstractgeometry.sip
Expand Up @@ -311,7 +311,7 @@ class QgsAbstractGeometry

/** Returns true if the geometry is empty
*/
bool isEmpty() const;
virtual bool isEmpty() const;

/** Returns true if the geometry contains curved segments
*/
Expand Down
1 change: 1 addition & 0 deletions python/core/geometry/qgscircularstring.sip
Expand Up @@ -25,6 +25,7 @@ class QgsCircularString: public QgsCurve
QDomElement asGML3( QDomDocument& doc, int precision = 17, const QString& ns = "gml" ) const;
QString asJSON( int precision = 17 ) const;

bool isEmpty() const;
int numPoints() const;

/** Returns the point at index i within the circular string.
Expand Down
2 changes: 2 additions & 0 deletions python/core/geometry/qgscompoundcurve.sip
Expand Up @@ -33,6 +33,8 @@ class QgsCompoundCurve: public QgsCurve
virtual QgsPointV2 endPoint() const;
virtual void points( QList<QgsPointV2>& pts ) const;
virtual int numPoints() const;
bool isEmpty() const;

/** Returns a new line string geometry corresponding to a segmentized approximation
* of the curve.
* @param tolerance segmentation tolerance
Expand Down
1 change: 1 addition & 0 deletions python/core/geometry/qgscurvepolygon.sip
Expand Up @@ -83,6 +83,7 @@ class QgsCurvePolygon: public QgsSurface

virtual QList< QList< QList< QgsPointV2 > > > coordinateSequence() const;
virtual int nCoordinates() const;
bool isEmpty() const;
double closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const;
bool nextVertex( QgsVertexId& id, QgsPointV2& vertex ) const;

Expand Down
14 changes: 3 additions & 11 deletions python/core/geometry/qgsgeometry.sip
Expand Up @@ -57,12 +57,7 @@ class QgsGeometry
*/
void setGeometry( QgsAbstractGeometry* geometry /Transfer/ );

/** Returns true if the geometry is empty (ie, contains no underlying geometry
* accessible via @link geometry @endlink).
* @see geometry
* @note added in QGIS 2.10
*/
bool isEmpty() const;
bool isNull() const;

/** Creates a new geometry from a WKT string */
static QgsGeometry fromWkt( const QString& wkt );
Expand Down Expand Up @@ -120,6 +115,8 @@ class QgsGeometry
*/
QgsWkbTypes::GeometryType type() const;

bool isEmpty() const;

/** Returns true if WKB of the geometry is of WKBMulti* type */
bool isMultipart() const;

Expand All @@ -133,11 +130,6 @@ class QgsGeometry
*/
bool isGeosValid() const;

/** Check if the geometry is empty using GEOS
@note added in 1.5
*/
bool isGeosEmpty() const;

/** Returns the area of the geometry using GEOS
@note added in 1.5
*/
Expand Down
1 change: 1 addition & 0 deletions python/core/geometry/qgsgeometrycollection.sip
Expand Up @@ -27,6 +27,7 @@ class QgsGeometryCollection: public QgsAbstractGeometry
QgsAbstractGeometry* geometryN( int n );

//methods inherited from QgsAbstractGeometry
bool isEmpty() const;
virtual int dimension() const;
virtual QString geometryType() const;
virtual void clear();
Expand Down
2 changes: 1 addition & 1 deletion python/core/geometry/qgslinestring.sip
Expand Up @@ -106,7 +106,7 @@ class QgsLineString: public QgsCurve
virtual int dimension() const;
virtual QgsLineString* clone() const /Factory/;
virtual void clear();

bool isEmpty() const;
virtual bool fromWkb( QgsConstWkbPtr& wkb );
virtual bool fromWkt( const QString& wkt );

Expand Down
1 change: 1 addition & 0 deletions python/core/geometry/qgspointv2.sip
Expand Up @@ -245,6 +245,7 @@ class QgsPointV2: public QgsAbstractGeometry
virtual int dimension() const;
virtual QgsPointV2* clone() const /Factory/;
void clear();
bool isEmpty() const;
virtual bool fromWkb( QgsConstWkbPtr& wkb );
virtual bool fromWkt( const QString& wkt );
QByteArray asWkb() const;
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/CheckValidity.py
Expand Up @@ -137,7 +137,7 @@ def doCheck(self, feedback):
attrs = inFeat.attributes()

valid = True
if not geom.isEmpty() and not geom.isGeosEmpty():
if not geom.isNull() and not geom.isEmpty():
errors = list(geom.validateGeometry())
if errors:
# QGIS method return a summary at the end
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/Delaunay.py
Expand Up @@ -82,7 +82,7 @@ def processAlgorithm(self, feedback):
total = 100.0 / len(features)
for current, inFeat in enumerate(features):
geom = QgsGeometry(inFeat.geometry())
if geom.isEmpty():
if geom.isNull():
continue
if geom.isMultipart():
points = geom.asMultiPoint()
Expand Down
4 changes: 2 additions & 2 deletions python/plugins/processing/algs/qgis/Dissolve.py
Expand Up @@ -93,7 +93,7 @@ def processAlgorithm(self, feedback):
first = False

tmpInGeom = inFeat.geometry()
if tmpInGeom.isEmpty() or tmpInGeom.isGeosEmpty():
if tmpInGeom.isNull() or tmpInGeom.isEmpty():
continue

errors = tmpInGeom.validateGeometry()
Expand Down Expand Up @@ -137,7 +137,7 @@ def processAlgorithm(self, feedback):
index_attrs = tuple([attrs[i] for i in field_indexes])

tmpInGeom = QgsGeometry(inFeat.geometry())
if tmpInGeom.isGeosEmpty():
if tmpInGeom and tmpInGeom.isEmpty():
continue
errors = tmpInGeom.validateGeometry()
if len(errors) != 0:
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/HypsometricCurves.py
Expand Up @@ -105,7 +105,7 @@ def processAlgorithm(self, feedback):
geom = f.geometry()
intersectedGeom = rasterGeom.intersection(geom)

if intersectedGeom.isGeosEmpty():
if intersectedGeom.isEmpty():
feedback.pushInfo(
self.tr('Feature %d does not intersect raster or '
'entirely located in NODATA area' % f.id()))
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/Intersection.py
Expand Up @@ -107,7 +107,7 @@ def processAlgorithm(self, feedback):
if int_com:
int_sym = geom.symDifference(tmpGeom)
int_geom = QgsGeometry(int_com.difference(int_sym))
if int_geom.isGeosEmpty() or not int_geom.isGeosValid():
if int_geom.isEmpty() or not int_geom.isGeosValid():
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
self.tr('GEOS geoprocessing error: One or '
'more input features have invalid '
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/PolygonCentroids.py
Expand Up @@ -80,7 +80,7 @@ def processAlgorithm(self, feedback):
inGeom = feat.geometry()
attrs = feat.attributes()

if inGeom.isEmpty():
if inGeom.isNull():
outGeom = QgsGeometry(None)
else:
outGeom = QgsGeometry(inGeom.centroid())
Expand Down
Expand Up @@ -65,7 +65,7 @@ def processAlgorithm(self, feedback):
attrs = inFeat.attributes()

outGeom = None
if not inGeom.isEmpty():
if not inGeom.isNull():
reversedLine = inGeom.geometry().reversed()
if not reversedLine:
raise GeoAlgorithmExecutionException(
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/SplitWithLines.py
Expand Up @@ -127,7 +127,7 @@ def processAlgorithm(self, feedback):
while len(inGeoms) > 0:
inGeom = inGeoms.pop()

if inGeom.isEmpty(): # this has been encountered and created a run-time error
if inGeom.isNull(): # this has been encountered and created a run-time error
continue

if split_geom_engine.intersects(inGeom.geometry()):
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/tests/AlgorithmsTestBase.py
Expand Up @@ -255,7 +255,7 @@ def check_results(self, results, params, expected):
data = file.read()

for rule in expected_result.get('rules', []):
self.assertRegexpMatches(data, rule)
self.assertRegex(data, rule)


if __name__ == '__main__':
Expand Down
2 changes: 1 addition & 1 deletion src/analysis/interpolation/qgsinterpolator.cpp
Expand Up @@ -105,7 +105,7 @@ int QgsInterpolator::cacheBaseData()

int QgsInterpolator::addVerticesToCache( const QgsGeometry& geom, bool zCoord, double attributeValue )
{
if ( geom.isEmpty() )
if ( geom.isNull() )
return 1;

bool hasZValue = false;
Expand Down
2 changes: 1 addition & 1 deletion src/analysis/interpolation/qgstininterpolator.cpp
Expand Up @@ -175,7 +175,7 @@ int QgsTINInterpolator::insertData( QgsFeature* f, bool zCoord, int attr, InputT

QgsGeometry g = f->geometry();
{
if ( g.isEmpty() )
if ( g.isNull() )
{
return 2;
}
Expand Down
2 changes: 1 addition & 1 deletion src/analysis/openstreetmap/qgsosmdatabase.cpp
Expand Up @@ -504,7 +504,7 @@ void QgsOSMDatabase::exportSpatiaLiteWays( bool closed, const QString& tableName
sqlite3_bind_null( stmtInsert, ++col );
}

if ( !geom.isEmpty() )
if ( !geom.isNull() )
{
QByteArray wkb( geom.exportToWkb() );
sqlite3_bind_blob( stmtInsert, ++col, wkb.constData(), wkb.length(), SQLITE_STATIC );
Expand Down
2 changes: 1 addition & 1 deletion src/analysis/raster/qgskde.cpp
Expand Up @@ -110,7 +110,7 @@ QgsKernelDensityEstimation::Result QgsKernelDensityEstimation::prepare()
QgsKernelDensityEstimation::Result QgsKernelDensityEstimation::addFeature( const QgsFeature& feature )
{
QgsGeometry featureGeometry = feature.geometry();
if ( featureGeometry.isEmpty() )
if ( featureGeometry.isNull() )
{
return Success;
}
Expand Down
20 changes: 10 additions & 10 deletions src/analysis/vector/qgsgeometryanalyzer.cpp
Expand Up @@ -475,7 +475,7 @@ bool QgsGeometryAnalyzer::convexHull( QgsVectorLayer* layer, const QString& shap
++jt;
}
QList<double> values;
if ( dissolveGeometry.isEmpty() )
if ( dissolveGeometry.isNull() )
{
QgsDebugMsg( "no dissolved geometry - should not happen" );
return false;
Expand Down Expand Up @@ -520,7 +520,7 @@ bool QgsGeometryAnalyzer::convexHull( QgsVectorLayer* layer, const QString& shap
++jt;
}
QList<double> values;
if ( dissolveGeometry.isEmpty() )
if ( dissolveGeometry.isNull() )
{
QgsDebugMsg( "no dissolved geometry - should not happen" );
return false;
Expand Down Expand Up @@ -705,7 +705,7 @@ QgsGeometry QgsGeometryAnalyzer::dissolveFeature( const QgsFeature& f, const Qgs

QgsGeometry featureGeometry = f.geometry();

if ( dissolveInto.isEmpty() )
if ( dissolveInto.isNull() )
{
return featureGeometry;
}
Expand Down Expand Up @@ -810,7 +810,7 @@ bool QgsGeometryAnalyzer::buffer( QgsVectorLayer* layer, const QString& shapefil
if ( dissolve )
{
QgsFeature dissolveFeature;
if ( dissolveGeometry.isEmpty() )
if ( dissolveGeometry.isNull() )
{
QgsDebugMsg( "no dissolved geometry - should not happen" );
return false;
Expand Down Expand Up @@ -967,7 +967,7 @@ bool QgsGeometryAnalyzer::eventLayer( QgsVectorLayer* lineLayer, QgsVectorLayer*
lrsGeom = locateBetweenMeasures( measure1, measure2, featureIdIt->geometry() );
}

if ( !lrsGeom.isEmpty() )
if ( !lrsGeom.isNull() )
{
++nOutputFeatures;
addEventLayerFeature( fet, lrsGeom, featureIdIt->geometry(), fileWriter, memoryProviderFeatures, offsetField, offsetScale, forceSingleGeometry );
Expand Down Expand Up @@ -995,7 +995,7 @@ bool QgsGeometryAnalyzer::eventLayer( QgsVectorLayer* lineLayer, QgsVectorLayer*
void QgsGeometryAnalyzer::addEventLayerFeature( QgsFeature& feature, const QgsGeometry& geom, const QgsGeometry& lineGeom, QgsVectorFileWriter* fileWriter, QgsFeatureList& memoryFeatures,
int offsetField, double offsetScale, bool forceSingleType )
{
if ( geom.isEmpty() )
if ( geom.isNull() )
{
return;
}
Expand All @@ -1020,7 +1020,7 @@ void QgsGeometryAnalyzer::addEventLayerFeature( QgsFeature& feature, const QgsGe
double offsetVal = feature.attribute( offsetField ).toDouble();
offsetVal *= offsetScale;
newGeom = createOffsetGeometry( *geomIt, lineGeom, offsetVal );
if ( newGeom.isEmpty() )
if ( newGeom.isNull() )
{
continue;
}
Expand All @@ -1040,7 +1040,7 @@ void QgsGeometryAnalyzer::addEventLayerFeature( QgsFeature& feature, const QgsGe

QgsGeometry QgsGeometryAnalyzer::createOffsetGeometry( const QgsGeometry& geom, const QgsGeometry& lineGeom, double offset )
{
if ( !geom || lineGeom.isEmpty() )
if ( !geom || lineGeom.isNull() )
{
return QgsGeometry();
}
Expand Down Expand Up @@ -1147,7 +1147,7 @@ QgsPoint QgsGeometryAnalyzer::createPointOffset( double x, double y, double dist

QgsGeometry QgsGeometryAnalyzer::locateBetweenMeasures( double fromMeasure, double toMeasure, const QgsGeometry& lineGeom )
{
if ( lineGeom.isEmpty() )
if ( lineGeom.isNull() )
{
return QgsGeometry();
}
Expand Down Expand Up @@ -1189,7 +1189,7 @@ QgsGeometry QgsGeometryAnalyzer::locateBetweenMeasures( double fromMeasure, doub

QgsGeometry QgsGeometryAnalyzer::locateAlongMeasure( double measure, const QgsGeometry& lineGeom )
{
if ( lineGeom.isEmpty() )
if ( lineGeom.isNull() )
{
return QgsGeometry();
}
Expand Down
2 changes: 1 addition & 1 deletion src/analysis/vector/qgsgeometrysnapper.cpp
Expand Up @@ -475,7 +475,7 @@ QgsFeatureList QgsGeometrySnapper::snapFeatures( const QgsFeatureList& features,

void QgsGeometrySnapper::processFeature( QgsFeature& feature, double snapTolerance, SnapMode mode )
{
if ( !feature.geometry().isEmpty() )
if ( !feature.geometry().isNull() )
feature.setGeometry( snapGeometry( feature.geometry(), snapTolerance, mode ) );
}

Expand Down

0 comments on commit 8709e1f

Please sign in to comment.