[QGIS Commit] r14036 - in branches/threading-branch/src/providers:
delimitedtext gpx grass ogr osm postgres spatialite wfs
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Mon Aug 9 10:08:05 EDT 2010
Author: wonder
Date: 2010-08-09 14:08:05 +0000 (Mon, 09 Aug 2010)
New Revision: 14036
Modified:
branches/threading-branch/src/providers/delimitedtext/qgsdelimitedtextfeatureiterator.cpp
branches/threading-branch/src/providers/delimitedtext/qgsdelimitedtextprovider.cpp
branches/threading-branch/src/providers/delimitedtext/qgsdelimitedtextprovider.h
branches/threading-branch/src/providers/gpx/qgsgpxfeatureiterator.cpp
branches/threading-branch/src/providers/gpx/qgsgpxfeatureiterator.h
branches/threading-branch/src/providers/gpx/qgsgpxprovider.cpp
branches/threading-branch/src/providers/gpx/qgsgpxprovider.h
branches/threading-branch/src/providers/grass/qgsgrassprovider.cpp
branches/threading-branch/src/providers/grass/qgsgrassprovider.h
branches/threading-branch/src/providers/ogr/qgsogrfeatureiterator.cpp
branches/threading-branch/src/providers/ogr/qgsogrprovider.cpp
branches/threading-branch/src/providers/ogr/qgsogrprovider.h
branches/threading-branch/src/providers/osm/osmprovider.cpp
branches/threading-branch/src/providers/osm/osmprovider.h
branches/threading-branch/src/providers/postgres/qgspostgresfeatureiterator.cpp
branches/threading-branch/src/providers/postgres/qgspostgresprovider.cpp
branches/threading-branch/src/providers/postgres/qgspostgresprovider.h
branches/threading-branch/src/providers/spatialite/qgsspatialitefeatureiterator.cpp
branches/threading-branch/src/providers/spatialite/qgsspatialiteprovider.cpp
branches/threading-branch/src/providers/spatialite/qgsspatialiteprovider.h
branches/threading-branch/src/providers/wfs/qgswfsfeatureiterator.cpp
branches/threading-branch/src/providers/wfs/qgswfsprovider.cpp
branches/threading-branch/src/providers/wfs/qgswfsprovider.h
Log:
Adapted vector data providers to gain some speed improvements:
- use plain vector of fields (instead of a map)
- use vector of attributes when adding attributes
- use implicit sharing of QgsFeature
Modified: branches/threading-branch/src/providers/delimitedtext/qgsdelimitedtextfeatureiterator.cpp
===================================================================
--- branches/threading-branch/src/providers/delimitedtext/qgsdelimitedtextfeatureiterator.cpp 2010-08-09 12:23:27 UTC (rev 14035)
+++ branches/threading-branch/src/providers/delimitedtext/qgsdelimitedtextfeatureiterator.cpp 2010-08-09 14:08:05 UTC (rev 14036)
@@ -63,7 +63,7 @@
bool yOk = false;
// Skip indexing malformed lines.
- if ( P->attributeFields.size() == tokens.size() )
+ if ( P->mAttributeVector.size() == tokens.size() )
{
x = tokens[P->mXFieldIndex].toDouble( &xOk );
y = tokens[P->mYFieldIndex].toDouble( &yOk );
@@ -125,30 +125,27 @@
feature.setGeometryAndOwnership( geometry, buffer.size() );
+ QVariant* attrs = feature.resizeAttributeVector( P->fieldCount() );
+
for ( QgsAttributeList::const_iterator i = mFetchAttributes.begin();
i != mFetchAttributes.end();
++i )
{
- QVariant val;
- switch ( P->attributeFields[*i].type() )
+ int index = *i;
+ switch ( P->mAttributeVector[index].type() )
{
case QVariant::Int:
- if( !tokens[*i].isEmpty() )
- val = QVariant( tokens[*i].toInt() );
- else
- val = QVariant( P->attributeFields[*i].type() );
+ if( !tokens[index].isEmpty() )
+ attrs[index] = tokens[index].toInt();
break;
case QVariant::Double:
- if( !tokens[*i].isEmpty() )
- val = QVariant( tokens[*i].toDouble() );
- else
- val = QVariant( P->attributeFields[*i].type() );
+ if( !tokens[index].isEmpty() )
+ attrs[index] = tokens[index].toDouble();
break;
default:
- val = QVariant( tokens[*i] );
+ attrs[index] = tokens[index];
break;
}
- feature.addAttribute( *i, val );
}
// We have a good line, so return
Modified: branches/threading-branch/src/providers/delimitedtext/qgsdelimitedtextprovider.cpp
===================================================================
--- branches/threading-branch/src/providers/delimitedtext/qgsdelimitedtextprovider.cpp 2010-08-09 12:23:27 UTC (rev 14035)
+++ branches/threading-branch/src/providers/delimitedtext/qgsdelimitedtextprovider.cpp 2010-08-09 14:08:05 UTC (rev 14036)
@@ -200,34 +200,33 @@
// than its name. All fields are assumed to be text
int fieldPos = 0;
for ( QStringList::Iterator it = fieldList.begin();
- it != fieldList.end(); ++it )
+ it != fieldList.end(); ++it, ++fieldPos )
{
QString field = *it;
- if ( field.length() > 0 )
- {
- // for now, let's set field type as text
- attributeFields[fieldPos] = QgsField( *it, QVariant::String, "Text" );
+ if ( field.length() == 0 )
+ continue; // ignore
- // check to see if this field matches either the x or y field
- if ( xField == *it )
- {
- QgsDebugMsg( "Found x field: " + ( *it ) );
- mXFieldIndex = fieldPos;
- }
- else if ( yField == *it )
- {
- QgsDebugMsg( "Found y field: " + ( *it ) );
- mYFieldIndex = fieldPos;
- }
+ // for now, let's set field type as text
+ mAttributeVector.append( QgsField( *it, QVariant::String, "Text" ) );
- QgsDebugMsg( "Adding field: " + ( *it ) );
- // assume that the field could be integer or double
- couldBeInt.insert( fieldPos, true );
- couldBeDouble.insert( fieldPos, true );
- fieldPos++;
+ // check to see if this field matches either the x or y field
+ if ( xField == *it )
+ {
+ QgsDebugMsg( "Found x field: " + ( *it ) );
+ mXFieldIndex = fieldPos;
}
+ else if ( yField == *it )
+ {
+ QgsDebugMsg( "Found y field: " + ( *it ) );
+ mYFieldIndex = fieldPos;
+ }
+
+ QgsDebugMsg( "Adding field: " + ( *it ) );
+ // assume that the field could be integer or double
+ couldBeInt.insert( fieldPos, true );
+ couldBeDouble.insert( fieldPos, true );
}
- QgsDebugMsg( "Field count for the delimited text file is " + QString::number( attributeFields.size() ) );
+ QgsDebugMsg( "Field count for the delimited text file is " + QString::number( mAttributeVector.size() ) );
hasFields = true;
}
else if ( mXFieldIndex != -1 && mYFieldIndex != -1 )
@@ -238,7 +237,7 @@
QStringList parts = splitLine( line );
// Skip malformed lines silently. Report line number with nextFeature()
- if ( attributeFields.size() != parts.size() )
+ if ( mAttributeVector.size() != parts.size() )
{
continue;
}
@@ -283,18 +282,21 @@
}
// now it's time to decide the types for the fields
- for ( QgsFieldMap::iterator it = attributeFields.begin(); it != attributeFields.end(); ++it )
+ for ( int i = 0; i < mAttributeVector.size(); i++ )
{
- if ( couldBeInt[it.key()] )
+ if ( couldBeInt[i] )
{
- it->setType( QVariant::Int );
- it->setTypeName( "integer" );
+ mAttributeVector[i].setType( QVariant::Int );
+ mAttributeVector[i].setTypeName( "integer" );
}
- else if ( couldBeDouble[it.key()] )
+ else if ( couldBeDouble[i] )
{
- it->setType( QVariant::Double );
- it->setTypeName( "double" );
+ mAttributeVector[i].setType( QVariant::Double );
+ mAttributeVector[i].setTypeName( "double" );
}
+
+ // convert mAttributeVector items to field map (legacy)
+ mAttributeFields[i] = mAttributeVector[i];
}
if ( mXFieldIndex != -1 && mYFieldIndex != -1 )
@@ -391,13 +393,13 @@
*/
uint QgsDelimitedTextProvider::fieldCount() const
{
- return attributeFields.size();
+ return mAttributeVector.size();
}
const QgsFieldMap & QgsDelimitedTextProvider::fields() const
{
- return attributeFields;
+ return mAttributeFields;
}
bool QgsDelimitedTextProvider::isValid()
Modified: branches/threading-branch/src/providers/delimitedtext/qgsdelimitedtextprovider.h
===================================================================
--- branches/threading-branch/src/providers/delimitedtext/qgsdelimitedtextprovider.h 2010-08-09 12:23:27 UTC (rev 14035)
+++ branches/threading-branch/src/providers/delimitedtext/qgsdelimitedtextprovider.h 2010-08-09 14:08:05 UTC (rev 14036)
@@ -152,8 +152,10 @@
private:
//! Fields
- QgsFieldMap attributeFields;
+ QgsFieldMap mAttributeFields;
+ QVector<QgsField> mAttributeVector;
+
QgsAttributeList mAttributesToFetch;
QString mFileName;
Modified: branches/threading-branch/src/providers/gpx/qgsgpxfeatureiterator.cpp
===================================================================
--- branches/threading-branch/src/providers/gpx/qgsgpxfeatureiterator.cpp 2010-08-09 12:23:27 UTC (rev 14035)
+++ branches/threading-branch/src/providers/gpx/qgsgpxfeatureiterator.cpp 2010-08-09 14:08:05 UTC (rev 14036)
@@ -89,36 +89,17 @@
feature.setGeometryAndOwnership(( unsigned char * )geo, 1+4+8+8 );
}
+ QVariant* attrs = feature.resizeAttributeVector( P->fieldCount() );
+
// add attributes if they are wanted
for ( QgsAttributeList::const_iterator iter = mFetchAttributes.begin(); iter != mFetchAttributes.end(); ++iter )
{
- switch ( *iter )
+ if ( !setCommonAttribute( wpt, attrs, *iter ) )
{
- case QgsGPXProvider::NameAttr:
- feature.addAttribute( QgsGPXProvider::NameAttr, QVariant( wpt->name ) );
- break;
- case QgsGPXProvider::EleAttr:
- if ( wpt->ele != -std::numeric_limits<double>::max() )
- feature.addAttribute( QgsGPXProvider::EleAttr, QVariant( wpt->ele ) );
- break;
- case QgsGPXProvider::SymAttr:
- feature.addAttribute( QgsGPXProvider::SymAttr, QVariant( wpt->sym ) );
- break;
- case QgsGPXProvider::CmtAttr:
- feature.addAttribute( QgsGPXProvider::CmtAttr, QVariant( wpt->cmt ) );
- break;
- case QgsGPXProvider::DscAttr:
- feature.addAttribute( QgsGPXProvider::DscAttr, QVariant( wpt->desc ) );
- break;
- case QgsGPXProvider::SrcAttr:
- feature.addAttribute( QgsGPXProvider::SrcAttr, QVariant( wpt->src ) );
- break;
- case QgsGPXProvider::URLAttr:
- feature.addAttribute( QgsGPXProvider::URLAttr, QVariant( wpt->url ) );
- break;
- case QgsGPXProvider::URLNameAttr:
- feature.addAttribute( QgsGPXProvider::URLNameAttr, QVariant( wpt->urlname ) );
- break;
+ if ( *iter == QgsGPXProvider::EleAttr && wpt->ele != -std::numeric_limits<double>::max() )
+ attrs[ QgsGPXProvider::EleAttr ] = wpt->ele;
+ else if ( *iter == QgsGPXProvider::SymAttr )
+ attrs[ QgsGPXProvider::SymAttr ] = wpt->sym;
}
}
@@ -181,33 +162,15 @@
feature.setFeatureId( rte->id );
feature.setValid( true );
+ QVariant* attrs = feature.resizeAttributeVector( P->fieldCount() );
+
// add attributes if they are wanted
for ( QgsAttributeList::const_iterator iter = mFetchAttributes.begin(); iter != mFetchAttributes.end(); ++iter )
{
- switch ( *iter )
+ if ( !setCommonAttribute( rte, attrs, *iter ) )
{
- case QgsGPXProvider::NameAttr:
- feature.addAttribute( QgsGPXProvider::NameAttr, QVariant( rte->name ) );
- break;
- case QgsGPXProvider::NumAttr:
- if ( rte->number != std::numeric_limits<int>::max() )
- feature.addAttribute( QgsGPXProvider::NumAttr, QVariant( rte->number ) );
- break;
- case QgsGPXProvider::CmtAttr:
- feature.addAttribute( QgsGPXProvider::CmtAttr, QVariant( rte->cmt ) );
- break;
- case QgsGPXProvider::DscAttr:
- feature.addAttribute( QgsGPXProvider::DscAttr, QVariant( rte->desc ) );
- break;
- case QgsGPXProvider::SrcAttr:
- feature.addAttribute( QgsGPXProvider::SrcAttr, QVariant( rte->src ) );
- break;
- case QgsGPXProvider::URLAttr:
- feature.addAttribute( QgsGPXProvider::URLAttr, QVariant( rte->url ) );
- break;
- case QgsGPXProvider::URLNameAttr:
- feature.addAttribute( QgsGPXProvider::URLNameAttr, QVariant( rte->urlname ) );
- break;
+ if ( *iter == QgsGPXProvider::NumAttr && rte->number != std::numeric_limits<int>::max() )
+ attrs[ QgsGPXProvider::NumAttr ] = rte->number;
}
}
@@ -291,33 +254,15 @@
feature.setFeatureId( trk->id );
feature.setValid( true );
+ QVariant* attrs = feature.resizeAttributeVector( P->fieldCount() );
+
// add attributes if they are wanted
for ( QgsAttributeList::const_iterator iter = mFetchAttributes.begin(); iter != mFetchAttributes.end(); ++iter )
{
- switch ( *iter )
+ if ( !setCommonAttribute( trk, attrs, *iter ) )
{
- case QgsGPXProvider::NameAttr:
- feature.addAttribute( QgsGPXProvider::NameAttr, QVariant( trk->name ) );
- break;
- case QgsGPXProvider::NumAttr:
- if ( trk->number != std::numeric_limits<int>::max() )
- feature.addAttribute( QgsGPXProvider::NumAttr, QVariant( trk->number ) );
- break;
- case QgsGPXProvider::CmtAttr:
- feature.addAttribute( QgsGPXProvider::CmtAttr, QVariant( trk->cmt ) );
- break;
- case QgsGPXProvider::DscAttr:
- feature.addAttribute( QgsGPXProvider::DscAttr, QVariant( trk->desc ) );
- break;
- case QgsGPXProvider::SrcAttr:
- feature.addAttribute( QgsGPXProvider::SrcAttr, QVariant( trk->src ) );
- break;
- case QgsGPXProvider::URLAttr:
- feature.addAttribute( QgsGPXProvider::URLAttr, QVariant( trk->url ) );
- break;
- case QgsGPXProvider::URLNameAttr:
- feature.addAttribute( QgsGPXProvider::URLNameAttr, QVariant( trk->urlname ) );
- break;
+ if ( *iter == QgsGPXProvider::NumAttr && trk->number != std::numeric_limits<int>::max() )
+ attrs[ QgsGPXProvider::NumAttr ] = trk->number;
}
}
@@ -327,6 +272,31 @@
return false;
}
+bool QgsGPXFeatureIterator::setCommonAttribute( const QgsGPSObject* obj, QVariant* attrs, int index )
+{
+ switch ( index )
+ {
+ case QgsGPXProvider::NameAttr:
+ attrs[ QgsGPXProvider::NameAttr ] = obj->name;
+ return true;
+ case QgsGPXProvider::CmtAttr:
+ attrs[ QgsGPXProvider::CmtAttr ] = obj->cmt;
+ return true;
+ case QgsGPXProvider::DscAttr:
+ attrs[ QgsGPXProvider::DscAttr ] = obj->desc;
+ return true;
+ case QgsGPXProvider::SrcAttr:
+ attrs[ QgsGPXProvider::SrcAttr ] = obj->src;
+ return true;
+ case QgsGPXProvider::URLAttr:
+ attrs[ QgsGPXProvider::URLAttr ] = obj->url;
+ return true;
+ case QgsGPXProvider::URLNameAttr:
+ attrs[ QgsGPXProvider::URLNameAttr ] = obj->urlname;
+ return true;
+ }
+ return false;
+}
bool QgsGPXFeatureIterator::boundsCheck( double x, double y )
{
Modified: branches/threading-branch/src/providers/gpx/qgsgpxfeatureiterator.h
===================================================================
--- branches/threading-branch/src/providers/gpx/qgsgpxfeatureiterator.h 2010-08-09 12:23:27 UTC (rev 14035)
+++ branches/threading-branch/src/providers/gpx/qgsgpxfeatureiterator.h 2010-08-09 14:08:05 UTC (rev 14036)
@@ -35,6 +35,8 @@
bool nextRoute(QgsFeature& feature);
bool nextTrack(QgsFeature& feature);
+ bool setCommonAttribute( const QgsGPSObject* obj, QVariant* attrs, int index );
+
/**
* Check to see if the point is withn the selection
* rectangle
Modified: branches/threading-branch/src/providers/gpx/qgsgpxprovider.cpp
===================================================================
--- branches/threading-branch/src/providers/gpx/qgsgpxprovider.cpp 2010-08-09 12:23:27 UTC (rev 14035)
+++ branches/threading-branch/src/providers/gpx/qgsgpxprovider.cpp 2010-08-09 14:08:05 UTC (rev 14036)
@@ -46,12 +46,7 @@
#include "gpsdata.h"
#include "qgslogger.h"
-const char* QgsGPXProvider::attr[] = { "name", "elevation", "symbol", "number",
- "comment", "description", "source",
- "url", "url name"
- };
-
const QString GPX_KEY = "gpx";
const QString GPX_DESCRIPTION = QObject::tr( "GPS eXchange format provider" );
@@ -78,21 +73,27 @@
( typeStr == "route" ? RouteType : TrackType ) );
// set up the attributes and the geometry type depending on the feature type
- attributeFields[NameAttr] = QgsField( attr[NameAttr], QVariant::String, "text" );
+ mAttributeVector.append( QgsField( "name", QVariant::String, "text" ) );
+ mAttributeVector.append( QgsField( "comment", QVariant::String, "text" ) );
+ mAttributeVector.append( QgsField( "description", QVariant::String, "text" ) );
+ mAttributeVector.append( QgsField( "source", QVariant::String, "text" ) );
+ mAttributeVector.append( QgsField( "url", QVariant::String, "text" ) );
+ mAttributeVector.append( QgsField( "url name", QVariant::String, "text" ) );
+
if ( mFeatureType == WaypointType )
{
- attributeFields[EleAttr] = QgsField( attr[EleAttr], QVariant::Double, "double" );
- attributeFields[SymAttr] = QgsField( attr[SymAttr], QVariant::String, "text" );
+ mAttributeVector.append( QgsField( "elevation", QVariant::Double, "double" ) );
+ mAttributeVector.append( QgsField( "symbol", QVariant::String, "text" ) );
}
else if ( mFeatureType == RouteType || mFeatureType == TrackType )
{
- attributeFields[NumAttr] = QgsField( attr[NumAttr], QVariant::Int, "int" );
+ mAttributeVector.append( QgsField( "number", QVariant::Int, "int" ) );
}
- attributeFields[CmtAttr] = QgsField( attr[CmtAttr], QVariant::String, "text" );
- attributeFields[DscAttr] = QgsField( attr[DscAttr], QVariant::String, "text" );
- attributeFields[SrcAttr] = QgsField( attr[SrcAttr], QVariant::String, "text" );
- attributeFields[URLAttr] = QgsField( attr[URLAttr], QVariant::String, "text" );
- attributeFields[URLNameAttr] = QgsField( attr[URLNameAttr], QVariant::String, "text" );
+
+ // construct QgsFieldMap from the field vector (legacy)
+ for (int i = 0; i < mAttributeVector.count(); i++)
+ mAttributeFields.insert(i, mAttributeVector[i]);
+
mFileName = uri.left( fileNameEnd );
// parse the file
@@ -177,13 +178,13 @@
*/
uint QgsGPXProvider::fieldCount() const
{
- return attributeFields.size();
+ return mAttributeVector.size();
}
const QgsFieldMap& QgsGPXProvider::fields() const
{
- return attributeFields;
+ return mAttributeFields;
}
Modified: branches/threading-branch/src/providers/gpx/qgsgpxprovider.h
===================================================================
--- branches/threading-branch/src/providers/gpx/qgsgpxprovider.h 2010-08-09 12:23:27 UTC (rev 14035)
+++ branches/threading-branch/src/providers/gpx/qgsgpxprovider.h 2010-08-09 14:08:05 UTC (rev 14036)
@@ -151,14 +151,27 @@
QgsGPSData* data;
//! Fields
- QgsFieldMap attributeFields;
+ QgsFieldMap mAttributeFields;
+ QVector<QgsField> mAttributeVector;
+
QString mFileName;
enum { WaypointType, RouteType, TrackType } mFeatureType;
- enum Attribute { NameAttr = 0, EleAttr, SymAttr, NumAttr,
- CmtAttr, DscAttr, SrcAttr, URLAttr, URLNameAttr
- };
+ enum Attribute {
+ /* common attributes */
+ NameAttr = 0,
+ CmtAttr,
+ DscAttr,
+ SrcAttr,
+ URLAttr,
+ URLNameAttr,
+ /* waypoint attributes */
+ EleAttr = 6,
+ SymAttr = 7,
+ /* route/track attributes */
+ NumAttr = 6
+ };
static const char* attr[];
bool mValid;
Modified: branches/threading-branch/src/providers/grass/qgsgrassprovider.cpp
===================================================================
--- branches/threading-branch/src/providers/grass/qgsgrassprovider.cpp 2010-08-09 12:23:27 UTC (rev 14035)
+++ branches/threading-branch/src/providers/grass/qgsgrassprovider.cpp 2010-08-09 14:08:05 UTC (rev 14036)
@@ -290,8 +290,8 @@
*/
uint QgsGrassProvider::fieldCount() const
{
- QgsDebugMsg( QString( "return: %1" ).arg( mLayers[mLayerId].fields.size() ) );
- return mLayers[mLayerId].fields.size();
+ QgsDebugMsg( QString( "return: %1" ).arg( mLayers[mLayerId].fieldVector.size() ) );
+ return mLayers[mLayerId].fieldVector.size();
}
/**
@@ -419,6 +419,7 @@
// Reset and free
layer.fields.clear();
+ layer.fieldVector.clear();
if ( layer.attributes )
{
for ( int i = 0; i < layer.nAttributes; i ++ )
@@ -451,6 +452,7 @@
layer.nAttributes = 0;
layer.attributes = 0;
layer.fields.clear();
+ layer.fieldVector.clear();
layer.keyColumn = -1;
if ( layer.fieldInfo == NULL )
{
@@ -525,8 +527,8 @@
qtype = QVariant::String;
break;
}
- layer.fields[i] = QgsField( db_get_column_name( column ), qtype, ctypeStr,
- db_get_column_length( column ), db_get_column_precision( column ) );
+ layer.fieldVector.append( QgsField( db_get_column_name( column ), qtype, ctypeStr,
+ db_get_column_length( column ), db_get_column_precision( column ) ) );
if ( G_strcasecmp( db_get_column_name( column ), layer.fieldInfo->key ) == 0 )
{
@@ -534,9 +536,14 @@
}
}
+ // make a copy of field vector - field map (legacy)
+ for ( int i = 0; i < layer.fieldVector.size(); i++ )
+ layer.fields.insert( i, layer.fieldVector[i] );
+
if ( layer.keyColumn < 0 )
{
layer.fields.clear();
+ layer.fieldVector.clear();
layer.nColumns = 0;
QMessageBox::warning( 0, "Warning", "Key column '" + QString( layer.fieldInfo->key ) +
@@ -616,7 +623,7 @@
db_close_database_shutdown_driver( databaseDriver );
db_free_string( &dbstr );
- QgsDebugMsg( QString( "fields.size = %1" ).arg( layer.fields.size() ) );
+ QgsDebugMsg( QString( "fieldVector.size = %1" ).arg( layer.fieldVector.size() ) );
QgsDebugMsg( QString( "number of attributes = %1" ).arg( layer.nAttributes ) );
}
@@ -627,7 +634,8 @@
if ( layer.nColumns == 0 )
{
layer.keyColumn = 0;
- layer.fields[0] = ( QgsField( "cat", QVariant::Int, "integer" ) );
+ layer.fieldVector.append( QgsField( "cat", QVariant::Int, "integer" ) );
+ layer.fields[0] = layer.fieldVector[0]; // legacy
layer.minmax = new double[1][2];
layer.minmax[0][0] = 0;
layer.minmax[0][1] = 0;
@@ -671,6 +679,7 @@
// Column names/types
mLayers[layerId].fields.clear();
+ mLayers[layerId].fieldVector.clear();
// Attributes
QgsDebugMsg( "Delete attribute values" );
@@ -961,6 +970,9 @@
#if QGISDEBUG > 3
QgsDebugMsg( QString( "setFeatureAttributes cat = %1" ).arg( cat ) );
#endif
+
+ QVariant* attrs = feature->resizeAttributeVector( fieldCount() );
+
if ( mLayers[layerId].nColumns > 0 )
{
// find cat
@@ -975,17 +987,17 @@
if ( att != NULL )
{
QByteArray cstr( att->values[i] );
- feature->addAttribute( i, convertValue( mLayers[mLayerId].fields[i].type(), mEncoding->toUnicode( cstr ) ) );
+ attrs[i] = convertValue( mLayers[mLayerId].fieldVector[i].type(), mEncoding->toUnicode( cstr ) );
}
else /* it may happen that attributes are missing -> set to empty string */
{
- feature->addAttribute( i, QVariant() );
+ attrs[i].clear();
}
}
}
else
{
- feature->addAttribute( 0, QVariant( cat ) );
+ attrs[0] = cat;
}
}
@@ -994,6 +1006,9 @@
#if QGISDEBUG > 3
QgsDebugMsg( QString( "setFeatureAttributes cat = %1" ).arg( cat ) );
#endif
+
+ QVariant* attrs = feature->resizeAttributeVector( fieldCount() );
+
if ( mLayers[layerId].nColumns > 0 )
{
// find cat
@@ -1004,20 +1019,21 @@
for ( QgsAttributeList::const_iterator iter = attlist.begin(); iter != attlist.end(); ++iter )
{
+ int i = *iter;
if ( att != NULL )
{
- QByteArray cstr( att->values[*iter] );
- feature->addAttribute( *iter, convertValue( mLayers[mLayerId].fields[*iter].type(), mEncoding->toUnicode( cstr ) ) );
+ QByteArray cstr( att->values[i] );
+ attrs[i] = convertValue( mLayers[mLayerId].fieldVector[i].type(), mEncoding->toUnicode( cstr ) );
}
else /* it may happen that attributes are missing -> set to empty string */
{
- feature->addAttribute( *iter, QVariant() );
+ attrs[i].clear();
}
}
}
else
{
- feature->addAttribute( 0, QVariant( cat ) );
+ attrs[0] = cat;
}
}
Modified: branches/threading-branch/src/providers/grass/qgsgrassprovider.h
===================================================================
--- branches/threading-branch/src/providers/grass/qgsgrassprovider.h 2010-08-09 12:23:27 UTC (rev 14035)
+++ branches/threading-branch/src/providers/grass/qgsgrassprovider.h 2010-08-09 14:08:05 UTC (rev 14036)
@@ -74,7 +74,8 @@
int nColumns; // number of columns in database table, if 0, attributes are not available
// and category (column name 'cat') is used instead
int keyColumn; // number of key column
- QgsFieldMap fields; // description of layer fields
+ QgsFieldMap fields; // description of layer fields (legacy)
+ QVector<QgsField> fieldVector; // description of layer fields
int nAttributes; // number of attributes read to the memory (may be < nRecords)
GATT *attributes; // vector of attributes
double( *minmax )[2]; // minimum and maximum values of attributes
Modified: branches/threading-branch/src/providers/ogr/qgsogrfeatureiterator.cpp
===================================================================
--- branches/threading-branch/src/providers/ogr/qgsogrfeatureiterator.cpp 2010-08-09 12:23:27 UTC (rev 14035)
+++ branches/threading-branch/src/providers/ogr/qgsogrfeatureiterator.cpp 2010-08-09 14:08:05 UTC (rev 14036)
@@ -16,11 +16,11 @@
QgsRectangle rect,
bool fetchGeometry,
bool useIntersect )
- : QgsVectorDataProviderIterator(fetchAttributes, rect, fetchGeometry, useIntersect),
- P(p)
+ : QgsVectorDataProviderIterator( fetchAttributes, rect, fetchGeometry, useIntersect ),
+ P( p )
{
// first of all, lock the OGR layer!
- QgsDebugMsg("trying to lock OGR layer");
+ QgsDebugMsg( "trying to lock OGR layer" );
P->mLayerMutex.lock();
// set the selection rectangle pointer to 0
@@ -67,7 +67,7 @@
}
-bool QgsOgrFeatureIterator::nextFeature(QgsFeature& feature)
+bool QgsOgrFeatureIterator::nextFeature( QgsFeature& feature )
{
feature.setValid( false );
@@ -85,7 +85,6 @@
}
feature.setFeatureId( OGR_F_GetFID( fet ) );
- feature.clearAttributeMap();
/* fetch geometry */
if ( mFetchGeometry || mUseIntersect )
@@ -102,7 +101,13 @@
unsigned char *wkb = new unsigned char[OGR_G_WkbSize( geom )];
OGR_G_ExportToWkb( geom, ( OGRwkbByteOrder ) QgsApplication::endian(), wkb );
- feature.setGeometryAndOwnership( wkb, OGR_G_WkbSize( geom ) );
+ QgsGeometry* g = feature.geometry();
+ if ( !g )
+ feature.setGeometryAndOwnership( wkb, OGR_G_WkbSize( geom ) );
+ else
+ {
+ g->fromWkb( wkb, OGR_G_WkbSize( geom ) );
+ }
if ( mUseIntersect )
{
@@ -125,10 +130,12 @@
}
}
+ QVariant* attrs = feature.resizeAttributeVector( P->fieldCount() );
+
/* fetch attributes */
for ( QgsAttributeList::iterator it = mFetchAttributes.begin(); it != mFetchAttributes.end(); ++it )
{
- P->getFeatureAttribute( fet, feature, *it );
+ P->getFeatureAttribute( fet, feature, *it, attrs );
}
/* we have a feature, end this cycle */
@@ -168,7 +175,7 @@
bool QgsOgrFeatureIterator::close()
{
- if (mClosed)
+ if ( mClosed )
return false;
if ( mSelectionRectangle )
@@ -178,7 +185,7 @@
}
// we're done - unlock the mutex
- QgsDebugMsg("unlocking OGR layer");
+ QgsDebugMsg( "unlocking OGR layer" );
P->mLayerMutex.unlock();
mClosed = true;
Modified: branches/threading-branch/src/providers/ogr/qgsogrprovider.cpp
===================================================================
--- branches/threading-branch/src/providers/ogr/qgsogrprovider.cpp 2010-08-09 12:23:27 UTC (rev 14035)
+++ branches/threading-branch/src/providers/ogr/qgsogrprovider.cpp 2010-08-09 14:08:05 UTC (rev 14036)
@@ -341,6 +341,7 @@
{
//the attribute fields need to be read again when the encoding changes
mAttributeFields.clear();
+ mAttributeVector.clear();
OGRFeatureDefnH fdef = OGR_L_GetLayerDefn( ogrLayer );
if ( fdef )
{
@@ -381,12 +382,10 @@
default: varType = QVariant::String; // other unsupported, leave it as a string
}
- mAttributeFields.insert(
- i, QgsField(
- mEncoding->toUnicode( OGR_Fld_GetNameRef( fldDef ) ), varType,
- mEncoding->toUnicode( OGR_GetFieldTypeName( ogrType ) ),
- OGR_Fld_GetWidth( fldDef ),
- OGR_Fld_GetPrecision( fldDef ) ) );
+ QString fldName = mEncoding->toUnicode( OGR_Fld_GetNameRef( fldDef ) );
+ QString fldTypeName = mEncoding->toUnicode( OGR_GetFieldTypeName( ogrType ) );
+ mAttributeFields.insert( i, QgsField( fldName, varType, fldTypeName, OGR_Fld_GetWidth( fldDef ), OGR_Fld_GetPrecision( fldDef ) ) );
+ mAttributeVector.append( QgsField( fldName, varType, fldTypeName, OGR_Fld_GetWidth( fldDef ), OGR_Fld_GetPrecision( fldDef ) ) );
}
}
}
@@ -411,7 +410,7 @@
return QgsFeatureIterator();
}
- return QgsFeatureIterator( new QgsOgrFeatureIterator(this, fetchAttributes, rect, fetchGeometry, useIntersect) );
+ return QgsFeatureIterator( new QgsOgrFeatureIterator( this, fetchAttributes, rect, fetchGeometry, useIntersect ) );
}
@@ -421,14 +420,14 @@
QgsAttributeList fetchAttributes )
{
// make sure no other thread is accessing the layer right now
- QMutexLocker layerLocker(&mLayerMutex);
+ QMutexLocker layerLocker( &mLayerMutex );
OGRFeatureH fet = OGR_L_GetFeature( ogrLayer, featureId );
if ( fet == NULL )
return false;
feature.setFeatureId( OGR_F_GetFID( fet ) );
- feature.clearAttributeMap();
+ //feature.clearAttributeVector();
// skip features without geometry
if ( OGR_F_GetGeometryRef( fet ) == NULL && !mFetchFeaturesWithoutGeom )
{
@@ -450,10 +449,12 @@
feature.setGeometryAndOwnership( wkb, OGR_G_WkbSize( geom ) );
}
+ QVariant* attrs = feature.resizeAttributeVector( mAttributeVector.count() );
+
/* fetch attributes */
for ( QgsAttributeList::iterator it = fetchAttributes.begin(); it != fetchAttributes.end(); ++it )
{
- getFeatureAttribute( fet, feature, *it );
+ getFeatureAttribute( fet, feature, *it, attrs );
}
if ( OGR_F_GetGeometryRef( fet ) != NULL )
@@ -490,7 +491,7 @@
if ( !extent_ )
{
// make sure no other thread is accessing the layer right now
- QMutexLocker layerLocker(&mLayerMutex);
+ QMutexLocker layerLocker( &mLayerMutex );
extent_ = calloc( sizeof( OGREnvelope ), 1 );
@@ -572,7 +573,7 @@
return mAttributeFields.size();
}
-void QgsOgrProvider::getFeatureAttribute( OGRFeatureH ogrFet, QgsFeature & f, int attindex )
+void QgsOgrProvider::getFeatureAttribute( OGRFeatureH ogrFet, QgsFeature & f, int attindex, QVariant* attrs )
{
OGRFieldDefnH fldDef = OGR_F_GetFieldDefnRef( ogrFet, attindex );
@@ -582,25 +583,22 @@
return;
}
- QVariant value;
-
if ( OGR_F_IsFieldSet( ogrFet, attindex ) )
{
- switch ( mAttributeFields.value(attindex).type() )
+ switch ( mAttributeVector.at( attindex ).type() )
{
- case QVariant::String: value = QVariant( mEncoding->toUnicode( OGR_F_GetFieldAsString( ogrFet, attindex ) ) ); break;
- case QVariant::Int: value = QVariant( OGR_F_GetFieldAsInteger( ogrFet, attindex ) ); break;
- case QVariant::Double: value = QVariant( OGR_F_GetFieldAsDouble( ogrFet, attindex ) ); break;
+ case QVariant::String: attrs[attindex].setValue( mEncoding->toUnicode( OGR_F_GetFieldAsString( ogrFet, attindex ) ) ); break;
+ case QVariant::Int: attrs[attindex].setValue( OGR_F_GetFieldAsInteger( ogrFet, attindex ) ); break;
+ case QVariant::Double: attrs[attindex].setValue( OGR_F_GetFieldAsDouble( ogrFet, attindex ) ); break;
//case QVariant::DateTime: value = QVariant(QDateTime::fromString(str)); break;
default: assert( NULL && "unsupported field type" );
}
}
else
{
- value = QVariant( QString::null );
+ attrs[attindex].clear();
}
- f.addAttribute( attindex, value );
}
@@ -621,7 +619,7 @@
bool QgsOgrProvider::addFeature( QgsFeature& f )
{
// make sure no other thread is accessing the layer right now
- QMutexLocker layerLocker(&mLayerMutex);
+ QMutexLocker layerLocker( &mLayerMutex );
bool returnValue = true;
OGRFeatureDefnH fdef = OGR_L_GetLayerDefn( ogrLayer );
@@ -726,7 +724,7 @@
bool QgsOgrProvider::addAttributes( const QList<QgsField> &attributes )
{
// make sure no other thread is accessing the layer right now
- QMutexLocker layerLocker(&mLayerMutex);
+ QMutexLocker layerLocker( &mLayerMutex );
bool returnvalue = true;
@@ -769,7 +767,7 @@
bool QgsOgrProvider::changeAttributeValues( const QgsChangedAttributesMap & attr_map )
{
// make sure no other thread is accessing the layer right now
- QMutexLocker layerLocker(&mLayerMutex);
+ QMutexLocker layerLocker( &mLayerMutex );
for ( QgsChangedAttributesMap::const_iterator it = attr_map.begin(); it != attr_map.end(); ++it )
{
@@ -837,7 +835,7 @@
bool QgsOgrProvider::changeGeometryValues( QgsGeometryMap & geometry_map )
{
// make sure no other thread is accessing the layer right now
- QMutexLocker layerLocker(&mLayerMutex);
+ QMutexLocker layerLocker( &mLayerMutex );
OGRErr res;
OGRFeatureH theOGRFeature = 0;
@@ -947,7 +945,7 @@
bool QgsOgrProvider::deleteFeature( int id )
{
// make sure no other thread is accessing the layer right now
- QMutexLocker layerLocker(&mLayerMutex);
+ QMutexLocker layerLocker( &mLayerMutex );
return OGR_L_DeleteFeature( ogrLayer, id ) == OGRERR_NONE;
}
@@ -1674,7 +1672,7 @@
void QgsOgrProvider::uniqueValues( int index, QList<QVariant> &uniqueValues, int limit )
{
// make sure no other thread is accessing the layer right now
- QMutexLocker layerLocker(&mLayerMutex);
+ QMutexLocker layerLocker( &mLayerMutex );
QgsField fld = mAttributeFields[index];
QString theLayerName = OGR_FD_GetName( OGR_L_GetLayerDefn( ogrLayer ) );
@@ -1713,7 +1711,7 @@
QVariant QgsOgrProvider::minimumValue( int index )
{
// make sure no other thread is accessing the layer right now
- QMutexLocker layerLocker(&mLayerMutex);
+ QMutexLocker layerLocker( &mLayerMutex );
QgsField fld = mAttributeFields[index];
QString theLayerName = OGR_FD_GetName( OGR_L_GetLayerDefn( ogrLayer ) );
@@ -1750,7 +1748,7 @@
QVariant QgsOgrProvider::maximumValue( int index )
{
// make sure no other thread is accessing the layer right now
- QMutexLocker layerLocker(&mLayerMutex);
+ QMutexLocker layerLocker( &mLayerMutex );
QgsField fld = mAttributeFields[index];
QString theLayerName = OGR_FD_GetName( OGR_L_GetLayerDefn( ogrLayer ) );
@@ -1794,7 +1792,7 @@
bool QgsOgrProvider::syncToDisc()
{
// make sure no other thread is accessing the layer right now
- QMutexLocker layerLocker(&mLayerMutex);
+ QMutexLocker layerLocker( &mLayerMutex );
OGR_L_SyncToDisk( ogrLayer );
@@ -1825,7 +1823,7 @@
void QgsOgrProvider::recalculateFeatureCount()
{
// make sure no other thread is accessing the layer right now
- QMutexLocker layerLocker(&mLayerMutex);
+ QMutexLocker layerLocker( &mLayerMutex );
OGRGeometryH filter = OGR_L_GetSpatialFilter( ogrLayer );
if ( filter )
Modified: branches/threading-branch/src/providers/ogr/qgsogrprovider.h
===================================================================
--- branches/threading-branch/src/providers/ogr/qgsogrprovider.h 2010-08-09 12:23:27 UTC (rev 14035)
+++ branches/threading-branch/src/providers/ogr/qgsogrprovider.h 2010-08-09 14:08:05 UTC (rev 14036)
@@ -239,7 +239,7 @@
void loadFields();
/**Get an attribute associated with a feature*/
- void getFeatureAttribute( OGRFeatureH ogrFet, QgsFeature & f, int attindex );
+ void getFeatureAttribute( OGRFeatureH ogrFet, QgsFeature & f, int attindex, QVariant* attrs );
/** find out the number of features of the whole layer */
void recalculateFeatureCount();
@@ -247,6 +247,7 @@
private:
unsigned char *getGeometryPointer( OGRFeatureH fet );
QgsFieldMap mAttributeFields;
+ QVector<QgsField> mAttributeVector;
OGRDataSourceH ogrDataSource;
void *extent_;
Modified: branches/threading-branch/src/providers/osm/osmprovider.cpp
===================================================================
--- branches/threading-branch/src/providers/osm/osmprovider.cpp 2010-08-09 12:23:27 UTC (rev 14035)
+++ branches/threading-branch/src/providers/osm/osmprovider.cpp 2010-08-09 14:08:05 UTC (rev 14036)
@@ -126,16 +126,20 @@
}
// set up attributes depending on the feature type - same attributes for both point and way type so far
- mAttributeFields[TimestampAttr] = QgsField( attr[TimestampAttr], QVariant::String, "string" );
- mAttributeFields[UserAttr] = QgsField( attr[UserAttr], QVariant::String, "string" );
- mAttributeFields[TagAttr] = QgsField( attr[TagAttr], QVariant::String, "string" );
+ mAttributeVector.append( QgsField( attr[TimestampAttr], QVariant::String, "string" ) );
+ mAttributeVector.append( QgsField( attr[UserAttr], QVariant::String, "string" ) );
+ mAttributeVector.append( QgsField( attr[TagAttr], QVariant::String, "string" ) );
// add custom attributes - these were chosen by user through OSM plugin
for ( int tagId = 0; tagId < mCustomTagsList.count(); ++tagId )
{
- mAttributeFields[CustomTagAttr+tagId] = QgsField( mCustomTagsList[tagId], QVariant::String, "string" );
+ mAttributeVector.append( QgsField( mCustomTagsList[tagId], QVariant::String, "string" ) );
}
+ // copy the vector to field map (legacy)
+ for ( int i = 0; i < mAttributeVector.size(); i++ )
+ mAttributeFields.insert( i, mAttributeVector[i] );
+
// get source file name and database file name
mFileName = uri.left( fileNameEnd );
mDatabaseFileName = mFileName + ".db";
@@ -520,6 +524,8 @@
feature.setGeometryAndOwnership(( unsigned char * )geo, 24 ); // 24 is size of wkb point structure!
}
+ QVariant* attrs = feature.resizeAttributeVector( fieldCount() );
+
// fetch attributes
QgsAttributeList::const_iterator iter;
for ( iter = fetchAttrs.begin(); iter != fetchAttrs.end(); ++iter )
@@ -527,16 +533,16 @@
switch ( *iter )
{
case TimestampAttr:
- feature.addAttribute( TimestampAttr, QString::fromUtf8( selTimestamp ) ); break;
+ attrs[*iter] = QString::fromUtf8( selTimestamp ); break;
case UserAttr:
- feature.addAttribute( UserAttr, QString::fromUtf8( selUser ) ); break;
+ attrs[*iter] = QString::fromUtf8( selUser ); break;
case TagAttr:
- feature.addAttribute( TagAttr, tagsForObject( "node", selId ) ); break;
+ attrs[*iter] = tagsForObject( "node", selId ); break;
default: // suppose it's a custom tag
if ( *iter >= CustomTagAttr && *iter < CustomTagAttr + mCustomTagsList.count() )
{
- feature.addAttribute( *iter, tagForObject( "node", selId, mCustomTagsList[*iter-CustomTagAttr] ) );
+ attrs[*iter] = tagForObject( "node", selId, mCustomTagsList[*iter-CustomTagAttr] );
}
}
}
@@ -631,6 +637,8 @@
delete theGeometry; // make sure it's deleted
}
+ QVariant* attrs = feature.resizeAttributeVector( fieldCount() );
+
// fetch attributes
QgsAttributeList::const_iterator iter;
for ( iter = fetchAttrs.begin(); iter != fetchAttrs.end(); ++iter )
@@ -638,18 +646,18 @@
switch ( *iter )
{
case TimestampAttr:
- feature.addAttribute( TimestampAttr, QString::fromUtf8( selTimestamp ) );
+ attrs[*iter] = QString::fromUtf8( selTimestamp );
break;
case UserAttr:
- feature.addAttribute( UserAttr, QString::fromUtf8( selUser ) );
+ attrs[*iter] = QString::fromUtf8( selUser );
break;
case TagAttr:
- feature.addAttribute( TagAttr, tagsForObject( "way", selId ) );
+ attrs[*iter] = tagsForObject( "way", selId );
break;
default: // suppose it's a custom tag
if ( *iter >= CustomTagAttr && *iter < CustomTagAttr + mCustomTagsList.count() )
{
- feature.addAttribute( *iter, tagForObject( "way", selId, mCustomTagsList[*iter-CustomTagAttr] ) );
+ attrs[*iter] = tagForObject( "way", selId, mCustomTagsList[*iter-CustomTagAttr] );
}
}
}
@@ -778,7 +786,7 @@
uint QgsOSMDataProvider::fieldCount() const
{
- return mAttributeFields.size();
+ return mAttributeVector.size();
}
Modified: branches/threading-branch/src/providers/osm/osmprovider.h
===================================================================
--- branches/threading-branch/src/providers/osm/osmprovider.h 2010-08-09 12:23:27 UTC (rev 14035)
+++ branches/threading-branch/src/providers/osm/osmprovider.h 2010-08-09 14:08:05 UTC (rev 14036)
@@ -93,6 +93,8 @@
//! list of supported attribute fields
QgsFieldMap mAttributeFields;
+ QVector<QgsField> mAttributeVector;
+
friend class QgsOSMFeatureIterator;
mutable QMutex mDatabaseMutex;
Modified: branches/threading-branch/src/providers/postgres/qgspostgresfeatureiterator.cpp
===================================================================
--- branches/threading-branch/src/providers/postgres/qgspostgresfeatureiterator.cpp 2010-08-09 12:23:27 UTC (rev 14035)
+++ branches/threading-branch/src/providers/postgres/qgspostgresfeatureiterator.cpp 2010-08-09 14:08:05 UTC (rev 14036)
@@ -20,9 +20,8 @@
QgsRectangle rect,
bool fetchGeometry,
bool useIntersect )
-: QgsVectorDataProviderIterator(fetchAttributes, rect, fetchGeometry, useIntersect),
- P(p)
- , mFeatureQueueSize( 200 )
+: QgsVectorDataProviderIterator( fetchAttributes, rect, fetchGeometry, useIntersect ),
+ P( p ), mFeatureQueueSize( 200 )
{
P->mConnectionROMutex.lock();
@@ -73,7 +72,7 @@
}
-bool QgsPostgresFeatureIterator::nextFeature(QgsFeature& feature)
+bool QgsPostgresFeatureIterator::nextFeature( QgsFeature& feature )
{
feature.setValid( false );
@@ -118,22 +117,10 @@
}
// Now return the next feature from the queue
- if ( mFetchGeometry )
- {
- QgsGeometry* featureGeom = mFeatureQueue.front().geometryAndOwnership();
- feature.setGeometry( featureGeom );
- }
- else
- {
- feature.setGeometryAndOwnership( 0, 0 );
- }
- feature.setFeatureId( mFeatureQueue.front().id() );
- feature.setAttributeMap( mFeatureQueue.front().attributeMap() );
-
+ feature = mFeatureQueue.front();
mFeatureQueue.pop();
mFetched++;
- feature.setValid( true );
return true;
}
Modified: branches/threading-branch/src/providers/postgres/qgspostgresprovider.cpp
===================================================================
--- branches/threading-branch/src/providers/postgres/qgspostgresprovider.cpp 2010-08-09 12:23:27 UTC (rev 14035)
+++ branches/threading-branch/src/providers/postgres/qgspostgresprovider.cpp 2010-08-09 14:08:05 UTC (rev 14036)
@@ -456,7 +456,7 @@
}
feature.setFeatureId( oid );
- feature.clearAttributeMap();
+ //feature.clearAttributeVector();
int col; // first attribute column after geometry
@@ -483,25 +483,42 @@
col = 1;
}
+ QVariant* attrs = feature.resizeAttributeVector( mAttributeVector.count() );
+
// iterate attributes
for ( QgsAttributeList::const_iterator it = fetchAttributes.constBegin(); it != fetchAttributes.constEnd(); it++ )
{
- const QgsField &fld = field( *it );
+ int idx = *it;
+ const QgsField &fld = field( idx );
if ( fld.name() == primaryKey )
{
// primary key was already processed
- feature.addAttribute( *it, convertValue( fld.type(), QString::number( oid ) ) );
+ attrs[idx] = oid;
continue;
}
if ( !PQgetisnull( queryResult, row, col ) )
{
- feature.addAttribute( *it, convertValue( fld.type(), QString::fromUtf8( PQgetvalue( queryResult, row, col ) ) ) );
+ switch ( fld.type() )
+ {
+ case QVariant::Int:
+ attrs[idx] = atoi( PQgetvalue( queryResult, row, col ) );
+ break;
+ case QVariant::Double:
+ attrs[idx] = atof( PQgetvalue( queryResult, row, col ) );
+ break;
+ case QVariant::String:
+ attrs[idx] = QString::fromUtf8( PQgetvalue( queryResult, row, col ) );
+ break;
+ default:
+ attrs[idx] = convertValue( fld.type(), QString::fromUtf8( PQgetvalue( queryResult, row, col ) ) );
+ }
+
}
else
{
- feature.addAttribute( *it, QVariant( QString::null ) );
+ attrs[idx].clear();
}
col++;
@@ -516,11 +533,11 @@
}
QgsFeatureIterator QgsPostgresProvider::getFeatures( QgsAttributeList fetchAttributes,
- QgsRectangle rect,
- bool fetchGeometry,
- bool useIntersect )
+ QgsRectangle rect,
+ bool fetchGeometry,
+ bool useIntersect )
{
- return QgsFeatureIterator( new QgsPostgresFeatureIterator(this, fetchAttributes, rect, fetchGeometry, useIntersect ) );
+ return QgsFeatureIterator( new QgsPostgresFeatureIterator( this, fetchAttributes, rect, fetchGeometry, useIntersect ) );
}
@@ -550,7 +567,7 @@
bool QgsPostgresProvider::featureAtId( int featureId, QgsFeature& feature, bool fetchGeometry, QgsAttributeList fetchAttributes )
{
- QMutexLocker connectionROLocker(&mConnectionROMutex);
+ QMutexLocker connectionROLocker( &mConnectionROMutex );
feature.setValid( false );
QString cursorName = QString( "qgisfid%1" ).arg( providerId );
@@ -604,25 +621,12 @@
return geomType;
}
-const QgsField &QgsPostgresProvider::field( int index ) const
-{
- QgsFieldMap::const_iterator it = attributeFields.find( index );
-
- if ( it == attributeFields.constEnd() )
- {
- QgsDebugMsg( "Field " + QString::number( index ) + " not found." );
- throw PGFieldNotFound();
- }
-
- return it.value();
-}
-
/**
* Return the number of fields
*/
uint QgsPostgresProvider::fieldCount() const
{
- return attributeFields.size();
+ return mAttributeVector.size();
}
const QgsFieldMap & QgsPostgresProvider::fields() const
@@ -679,7 +683,7 @@
// The queries inside this loop could possibly be combined into one
// single query - this would make the code run faster.
- attributeFields.clear();
+ mAttributeVector.clear();
for ( int i = 0; i < PQnfields( result ); i++ )
{
QString fieldName = QString::fromUtf8( PQfname( result, i ) );
@@ -797,9 +801,14 @@
fields << fieldName;
- attributeFields.insert( i, QgsField( fieldName, fieldType, fieldTypeName, fieldSize, fieldModifier, fieldComment ) );
+ mAttributeVector.append( QgsField( fieldName, fieldType, fieldTypeName, fieldSize, fieldModifier, fieldComment ) );
}
+ // construct QgsFieldMap (for compatibility)
+ attributeFields.clear();
+ for ( int i = 0; i < mAttributeVector.count(); i++ )
+ attributeFields.insert( i, mAttributeVector.at( i ) );
+
return true;
}
@@ -1454,7 +1463,7 @@
bool QgsPostgresProvider::uniqueData( QString query, QString colName )
{
- QMutexLocker connectionROLocker(&mConnectionROMutex);
+ QMutexLocker connectionROLocker( &mConnectionROMutex );
// Check to see if the given column contains unique data
@@ -1725,7 +1734,7 @@
// Returns the minimum value of an attribute
QVariant QgsPostgresProvider::minimumValue( int index )
{
- QMutexLocker connectionROLocker(&mConnectionROMutex);
+ QMutexLocker connectionROLocker( &mConnectionROMutex );
try
{
@@ -1752,7 +1761,7 @@
// Returns the list of unique values of an attribute
void QgsPostgresProvider::uniqueValues( int index, QList<QVariant> &uniqueValues, int limit )
{
- QMutexLocker connectionROLocker(&mConnectionROMutex);
+ QMutexLocker connectionROLocker( &mConnectionROMutex );
uniqueValues.clear();
@@ -1791,22 +1800,17 @@
void QgsPostgresProvider::enumValues( int index, QStringList& enumList )
{
- QMutexLocker connectionROLocker(&mConnectionROMutex);
+ QMutexLocker connectionROLocker( &mConnectionROMutex );
enumList.clear();
- QString typeName;
- //find out type of index
- QgsFieldMap::const_iterator f_it = attributeFields.find( index );
- if ( f_it != attributeFields.constEnd() )
- {
- typeName = f_it.value().typeName();
- }
- else
- {
+ if ( index < 0 || index >= mAttributeVector.count() )
return;
- }
+ //find out type of index
+ QString typeName = mAttributeVector[index].typeName();
+ QString fldName = mAttributeVector[index].name();
+
//is type an enum?
QString typeSql = QString( "SELECT typtype FROM pg_type where typname = %1" ).arg( quotedValue( typeName ) );
Result typeRes = connectionRO->PQexec( typeSql );
@@ -1820,7 +1824,7 @@
if ( typtype.compare( "e", Qt::CaseInsensitive ) == 0 )
{
//try to read enum_range of attribute
- if ( !parseEnumRange( enumList, f_it->name() ) )
+ if ( !parseEnumRange( enumList, fldName ) )
{
enumList.clear();
}
@@ -1828,7 +1832,7 @@
else
{
//is there a domain check constraint for the attribute?
- if ( !parseDomainCheckConstraint( enumList, f_it->name() ) )
+ if ( !parseDomainCheckConstraint( enumList, fldName ) )
{
enumList.clear();
}
@@ -1924,7 +1928,7 @@
// Returns the maximum value of an attribute
QVariant QgsPostgresProvider::maximumValue( int index )
{
- QMutexLocker connectionROLocker(&mConnectionROMutex);
+ QMutexLocker connectionROLocker( &mConnectionROMutex );
try
{
@@ -1986,7 +1990,7 @@
QVariant QgsPostgresProvider::defaultValue( int fieldId )
{
- QMutexLocker connectionROLocker(&mConnectionROMutex);
+ QMutexLocker connectionROLocker( &mConnectionROMutex );
try
{
@@ -2140,11 +2144,11 @@
// e.g. for defaults
for ( QgsAttributeMap::const_iterator it = attributevec.begin(); it != attributevec.end(); it++ )
{
- QgsFieldMap::const_iterator fit = attributeFields.find( it.key() );
- if ( fit == attributeFields.end() )
+ int index = it.key();
+ if ( index < 0 || index >= mAttributeVector.count() )
continue;
- QString fieldname = fit->name();
+ QString fieldname = mAttributeVector[index].name();
QgsDebugMsg( "Checking field against: " + fieldname );
@@ -2156,7 +2160,7 @@
{
const QgsAttributeMap &attributevec = flist[i].attributeMap();
- QgsAttributeMap::const_iterator thisit = attributevec.find( it.key() );
+ QgsAttributeMap::const_iterator thisit = attributevec.find( index );
if ( thisit == attributevec.end() )
break;
@@ -2166,7 +2170,7 @@
insert += "," + quotedIdentifier( fieldname );
- QString defVal = defaultValue( it.key() ).toString();
+ QString defVal = defaultValue( index ).toString();
if ( i == flist.size() )
{
@@ -2181,7 +2185,7 @@
values += "," + defVal;
}
}
- else if ( fit->typeName() == "geometry" )
+ else if ( mAttributeVector[index].typeName() == "geometry" )
{
values += QString( ",geomfromewkt(%1)" ).arg( quotedValue( it->toString() ) );
}
@@ -2193,7 +2197,7 @@
else
{
// value is not unique => add parameter
- if ( fit->typeName() == "geometry" )
+ if ( mAttributeVector[index].typeName() == "geometry" )
{
values += QString( ",geomfromewkt($%1)" ).arg( defaultValues.size() + offset );
}
@@ -2364,7 +2368,7 @@
returnvalue = false;
}
- rewind();
+ loadFields();
return returnvalue;
}
@@ -2384,11 +2388,11 @@
for ( QgsAttributeIds::const_iterator iter = ids.begin(); iter != ids.end(); ++iter )
{
- QgsFieldMap::const_iterator field_it = attributeFields.find( *iter );
- if ( field_it == attributeFields.constEnd() )
+ int index = *iter;
+ if ( index < 0 || index >= mAttributeVector.count() )
continue;
- QString column = field_it->name();
+ QString column = mAttributeVector[index].name();
QString sql = QString( "ALTER TABLE %1 DROP COLUMN %2" )
.arg( mQuery )
.arg( quotedIdentifier( column ) );
@@ -2398,9 +2402,6 @@
if ( result == 0 || PQresultStatus( result ) == PGRES_FATAL_ERROR )
throw PGException( result );
PQclear( result );
-
- //delete the attribute from attributeFields
- attributeFields.remove( *iter );
}
connectionRW->PQexecNR( "COMMIT" );
@@ -2412,7 +2413,7 @@
returnvalue = false;
}
- rewind();
+ loadFields();
return returnvalue;
}
@@ -2583,9 +2584,9 @@
QgsAttributeList QgsPostgresProvider::attributeIndexes()
{
QgsAttributeList attributes;
- for ( QgsFieldMap::const_iterator it = attributeFields.constBegin(); it != attributeFields.constEnd(); ++it )
+ for ( int i = 0; i < mAttributeVector.count(); i++ )
{
- attributes.push_back( it.key() );
+ attributes.push_back( i );
}
return attributes;
}
@@ -2628,7 +2629,7 @@
if ( featuresCounted >= 0 )
return featuresCounted;
- QMutexLocker connectionROLocker(&mConnectionROMutex);
+ QMutexLocker connectionROLocker( &mConnectionROMutex );
// get total number of features
QString sql;
@@ -2663,7 +2664,7 @@
{
if ( layerExtent.isEmpty() )
{
- QMutexLocker connectionROLocker(&mConnectionROMutex);
+ QMutexLocker connectionROLocker( &mConnectionROMutex );
QString sql;
Result result;
Modified: branches/threading-branch/src/providers/postgres/qgspostgresprovider.h
===================================================================
--- branches/threading-branch/src/providers/postgres/qgspostgresprovider.h 2010-08-09 12:23:27 UTC (rev 14035)
+++ branches/threading-branch/src/providers/postgres/qgspostgresprovider.h 2010-08-09 14:08:05 UTC (rev 14036)
@@ -325,7 +325,7 @@
bool hasSufficientPermsAndCapabilities();
- const QgsField &field( int index ) const;
+ inline const QgsField &field( int index ) const;
/** Double quote a PostgreSQL identifier for placement in a SQL string.
*/
@@ -358,6 +358,7 @@
std::vector < QgsFeature > features;
QgsFieldMap attributeFields;
+ QVector<QgsField> mAttributeVector;
QString mDataComment;
friend class QgsPostgresFeatureIterator;
@@ -690,6 +691,13 @@
QString mPrimaryKeyDefault;
mutable QMutex mConnectionROMutex;
- };
+};
+
+const QgsField &QgsPostgresProvider::field( int index ) const
+{
+ return mAttributeVector.at( index );
+}
+
+
#endif
Modified: branches/threading-branch/src/providers/spatialite/qgsspatialitefeatureiterator.cpp
===================================================================
--- branches/threading-branch/src/providers/spatialite/qgsspatialitefeatureiterator.cpp 2010-08-09 12:23:27 UTC (rev 14035)
+++ branches/threading-branch/src/providers/spatialite/qgsspatialitefeatureiterator.cpp 2010-08-09 14:08:05 UTC (rev 14036)
@@ -24,7 +24,10 @@
{
P->mHandleMutex.lock();
- // preparing the SQL statement
+ // prepare the SQL statement:
+ // - first column is always ROWID
+ // - next columns are attributes (if required)
+ // - last column is geometry (if required)
QString sql = "SELECT ROWID";
for ( QgsAttributeList::const_iterator it = fetchAttributes.constBegin(); it != fetchAttributes.constEnd(); ++it )
@@ -151,89 +154,7 @@
if ( ret == SQLITE_ROW )
{
// one valid row has been fetched from the result set
- if ( !mFetchGeometry )
- {
- // no geometry was required
- feature.setGeometryAndOwnership( 0, 0 );
- }
-
- feature.clearAttributeMap();
-
- int ic;
- int n_columns = sqlite3_column_count( sqliteStatement );
- for ( ic = 0; ic < n_columns; ic++ )
- {
- if ( ic == 0 )
- {
- // first column always contains the ROWID
- feature.setFeatureId( sqlite3_column_int( sqliteStatement, ic ) );
- }
- else
- {
- // iterate attributes
- bool fetched = false;
- int nAttr = 1;
- for ( QgsAttributeList::const_iterator it = mFetchAttributes.constBegin(); it != mFetchAttributes.constEnd(); it++ )
- {
- if ( nAttr == ic )
- {
- // ok, this one is the corresponding attribure
- if ( sqlite3_column_type( sqliteStatement, ic ) == SQLITE_INTEGER )
- {
- // INTEGER value
- feature.addAttribute( *it, sqlite3_column_int( sqliteStatement, ic ) );
- fetched = true;
- }
- else if ( sqlite3_column_type( sqliteStatement, ic ) == SQLITE_FLOAT )
- {
- // DOUBLE value
- feature.addAttribute( *it, sqlite3_column_double( sqliteStatement, ic ) );
- fetched = true;
- }
- else if ( sqlite3_column_type( sqliteStatement, ic ) == SQLITE_TEXT )
- {
- // TEXT value
- const char *txt = ( const char * ) sqlite3_column_text( sqliteStatement, ic );
- QString str = QString::fromUtf8( txt );
- feature.addAttribute( *it, str );
- fetched = true;
- }
- else
- {
- // assuming NULL
- feature.addAttribute( *it, QVariant( QString::null ) );
- fetched = true;
- }
- }
- nAttr++;
- }
- if ( fetched )
- {
- continue;
- }
- if ( mFetchGeometry )
- {
- QString geoCol = QString( "AsBinary(%1)" ).arg( QgsSpatiaLiteProvider::quotedIdentifier( P->mGeometryColumn ) );
- if ( strcasecmp( geoCol.toUtf8().constData(), sqlite3_column_name( sqliteStatement, ic ) ) == 0 )
- {
- if ( sqlite3_column_type( sqliteStatement, ic ) == SQLITE_BLOB )
- {
- const void *blob = sqlite3_column_blob( sqliteStatement, ic );
- size_t blob_size = sqlite3_column_bytes( sqliteStatement, ic );
- unsigned char *featureGeom = new unsigned char[blob_size + 1];
- memset( featureGeom, '\0', blob_size + 1 );
- memcpy( featureGeom, blob, blob_size );
- feature.setGeometryAndOwnership( featureGeom, blob_size + 1 );
- }
- else
- {
- // NULL geometry
- feature.setGeometryAndOwnership( 0, 0 );
- }
- }
- }
- }
- }
+ P->getFeature( feature, sqliteStatement, mFetchAttributes, mFetchGeometry );
}
else
{
Modified: branches/threading-branch/src/providers/spatialite/qgsspatialiteprovider.cpp
===================================================================
--- branches/threading-branch/src/providers/spatialite/qgsspatialiteprovider.cpp 2010-08-09 12:23:27 UTC (rev 14035)
+++ branches/threading-branch/src/providers/spatialite/qgsspatialiteprovider.cpp 2010-08-09 14:08:05 UTC (rev 14036)
@@ -255,89 +255,7 @@
if ( ret == SQLITE_ROW )
{
// one valid row has been fetched from the result set
- if ( !fetchGeometry )
- {
- // no geometry was required
- feature.setGeometryAndOwnership( 0, 0 );
- }
-
- feature.clearAttributeMap();
-
- int ic;
- int n_columns = sqlite3_column_count( stmt );
- for ( ic = 0; ic < n_columns; ic++ )
- {
- if ( ic == 0 )
- {
- // first column always contains the ROWID
- feature.setFeatureId( sqlite3_column_int( stmt, ic ) );
- }
- else
- {
- // iterate attributes
- bool fetched = false;
- int nAttr = 1;
- for ( QgsAttributeList::const_iterator it = fetchAttributes.constBegin(); it != fetchAttributes.constEnd(); it++ )
- {
- if ( nAttr == ic )
- {
- // ok, this one is the corresponding attribure
- if ( sqlite3_column_type( stmt, ic ) == SQLITE_INTEGER )
- {
- // INTEGER value
- feature.addAttribute( *it, sqlite3_column_int( stmt, ic ) );
- fetched = true;
- }
- else if ( sqlite3_column_type( stmt, ic ) == SQLITE_FLOAT )
- {
- // DOUBLE value
- feature.addAttribute( *it, sqlite3_column_double( stmt, ic ) );
- fetched = true;
- }
- else if ( sqlite3_column_type( stmt, ic ) == SQLITE_TEXT )
- {
- // TEXT value
- const char *txt = ( const char * ) sqlite3_column_text( stmt, ic );
- QString str = QString::fromUtf8( txt );
- feature.addAttribute( *it, str );
- fetched = true;
- }
- else
- {
- // assuming NULL
- feature.addAttribute( *it, QVariant( QString::null ) );
- fetched = true;
- }
- }
- nAttr++;
- }
- if ( fetched )
- {
- continue;
- }
- if ( fetchGeometry )
- {
- QString geoCol = QString( "AsBinary(%1)" ).arg( quotedIdentifier( mGeometryColumn ) );
- if ( strcasecmp( geoCol.toUtf8().constData(), sqlite3_column_name( stmt, ic ) ) == 0 )
- {
- if ( sqlite3_column_type( stmt, ic ) == SQLITE_BLOB )
- {
- const void *blob = sqlite3_column_blob( stmt, ic );
- size_t blob_size = sqlite3_column_bytes( stmt, ic );
- unsigned char *featureGeom = new unsigned char[blob_size + 1];
- memset( featureGeom, '\0', blob_size + 1 );
- memcpy( featureGeom, blob, blob_size );
- feature.setGeometryAndOwnership( featureGeom, blob_size + 1 );
- }
- else
- {
- // NULL geometry
- feature.setGeometryAndOwnership( 0, 0 );
- }
- }
- }
- }
- }
+ getFeature( feature, stmt, fetchAttributes, fetchGeometry );
}
else
{
@@ -353,6 +271,58 @@
return true;
}
+void QgsSpatiaLiteProvider::getFeature( QgsFeature& feature, sqlite3_stmt* stmt, const QgsAttributeList& fetchAttributes, bool fetchGeometry )
+{
+ // first column always contains the ROWID
+ feature.setFeatureId( sqlite3_column_int( stmt, 0 ) );
+
+ int ic = 1; // starting from second column
+
+ QVariant* attrs = feature.resizeAttributeVector( fieldCount() );
+
+ // fetch attributes
+ for ( QgsAttributeList::const_iterator it = fetchAttributes.constBegin(); it != fetchAttributes.constEnd(); ++it, ++ic )
+ {
+ // ok, this one is the corresponding attribure
+ if ( sqlite3_column_type( stmt, ic ) == SQLITE_INTEGER )
+ {
+ // INTEGER value
+ attrs[ *it ] = sqlite3_column_int( stmt, ic );
+ }
+ else if ( sqlite3_column_type( stmt, ic ) == SQLITE_FLOAT )
+ {
+ // DOUBLE value
+ attrs[ *it ] = sqlite3_column_double( stmt, ic );
+ }
+ else if ( sqlite3_column_type( stmt, ic ) == SQLITE_TEXT )
+ {
+ // TEXT value
+ const char *txt = ( const char * ) sqlite3_column_text( stmt, ic );
+ attrs[ *it ] = QString::fromUtf8( txt );
+ }
+ else
+ {
+ // assuming NULL
+ }
+ }
+
+ // fetch geometry
+ if ( fetchGeometry && sqlite3_column_type( stmt, ic ) == SQLITE_BLOB )
+ {
+ const void *blob = sqlite3_column_blob( stmt, ic );
+ size_t blob_size = sqlite3_column_bytes( stmt, ic );
+ unsigned char *featureGeom = new unsigned char[blob_size];
+ memcpy( featureGeom, blob, blob_size );
+ feature.setGeometryAndOwnership( featureGeom, blob_size );
+ }
+ else
+ {
+ // no geometry was required or NULL geometry
+ feature.setGeometryAndOwnership( 0, 0 );
+ }
+
+}
+
QString QgsSpatiaLiteProvider::subsetString()
{
return mSubsetString;
Modified: branches/threading-branch/src/providers/spatialite/qgsspatialiteprovider.h
===================================================================
--- branches/threading-branch/src/providers/spatialite/qgsspatialiteprovider.h 2010-08-09 12:23:27 UTC (rev 14035)
+++ branches/threading-branch/src/providers/spatialite/qgsspatialiteprovider.h 2010-08-09 14:08:05 UTC (rev 14036)
@@ -258,6 +258,8 @@
/** loads fields from input file to member attributeFields */
void loadFields();
+ void getFeature( QgsFeature& feature, sqlite3_stmt* stmt, const QgsAttributeList& fetchAttributes, bool fetchGeometry );
+
QgsFieldMap attributeFields;
/**
* Flag indicating if the layer data source is a valid SpatiaLite layer
Modified: branches/threading-branch/src/providers/wfs/qgswfsfeatureiterator.cpp
===================================================================
--- branches/threading-branch/src/providers/wfs/qgswfsfeatureiterator.cpp 2010-08-09 12:23:27 UTC (rev 14035)
+++ branches/threading-branch/src/providers/wfs/qgswfsfeatureiterator.cpp 2010-08-09 14:08:05 UTC (rev 14036)
@@ -38,37 +38,24 @@
if (mClosed)
return false;
- feature.setValid( false );
-
//go through the loop until we find a feature in the filter
while ( mSelectedFeatures.size() != 0 && mFeatureIterator != mSelectedFeatures.end() )
{
QgsFeature* origFeature = P->mFeatures[*mFeatureIterator];
- feature.setFeatureId( origFeature->id() );
-
- //we need geometry anyway, e.g. for intersection tests
- QgsGeometry* geometry = origFeature->geometry();
- unsigned char *geom = geometry->asWkb();
- int geomSize = geometry->wkbSize();
- unsigned char* copiedGeom = new unsigned char[geomSize];
- memcpy( copiedGeom, geom, geomSize );
- feature.setGeometryAndOwnership( copiedGeom, geomSize );
-
- const QgsAttributeMap& attributes = origFeature->attributeMap();
- for ( QgsAttributeList::const_iterator it = mFetchAttributes.begin(); it != mFetchAttributes.end(); ++it )
+ if ( mUseIntersect && feature.geometry() && !feature.geometry()->intersects( mRect ) )
{
- feature.addAttribute( *it, attributes[*it] );
+ ++mFeatureIterator;
+ continue;
}
- ++mFeatureIterator;
- if ( mUseIntersect && feature.geometry() && !feature.geometry()->intersects( mRect ) )
- continue;
+ feature = *origFeature; // copy feature
- feature.setValid( true );
+ ++mFeatureIterator;
return true;
}
+ feature.setValid( false );
return false;
}
Modified: branches/threading-branch/src/providers/wfs/qgswfsprovider.cpp
===================================================================
--- branches/threading-branch/src/providers/wfs/qgswfsprovider.cpp 2010-08-09 12:23:27 UTC (rev 14035)
+++ branches/threading-branch/src/providers/wfs/qgswfsprovider.cpp 2010-08-09 14:08:05 UTC (rev 14036)
@@ -80,7 +80,7 @@
const QgsFieldMap & QgsWFSProvider::fields() const
{
- return mFields;
+ return mFieldMap;
}
QgsCoordinateReferenceSystem QgsWFSProvider::crs()
@@ -140,6 +140,10 @@
}
}
+ // copy field vector to field map (legacy)
+ for ( int i = 0; i < mFields.size(); i++ )
+ mFieldMap.insert( i, mFields[i] );
+
if ( mEncoding == QgsWFSProvider::GET )
{
return getFeatureGET( uri, geometryAttribute );
@@ -150,7 +154,7 @@
}
}
-int QgsWFSProvider::describeFeatureType( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields )
+int QgsWFSProvider::describeFeatureType( const QString& uri, QString& geometryAttribute, QgsFieldVector& fields )
{
switch ( mEncoding )
{
@@ -203,9 +207,9 @@
//allows fast searchings with attribute name. Also needed is attribute Index and type infos
QMap<QString, QPair<int, QgsField> > thematicAttributes;
- for ( QgsFieldMap::const_iterator it = mFields.begin(); it != mFields.end(); ++it )
+ for ( int i = 0; i < mFields.size(); i++ )
{
- thematicAttributes.insert( it.value().name(), qMakePair( it.key(), it.value() ) );
+ thematicAttributes.insert( mFields[i].name(), qMakePair( i, mFields[i] ) );
}
QgsWFSData dataReader( uri, &mExtent, &mSourceCRS, mFeatures, geometryAttribute, thematicAttributes, &mWKBType );
@@ -294,7 +298,7 @@
return 0;
}
-int QgsWFSProvider::describeFeatureTypeGET( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields )
+int QgsWFSProvider::describeFeatureTypeGET( const QString& uri, QString& geometryAttribute, QgsFieldVector& fields )
{
QByteArray result;
QgsHttpTransaction http( uri );
@@ -317,17 +321,17 @@
return 0;
}
-int QgsWFSProvider::describeFeatureTypePOST( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields )
+int QgsWFSProvider::describeFeatureTypePOST( const QString& uri, QString& geometryAttribute, QgsFieldVector& fields )
{
return 1; //soon...
}
-int QgsWFSProvider::describeFeatureTypeSOAP( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields )
+int QgsWFSProvider::describeFeatureTypeSOAP( const QString& uri, QString& geometryAttribute, QgsFieldVector& fields )
{
return 1; //soon...
}
-int QgsWFSProvider::describeFeatureTypeFile( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields )
+int QgsWFSProvider::describeFeatureTypeFile( const QString& uri, QString& geometryAttribute, QgsFieldVector& fields )
{
//first look in the schema file
QString noExtension = uri;
@@ -362,13 +366,12 @@
int i = 0;
for ( std::list<QString>::const_iterator it = thematicAttributes.begin(); it != thematicAttributes.end(); ++it, ++i )
{
- // TODO: is this correct?
- fields[i] = QgsField( *it, QVariant::String, "unknown" );
+ fields.append( QgsField( *it, QVariant::String, "unknown" ) );
}
return 0;
}
-int QgsWFSProvider::readAttributesFromSchema( QDomDocument& schemaDoc, QString& geometryAttribute, QgsFieldMap& fields ) const
+int QgsWFSProvider::readAttributesFromSchema( QDomDocument& schemaDoc, QString& geometryAttribute, QgsFieldVector& fields ) const
{
//get the <schema> root element
QDomNodeList schemaNodeList = schemaDoc.elementsByTagNameNS( "http://www.w3.org/2001/XMLSchema", "schema" );
@@ -432,6 +435,7 @@
return 5;
}
+ fields.clear();
for ( uint i = 0; i < attributeNodeList.length(); ++i )
{
QDomElement attributeElement = attributeNodeList.at( i ).toElement();
@@ -461,7 +465,7 @@
{
attributeType = QVariant::LongLong;
}
- fields[fields.size()] = QgsField( name, attributeType, type );
+ fields.append( QgsField( name, attributeType, type ) );
}
}
return 0;
Modified: branches/threading-branch/src/providers/wfs/qgswfsprovider.h
===================================================================
--- branches/threading-branch/src/providers/wfs/qgswfsprovider.h 2010-08-09 12:23:27 UTC (rev 14035)
+++ branches/threading-branch/src/providers/wfs/qgswfsprovider.h 2010-08-09 14:08:05 UTC (rev 14036)
@@ -99,7 +99,8 @@
protected:
- QgsFieldMap mFields;
+ QgsFieldMap mFieldMap;
+ QgsFieldVector mFields;
/**The encoding used for request/response. Can be GET, POST or SOAP*/
REQUEST_ENCODING mEncoding;
/**Bounding box for the layer*/
@@ -122,7 +123,7 @@
/**Collects information about the field types. Is called internally from QgsWFSProvider::getFeature. The method delegates the work to request specific ones and gives back the name of the geometry attribute and the thematic attributes with their types*/
- int describeFeatureType( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields );
+ int describeFeatureType( const QString& uri, QString& geometryAttribute, QgsFieldVector& fields );
//encoding specific methods of getFeature
int getFeatureGET( const QString& uri, const QString& geometryAttribute );
@@ -130,13 +131,13 @@
int getFeatureSOAP( const QString& uri, const QString& geometryAttribute );
int getFeatureFILE( const QString& uri, const QString& geometryAttribute );
//encoding specific methods of describeFeatureType
- int describeFeatureTypeGET( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields );
- int describeFeatureTypePOST( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields );
- int describeFeatureTypeSOAP( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields );
- int describeFeatureTypeFile( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields );
+ int describeFeatureTypeGET( const QString& uri, QString& geometryAttribute, QgsFieldVector& fields );
+ int describeFeatureTypePOST( const QString& uri, QString& geometryAttribute, QgsFieldVector& fields );
+ int describeFeatureTypeSOAP( const QString& uri, QString& geometryAttribute, QgsFieldVector& fields );
+ int describeFeatureTypeFile( const QString& uri, QString& geometryAttribute, QgsFieldVector& fields );
/**Reads the name of the geometry attribute, the thematic attributes and their types from a dom document. Returns 0 in case of success*/
- int readAttributesFromSchema( QDomDocument& schemaDoc, QString& geometryAttribute, QgsFieldMap& fields ) const;
+ int readAttributesFromSchema( QDomDocument& schemaDoc, QString& geometryAttribute, QgsFieldVector& fields ) const;
/**This method tries to guess the geometry attribute and the other attribute names from the .gml file if no schema is present. Returns 0 in case of success*/
int guessAttributesFromFile( const QString& uri, QString& geometryAttribute, std::list<QString>& thematicAttributes ) const;
More information about the QGIS-commit
mailing list