Skip to content

Commit 2b2d5e3

Browse files
committed
[FEATURE] Give access to geometry errors
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.
1 parent db11185 commit 2b2d5e3

File tree

3 files changed

+199
-33
lines changed

3 files changed

+199
-33
lines changed

python/core/geometry/qgsgeometry.sip

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,12 @@ Returns a simplified version of this geometry using a specified tolerance value
716716
QgsGeometry centroid() const;
717717
%Docstring
718718
Returns the center of mass of a geometry.
719+
720+
If the input is a NULL geometry, the output will also be a NULL geometry.
721+
722+
If an error was encountered while creating the result, more information can be retrieved
723+
by calling `error()` on the returned geometry.
724+
719725
.. note::
720726

721727
for line based geometries, the center point of the line is returned,
@@ -730,6 +736,12 @@ Returns a simplified version of this geometry using a specified tolerance value
730736
Returns a point guaranteed to lie on the surface of a geometry. While the centroid()
731737
of a geometry may be located outside of the geometry itself (e.g., for concave shapes),
732738
the point on surface will always be inside the geometry.
739+
740+
If the input is a NULL geometry, the output will also be a NULL geometry.
741+
742+
If an error was encountered while creating the result, more information can be retrieved
743+
by calling `error()` on the returned geometry.
744+
733745
.. seealso:: centroid()
734746
.. seealso:: poleOfInaccessibility()
735747
:rtype: QgsGeometry
@@ -752,7 +764,12 @@ Returns a simplified version of this geometry using a specified tolerance value
752764

753765
QgsGeometry convexHull() const;
754766
%Docstring
755-
Returns the smallest convex polygon that contains all the points in the geometry.
767+
Returns the smallest convex polygon that contains all the points in the geometry.
768+
769+
If the input is a NULL geometry, the output will also be a NULL geometry.
770+
771+
If an error was encountered while creating the result, more information can be retrieved
772+
by calling `error()` on the returned geometry.
756773
:rtype: QgsGeometry
757774
%End
758775

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

800817
Curved geometries will be segmentized before subdivision.
801818

819+
If the input is a NULL geometry, the output will also be a NULL geometry.
820+
821+
If an error was encountered while creating the result, more information can be retrieved
822+
by calling `error()` on the returned geometry.
823+
802824
.. versionadded:: 3.0
803825
:rtype: QgsGeometry
804826
%End
805827

806828
QgsGeometry interpolate( double distance ) const;
807829
%Docstring
808-
Return interpolated point on line at distance
809-
.. versionadded:: 1.9
830+
Return interpolated point on line at distance.
831+
832+
If the input is a NULL geometry, the output will also be a NULL geometry.
833+
834+
If an error was encountered while creating the result, more information can be retrieved
835+
by calling `error()` on the returned geometry.
836+
837+
.. versionadded:: 2.0
810838
.. seealso:: lineLocatePoint()
811839
:rtype: QgsGeometry
812840
%End
@@ -841,7 +869,12 @@ Returns the smallest convex polygon that contains all the points in the geometry
841869

842870
QgsGeometry intersection( const QgsGeometry &geometry ) const;
843871
%Docstring
844-
Returns a geometry representing the points shared by this geometry and other.
872+
Returns a geometry representing the points shared by this geometry and other.
873+
874+
If the input is a NULL geometry, the output will also be a NULL geometry.
875+
876+
If an error was encountered while creating the result, more information can be retrieved
877+
by calling `error()` on the returned geometry.
845878
:rtype: QgsGeometry
846879
%End
847880

@@ -859,6 +892,12 @@ Returns a geometry representing the points shared by this geometry and other.
859892
%Docstring
860893
Returns a geometry representing all the points in this geometry and other (a
861894
union geometry operation).
895+
896+
If the input is a NULL geometry, the output will also be a NULL geometry.
897+
898+
If an error was encountered while creating the result, more information can be retrieved
899+
by calling `error()` on the returned geometry.
900+
862901
.. note::
863902

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

