Skip to content
Permalink
Browse files

makeFeatureCompatible on a single input feature

  • Loading branch information
elpaso committed Sep 25, 2018
1 parent 7e8592b commit 8d82ce86cc9485bc5f545fc0379f64d3a423a0ea
@@ -177,8 +177,26 @@ are padded with NULL values to match the required length).
.. versionadded:: 3.4
%End

static const QgsFeatureList makeFeatureCompatible( const QgsFeature &feature, const QgsVectorLayer &layer );
%Docstring
Converts input ``feature`` to be compatible with the given ``layer``.

This function returns a new list of transformed features compatible with the input
layer, note that the number of features returned might be greater than one.

The following operations will be performed to convert the input features:
- convert single geometries to multi part
- drop additional attributes
- drop geometry if layer is geometry-less
- add missing attribute fields
- add back M/Z values (initialized to 0)
- drop Z/M
- convert multi part geometries to single part

.. versionadded:: 3.4
%End

static QgsFeatureList makeFeaturesCompatible( const QgsFeatureList &features, const QgsVectorLayer &layer );
static const QgsFeatureList makeFeaturesCompatible( const QgsFeatureList &features, const QgsVectorLayer &layer );
%Docstring
Converts input ``features`` to be compatible with the given ``layer``.

@@ -561,31 +561,30 @@ void QgsVectorLayerUtils::matchAttributesToFields( QgsFeature &feature, const Qg
}
}

QgsFeatureList QgsVectorLayerUtils::makeFeaturesCompatible( const QgsFeatureList &features, const QgsVectorLayer &layer )
const QgsFeatureList QgsVectorLayerUtils::makeFeatureCompatible( const QgsFeature &feature, const QgsVectorLayer &layer )
{
QgsWkbTypes::Type inputWkbType( layer.wkbType( ) );
QgsFeatureList resultFeatures;
for ( const QgsFeature &f : features )
QgsFeature newF( feature );
// Fix attributes
QgsVectorLayerUtils::matchAttributesToFields( newF, layer.fields( ) );
// Does geometry need tranformations?
QgsWkbTypes::GeometryType newFGeomType( QgsWkbTypes::geometryType( newF.geometry().wkbType() ) );
bool newFHasGeom = newFGeomType !=
QgsWkbTypes::GeometryType::UnknownGeometry &&
newFGeomType != QgsWkbTypes::GeometryType::NullGeometry;
bool layerHasGeom = inputWkbType !=
QgsWkbTypes::Type::NoGeometry &&
inputWkbType != QgsWkbTypes::Type::Unknown;
// Drop geometry if layer is geometry-less
if ( newFHasGeom && ! layerHasGeom )
{
QgsFeature _f = QgsFeature( layer.fields() );
_f.setAttributes( newF.attributes() );
resultFeatures.append( _f );
}
else
{
QgsFeature newF( f );
// Fix attributes
QgsVectorLayerUtils::matchAttributesToFields( newF, layer.fields( ) );
// Does geometry need tranformations?
QgsWkbTypes::GeometryType newFGeomType( QgsWkbTypes::geometryType( newF.geometry().wkbType() ) );
bool newFHasGeom = newFGeomType !=
QgsWkbTypes::GeometryType::UnknownGeometry &&
newFGeomType != QgsWkbTypes::GeometryType::NullGeometry;
bool layerHasGeom = inputWkbType !=
QgsWkbTypes::Type::NoGeometry &&
inputWkbType != QgsWkbTypes::Type::Unknown;
// Drop geometry if layer is geometry-less
if ( newFHasGeom && ! layerHasGeom )
{
QgsFeature _f = QgsFeature( layer.fields() );
_f.setAttributes( newF.attributes() );
resultFeatures.append( _f );
continue; // Skip the rest
}
// Geometry need fixing
if ( newFHasGeom && layerHasGeom && newF.geometry().wkbType() != inputWkbType )
{
@@ -627,15 +626,15 @@ QgsFeatureList QgsVectorLayerUtils::makeFeaturesCompatible( const QgsFeatureList
{
QgsGeometry newGeom( newF.geometry( ) );
const QgsGeometryCollection *parts( static_cast< const QgsGeometryCollection * >( newGeom.constGet() ) );
QgsAttributeMap attrMap;
for ( int j = 0; j < newF.fields().count(); j++ )
{
attrMap[j] = newF.attribute( j );
}
for ( int i = 0; i < parts->partCount( ); i++ )
{
QgsGeometry g( parts->geometryN( i )->clone() );
QgsAttributeMap attrMap;
for ( int j = 0; j < newF.fields().count(); j++ )
{
attrMap[j] = newF.attribute( j );
}
QgsFeature _f( QgsVectorLayerUtils::createFeature( &layer, g, attrMap ) );
QgsFeature _f( createFeature( &layer, g, attrMap ) );
resultFeatures.append( _f );
}
}
@@ -649,7 +648,20 @@ QgsFeatureList QgsVectorLayerUtils::makeFeaturesCompatible( const QgsFeatureList
resultFeatures.append( newF );
}
}
return resultFeatures;
return resultFeatures;
}

const QgsFeatureList QgsVectorLayerUtils::makeFeaturesCompatible( const QgsFeatureList &features, const QgsVectorLayer &layer )
{
QgsFeatureList resultFeatures;
for ( const QgsFeature &f : features )
{
for ( const auto &_f : makeFeatureCompatible( f, layer ) )
{
resultFeatures.append( _f );
}
}
return resultFeatures;
}

QList<QgsVectorLayer *> QgsVectorLayerUtils::QgsDuplicateFeatureContext::layers() const
@@ -188,6 +188,24 @@ class CORE_EXPORT QgsVectorLayerUtils
*/
static void matchAttributesToFields( QgsFeature &feature, const QgsFields &fields );

/**
* Converts input \a feature to be compatible with the given \a layer.
*
* This function returns a new list of transformed features compatible with the input
* layer, note that the number of features returned might be greater than one.
*
* The following operations will be performed to convert the input features:
* - convert single geometries to multi part
* - drop additional attributes
* - drop geometry if layer is geometry-less
* - add missing attribute fields
* - add back M/Z values (initialized to 0)
* - drop Z/M
* - convert multi part geometries to single part
*
* \since QGIS 3.4
*/
static const QgsFeatureList makeFeatureCompatible( const QgsFeature &feature, const QgsVectorLayer &layer );

/**
* Converts input \a features to be compatible with the given \a layer.
@@ -207,7 +225,7 @@ class CORE_EXPORT QgsVectorLayerUtils
*
* \since QGIS 3.4
*/
static QgsFeatureList makeFeaturesCompatible( const QgsFeatureList &features, const QgsVectorLayer &layer );
static const QgsFeatureList makeFeaturesCompatible( const QgsFeatureList &features, const QgsVectorLayer &layer );

};

0 comments on commit 8d82ce8

Please sign in to comment.
You can’t perform that action at this time.