Skip to content

Commit

Permalink
[FEATURE] Give access to geometry errors
Browse files Browse the repository at this point in the history
When methods are called that use GEOS to create new geometries, the
result geometries now contain information about what has gone wrong in
case of an error.

In practice, this means it's possible to give more detailed information
in place (and not only in the message log) when things like processing
algorithms fail.
  • Loading branch information
m-kuhn committed Jul 17, 2017
1 parent db11185 commit 2b2d5e3
Show file tree
Hide file tree
Showing 3 changed files with 199 additions and 33 deletions.
70 changes: 64 additions & 6 deletions python/core/geometry/qgsgeometry.sip
Expand Up @@ -716,6 +716,12 @@ Returns a simplified version of this geometry using a specified tolerance value
QgsGeometry centroid() const;
%Docstring
Returns the center of mass of a geometry.

If the input is a NULL geometry, the output will also be a NULL geometry.

If an error was encountered while creating the result, more information can be retrieved
by calling `error()` on the returned geometry.

.. note::

for line based geometries, the center point of the line is returned,
Expand All @@ -730,6 +736,12 @@ Returns a simplified version of this geometry using a specified tolerance value
Returns a point guaranteed to lie on the surface of a geometry. While the centroid()
of a geometry may be located outside of the geometry itself (e.g., for concave shapes),
the point on surface will always be inside the geometry.

If the input is a NULL geometry, the output will also be a NULL geometry.

If an error was encountered while creating the result, more information can be retrieved
by calling `error()` on the returned geometry.

.. seealso:: centroid()
.. seealso:: poleOfInaccessibility()
:rtype: QgsGeometry
Expand All @@ -752,7 +764,12 @@ Returns a simplified version of this geometry using a specified tolerance value

QgsGeometry convexHull() const;
%Docstring
Returns the smallest convex polygon that contains all the points in the geometry.
Returns the smallest convex polygon that contains all the points in the geometry.

If the input is a NULL geometry, the output will also be a NULL geometry.

If an error was encountered while creating the result, more information can be retrieved
by calling `error()` on the returned geometry.
:rtype: QgsGeometry
%End

Expand Down Expand Up @@ -799,14 +816,25 @@ Returns the smallest convex polygon that contains all the points in the geometry

Curved geometries will be segmentized before subdivision.

If the input is a NULL geometry, the output will also be a NULL geometry.

If an error was encountered while creating the result, more information can be retrieved
by calling `error()` on the returned geometry.

.. versionadded:: 3.0
:rtype: QgsGeometry
%End

QgsGeometry interpolate( double distance ) const;
%Docstring
Return interpolated point on line at distance
.. versionadded:: 1.9
Return interpolated point on line at distance.

If the input is a NULL geometry, the output will also be a NULL geometry.

If an error was encountered while creating the result, more information can be retrieved
by calling `error()` on the returned geometry.

.. versionadded:: 2.0
.. seealso:: lineLocatePoint()
:rtype: QgsGeometry
%End
Expand Down Expand Up @@ -841,7 +869,12 @@ Returns the smallest convex polygon that contains all the points in the geometry

QgsGeometry intersection( const QgsGeometry &geometry ) const;
%Docstring
Returns a geometry representing the points shared by this geometry and other.
Returns a geometry representing the points shared by this geometry and other.

If the input is a NULL geometry, the output will also be a NULL geometry.

If an error was encountered while creating the result, more information can be retrieved
by calling `error()` on the returned geometry.
:rtype: QgsGeometry
%End

Expand All @@ -859,6 +892,12 @@ Returns a geometry representing the points shared by this geometry and other.
%Docstring
Returns a geometry representing all the points in this geometry and other (a
union geometry operation).

If the input is a NULL geometry, the output will also be a NULL geometry.

If an error was encountered while creating the result, more information can be retrieved
by calling `error()` on the returned geometry.

.. note::

this operation is not called union since its a reserved word in C++.
Expand All @@ -878,13 +917,23 @@ Returns a geometry representing the points shared by this geometry and other.

QgsGeometry difference( const QgsGeometry &geometry ) const;
%Docstring
Returns a geometry representing the points making up this geometry that do not make up other.
Returns a geometry representing the points making up this geometry that do not make up other.

If the input is a NULL geometry, the output will also be a NULL geometry.

If an error was encountered while creating the result, more information can be retrieved
by calling `error()` on the returned geometry.
:rtype: QgsGeometry
%End

QgsGeometry symDifference( const QgsGeometry &geometry ) const;
%Docstring
Returns a geometry representing the points making up this geometry that do not make up other.
Returns a geometry representing the points making up this geometry that do not make up other.

If the input is a NULL geometry, the output will also be a NULL geometry.

If an error was encountered while creating the result, more information can be retrieved
by calling `error()` on the returned geometry.
:rtype: QgsGeometry
%End

Expand Down Expand Up @@ -1184,6 +1233,15 @@ Ring 0 is outer ring and can't be deleted.
:rtype: int
%End

QString error() const;
%Docstring
Returns an error string referring to an error that was produced
when this geometry was created.

.. versionadded:: 3.0
:rtype: str
%End


static QgsGeometry fromQPointF( QPointF point );
%Docstring
Expand Down
79 changes: 60 additions & 19 deletions src/core/geometry/qgsgeometry.cpp
Expand Up @@ -51,6 +51,7 @@ struct QgsGeometryPrivate
~QgsGeometryPrivate() { delete geometry; }
QAtomicInt ref;
QgsAbstractGeometry *geometry = nullptr;
QString error;
};

