[QGIS Commit] r14035 - branches/threading-branch/src/core
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Mon Aug 9 08:23:27 EDT 2010
Author: wonder
Date: 2010-08-09 12:23:27 +0000 (Mon, 09 Aug 2010)
New Revision: 14035
Modified:
branches/threading-branch/src/core/qgsfeature.cpp
branches/threading-branch/src/core/qgsfeature.h
branches/threading-branch/src/core/qgsfield.h
Log:
QgsFeature: use implicit sharing, store attributes in a vector of QVariant values, map of QVariants kept only for compatibility
Modified: branches/threading-branch/src/core/qgsfeature.cpp
===================================================================
--- branches/threading-branch/src/core/qgsfeature.cpp 2010-08-09 10:38:46 UTC (rev 14034)
+++ branches/threading-branch/src/core/qgsfeature.cpp 2010-08-09 12:23:27 UTC (rev 14035)
@@ -18,204 +18,262 @@
#include "qgsgeometry.h"
#include "qgsrectangle.h"
-/** \class QgsFeature
- * \brief Encapsulates a spatial feature with attributes
- */
-QgsFeature::QgsFeature( int id, QString typeName )
+QgsFeatureData::QgsFeatureData( int id )
: mFid( id ),
mGeometry( 0 ),
mOwnsGeometry( 0 ),
mValid( false ),
- mDirty( 0 ),
- mTypeName( typeName )
-{
- // NOOP
-}
+ mAttributeMapDirty( false )
+{}
-QgsFeature::QgsFeature( QgsFeature const & rhs )
- : mFid( rhs.mFid ),
+QgsFeatureData::QgsFeatureData( const QgsFeatureData & rhs )
+ : QSharedData( rhs ),
+ mFid( rhs.mFid ),
mAttributes( rhs.mAttributes ),
+ mAttributeVector( rhs.mAttributeVector ),
mGeometry( 0 ),
mOwnsGeometry( false ),
mValid( rhs.mValid ),
- mDirty( rhs.mDirty ),
- mTypeName( rhs.mTypeName )
+ mAttributeMapDirty( rhs.mAttributeMapDirty )
{
-
// copy embedded geometry
if ( rhs.mGeometry )
{
- setGeometry( *rhs.mGeometry );
+ setGeometry( new QgsGeometry( *rhs.mGeometry ) );
}
}
+QgsFeatureData::~QgsFeatureData()
+{
+ // Destruct the attached geometry only if we still own it.
+ if ( mOwnsGeometry && mGeometry )
+ delete mGeometry;
+}
-QgsFeature & QgsFeature::operator=( QgsFeature const & rhs )
+void QgsFeatureData::setGeometry( QgsGeometry* geom )
{
- if ( &rhs == this )
- return *this;
+ // Destruct the attached geometry only if we still own it, before assigning new one.
+ if ( mOwnsGeometry && mGeometry )
+ {
+ delete mGeometry;
+ mGeometry = 0;
+ }
- mFid = rhs.mFid;
- mDirty = rhs.mDirty;
- mAttributes = rhs.mAttributes;
- mValid = rhs.mValid;
- mTypeName = rhs.mTypeName;
+ mGeometry = geom;
+ mOwnsGeometry = true;
+}
- // make sure to delete the old geometry (if exists)
- if ( mGeometry && mOwnsGeometry )
- delete mGeometry;
+void QgsFeatureData::clearAttributes()
+{
+ mAttributeVector.clear();
+ //qFill(d->mAttributeVector, QVariant() );
+ mAttributeMapDirty = true;
+}
- mGeometry = 0;
- mOwnsGeometry = false;
+void QgsFeatureData::setAttributes( const QgsAttributeMap& attributes )
+{
+ mAttributes = attributes;
+ mAttributeMapDirty = false;
- if ( rhs.mGeometry )
- setGeometry( *rhs.mGeometry );
+ // update attribute vector from the map
+ convertMapToVector();
+}
- return *this;
-} // QgsFeature::operator=( QgsFeature const & rhs )
+void QgsFeatureData::convertMapToVector()
+{
+ int max_key = 0;
+ QgsAttributeMap::const_iterator it;
+ for ( it = mAttributes.constBegin(); it != mAttributes.constEnd(); ++it )
+ {
+ if ( it.key() > max_key )
+ max_key = it.key();
+ }
+ mAttributeVector.resize( max_key + 1 );
+ QVariant* data = mAttributeVector.data();
+ for ( it = mAttributes.constBegin(); it != mAttributes.constEnd(); ++it )
+ {
+ data[ it.key()] = it.value();
+ }
+}
-//! Destructor
+void QgsFeatureData::convertVectorToMap() const
+{
+ int count = mAttributeVector.size();
+ const QVariant* data = mAttributeVector.constData();
+
+ mAttributes.clear();
+ for ( int i = 0; i < count; i++ )
+ {
+ mAttributes.insert( i, data[i] );
+ }
+
+ mAttributeMapDirty = false;
+}
+
+void QgsFeatureData::setAttributes( const QgsAttributeVector& attributes )
+{
+ mAttributeVector = attributes;
+ mAttributeMapDirty = true;
+}
+
+void QgsFeatureData::addAttribute( int field, QVariant attr )
+{
+ //if (field >= mAttributeVector.count())
+ // mAttributeVector.resize(field+1);
+ mAttributeVector.insert( field, attr );
+
+ mAttributeMapDirty = true;
+}
+
+void QgsFeatureData::deleteAttribute( int field )
+{
+ mAttributeVector.remove( field );
+ mAttributeMapDirty = true;
+}
+
+void QgsFeatureData::changeAttribute( int field, QVariant attr )
+{
+ mAttributeVector[field] = attr;
+ mAttributeMapDirty = true;
+}
+
+
+
+////////
+
+QgsFeature::QgsFeature( int id, QString )
+{
+ d = new QgsFeatureData( id );
+}
+
+QgsFeature::QgsFeature( QgsFeature const & rhs )
+ : d( rhs.d )
+{
+}
+
QgsFeature::~QgsFeature()
{
- // Destruct the attached geometry only if we still own it.
- if ( mOwnsGeometry && mGeometry )
- delete mGeometry;
+
}
-/**
- * Get the feature id for this feature
- * @return Feature id
- */
int QgsFeature::id() const
{
- return mFid;
+ return d->mFid;
}
-/**
- * Get the attributes for this feature.
- * @return A std::map containing the field name/value mapping
- */
+void QgsFeature::setFeatureId( int id )
+{
+ d->mFid = id;
+}
+
const QgsAttributeMap& QgsFeature::attributeMap() const
{
- return mAttributes;
+ if ( d->mAttributeMapDirty )
+ {
+ d->convertVectorToMap();
+ }
+ return d->mAttributes;
}
-/**Sets the attributes for this feature*/
void QgsFeature::setAttributeMap( const QgsAttributeMap& attributes )
{
- mAttributes = attributes;
+ d->setAttributes( attributes );
}
-/**Clear attribute map for this feature*/
void QgsFeature::clearAttributeMap()
{
- mAttributes.clear();
+ d->clearAttributes();
}
-/**
- * Add an attribute to the map
- */
void QgsFeature::addAttribute( int field, QVariant attr )
{
- mAttributes.insert( field, attr );
+ d->addAttribute( field, attr );
}
-/**Deletes an attribute and its value*/
void QgsFeature::deleteAttribute( int field )
{
- mAttributes.remove( field );
+ d->deleteAttribute( field );
}
-
void QgsFeature::changeAttribute( int field, QVariant attr )
{
- mAttributes[field] = attr;
+ d->changeAttribute( field, attr );
}
QgsGeometry *QgsFeature::geometry()
{
- return mGeometry;
+ return d->mGeometry;
}
QgsGeometry *QgsFeature::geometryAndOwnership()
{
- mOwnsGeometry = false;
+ d->mOwnsGeometry = false;
- return mGeometry;
+ return d->mGeometry;
}
-
-
-/** Set the feature id
-*/
-void QgsFeature::setFeatureId( int id )
+QString QgsFeature::typeName() const
{
- mFid = id;
+ return QString();
}
-
-QString QgsFeature::typeName() const
-{
- return mTypeName;
-} // QgsFeature::typeName
-
-
-
-/** sets the feature's type name
- */
void QgsFeature::setTypeName( QString typeName )
{
- mTypeName = typeName;
-} // QgsFeature::typeName
+}
-
void QgsFeature::setGeometry( const QgsGeometry& geom )
{
- setGeometry( new QgsGeometry( geom ) );
+ d->setGeometry( new QgsGeometry( geom ) );
}
void QgsFeature::setGeometry( QgsGeometry* geom )
{
- // Destruct the attached geometry only if we still own it, before assigning new one.
- if ( mOwnsGeometry && mGeometry )
- {
- delete mGeometry;
- mGeometry = 0;
- }
-
- mGeometry = geom;
- mOwnsGeometry = true;
+ d->setGeometry( geom );
}
-/** Set the pointer to the feature geometry
-*/
void QgsFeature::setGeometryAndOwnership( unsigned char *geom, size_t length )
{
QgsGeometry *g = new QgsGeometry();
g->fromWkb( geom, length );
- setGeometry( g );
+ d->setGeometry( g );
}
bool QgsFeature::isValid() const
{
- return mValid;
+ return d->mValid;
}
void QgsFeature::setValid( bool validity )
{
- mValid = validity;
+ d->mValid = validity;
}
bool QgsFeature::isDirty() const
{
- return mDirty;
+ return false;
}
void QgsFeature::clean()
{
- mDirty = false;
}
+
+QVariant* QgsFeature::resizeAttributeVector( int fieldCount )
+{
+ d->mAttributeVector.resize( fieldCount );
+ d->mAttributeMapDirty = true;
+ return d->mAttributeVector.data();
+}
+
+void QgsFeature::setAttributeVector( const QgsAttributeVector& attrs )
+{
+ d->setAttributes( attrs );
+}
+
+const QgsAttributeVector& QgsFeature::attributeVector() const
+{
+ return d->mAttributeVector;
+}
Modified: branches/threading-branch/src/core/qgsfeature.h
===================================================================
--- branches/threading-branch/src/core/qgsfeature.h 2010-08-09 10:38:46 UTC (rev 14034)
+++ branches/threading-branch/src/core/qgsfeature.h 2010-08-09 12:23:27 UTC (rev 14035)
@@ -21,11 +21,17 @@
#include <QString>
#include <QVariant>
#include <QList>
+#include <QVector>
+#include <QSharedDataPointer>
+
class QgsGeometry;
class QgsRectangle;
class QgsFeature;
+
+typedef QVector<QVariant> QgsAttributeVector;
+
// key = field index, value = field value
typedef QMap<int, QVariant> QgsAttributeMap;
@@ -40,6 +46,54 @@
typedef QList<QgsFeature> QgsFeatureList;
+
+#include <QSharedData>
+
+class QgsFeatureData : public QSharedData
+{
+ public:
+
+ QgsFeatureData( int id );
+ QgsFeatureData( const QgsFeatureData & rhs );
+
+ ~QgsFeatureData();
+
+ void setGeometry( QgsGeometry* geom );
+
+ void clearAttributes();
+ void setAttributes( const QgsAttributeMap& attributes );
+ void setAttributes( const QgsAttributeVector& attributes );
+ void addAttribute( int field, QVariant attr );
+ void deleteAttribute( int field );
+ void changeAttribute( int field, QVariant attr );
+
+ void convertVectorToMap() const;
+ void convertMapToVector();
+
+ //! feature id
+ int mFid;
+
+ /** map of attributes accessed by field index */
+ mutable QgsAttributeMap mAttributes;
+ mutable bool mAttributeMapDirty;
+
+ /** vector of attributes */
+ QgsAttributeVector mAttributeVector;
+
+ /** pointer to geometry */
+ QgsGeometry *mGeometry;
+
+ /** Indicator if the mGeometry is owned by this QgsFeature.
+ If so, this QgsFeature takes responsibility for the mGeometry's destruction.
+ */
+ bool mOwnsGeometry;
+
+ //! Flag to indicate if this feature is valid
+ bool mValid;
+};
+
+
+
/** \ingroup core
* The feature class encapsulates a single feature including its id,
* geometry and a list of field/values attributes.
@@ -50,14 +104,11 @@
{
public:
//! Constructor
- QgsFeature( int id = 0, QString typeName = "" );
+ QgsFeature( int id = 0, QString typeName = QString() );
/** copy ctor needed due to internal pointer */
- QgsFeature( QgsFeature const & rhs );
+ QgsFeature( const QgsFeature & rhs );
- /** assignment operator needed due to internal pointer */
- QgsFeature & operator=( QgsFeature const & rhs );
-
//! Destructor
~QgsFeature();
@@ -74,21 +125,9 @@
*/
void setFeatureId( int id );
-
- /** returns the feature's type name
- * @deprecated not used anymore
- */
- QString typeName() const;
-
-
- /** sets the feature's type name
- * @deprecated not used anymore
- */
- void setTypeName( QString typeName );
-
/**
* Get the attributes for this feature.
- * @return A std::map containing the field name/value mapping
+ * @return A QMap containing the field name/value mapping
*/
const QgsAttributeMap& attributeMap() const;
@@ -113,6 +152,10 @@
@param attr attribute name and value to be set */
void changeAttribute( int field, QVariant attr );
+ QVariant* resizeAttributeVector( int fieldCount );
+ void setAttributeVector( const QgsAttributeVector& attrList );
+ const QgsAttributeVector& attributeVector() const;
+
/**
* Return the validity of this feature. This is normally set by
* the provider to indicate some problem that makes the feature
@@ -125,16 +168,13 @@
*/
void setValid( bool validity );
- /**
- * Return the dirty state of this feature.
- * Dirty is set if (e.g.) the feature's geometry has been modified in-memory.
- */
+ /** @deprecated not used anymore */
+ QString typeName() const;
+ /** @deprecated not used anymore */
+ void setTypeName( QString typeName );
+ /** @deprecated not used anymore */
bool isDirty() const;
-
- /**
- * Reset the dirtiness of the feature. (i.e. make clean)
- * You would normally do this after it's saved to permanent storage (e.g. disk, an ACID-compliant database)
- */
+ /** @deprecated not used anymore */
void clean();
/**
@@ -165,35 +205,8 @@
private:
- //! feature id
- int mFid;
+ QSharedDataPointer<QgsFeatureData> d;
- /** map of attributes accessed by field index */
- QgsAttributeMap mAttributes;
-
- /** pointer to geometry in binary WKB format
-
- This is usually set by a call to OGRGeometry::exportToWkb()
- */
- QgsGeometry *mGeometry;
-
- /** Indicator if the mGeometry is owned by this QgsFeature.
- If so, this QgsFeature takes responsibility for the mGeometry's destruction.
- */
- bool mOwnsGeometry;
-
- //! Flag to indicate if this feature is valid
- // TODO: still applies? [MD]
- bool mValid;
-
- //! Flag to indicate if this feature is dirty (e.g. geometry has been modified in-memory)
- // TODO: still applies? [MD]
- bool mDirty;
-
- /// feature type name
- QString mTypeName;
-
-
}; // class QgsFeature
Modified: branches/threading-branch/src/core/qgsfield.h
===================================================================
--- branches/threading-branch/src/core/qgsfield.h 2010-08-09 10:38:46 UTC (rev 14034)
+++ branches/threading-branch/src/core/qgsfield.h 2010-08-09 12:23:27 UTC (rev 14035)
@@ -145,5 +145,6 @@
// key = field index, value=field data
typedef QMap<int, QgsField> QgsFieldMap;
+typedef QVector<QgsField> QgsFieldVector;
#endif
More information about the QGIS-commit
mailing list