879918
QgsGeometry difference( const QgsGeometry &geometry ) const;
880919
%Docstring
881-
Returns a geometry representing the points making up this geometry that do not make up other.
920+
Returns a geometry representing the points making up this geometry that do not make up other.
921+
922+
If the input is a NULL geometry, the output will also be a NULL geometry.
923+
924+
If an error was encountered while creating the result, more information can be retrieved
925+
by calling `error()` on the returned geometry.
882926
:rtype: QgsGeometry
883927
%End
884928

885929
QgsGeometry symDifference( const QgsGeometry &geometry ) const;
886930
%Docstring
887-
Returns a geometry representing the points making up this geometry that do not make up other.
931+
Returns a geometry representing the points making up this geometry that do not make up other.
932+
933+
If the input is a NULL geometry, the output will also be a NULL geometry.
934+
935+
If an error was encountered while creating the result, more information can be retrieved
936+
by calling `error()` on the returned geometry.
888937
:rtype: QgsGeometry
889938
%End
890939

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

1236+
QString error() const;
1237+
%Docstring
1238+
Returns an error string referring to an error that was produced
1239+
when this geometry was created.
1240+
1241+
.. versionadded:: 3.0
1242+
:rtype: str
1243+
%End
1244+
11871245

11881246
static QgsGeometry fromQPointF( QPointF point );
11891247
%Docstring

src/core/geometry/qgsgeometry.cpp

Lines changed: 60 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ struct QgsGeometryPrivate
5151
~QgsGeometryPrivate() { delete geometry; }
5252
QAtomicInt ref;
5353
QgsAbstractGeometry *geometry = nullptr;
54+
QString error;
5455
};
5556

5657
QgsGeometry::QgsGeometry(): d( new QgsGeometryPrivate() )
@@ -1586,10 +1587,13 @@ QgsGeometry QgsGeometry::centroid() const
15861587

15871588
QgsGeos geos( d->geometry );
15881589
QgsPoint centroid;
1589-
bool ok = geos.centroid( centroid );
1590+
QString error;
1591+
bool ok = geos.centroid( centroid, &error );
15901592
if ( !ok )
15911593
{
1592-
return QgsGeometry();
1594+
QgsGeometry geom;
1595+
geom.d->error = error;
1596+
return geom;
15931597
}
15941598
return QgsGeometry( centroid.clone() );
15951599
}
@@ -1602,13 +1606,17 @@ QgsGeometry QgsGeometry::pointOnSurface() const
16021606
}
16031607

16041608
QgsGeos geos( d->geometry );
1605-
QgsPoint pt;
1606-
bool ok = geos.pointOnSurface( pt );
1609+
std::unique_ptr<QgsPoint>pt( new QgsPoint() );
1610+
1611+
QString error;
1612+
bool ok = geos.pointOnSurface( *pt.get(), &error );
16071613
if ( !ok )
16081614
{
1609-
return QgsGeometry();
1615+
QgsGeometry geom;
1616+
geom.d->error = error;
1617+
return geom;
16101618
}
1611-
return QgsGeometry( pt.clone() );
1619+
return QgsGeometry( pt.release() );
16121620
}
16131621

16141622
QgsGeometry QgsGeometry::poleOfInaccessibility( double precision, double *distanceToBoundary ) const
@@ -1625,10 +1633,13 @@ QgsGeometry QgsGeometry::convexHull() const
16251633
return QgsGeometry();
16261634
}
16271635
QgsGeos geos( d->geometry );
1628-
QgsAbstractGeometry *cHull = geos.convexHull();
1636+
QString error;
1637+
QgsAbstractGeometry *cHull = geos.convexHull( &error );
16291638
if ( !cHull )
16301639
{
1631-
return QgsGeometry();
1640+
QgsGeometry geom;
1641+
geom.d->error = error;
1642+
return geom;
16321643
}
16331644
return QgsGeometry( cHull );
16341645
}
@@ -1670,11 +1681,14 @@ QgsGeometry QgsGeometry::subdivide( int maxNodes ) const
16701681
geom = segmentizedCopy.get();
16711682
}
16721683

