Showing with 551 additions and 7 deletions.
  1. +8 −0 python/core/qgsgeometry.sip
  2. +46 −7 src/app/qgisapp.cpp
  3. +336 −0 src/core/qgsgeometry.cpp
  4. +16 −0 src/core/qgsgeometry.h
  5. +145 −0 tests/src/python/test_qgsgeometry.py
8 changes: 8 additions & 0 deletions python/core/qgsgeometry.sip
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,14 @@ class QgsGeometry
*/
QString exportToGeoJSON() const;

/** try to convert the geometry to the requested type
* @param destType the geometry type to be converted to
* @param destMultipart determines if the output geometry will be multipart or not
* @return the converted geometry or NULL pointer if the conversion fails.
* @note added in 2.2
*/
QgsGeometry* convertToType( QGis::GeometryType destType, bool destMultipart = false ) /Factory/;

/* Accessor functions for getting geometry data */

/** return contents of the geometry as a point
Expand Down
53 changes: 46 additions & 7 deletions src/app/qgisapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5580,6 +5580,7 @@ void QgisApp::editPaste( QgsMapLayer *destinationLayer )
{
features = clipboard()->copyOf( pasteVectorLayer->pendingFields() );
}
int nTotalFeatures = features.count();

QHash<int, int> remap;
const QgsFields &fields = clipboard()->fields();
Expand All @@ -5594,10 +5595,11 @@ void QgisApp::editPaste( QgsMapLayer *destinationLayer )
}

int dstAttrCount = pasteVectorLayer->pendingFields().count();
for ( int i = 0; i < features.size(); i++ )

QgsFeatureList::iterator featureIt = features.begin();
while ( featureIt != features.end() )
{
QgsFeature &f = features[i];
const QgsAttributes &srcAttr = f.attributes();
const QgsAttributes &srcAttr = featureIt->attributes();
QgsAttributes dstAttr( dstAttrCount );

for ( int src = 0; src < srcAttr.count(); ++src )
Expand All @@ -5617,17 +5619,54 @@ void QgisApp::editPaste( QgsMapLayer *destinationLayer )
dstAttr[ dst ] = srcAttr[ src ];
}

f.setAttributes( dstAttr );
featureIt->setAttributes( dstAttr );

//avoid intersection if enabled in digitize settings
if ( f.geometry() )
if ( featureIt->geometry() )
{
f.geometry()->avoidIntersections();
// convert geometry to match destination layer
QGis::GeometryType destType = pasteVectorLayer->geometryType();
bool destIsMulti = QGis::isMultiType( pasteVectorLayer->wkbType() );
if ( destType != QGis::UnknownGeometry )
{
QgsGeometry* newGeometry = featureIt->geometry()->convertToType( destType, destIsMulti );
if ( !newGeometry )
{
featureIt = features.erase( featureIt );
continue;
}
featureIt->setGeometry( newGeometry );
}
// avoid intersection if enabled in digitize settings
featureIt->geometry()->avoidIntersections();
}

++featureIt;
}

pasteVectorLayer->addFeatures( features );
pasteVectorLayer->endEditCommand();

int nCopiedFeatures = features.count();
if ( nCopiedFeatures == 0 )
{
messageBar()->pushMessage( tr( "Paste features" ),
tr( "no features could be successfully pasted." ),
QgsMessageBar::WARNING , messageTimeout() );

}
else if ( nCopiedFeatures == nTotalFeatures )
{
messageBar()->pushMessage( tr( "Paste features" ),
tr( "%1 features were successfully pasted." ).arg( nCopiedFeatures ),
QgsMessageBar::INFO , messageTimeout() );
}
else
{
messageBar()->pushMessage( tr( "Paste features" ),
tr( "%1 of %2 features could be successfully pasted." ).arg( nCopiedFeatures ).arg( nTotalFeatures ),
QgsMessageBar::WARNING , messageTimeout() );
}

mMapCanvas->refresh();
}

Expand Down
Loading