Skip to content

Commit

Permalink
Simplify paste by using QgsVectorLayerUtils::makeFeaturesCompatible
Browse files Browse the repository at this point in the history
  • Loading branch information
elpaso committed Oct 6, 2018
1 parent a3bf98d commit dbfbcca
Showing 1 changed file with 16 additions and 51 deletions.
67 changes: 16 additions & 51 deletions src/app/qgisapp.cpp
Expand Up @@ -8597,70 +8597,35 @@ void QgisApp::pasteFromClipboard( QgsMapLayer *destinationLayer )
pasteVectorLayer->beginEditCommand( tr( "Features pasted" ) );
QgsFeatureList features = clipboard()->transformedCopyOf( pasteVectorLayer->crs(), pasteVectorLayer->fields() );
int nTotalFeatures = features.count();

QHash<int, int> remap;
QgsFields fields = clipboard()->fields();
for ( int idx = 0; idx < fields.count(); ++idx )
{
int dst = pasteVectorLayer->fields().lookupField( fields.at( idx ).name() );
if ( dst < 0 )
continue;

remap.insert( idx, dst );
}

QgsExpressionContext context = pasteVectorLayer->createExpressionContext();

int invalidGeometriesCount = 0;
QgsFeatureList compatibleFeatures( QgsVectorLayerUtils::makeFeaturesCompatible( features, pasteVectorLayer ) );
QgsFeatureList newFeatures;
QgsFeatureList::const_iterator featureIt = features.constBegin();
while ( featureIt != features.constEnd() )
// Count collapsed geometries
int invalidGeometriesCount = 0;

for ( const auto &feature : qgis::as_const( compatibleFeatures ) )
{
QgsAttributes srcAttr = featureIt->attributes();
QgsAttributeMap dstAttr;

for ( int src = 0; src < srcAttr.count(); ++src )
{
int dst = remap.value( src, -1 );
if ( dst < 0 )
continue;
QgsGeometry geom = feature.geometry();

dstAttr[ dst ] = srcAttr.at( src );
}

QgsGeometry geom = featureIt->geometry();
bool geomWasInvalid = geom.isEmpty() || geom.isNull( );
if ( featureIt->hasGeometry() )
if ( !( geom.isEmpty() || geom.isNull( ) ) )
{
// convert geometry to match destination layer
QgsWkbTypes::GeometryType destType = pasteVectorLayer->geometryType();
bool destIsMulti = QgsWkbTypes::isMultiType( pasteVectorLayer->wkbType() );
if ( pasteVectorLayer->dataProvider() &&
!pasteVectorLayer->dataProvider()->doesStrictFeatureTypeCheck() )
{
// force destination to multi if provider doesn't do a feature strict check
destIsMulti = true;
}

if ( destType != QgsWkbTypes::UnknownGeometry )
{
QgsGeometry newGeometry = geom.convertToType( destType, destIsMulti );
if ( newGeometry.isNull() )
{
continue;
}
geom = newGeometry;
}
// avoid intersection if enabled in digitize settings
geom.avoidIntersections( QgsProject::instance()->avoidIntersectionsLayers() );
// Count collapsed geometries
if ( geom.isEmpty() || geom.isNull( ) )
invalidGeometriesCount++;
}
if ( ! geomWasInvalid && ( geom.isEmpty() || geom.isNull( ) ) )
invalidGeometriesCount++;

QgsAttributeMap attrMap;
for ( int i = 0; i < feature.fields().count(); i++ )
{
attrMap[i] = feature.attribute( i );
}
// now create new feature using pasted feature as a template. This automatically handles default
// values and field constraints
newFeatures << QgsVectorLayerUtils::createFeature( pasteVectorLayer, geom, dstAttr, &context );
++featureIt;
newFeatures << QgsVectorLayerUtils::createFeature( pasteVectorLayer, geom, attrMap, &context );
}
pasteVectorLayer->addFeatures( newFeatures );
QgsFeatureIds newIds;
Expand Down

0 comments on commit dbfbcca

Please sign in to comment.