Skip to content

Commit

Permalink
Make convertToProviderType static to bypass thread check
Browse files Browse the repository at this point in the history
  • Loading branch information
elpaso committed Sep 30, 2023
1 parent d98fb4d commit 3cac4c0
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 38 deletions.
14 changes: 14 additions & 0 deletions python/core/auto_generated/vector/qgsvectordataprovider.sip.in
Expand Up @@ -703,6 +703,10 @@ For general debug information use :py:func:`QgsMessageLog.logMessage()` instead.
%Docstring
Converts the geometry to the provider type if possible / necessary

.. note::

The default implementation simply calls the static version of this function.

:return: the converted geometry or ``None`` if no conversion was necessary or possible
%End

Expand All @@ -721,6 +725,16 @@ Gets this providers encoding
.. versionadded:: 3.0
%End

static QgsGeometry convertToProviderType( const QgsGeometry &geometry, Qgis::WkbType providerGeometryType );
%Docstring
Converts the ``geometry`` to the provider geometry type ``providerGeometryType`` if possible / necessary

:return: the converted geometry or ``None`` if no conversion was necessary or possible

.. versionadded:: 3.34
%End


};

QFlags<QgsVectorDataProvider::Capability> operator|(QgsVectorDataProvider::Capability f1, QFlags<QgsVectorDataProvider::Capability> f2);
Expand Down
78 changes: 42 additions & 36 deletions src/core/vector/qgsvectordataprovider.cpp
Expand Up @@ -898,31 +898,52 @@ QgsGeometry QgsVectorDataProvider::convertToProviderType( const QgsGeometry &geo
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS

if ( geom.isNull() )
// Call the static version
return QgsVectorDataProvider::convertToProviderType( geom, wkbType() );

}

void QgsVectorDataProvider::setNativeTypes( const QList<NativeType> &nativeTypes )
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS

mNativeTypes = nativeTypes;
}

QTextCodec *QgsVectorDataProvider::textEncoding() const
{
// non fatal for now -- the "rasterize" processing algorithm is not thread safe and calls this
QGIS_PROTECT_QOBJECT_THREAD_ACCESS_NON_FATAL

return mEncoding;
}

