Use precision if compiled with geos >= 3.9

This commit is contained in:
Loïc Bartoletti 2021-12-20 09:03:47 +01:00 committed by Nyall Dawson
parent 583cec33df
commit c0c631a9f9
4 changed files with 64 additions and 40 deletions

View File

@ -89,42 +89,42 @@ tests against other geometries.
.. seealso:: :py:func:`geometryChanged`
%End
virtual QgsAbstractGeometry *intersection( const QgsAbstractGeometry *geom, QString *errorMsg = 0 ) const = 0 /Factory/;
virtual QgsAbstractGeometry *intersection( const QgsAbstractGeometry *geom, QString *errorMsg = 0, double gridSize = -1 ) const = 0 /Factory/;
%Docstring
Calculate the intersection of this and ``geom``.
.. versionadded:: 3.0
%End
virtual QgsAbstractGeometry *difference( const QgsAbstractGeometry *geom, QString *errorMsg = 0 ) const = 0 /Factory/;
virtual QgsAbstractGeometry *difference( const QgsAbstractGeometry *geom, QString *errorMsg = 0, double gridSize = -1 ) const = 0 /Factory/;
%Docstring
Calculate the difference of this and ``geom``.
.. versionadded:: 3.0
%End
virtual QgsAbstractGeometry *combine( const QgsAbstractGeometry *geom, QString *errorMsg = 0 ) const = 0 /Factory/;
virtual QgsAbstractGeometry *combine( const QgsAbstractGeometry *geom, QString *errorMsg = 0, double gridSize = -1 ) const = 0 /Factory/;
%Docstring
Calculate the combination of this and ``geom``.
.. versionadded:: 3.0
%End
virtual QgsAbstractGeometry *combine( const QVector<QgsAbstractGeometry *> &geomList, QString *errorMsg ) const = 0 /Factory/;
virtual QgsAbstractGeometry *combine( const QVector<QgsAbstractGeometry *> &geomList, QString *errorMsg, double gridSize = -1 ) const = 0 /Factory/;
%Docstring
Calculate the combination of this and ``geometries``.
.. versionadded:: 3.0
%End
virtual QgsAbstractGeometry *combine( const QVector< QgsGeometry > &geometries, QString *errorMsg = 0 ) const = 0 /Factory/;
virtual QgsAbstractGeometry *combine( const QVector< QgsGeometry > &geometries, QString *errorMsg = 0, double gridSize = -1 ) const = 0 /Factory/;
%Docstring
Calculate the combination of this and ``geometries``.
.. versionadded:: 3.0
%End
virtual QgsAbstractGeometry *symDifference( const QgsAbstractGeometry *geom, QString *errorMsg = 0 ) const = 0 /Factory/;
virtual QgsAbstractGeometry *symDifference( const QgsAbstractGeometry *geom, QString *errorMsg = 0, double gridSize = -1 ) const = 0 /Factory/;
%Docstring
Calculate the symmetric difference of this and ``geom``.
@ -330,7 +330,6 @@ Logs an error ``message`` encountered during an operation.
QgsGeometryEngine( const QgsAbstractGeometry *geometry );
};
/************************************************************************
* This file has been generated automatically from *
* *

View File

@ -110,42 +110,42 @@ class CORE_EXPORT QgsGeometryEngine
*
* \since QGIS 3.0 \a geom is a pointer
*/
virtual QgsAbstractGeometry *intersection( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const = 0 SIP_FACTORY;
virtual QgsAbstractGeometry *intersection( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr, double gridSize = -1 ) const = 0 SIP_FACTORY;
/**
* Calculate the difference of this and \a geom.
*
* \since QGIS 3.0 \a geom is a pointer
*/
virtual QgsAbstractGeometry *difference( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const = 0 SIP_FACTORY;
virtual QgsAbstractGeometry *difference( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr, double gridSize = -1 ) const = 0 SIP_FACTORY;
/**
* Calculate the combination of this and \a geom.
*
* \since QGIS 3.0 \a geom is a pointer
*/
virtual QgsAbstractGeometry *combine( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const = 0 SIP_FACTORY;
virtual QgsAbstractGeometry *combine( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr, double gridSize = -1 ) const = 0 SIP_FACTORY;
/**
* Calculate the combination of this and \a geometries.
*
* \since QGIS 3.0 \a geom is a pointer
*/
virtual QgsAbstractGeometry *combine( const QVector<QgsAbstractGeometry *> &geomList, QString *errorMsg ) const = 0 SIP_FACTORY;
virtual QgsAbstractGeometry *combine( const QVector<QgsAbstractGeometry *> &geomList, QString *errorMsg, double gridSize = -1 ) const = 0 SIP_FACTORY;
/**
* Calculate the combination of this and \a geometries.
*
* \since QGIS 3.0 \a geom is a pointer
*/
virtual QgsAbstractGeometry *combine( const QVector< QgsGeometry > &geometries, QString *errorMsg = nullptr ) const = 0 SIP_FACTORY;
virtual QgsAbstractGeometry *combine( const QVector< QgsGeometry > &geometries, QString *errorMsg = nullptr, double gridSize = -1 ) const = 0 SIP_FACTORY;
/**
* Calculate the symmetric difference of this and \a geom.
*
* \since QGIS 3.0 \a geom is a pointer
*/
virtual QgsAbstractGeometry *symDifference( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const = 0 SIP_FACTORY;
virtual QgsAbstractGeometry *symDifference( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr, double gridSize = -1 ) const = 0 SIP_FACTORY;
virtual QgsAbstractGeometry *buffer( double distance, int segments, QString *errorMsg = nullptr ) const = 0 SIP_FACTORY;
/**
@ -358,4 +358,3 @@ class CORE_EXPORT QgsGeometryEngine
};
#endif // QGSGEOMETRYENGINE_H

View File

@ -277,14 +277,14 @@ void QgsGeos::cacheGeos() const
mGeos = asGeos( mGeometry, mPrecision );
}
QgsAbstractGeometry *QgsGeos::intersection( const QgsAbstractGeometry *geom, QString *errorMsg ) const
QgsAbstractGeometry *QgsGeos::intersection( const QgsAbstractGeometry *geom, QString *errorMsg, double gridSize ) const
{
return overlay( geom, OverlayIntersection, errorMsg ).release();
return overlay( geom, OverlayIntersection, errorMsg, gridSize ).release();
}
QgsAbstractGeometry *QgsGeos::difference( const QgsAbstractGeometry *geom, QString *errorMsg ) const
QgsAbstractGeometry *QgsGeos::difference( const QgsAbstractGeometry *geom, QString *errorMsg, double gridSize ) const
{
return overlay( geom, OverlayDifference, errorMsg ).release();
return overlay( geom, OverlayDifference, errorMsg, gridSize ).release();
}
std::unique_ptr<QgsAbstractGeometry> QgsGeos::clip( const QgsRectangle &rect, QString *errorMsg ) const
@ -313,7 +313,7 @@ std::unique_ptr<QgsAbstractGeometry> QgsGeos::clip( const QgsRectangle &rect, QS
void QgsGeos::subdivideRecursive( const GEOSGeometry *currentPart, int maxNodes, int depth, QgsGeometryCollection *parts, const QgsRectangle &clipRect ) const
void QgsGeos::subdivideRecursive( const GEOSGeometry *currentPart, int maxNodes, int depth, QgsGeometryCollection *parts, const QgsRectangle &clipRect, double gridSize ) const
{
int partType = GEOSGeomTypeId_r( geosinit()->ctxt, currentPart );
if ( qgsDoubleNear( clipRect.width(), 0.0 ) && qgsDoubleNear( clipRect.height(), 0.0 ) )
@ -334,7 +334,7 @@ void QgsGeos::subdivideRecursive( const GEOSGeometry *currentPart, int maxNodes,
int partCount = GEOSGetNumGeometries_r( geosinit()->ctxt, currentPart );
for ( int i = 0; i < partCount; ++i )
{
subdivideRecursive( GEOSGetGeometryN_r( geosinit()->ctxt, currentPart, i ), maxNodes, depth, parts, clipRect );
subdivideRecursive( GEOSGetGeometryN_r( geosinit()->ctxt, currentPart, i ), maxNodes, depth, parts, clipRect, gridSize );
}
return;
}
@ -394,15 +394,15 @@ void QgsGeos::subdivideRecursive( const GEOSGeometry *currentPart, int maxNodes,
if ( clipPart1 )
{
subdivideRecursive( clipPart1.get(), maxNodes, depth, parts, halfClipRect1 );
subdivideRecursive( clipPart1.get(), maxNodes, depth, parts, halfClipRect1, gridSize );
}
if ( clipPart2 )
{
subdivideRecursive( clipPart2.get(), maxNodes, depth, parts, halfClipRect2 );
subdivideRecursive( clipPart2.get(), maxNodes, depth, parts, halfClipRect2, gridSize );
}
}
std::unique_ptr<QgsAbstractGeometry> QgsGeos::subdivide( int maxNodes, QString *errorMsg ) const
std::unique_ptr<QgsAbstractGeometry> QgsGeos::subdivide( int maxNodes, QString *errorMsg, double gridSize ) const
{
if ( !mGeos )
{
@ -415,19 +415,19 @@ std::unique_ptr<QgsAbstractGeometry> QgsGeos::subdivide( int maxNodes, QString *
std::unique_ptr< QgsGeometryCollection > parts = QgsGeometryFactory::createCollectionOfType( mGeometry->wkbType() );
try
{
subdivideRecursive( mGeos.get(), maxNodes, 0, parts.get(), mGeometry->boundingBox() );
subdivideRecursive( mGeos.get(), maxNodes, 0, parts.get(), mGeometry->boundingBox(), gridSize );
}
CATCH_GEOS_WITH_ERRMSG( nullptr )
return std::move( parts );
}
QgsAbstractGeometry *QgsGeos::combine( const QgsAbstractGeometry *geom, QString *errorMsg ) const
QgsAbstractGeometry *QgsGeos::combine( const QgsAbstractGeometry *geom, QString *errorMsg, double gridSize ) const
{
return overlay( geom, OverlayUnion, errorMsg ).release();
return overlay( geom, OverlayUnion, errorMsg, gridSize ).release();
}
QgsAbstractGeometry *QgsGeos::combine( const QVector<QgsAbstractGeometry *> &geomList, QString *errorMsg ) const
QgsAbstractGeometry *QgsGeos::combine( const QVector<QgsAbstractGeometry *> &geomList, QString *errorMsg, double gridSize ) const
{
QVector< GEOSGeometry * > geosGeometries;
geosGeometries.reserve( geomList.size() );
@ -443,7 +443,11 @@ QgsAbstractGeometry *QgsGeos::combine( const QVector<QgsAbstractGeometry *> &geo
try
{
geos::unique_ptr geomCollection = createGeosCollection( GEOS_GEOMETRYCOLLECTION, geosGeometries );
#if ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR>=9 )
geomUnion.reset( GEOSUnaryUnionPrec_r( geosinit()->ctxt, geomCollection.get(), gridSize ) );
#else
geomUnion.reset( GEOSUnaryUnion_r( geosinit()->ctxt, geomCollection.get() ) );
#endif
}
CATCH_GEOS_WITH_ERRMSG( nullptr )
@ -451,7 +455,7 @@ QgsAbstractGeometry *QgsGeos::combine( const QVector<QgsAbstractGeometry *> &geo
return result.release();
}
QgsAbstractGeometry *QgsGeos::combine( const QVector<QgsGeometry> &geomList, QString *errorMsg ) const
QgsAbstractGeometry *QgsGeos::combine( const QVector<QgsGeometry> &geomList, QString *errorMsg, double gridSize ) const
{
QVector< GEOSGeometry * > geosGeometries;
geosGeometries.reserve( geomList.size() );
@ -467,7 +471,13 @@ QgsAbstractGeometry *QgsGeos::combine( const QVector<QgsGeometry> &geomList, QSt
try
{
geos::unique_ptr geomCollection = createGeosCollection( GEOS_GEOMETRYCOLLECTION, geosGeometries );
#if (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR>=9 )
geomUnion.reset( GEOSUnaryUnionPrec_r( geosinit()->ctxt, geomCollection.get(), gridSize ) );
#else
geomUnion.reset( GEOSUnaryUnion_r( geosinit()->ctxt, geomCollection.get() ) );
#endif
}
CATCH_GEOS_WITH_ERRMSG( nullptr )
@ -475,9 +485,9 @@ QgsAbstractGeometry *QgsGeos::combine( const QVector<QgsGeometry> &geomList, QSt
return result.release();
}
QgsAbstractGeometry *QgsGeos::symDifference( const QgsAbstractGeometry *geom, QString *errorMsg ) const
QgsAbstractGeometry *QgsGeos::symDifference( const QgsAbstractGeometry *geom, QString *errorMsg, double gridSize ) const
{
return overlay( geom, OverlaySymDifference, errorMsg ).release();
return overlay( geom, OverlaySymDifference, errorMsg, gridSize ).release();
}
double QgsGeos::distance( const QgsAbstractGeometry *geom, QString *errorMsg ) const
@ -1660,7 +1670,7 @@ geos::unique_ptr QgsGeos::asGeos( const QgsAbstractGeometry *geom, double precis
return nullptr;
}
std::unique_ptr<QgsAbstractGeometry> QgsGeos::overlay( const QgsAbstractGeometry *geom, Overlay op, QString *errorMsg ) const
std::unique_ptr<QgsAbstractGeometry> QgsGeos::overlay( const QgsAbstractGeometry *geom, Overlay op, QString *errorMsg, double gridSize ) const
{
if ( !mGeos || !geom )
{
@ -1679,16 +1689,28 @@ std::unique_ptr<QgsAbstractGeometry> QgsGeos::overlay( const QgsAbstractGeometry
switch ( op )
{
case OverlayIntersection:
#if (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR>=9 )
opGeom.reset( GEOSIntersectionPrec_r( geosinit()->ctxt, mGeos.get(), geosGeom.get(), gridSize ) );
#else
opGeom.reset( GEOSIntersection_r( geosinit()->ctxt, mGeos.get(), geosGeom.get() ) );
#endif
break;
case OverlayDifference:
#if (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR>=9 )
opGeom.reset( GEOSDifferencePrec_r( geosinit()->ctxt, mGeos.get(), geosGeom.get(), gridSize ) );
#else
opGeom.reset( GEOSDifference_r( geosinit()->ctxt, mGeos.get(), geosGeom.get() ) );
#endif
break;
case OverlayUnion:
{
#if (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR>=9 )
geos::unique_ptr unionGeometry( GEOSUnionPrec_r( geosinit()->ctxt, mGeos.get(), geosGeom.get(), gridSize ) );
#else
geos::unique_ptr unionGeometry( GEOSUnion_r( geosinit()->ctxt, mGeos.get(), geosGeom.get() ) );
#endif
if ( unionGeometry && GEOSGeomTypeId_r( geosinit()->ctxt, unionGeometry.get() ) == GEOS_MULTILINESTRING )
{
@ -1704,7 +1726,11 @@ std::unique_ptr<QgsAbstractGeometry> QgsGeos::overlay( const QgsAbstractGeometry
break;
case OverlaySymDifference:
#if (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR>=9 )
opGeom.reset( GEOSSymDifferencePrec_r( geosinit()->ctxt, mGeos.get(), geosGeom.get(), gridSize ) );
#else
opGeom.reset( GEOSSymDifference_r( geosinit()->ctxt, mGeos.get(), geosGeom.get() ) );
#endif
break;
}
return fromGeos( opGeom.get() );

View File

@ -138,8 +138,8 @@ class CORE_EXPORT QgsGeos: public QgsGeometryEngine
void geometryChanged() override;
void prepareGeometry() override;
QgsAbstractGeometry *intersection( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
QgsAbstractGeometry *difference( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
QgsAbstractGeometry *intersection( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr, double gridSize = -1 ) const override;
QgsAbstractGeometry *difference( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr, double gridSize = -1 ) const override;
/**
* Performs a fast, non-robust intersection between the geometry and
@ -161,12 +161,12 @@ class CORE_EXPORT QgsGeos: public QgsGeometryEngine
*
* \since QGIS 3.0
*/
std::unique_ptr< QgsAbstractGeometry > subdivide( int maxNodes, QString *errorMsg = nullptr ) const;
std::unique_ptr< QgsAbstractGeometry > subdivide( int maxNodes, QString *errorMsg = nullptr, double gridSize = -1 ) const;
QgsAbstractGeometry *combine( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
QgsAbstractGeometry *combine( const QVector<QgsAbstractGeometry *> &geomList, QString *errorMsg ) const override;
QgsAbstractGeometry *combine( const QVector< QgsGeometry > &, QString *errorMsg = nullptr ) const override;
QgsAbstractGeometry *symDifference( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
QgsAbstractGeometry *combine( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr, double gridSize = -1 ) const override;
QgsAbstractGeometry *combine( const QVector<QgsAbstractGeometry *> &geomList, QString *errorMsg, double gridSize = -1 ) const override;
QgsAbstractGeometry *combine( const QVector< QgsGeometry > &, QString *errorMsg = nullptr, double gridSize = -1 ) const override;
QgsAbstractGeometry *symDifference( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr, double gridSize = -1 ) const override;
QgsAbstractGeometry *buffer( double distance, int segments, QString *errorMsg = nullptr ) const override;
QgsAbstractGeometry *buffer( double distance, int segments, Qgis::EndCapStyle endCapStyle, Qgis::JoinStyle joinStyle, double miterLimit, QString *errorMsg = nullptr ) const override;
QgsAbstractGeometry *simplify( double tolerance, QString *errorMsg = nullptr ) const override;
@ -622,7 +622,7 @@ class CORE_EXPORT QgsGeos: public QgsGeometryEngine
//geos util functions
void cacheGeos() const;
std::unique_ptr< QgsAbstractGeometry > overlay( const QgsAbstractGeometry *geom, Overlay op, QString *errorMsg = nullptr ) const;
std::unique_ptr< QgsAbstractGeometry > overlay( const QgsAbstractGeometry *geom, Overlay op, QString *errorMsg = nullptr, double gridSize = -1 ) const;
bool relation( const QgsAbstractGeometry *geom, Relation r, QString *errorMsg = nullptr ) const;
static GEOSCoordSequence *createCoordinateSequence( const QgsCurve *curve, double precision, bool forceClose = false );
static std::unique_ptr< QgsLineString > sequenceToLinestring( const GEOSGeometry *geos, bool hasZ, bool hasM );
@ -652,7 +652,7 @@ class CORE_EXPORT QgsGeos: public QgsGeometryEngine
static int lineContainedInLine( const GEOSGeometry *line1, const GEOSGeometry *line2 );
static int pointContainedInLine( const GEOSGeometry *point, const GEOSGeometry *line );
static int geomDigits( const GEOSGeometry *geom );
void subdivideRecursive( const GEOSGeometry *currentPart, int maxNodes, int depth, QgsGeometryCollection *parts, const QgsRectangle &clipRect ) const;
void subdivideRecursive( const GEOSGeometry *currentPart, int maxNodes, int depth, QgsGeometryCollection *parts, const QgsRectangle &clipRect, double gridSize = -1 ) const;
};
/// @cond PRIVATE