Skip to content

Commit c3fdaa9

Browse files
committedOct 13, 2017
Some safer memory management for geos
1 parent 88e1360 commit c3fdaa9

File tree

6 files changed

+61
-29
lines changed

6 files changed

+61
-29
lines changed
 

‎doc/api_break.dox

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,6 +1288,7 @@ QgsGeometryEngine {#qgis_api_break_3_0_QgsGeometryEngine}
12881288
- `QgsAbstractGeometry&` parameters have been changed to `QgsAbstractGeometry*` (Affects C++ only)
12891289
- `centroid()` returns the point instead of working on a parameter. The return value is a `nullptr` when `false` has been returned in the past.
12901290
- `pointOnSurface()` returns the point instead of working on a parameter. The return value is a `nullptr` when `false` has been returned in the past.
1291+
- splitGeometry() now returns new geometries as QgsGeometry, instead of QgsAbstractGeometry
12911292

12921293

12931294
QgsGeometrySimplifier {#qgis_api_break_3_0_QgsGeometrySimplifier}

‎python/core/geometry/qgsgeometryengine.sip

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,21 @@ class QgsGeometryEngine
3737
virtual ~QgsGeometryEngine();
3838

3939
virtual void geometryChanged() = 0;
40+
%Docstring
41+
Should be called whenever the geometry associated with the engine
42+
has been modified and the engine must be updated to suit.
43+
%End
44+
4045
virtual void prepareGeometry() = 0;
46+
%Docstring
47+
Prepares the geometry, so that subsequent calls to spatial relation methods
48+
are much faster.
49+
50+
This should be called for any geometry which is used for multiple relation
51+
tests against other geometries.
52+
53+
.. seealso:: geometryChanged()
54+
%End
4155

4256
virtual QgsAbstractGeometry *intersection( const QgsAbstractGeometry *geom, QString *errorMsg = 0 ) const = 0 /Factory/;
4357
%Docstring
@@ -244,10 +258,17 @@ class QgsGeometryEngine
244258
%End
245259

246260
virtual QgsGeometryEngine::EngineOperationResult splitGeometry( const QgsLineString &splitLine,
247-
QList<QgsAbstractGeometry *> &newGeometries,
261+
QList<QgsGeometry > &newGeometries /Out/,
248262
bool topological,
249263
QgsPointSequence &topologyTestPoints, QString *errorMsg = 0 ) const;
250264
%Docstring
265+
Splits this geometry according to a given line.
266+
\param splitLine the line that splits the geometry
267+
\param[out] newGeometries list of new geometries that have been created with the split
268+
\param topological true if topological editing is enabled
269+
\param[out] topologyTestPoints points that need to be tested for topological completeness in the dataset
270+
\param[out] errorMsg error messages emitted, if any
271+
:return: 0 in case of success, 1 if geometry has not been split, error else
251272
:rtype: QgsGeometryEngine.EngineOperationResult
252273
%End
253274

‎src/core/geometry/qgsgeometry.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,7 @@ QgsGeometry::OperationResult QgsGeometry::splitGeometry( const QList<QgsPointXY>
797797
return InvalidBaseGeometry;
798798
}
799799

800-
QList<QgsAbstractGeometry *> newGeoms;
800+
QList<QgsGeometry > newGeoms;
801801
QgsLineString splitLineString( splitLine );
802802
QgsPointSequence tp;
803803

@@ -807,13 +807,9 @@ QgsGeometry::OperationResult QgsGeometry::splitGeometry( const QList<QgsPointXY>
807807

808808
if ( result == QgsGeometryEngine::Success )
809809
{
810-
reset( std::unique_ptr< QgsAbstractGeometry >( newGeoms.takeFirst() ) );
810+
*this = newGeoms.takeAt( 0 );
811811

812-
newGeometries.clear();
813-
for ( QgsAbstractGeometry *part : qgis::as_const( newGeoms ) )
814-
{
815-
newGeometries.push_back( QgsGeometry( part ) );
816-
}
812+
newGeometries = newGeoms;
817813
}
818814

819815
convertPointList( tp, topologyTestPoints );
@@ -2252,7 +2248,7 @@ QgsGeometry QgsGeometry::polygonize( const QList<QgsGeometry> &geometryList )
22522248
{
22532249
QgsGeos geos( nullptr );
22542250

2255-
QList<QgsAbstractGeometry *> geomV2List;
2251+
QList<const QgsAbstractGeometry *> geomV2List;
22562252
for ( const QgsGeometry &g : geometryList )
22572253
{
22582254
if ( !( g.isNull() ) )

‎src/core/geometry/qgsgeometryengine.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,21 @@ class CORE_EXPORT QgsGeometryEngine
5353

5454
virtual ~QgsGeometryEngine() = default;
5555

56+
/**
57+
* Should be called whenever the geometry associated with the engine
58+
* has been modified and the engine must be updated to suit.
59+
*/
5660
virtual void geometryChanged() = 0;
61+
62+
/**
63+
* Prepares the geometry, so that subsequent calls to spatial relation methods
64+
* are much faster.
65+
*
66+
* This should be called for any geometry which is used for multiple relation
67+
* tests against other geometries.
68+
*
69+
* \see geometryChanged()
70+
*/
5771
virtual void prepareGeometry() = 0;
5872

5973
/**
@@ -213,8 +227,17 @@ class CORE_EXPORT QgsGeometryEngine
213227
*/
214228
virtual bool isSimple( QString *errorMsg = nullptr ) const = 0;
215229

230+
/**
231+
* Splits this geometry according to a given line.
232+
* \param splitLine the line that splits the geometry
233+
* \param[out] newGeometries list of new geometries that have been created with the split
234+
* \param topological true if topological editing is enabled
235+
* \param[out] topologyTestPoints points that need to be tested for topological completeness in the dataset
236+
* \param[out] errorMsg error messages emitted, if any
237+
* \returns 0 in case of success, 1 if geometry has not been split, error else
238+
*/
216239
virtual QgsGeometryEngine::EngineOperationResult splitGeometry( const QgsLineString &splitLine,
217-
QList<QgsAbstractGeometry *> &newGeometries,
240+
QList<QgsGeometry > &newGeometries SIP_OUT,
218241
bool topological,
219242
QgsPointSequence &topologyTestPoints, QString *errorMsg = nullptr ) const
220243
{

‎src/core/geometry/qgsgeos.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ double QgsGeos::length( QString *errorMsg ) const
563563
}
564564

565565
QgsGeometryEngine::EngineOperationResult QgsGeos::splitGeometry( const QgsLineString &splitLine,
566-
QList<QgsAbstractGeometry *> &newGeometries,
566+
QList<QgsGeometry> &newGeometries,
567567
bool topological,
568568
QgsPointSequence &topologyTestPoints,
569569
QString *errorMsg ) const
@@ -767,7 +767,7 @@ GEOSGeometry *QgsGeos::linePointDifference( GEOSGeometry *GEOSsplitPoint ) const
767767
return asGeos( &lines, mPrecision );
768768
}
769769

770-
QgsGeometryEngine::EngineOperationResult QgsGeos::splitLinearGeometry( GEOSGeometry *splitLine, QList<QgsAbstractGeometry *> &newGeometries ) const
770+
QgsGeometryEngine::EngineOperationResult QgsGeos::splitLinearGeometry( GEOSGeometry *splitLine, QList<QgsGeometry> &newGeometries ) const
771771
{
772772
if ( !splitLine )
773773
return InvalidInput;
@@ -815,15 +815,15 @@ QgsGeometryEngine::EngineOperationResult QgsGeos::splitLinearGeometry( GEOSGeome
815815

816816
for ( int i = 0; i < lineGeoms.size(); ++i )
817817
{
818-
newGeometries << fromGeos( lineGeoms[i] ).release();
818+
newGeometries << QgsGeometry( fromGeos( lineGeoms[i] ) );
819819
GEOSGeom_destroy_r( geosinit.ctxt, lineGeoms[i] );
820820
}
821821

822822
GEOSGeom_destroy_r( geosinit.ctxt, splitGeom );
823823
return Success;
824824
}
825825

826-
QgsGeometryEngine::EngineOperationResult QgsGeos::splitPolygonGeometry( GEOSGeometry *splitLine, QList<QgsAbstractGeometry *> &newGeometries ) const
826+
QgsGeometryEngine::EngineOperationResult QgsGeos::splitPolygonGeometry( GEOSGeometry *splitLine, QList<QgsGeometry> &newGeometries ) const
827827
{
828828
if ( !splitLine )
829829
return InvalidInput;
@@ -917,7 +917,7 @@ QgsGeometryEngine::EngineOperationResult QgsGeos::splitPolygonGeometry( GEOSGeom
917917
}
918918

919919
for ( i = 0; i < testedGeometries.size(); ++i )
920-
newGeometries << fromGeos( testedGeometries[i] ).release();
920+
newGeometries << QgsGeometry( fromGeos( testedGeometries[i] ) );
921921

922922
return Success;
923923
}
@@ -2172,7 +2172,7 @@ double QgsGeos::lineLocatePoint( const QgsPoint &point, QString *errorMsg ) cons
21722172
return distance;
21732173
}
21742174

2175-
QgsGeometry QgsGeos::polygonize( const QList<QgsAbstractGeometry *> &geometries, QString *errorMsg )
2175+
QgsGeometry QgsGeos::polygonize( const QList<const QgsAbstractGeometry *> &geometries, QString *errorMsg )
21762176
{
21772177
GEOSGeometry **const lineGeosGeometries = new GEOSGeometry*[ geometries.size()];
21782178
int validLines = 0;

‎src/core/geometry/qgsgeos.h

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ class CORE_EXPORT QgsGeos: public QgsGeometryEngine
4545
QgsGeos( const QgsAbstractGeometry *geometry, double precision = 0 );
4646
~QgsGeos();
4747

48-
//! Removes caches
4948
void geometryChanged() override;
5049
void prepareGeometry() override;
5150

@@ -138,16 +137,8 @@ class CORE_EXPORT QgsGeos: public QgsGeometryEngine
138137
bool isEmpty( QString *errorMsg = nullptr ) const override;
139138
bool isSimple( QString *errorMsg = nullptr ) const override;
140139

141-
/**
142-
* Splits this geometry according to a given line.
143-
\param splitLine the line that splits the geometry
144-
\param[out] newGeometries list of new geometries that have been created with the split
145-
\param topological true if topological editing is enabled
146-
\param[out] topologyTestPoints points that need to be tested for topological completeness in the dataset
147-
\param[out] errorMsg error messages emitted, if any
148-
\returns 0 in case of success, 1 if geometry has not been split, error else*/
149140
EngineOperationResult splitGeometry( const QgsLineString &splitLine,
150-
QList<QgsAbstractGeometry *> &newGeometries,
141+
QList< QgsGeometry > &newGeometries,
151142
bool topological,
152143
QgsPointSequence &topologyTestPoints,
153144
QString *errorMsg = nullptr ) const override;
@@ -226,7 +217,7 @@ class CORE_EXPORT QgsGeos: public QgsGeometryEngine
226217
* An empty geometry will be returned in the case of errors.
227218
* \since QGIS 3.0
228219
*/
229-
static QgsGeometry polygonize( const QList<QgsAbstractGeometry *> &geometries, QString *errorMsg = nullptr );
220+
static QgsGeometry polygonize( const QList< const QgsAbstractGeometry *> &geometries, QString *errorMsg = nullptr );
230221

231222
/**
232223
* Creates a Voronoi diagram for the nodes contained within the geometry.
@@ -315,8 +306,8 @@ class CORE_EXPORT QgsGeos: public QgsGeometryEngine
315306
//utils for geometry split
316307
bool topologicalTestPointsSplit( const GEOSGeometry *splitLine, QgsPointSequence &testPoints, QString *errorMsg = nullptr ) const;
317308
GEOSGeometry *linePointDifference( GEOSGeometry *GEOSsplitPoint ) const;
318-
EngineOperationResult splitLinearGeometry( GEOSGeometry *splitLine, QList<QgsAbstractGeometry *> &newGeometries ) const;
319-
EngineOperationResult splitPolygonGeometry( GEOSGeometry *splitLine, QList<QgsAbstractGeometry *> &newGeometries ) const;
309+
EngineOperationResult splitLinearGeometry( GEOSGeometry *splitLine, QList<QgsGeometry > &newGeometries ) const;
310+
EngineOperationResult splitPolygonGeometry( GEOSGeometry *splitLine, QList<QgsGeometry > &newGeometries ) const;
320311

321312
//utils for reshape
322313
static GEOSGeometry *reshapeLine( const GEOSGeometry *line, const GEOSGeometry *reshapeLineGeos, double precision );

0 commit comments

Comments
 (0)
Please sign in to comment.