Skip to content
Permalink
Browse files

return geom compatibility check in addFeature and changeGeometry

  • Loading branch information
luipir committed Sep 26, 2017
1 parent ce11ebb commit c33ae017320149e7469b815b27ad9977f7da9f9b
Showing with 47 additions and 5 deletions.
  1. +45 −3 src/core/qgsvectorlayereditbuffer.cpp
  2. +2 −2 tests/src/python/test_qgsvectorlayereditbuffer.py
@@ -16,6 +16,7 @@

#include "qgsgeometry.h"
#include "qgslogger.h"
#include <qgsmessagelog.h>
#include "qgsvectorlayerundocommand.h"
#include "qgsvectordataprovider.h"
#include "qgsvectorlayer.h"
@@ -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;
@@ -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();
@@ -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;
}

@@ -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

0 comments on commit c33ae01

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