QgsGeometry::QgsGeometry(): d( new QgsGeometryPrivate() )
Expand Down Expand Up @@ -1586,10 +1587,13 @@ QgsGeometry QgsGeometry::centroid() const

QgsGeos geos( d->geometry );
QgsPoint centroid;
bool ok = geos.centroid( centroid );
QString error;
bool ok = geos.centroid( centroid, &error );
if ( !ok )
{
return QgsGeometry();
QgsGeometry geom;
geom.d->error = error;
return geom;
}
return QgsGeometry( centroid.clone() );
}
Expand All @@ -1602,13 +1606,17 @@ QgsGeometry QgsGeometry::pointOnSurface() const
}

QgsGeos geos( d->geometry );
QgsPoint pt;
bool ok = geos.pointOnSurface( pt );
std::unique_ptr<QgsPoint>pt( new QgsPoint() );

QString error;
bool ok = geos.pointOnSurface( *pt.get(), &error );
if ( !ok )
{
return QgsGeometry();
QgsGeometry geom;
geom.d->error = error;
return geom;
}
return QgsGeometry( pt.clone() );
return QgsGeometry( pt.release() );
}

QgsGeometry QgsGeometry::poleOfInaccessibility( double precision, double *distanceToBoundary ) const
Expand All @@ -1625,10 +1633,13 @@ QgsGeometry QgsGeometry::convexHull() const
return QgsGeometry();
}
QgsGeos geos( d->geometry );
QgsAbstractGeometry *cHull = geos.convexHull();
QString error;
QgsAbstractGeometry *cHull = geos.convexHull( &error );
if ( !cHull )
{
return QgsGeometry();
QgsGeometry geom;
geom.d->error = error;
return geom;
}
return QgsGeometry( cHull );
}
Expand Down Expand Up @@ -1670,11 +1681,14 @@ QgsGeometry QgsGeometry::subdivide( int maxNodes ) const
geom = segmentizedCopy.get();
}

QString error;
QgsGeos geos( geom );
QgsAbstractGeometry *result = geos.subdivide( maxNodes );
QgsAbstractGeometry *result = geos.subdivide( maxNodes, &error );
if ( !result )
{
return QgsGeometry();
QgsGeometry geom;
geom.d->error = error;
return geom;
}
return QgsGeometry( result );
}
Expand All @@ -1691,10 +1705,13 @@ QgsGeometry QgsGeometry::interpolate( double distance ) const
line = QgsGeometry( d->geometry->boundary() );

QgsGeos geos( line.geometry() );
QgsAbstractGeometry *result = geos.interpolate( distance );
QString error;
QgsAbstractGeometry *result = geos.interpolate( distance, &error );
if ( !result )
{
return QgsGeometry();
QgsGeometry geom;
geom.d->error = error;
return geom;
}
return QgsGeometry( result );
}
Expand Down Expand Up @@ -1780,7 +1797,16 @@ QgsGeometry QgsGeometry::intersection( const QgsGeometry &geometry ) const

QgsGeos geos( d->geometry );

QgsAbstractGeometry *resultGeom = geos.intersection( *( geometry.d->geometry ) );
QString error;
QgsAbstractGeometry *resultGeom = geos.intersection( *( geometry.d->geometry ), &error );

if ( !resultGeom )
{
QgsGeometry geom;
geom.d->error = error;
return geom;
}

return QgsGeometry( resultGeom );
}

Expand All @@ -1792,11 +1818,14 @@ QgsGeometry QgsGeometry::combine( const QgsGeometry &geometry ) const
}

QgsGeos geos( d->geometry );
QString error;

QgsAbstractGeometry *resultGeom = geos.combine( *( geometry.d->geometry ) );
QgsAbstractGeometry *resultGeom = geos.combine( *( geometry.d->geometry ), &error );
if ( !resultGeom )
{
return QgsGeometry();
QgsGeometry geom;
geom.d->error = error;
return geom;
}
return QgsGeometry( resultGeom );
}
Expand Down Expand Up @@ -1827,10 +1856,13 @@ QgsGeometry QgsGeometry::difference( const QgsGeometry &geometry ) const

QgsGeos geos( d->geometry );

QgsAbstractGeometry *resultGeom = geos.difference( *( geometry.d->geometry ) );
QString error;
QgsAbstractGeometry *resultGeom = geos.difference( *( geometry.d->geometry ), &error );
if ( !resultGeom )
{
return QgsGeometry();
QgsGeometry geom;
geom.d->error = error;
return geom;
}
return QgsGeometry( resultGeom );
}
Expand All @@ -1844,10 +1876,14 @@ QgsGeometry QgsGeometry::symDifference( const QgsGeometry &geometry ) const

QgsGeos geos( d->geometry );

QgsAbstractGeometry *resultGeom = geos.symDifference( *( geometry.d->geometry ) );
QString error;

QgsAbstractGeometry *resultGeom = geos.symDifference( *( geometry.d->geometry ), &error );
if ( !resultGeom )
{
return QgsGeometry();
QgsGeometry geom;
geom.d->error = error;
return geom;
}
return QgsGeometry( resultGeom );
}
Expand Down Expand Up @@ -2275,6 +2311,11 @@ int QgsGeometry::vertexNrFromVertexId( QgsVertexId id ) const
return -1;
}

QString QgsGeometry::error() const
{
return d->error;
}

void QgsGeometry::convertPointList( const QList<QgsPointXY> &input, QgsPointSequence &output )
{
output.clear();
Expand Down

0 comments on commit 2b2d5e3

Please sign in to comment.