QgsGeometry QgsVectorDataProvider::convertToProviderType( const QgsGeometry &geometry, Qgis::WkbType providerGeometryType )
{
if ( geometry.isNull() )
{
return QgsGeometry();
}

const QgsAbstractGeometry *geometry = geom.constGet();
if ( !geometry )
const QgsAbstractGeometry *convertedGeometry = geometry.constGet();
if ( !convertedGeometry )
{
return QgsGeometry();
}

const Qgis::WkbType providerGeomType = wkbType();

//geom is already in the provider geometry type
if ( geometry->wkbType() == providerGeomType )
if ( convertedGeometry->wkbType() == providerGeometryType )
{
return QgsGeometry();
}

std::unique_ptr< QgsAbstractGeometry > outputGeom;

//convert compoundcurve to circularstring (possible if compoundcurve consists of one circular string)
if ( QgsWkbTypes::flatType( providerGeomType ) == Qgis::WkbType::CircularString )
if ( QgsWkbTypes::flatType( providerGeometryType ) == Qgis::WkbType::CircularString )
{
QgsCompoundCurve *compoundCurve = qgsgeometry_cast<QgsCompoundCurve *>( geometry );
QgsCompoundCurve *compoundCurve = qgsgeometry_cast<QgsCompoundCurve *>( convertedGeometry );
if ( compoundCurve )
{
if ( compoundCurve->nCurves() == 1 )
Expand All @@ -937,49 +958,49 @@ QgsGeometry QgsVectorDataProvider::convertToProviderType( const QgsGeometry &geo
}

//convert to curved type if necessary
if ( !QgsWkbTypes::isCurvedType( geometry->wkbType() ) && QgsWkbTypes::isCurvedType( providerGeomType ) )
if ( !QgsWkbTypes::isCurvedType( convertedGeometry->wkbType() ) && QgsWkbTypes::isCurvedType( providerGeometryType ) )
{
QgsAbstractGeometry *curveGeom = outputGeom ? outputGeom->toCurveType() : geometry->toCurveType();
QgsAbstractGeometry *curveGeom = outputGeom ? outputGeom->toCurveType() : convertedGeometry->toCurveType();
if ( curveGeom )
{
outputGeom.reset( curveGeom );
}
}

//convert to linear type from curved type
if ( QgsWkbTypes::isCurvedType( geometry->wkbType() ) && !QgsWkbTypes::isCurvedType( providerGeomType ) )
if ( QgsWkbTypes::isCurvedType( convertedGeometry->wkbType() ) && !QgsWkbTypes::isCurvedType( providerGeometryType ) )
{
QgsAbstractGeometry *segmentizedGeom = outputGeom ? outputGeom->segmentize() : geometry->segmentize();
QgsAbstractGeometry *segmentizedGeom = outputGeom ? outputGeom->segmentize() : convertedGeometry->segmentize();
if ( segmentizedGeom )
{
outputGeom.reset( segmentizedGeom );
}
}

//convert to multitype if necessary
if ( QgsWkbTypes::isMultiType( providerGeomType ) && !QgsWkbTypes::isMultiType( geometry->wkbType() ) )
if ( QgsWkbTypes::isMultiType( providerGeometryType ) && !QgsWkbTypes::isMultiType( convertedGeometry->wkbType() ) )
{
std::unique_ptr< QgsAbstractGeometry > collGeom( QgsGeometryFactory::geomFromWkbType( providerGeomType ) );
std::unique_ptr< QgsAbstractGeometry > collGeom( QgsGeometryFactory::geomFromWkbType( providerGeometryType ) );
QgsGeometryCollection *geomCollection = qgsgeometry_cast<QgsGeometryCollection *>( collGeom.get() );
if ( geomCollection )
{
if ( geomCollection->addGeometry( outputGeom ? outputGeom->clone() : geometry->clone() ) )
if ( geomCollection->addGeometry( outputGeom ? outputGeom->clone() : convertedGeometry->clone() ) )
{
outputGeom.reset( collGeom.release() );
}
}
}

//convert to single type if there's a single part of compatible type
if ( !QgsWkbTypes::isMultiType( providerGeomType ) && QgsWkbTypes::isMultiType( geometry->wkbType() ) )
if ( !QgsWkbTypes::isMultiType( providerGeometryType ) && QgsWkbTypes::isMultiType( convertedGeometry->wkbType() ) )
{
const QgsGeometryCollection *collection = qgsgeometry_cast<const QgsGeometryCollection *>( geometry );
const QgsGeometryCollection *collection = qgsgeometry_cast<const QgsGeometryCollection *>( convertedGeometry );
if ( collection )
{
if ( collection->numGeometries() == 1 )
{
const QgsAbstractGeometry *firstGeom = collection->geometryN( 0 );
if ( firstGeom && firstGeom->wkbType() == providerGeomType )
if ( firstGeom && firstGeom->wkbType() == providerGeometryType )
{
outputGeom.reset( firstGeom->clone() );
}
Expand All @@ -988,20 +1009,20 @@ QgsGeometry QgsVectorDataProvider::convertToProviderType( const QgsGeometry &geo
}

//set z/m types
if ( QgsWkbTypes::hasZ( providerGeomType ) )
if ( QgsWkbTypes::hasZ( providerGeometryType ) )
{
if ( !outputGeom )
{
outputGeom.reset( geometry->clone() );
outputGeom.reset( convertedGeometry->clone() );
}
outputGeom->addZValue();
}

if ( QgsWkbTypes::hasM( providerGeomType ) )
if ( QgsWkbTypes::hasM( providerGeometryType ) )
{
if ( !outputGeom )
{
outputGeom.reset( geometry->clone() );
outputGeom.reset( convertedGeometry->clone() );
}
outputGeom->addMValue();
}
Expand All @@ -1014,21 +1035,6 @@ QgsGeometry QgsVectorDataProvider::convertToProviderType( const QgsGeometry &geo
return QgsGeometry();
}

void QgsVectorDataProvider::setNativeTypes( const QList<NativeType> &nativeTypes )
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS

mNativeTypes = nativeTypes;
}

QTextCodec *QgsVectorDataProvider::textEncoding() const
{
// non fatal for now -- the "rasterize" processing algorithm is not thread safe and calls this
QGIS_PROTECT_QOBJECT_THREAD_ACCESS_NON_FATAL

return mEncoding;
}

bool QgsVectorDataProvider::cancelReload()
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS
Expand Down
9 changes: 9 additions & 0 deletions src/core/vector/qgsvectordataprovider.h
Expand Up @@ -680,6 +680,7 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider, public QgsFeat

/**
* Converts the geometry to the provider type if possible / necessary
* \note The default implementation simply calls the static version of this function.
* \returns the converted geometry or NULLPTR if no conversion was necessary or possible
*/
QgsGeometry convertToProviderType( const QgsGeometry &geom ) const;
Expand All @@ -699,6 +700,14 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider, public QgsFeat
*/
QTextCodec *textEncoding() const;

/**
* Converts the \a geometry to the provider geometry type \a providerGeometryType if possible / necessary
* \returns the converted geometry or NULLPTR if no conversion was necessary or possible
* \since QGIS 3.34
*/
static QgsGeometry convertToProviderType( const QgsGeometry &geometry, Qgis::WkbType providerGeometryType );


private:
mutable bool mCacheMinMaxDirty = true;
mutable QMap<int, QVariant> mCacheMinValues, mCacheMaxValues;
Expand Down
2 changes: 1 addition & 1 deletion src/providers/postgres/qgspostgresprovider.cpp
Expand Up @@ -3312,7 +3312,7 @@ void QgsPostgresProvider::appendGeomParam( const QgsGeometry &geom, QStringList

QString param;

QgsGeometry convertedGeom( convertToProviderType( geom ) );
const QgsGeometry convertedGeom( convertToProviderType( geom, wkbType() ) );
QByteArray wkb( !convertedGeom.isNull() ? convertedGeom.asWkb() : geom.asWkb() );
const unsigned char *buf = reinterpret_cast< const unsigned char * >( wkb.constData() );
int wkbSize = wkb.length();
Expand Down
2 changes: 1 addition & 1 deletion src/providers/spatialite/qgsspatialiteprovider.cpp
Expand Up @@ -4231,7 +4231,7 @@ bool QgsSpatiaLiteProvider::addFeatures( QgsFeatureList &flist, Flags flags )
{
unsigned char *wkb = nullptr;
int wkb_size;
const QgsGeometry convertedGeom( convertToProviderType( feature->geometry() ) );
const QgsGeometry convertedGeom( QgsVectorDataProvider::convertToProviderType( feature->geometry(), wkbType() ) );
const QByteArray featureWkb{ !convertedGeom.isNull() ? convertedGeom.asWkb() : feature->geometry().asWkb() };
convertFromGeosWKB( reinterpret_cast<const unsigned char *>( featureWkb.constData() ),
featureWkb.length(),
Expand Down

0 comments on commit 3cac4c0

Please sign in to comment.