1684+
QString error;
16731685
QgsGeos geos( geom );
1674-
QgsAbstractGeometry *result = geos.subdivide( maxNodes );
1686+
QgsAbstractGeometry *result = geos.subdivide( maxNodes, &error );
16751687
if ( !result )
16761688
{
1677-
return QgsGeometry();
1689+
QgsGeometry geom;
1690+
geom.d->error = error;
1691+
return geom;
16781692
}
16791693
return QgsGeometry( result );
16801694
}
@@ -1691,10 +1705,13 @@ QgsGeometry QgsGeometry::interpolate( double distance ) const
16911705
line = QgsGeometry( d->geometry->boundary() );
16921706

16931707
QgsGeos geos( line.geometry() );
1694-
QgsAbstractGeometry *result = geos.interpolate( distance );
1708+
QString error;
1709+
QgsAbstractGeometry *result = geos.interpolate( distance, &error );
16951710
if ( !result )
16961711
{
1697-
return QgsGeometry();
1712+
QgsGeometry geom;
1713+
geom.d->error = error;
1714+
return geom;
16981715
}
16991716
return QgsGeometry( result );
17001717
}
@@ -1780,7 +1797,16 @@ QgsGeometry QgsGeometry::intersection( const QgsGeometry &geometry ) const
17801797

17811798
QgsGeos geos( d->geometry );
17821799

1783-
QgsAbstractGeometry *resultGeom = geos.intersection( *( geometry.d->geometry ) );
1800+
QString error;
1801+
QgsAbstractGeometry *resultGeom = geos.intersection( *( geometry.d->geometry ), &error );
1802+
1803+
if ( !resultGeom )
1804+
{
1805+
QgsGeometry geom;
1806+
geom.d->error = error;
1807+
return geom;
1808+
}
1809+
17841810
return QgsGeometry( resultGeom );
17851811
}
17861812

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

17941820
QgsGeos geos( d->geometry );
1821+
QString error;
17951822

1796-
QgsAbstractGeometry *resultGeom = geos.combine( *( geometry.d->geometry ) );
1823+
QgsAbstractGeometry *resultGeom = geos.combine( *( geometry.d->geometry ), &error );
17971824
if ( !resultGeom )
17981825
{
1799-
return QgsGeometry();
1826+
QgsGeometry geom;
1827+
geom.d->error = error;
1828+
return geom;
18001829
}
18011830
return QgsGeometry( resultGeom );
18021831
}
@@ -1827,10 +1856,13 @@ QgsGeometry QgsGeometry::difference( const QgsGeometry &geometry ) const
18271856

18281857
QgsGeos geos( d->geometry );
18291858

1830-
QgsAbstractGeometry *resultGeom = geos.difference( *( geometry.d->geometry ) );
1859+
QString error;
1860+
QgsAbstractGeometry *resultGeom = geos.difference( *( geometry.d->geometry ), &error );
18311861
if ( !resultGeom )
18321862
{
1833-
return QgsGeometry();
1863+
QgsGeometry geom;
1864+
geom.d->error = error;
1865+
return geom;
18341866
}
18351867
return QgsGeometry( resultGeom );
18361868
}
@@ -1844,10 +1876,14 @@ QgsGeometry QgsGeometry::symDifference( const QgsGeometry &geometry ) const
18441876

18451877
QgsGeos geos( d->geometry );
18461878

1847-
QgsAbstractGeometry *resultGeom = geos.symDifference( *( geometry.d->geometry ) );
1879+
QString error;
1880+
1881+
QgsAbstractGeometry *resultGeom = geos.symDifference( *( geometry.d->geometry ), &error );
18481882
if ( !resultGeom )
18491883
{
1850-
return QgsGeometry();
1884+
QgsGeometry geom;
1885+
geom.d->error = error;
1886+
return geom;
18511887
}
18521888
return QgsGeometry( resultGeom );
18531889
}
@@ -2275,6 +2311,11 @@ int QgsGeometry::vertexNrFromVertexId( QgsVertexId id ) const
22752311
return -1;
22762312
}
22772313

2314+
QString QgsGeometry::error() const
2315+
{
2316+
return d->error;
2317+
}
2318+
22782319
void QgsGeometry::convertPointList( const QList<QgsPointXY> &input, QgsPointSequence &output )
22792320
{
22802321
output.clear();

0 commit comments

Comments
 (0)