Skip to content

Commit

Permalink
return geom compatibility check in addFeature and changeGeometry
Browse files Browse the repository at this point in the history
  • Loading branch information
luipir committed Sep 26, 2017
1 parent ce11ebb commit c33ae01
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 5 deletions.
48 changes: 45 additions & 3 deletions src/core/qgsvectorlayereditbuffer.cpp
Expand Up @@ -16,6 +16,7 @@

#include "qgsgeometry.h"
#include "qgslogger.h"
#include <qgsmessagelog.h>
#include "qgsvectorlayerundocommand.h"
#include "qgsvectordataprovider.h"
#include "qgsvectorlayer.h"
Expand Down Expand Up @@ -117,14 +118,34 @@ void QgsVectorLayerEditBuffer::updateChangedAttributes( QgsFeature &f )

bool QgsVectorLayerEditBuffer::addFeature( QgsFeature& f )
{
if ( !( L->dataProvider()->capabilities() & QgsVectorDataProvider::AddFeatures ) )
QgsVectorDataProvider* provider = L->dataProvider();

if ( !( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) )
{
return false;
}
if ( L->mUpdatedFields.count() != f.attributes().count() )
return false;

// TODO: check correct geometry type
// if not then try to convert to a compatible geometry type
if ( f.geometry() && f.geometry()->geometry() &&
!f.geometry()->isEmpty() &&
f.geometry()->wkbType() != provider->geometryType() )
{
// check if provider do strict geometry control
// otherwise leave to the commit to rise provider errors
if ( provider->doesStrictFeatureTypeCheck() )
{
QgsGeometry* newGeom = provider->convertToProviderType( f.geometry() );
if ( !newGeom )
{
QgsMessageLog::logMessage( tr( "ERROR: feature not added - geometry type is not compatible with the current layer.", "not added feature" ) );
return false;
}
f.setGeometry( newGeom );
}
}

L->undoStack()->push( new QgsVectorLayerUndoCommandAddFeature( this, f ) );
return true;
Expand All @@ -138,7 +159,8 @@ bool QgsVectorLayerEditBuffer::addFeatures( QgsFeatureList& features )

for ( QgsFeatureList::iterator iter = features.begin(); iter != features.end(); ++iter )
{
addFeature( *iter );
if ( !addFeature( *iter ) )
return false;
}

L->updateExtents();
Expand Down Expand Up @@ -194,9 +216,29 @@ bool QgsVectorLayerEditBuffer::changeGeometry( QgsFeatureId fid, QgsGeometry* ge
else if ( !( L->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeGeometries ) )
return false;


// TODO: check compatible geometry
// if not then try to convert to a compatible geometry type
QgsGeometry* newGeom = nullptr;
QgsVectorDataProvider* provider = L->dataProvider();
if ( geom && geom->geometry() &&
!geom->isEmpty() &&
geom->wkbType() != provider->geometryType() )
{
// check if provider do strict geometry control
// otherwise leave to the commit to rise provider errors
if ( provider->doesStrictFeatureTypeCheck() )
{
newGeom = provider->convertToProviderType( geom );
if ( !newGeom )
{
QgsMessageLog::logMessage( tr( "ERROR: feature %1 not updated - geometry type is not compatible with the layer.", "not added feature" ).arg( fid ) );
return false;
}
}
}

L->undoStack()->push( new QgsVectorLayerUndoCommandChangeGeometry( this, fid, geom ) );
L->undoStack()->push( new QgsVectorLayerUndoCommandChangeGeometry( this, fid, newGeom ? newGeom : geom ) );
return true;
}

Expand Down
4 changes: 2 additions & 2 deletions tests/src/python/test_qgsvectorlayereditbuffer.py
Expand Up @@ -103,8 +103,8 @@ def testAddFeatures(self):
f1 = QgsFeature(layer.fields(), 1)
f1.setGeometry(QgsGeometry.fromMultiPolyline(multiline))
f1.setAttributes(["test", 123])
self.assertTrue(layer.addFeatures([f1]))
self.assertFalse(layer.commitChanges())
self.assertFalse(layer.addFeatures([f1]))
# self.assertFalse(layer.commitChanges())

def testAddMultipleFeatures(self):
# test adding multiple features to an edit buffer
Expand Down

0 comments on commit c33ae01

Please sign in to comment.