Skip to content

Commit

Permalink
Changed data structure for added features from list to map to allow e…
Browse files Browse the repository at this point in the history
…fficient lookups
  • Loading branch information
wonder-sk committed Dec 18, 2012
1 parent 9317ffd commit 31f6ce0
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 165 deletions.
133 changes: 78 additions & 55 deletions python/core/conversions.sip
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ which are not wrapped by PyQt:
- QMap<TYPE1, TYPE2*>
- QMap<double, TYPE>
- QMultiMap<double, TYPE2>
- QMap<qint64, QgsGeometry>
- QMap<qint64, TYPE>
- QMap<qint64, QgsOverlayObject*>
- QList< QPair< QString, QList<QString> > >
- QVector<TYPE*>
Expand Down Expand Up @@ -661,94 +661,117 @@ template<TYPE>
};


//
// copied from PyQt4 QMap<int, TYPE> and adapted to qint64
//

%MappedType QMap<qint64, QgsGeometry>
// QMap<qint64, TYPE> is implemented as a Python dictionary.
template<TYPE>
%MappedType QMap<qint64, TYPE> /DocType="dict-of-qint64-TYPE"/
{
%TypeHeaderCode
#include <QMap>
#include <qmap.h>
%End

%ConvertFromTypeCode
// Create the list.
PyObject *d;
// Create the dictionary.
PyObject *d = PyDict_New();

if ((d = PyDict_New()) == NULL)
return NULL;
if (!d)
return NULL;

// Set the list elements.
for (QMap<qint64, QgsGeometry>::iterator it = sipCpp->begin(); it != sipCpp->end(); ++it)
{
PyObject *kobj = PyLong_FromLongLong(it.key());
PyObject *tobj = sipConvertFromInstance( &it.value(), sipClass_QgsGeometry, sipTransferObj);
// Set the dictionary elements.
QMap<qint64, TYPE>::const_iterator i = sipCpp->constBegin();

if (kobj == NULL || tobj == NULL || PyDict_SetItem(d, kobj, tobj) < 0)
while (i != sipCpp->constEnd())
{
Py_DECREF(d);
TYPE *t = new TYPE(i.value());

if (kobj)
{
Py_DECREF(kobj);
}
PyObject *kobj = PyLong_FromLongLong(i.key());
//PyObject *kobj = SIPLong_FromLong(i.key());
PyObject *tobj = sipConvertFromNewType(t, sipType_TYPE, sipTransferObj);

if (tobj)
{
if (kobj == NULL || tobj == NULL || PyDict_SetItem(d, kobj, tobj) < 0)
{
Py_DECREF(d);

if (kobj)
{
Py_DECREF(kobj);
}

if (tobj)
{
Py_DECREF(tobj);
}
else
{
delete t;
}

return NULL;
}

Py_DECREF(kobj);
Py_DECREF(tobj);
}

return NULL;
++i;
}

Py_DECREF(tobj);
}

return d;
return d;
%End

%ConvertToTypeCode
PyObject *kobj, *tobj;
PyObject *kobj, *tobj;
SIP_SSIZE_T i = 0;

// Check the type if that is all that is required.
if (sipIsErr == NULL)
{
if (!PyDict_Check(sipPy))
return 0;
// Check the type if that is all that is required.
if (sipIsErr == NULL)
{
if (!PyDict_Check(sipPy))
return 0;

while (PyDict_Next(sipPy, &i, &kobj, &tobj))
if (!sipCanConvertToType(tobj, sipType_TYPE, SIP_NOT_NONE))
return 0;

return 1;
}

QMap<qint64, TYPE> *qm = new QMap<qint64, TYPE>;

Py_ssize_t i = 0;
while (PyDict_Next(sipPy, &i, &kobj, &tobj))
{
if (!sipCanConvertToInstance(tobj, sipClass_QgsGeometry, SIP_NOT_NONE))
return 0;
}
return 1;
}
int state;
//, k = SIPLong_AsLong(kobj);
qint64 k = PyLong_AsLongLong(kobj);
TYPE *t = reinterpret_cast<TYPE *>(sipConvertToType(tobj, sipType_TYPE, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr));

QMap<qint64, QgsGeometry> *qm = new QMap<qint64, QgsGeometry>;
if (*sipIsErr)
{
sipReleaseType(t, sipType_TYPE, state);

Py_ssize_t i = 0;
while (PyDict_Next(sipPy, &i, &kobj, &tobj))
{
int state;
qint64 k = PyLong_AsLongLong(kobj);
QgsGeometry * t = reinterpret_cast<QgsGeometry*>(sipConvertToInstance(tobj, sipClass_QgsGeometry, sipTransferObj,SIP_NOT_NONE,&state,sipIsErr));
delete qm;
return 0;
}

if (*sipIsErr)
{
sipReleaseInstance(t, sipClass_QgsGeometry, state);
delete qm;
return 0;
qm->insert(k, *t);

sipReleaseType(t, sipType_TYPE, state);
}

qm->insert(k, *t);
sipReleaseInstance(t, sipClass_QgsGeometry, state);
}
*sipCppPtr = qm;

*sipCppPtr = qm;
return sipGetState(sipTransferObj);
return sipGetState(sipTransferObj);
%End
};







%MappedType QMap<QString, QVariant::Type>
{
%TypeHeaderCode
Expand Down
3 changes: 2 additions & 1 deletion python/core/qgsvectorlayereditbuffer.sip
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

typedef QMap<qint64, QgsFeature> QgsFeatureMap;

class QgsVectorLayerEditBuffer : QObject
{
Expand Down Expand Up @@ -65,7 +66,7 @@ public:


/** New features which are not commited. */
const QgsFeatureList& addedFeatures();
const QgsFeatureMap& addedFeatures();

/** Changed attributes values which are not commited */
const QgsChangedAttributesMap& changedAttributeValues();
Expand Down
2 changes: 1 addition & 1 deletion src/core/qgsvectorlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1584,7 +1584,7 @@ QgsRectangle QgsVectorLayer::extent()
rect.combineExtentWith( &r );
}

for ( QgsFeatureList::iterator it = mEditBuffer->mAddedFeatures.begin(); it != mEditBuffer->mAddedFeatures.end(); it++ )
for ( QgsFeatureMap::iterator it = mEditBuffer->mAddedFeatures.begin(); it != mEditBuffer->mAddedFeatures.end(); it++ )
{
QgsRectangle r = it->geometry()->boundingBox();
rect.combineExtentWith( &r );
Expand Down
34 changes: 11 additions & 23 deletions src/core/qgsvectorlayereditbuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,16 +113,7 @@ bool QgsVectorLayerEditBuffer::deleteFeature( QgsFeatureId fid )
{
if ( FID_IS_NEW( fid ) )
{
bool found = false;
for ( int i = 0; i < mAddedFeatures.count(); ++i )
{
if ( mAddedFeatures[i].id() == fid )
{
found = true;
break;
}
}
if (!found)
if (!mAddedFeatures.contains(fid))
return false;
}
else // existing feature
Expand Down Expand Up @@ -304,25 +295,22 @@ bool QgsVectorLayerEditBuffer::commitChanges(QStringList& commitErrors)
{
if ( cap & QgsVectorDataProvider::AddFeatures )
{
QList<QgsFeatureId> ids;
foreach ( const QgsFeature &f, mAddedFeatures )
{
ids << f.id();
}
QList<QgsFeatureId> ids = mAddedFeatures.keys();
QgsFeatureList featuresToAdd = mAddedFeatures.values();

if ( provider->addFeatures( mAddedFeatures ) )
if ( provider->addFeatures( featuresToAdd ) )
{
commitErrors << tr( "SUCCESS: %n feature(s) added.", "added features count", mAddedFeatures.size() );
commitErrors << tr( "SUCCESS: %n feature(s) added.", "added features count", featuresToAdd.size() );

emit committedFeaturesAdded( L->id(), mAddedFeatures );
emit committedFeaturesAdded( L->id(), featuresToAdd );

// notify everyone that the features with temporary ids were updated with permanent ids
for ( int i = 0; i < mAddedFeatures.size(); i++ )
for ( int i = 0; i < featuresToAdd.count(); ++i )
{
if ( mAddedFeatures[i].id() != ids[i] )
if ( featuresToAdd[i].id() != ids[i] )
{
emit featureDeleted( ids[i] );
emit featureAdded( mAddedFeatures[i].id() );
emit featureAdded( featuresToAdd[i].id() );
}
}

Expand Down Expand Up @@ -448,7 +436,7 @@ void QgsVectorLayerEditBuffer::handleAttributeAdded( int index )
}

// go through added features and adapt attributes
QgsFeatureList::iterator featureIt = mAddedFeatures.begin();
QgsFeatureMap::iterator featureIt = mAddedFeatures.begin();
for ( ; featureIt != mAddedFeatures.end(); ++featureIt )
{
QgsAttributes& attrs = featureIt->attributes();
Expand All @@ -471,7 +459,7 @@ void QgsVectorLayerEditBuffer::handleAttributeDeleted( int index )
}

// go through added features and adapt attributes
QgsFeatureList::iterator featureIt = mAddedFeatures.begin();
QgsFeatureMap::iterator featureIt = mAddedFeatures.begin();
for ( ; featureIt != mAddedFeatures.end(); ++featureIt )
{
QgsAttributes& attrs = featureIt->attributes();
Expand Down
5 changes: 3 additions & 2 deletions src/core/qgsvectorlayereditbuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class QgsVectorLayer;

typedef QList<int> QgsAttributeList;
typedef QSet<int> QgsAttributeIds;
typedef QMap<QgsFeatureId, QgsFeature> QgsFeatureMap;

class CORE_EXPORT QgsVectorLayerEditBuffer : public QObject
{
Expand Down Expand Up @@ -79,7 +80,7 @@ class CORE_EXPORT QgsVectorLayerEditBuffer : public QObject


/** New features which are not commited. */
inline const QgsFeatureList& addedFeatures() { return mAddedFeatures; }
inline const QgsFeatureMap& addedFeatures() { return mAddedFeatures; }

/** Changed attributes values which are not commited */
inline const QgsChangedAttributesMap& changedAttributeValues() { return mChangedAttributeValues; }
Expand Down Expand Up @@ -161,7 +162,7 @@ protected slots:
QgsFeatureIds mDeletedFeatureIds;

/** New features which are not commited. */
QgsFeatureList mAddedFeatures;
QgsFeatureMap mAddedFeatures;

/** Changed attributes values which are not commited */
QgsChangedAttributesMap mChangedAttributeValues;
Expand Down
2 changes: 1 addition & 1 deletion src/core/qgsvectorlayerfeatureiterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ bool QgsVectorLayerFeatureIterator::nextFeatureFid( QgsFeature& f )
}

// added features
for ( QgsFeatureList::iterator iter = editBuffer->mAddedFeatures.begin(); iter != editBuffer->mAddedFeatures.end(); ++iter )
for ( QgsFeatureMap::iterator iter = editBuffer->mAddedFeatures.begin(); iter != editBuffer->mAddedFeatures.end(); ++iter )
{
if ( iter->id() == featureId )
{
Expand Down
4 changes: 3 additions & 1 deletion src/core/qgsvectorlayerfeatureiterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

#include <QSet>

typedef QMap<QgsFeatureId, QgsFeature> QgsFeatureMap;

class QgsVectorLayer;
class QgsVectorJoinInfo;

Expand Down Expand Up @@ -40,7 +42,7 @@ class QgsVectorLayerFeatureIterator : public QgsAbstractFeatureIterator
// only related to editing
QSet<QgsFeatureId> mFetchConsidered;
QgsGeometryMap::iterator mFetchChangedGeomIt;
QgsFeatureList::iterator mFetchAddedFeaturesIt;
QgsFeatureMap::iterator mFetchAddedFeaturesIt;

bool mFetchedFid; // when iterating by FID: indicator whether it has been fetched yet or not

Expand Down
Loading

0 comments on commit 31f6ce0

Please sign in to comment.