Skip to content

Commit

Permalink
Improved handling of attribute types in WFS provider
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@10866 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
mhugent committed May 31, 2009
1 parent dcb312e commit 6373876
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 14 deletions.
29 changes: 24 additions & 5 deletions src/providers/wfs/qgswfsdata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ QgsWFSData::QgsWFSData(
QgsCoordinateReferenceSystem* srs,
QList<QgsFeature*> &features,
const QString& geometryAttribute,
const QSet<QString>& thematicAttributes,
const QMap<QString, QPair<int, QgsField> >& thematicAttributes,
QGis::WkbType* wkbType )
: QObject(),
mUri( uri ),
Expand Down Expand Up @@ -193,7 +193,6 @@ void QgsWFSData::startElement( const XML_Char* el, const XML_Char** attr )
else if ( elementName == GML_NAMESPACE + NS_SEPARATOR + "featureMember" )
{
mCurrentFeature = new QgsFeature( mFeatureCount );
mAttributeIndex = 0;
mParseModeStack.push( QgsWFSData::featureMember );
}
else if ( elementName == GML_NAMESPACE + NS_SEPARATOR + "Box" && mParseModeStack.top() == QgsWFSData::boundingBox )
Expand Down Expand Up @@ -262,15 +261,35 @@ void QgsWFSData::endElement( const XML_Char* el )
mParseModeStack.pop();
}
}
else if ( localName == mAttributeName )
else if ( localName == mAttributeName ) //add a thematic attribute to the feature
{
if ( !mParseModeStack.empty() )
{
mParseModeStack.pop();
}

mCurrentFeature->addAttribute( mAttributeIndex, QVariant( mStringCash ) );
++mAttributeIndex;
//find index with attribute name
QMap<QString, QPair<int, QgsField> >::const_iterator att_it = mThematicAttributes.find(mAttributeName);
if(att_it != mThematicAttributes.constEnd())
{
QVariant var;
switch(att_it.value().second.type())
{
case QVariant::Double:
var = QVariant(mStringCash.toDouble());
break;
case QVariant::Int:
var = QVariant(mStringCash.toInt());
break;
case QVariant::LongLong:
var = QVariant(mStringCash.toLongLong());
break;
default: //string type is default
var = QVariant( mStringCash );
break;
}
mCurrentFeature->addAttribute(att_it.value().first, QVariant( mStringCash ));
}
}
else if ( localName == mGeometryAttribute )
{
Expand Down
7 changes: 3 additions & 4 deletions src/providers/wfs/qgswfsdata.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "qgsapplication.h"
#include "qgsdataprovider.h"
#include "qgsfeature.h"
#include "qgsfield.h"
#include "qgspoint.h"
#include <list>
#include <set>
Expand All @@ -40,7 +41,7 @@ class QgsWFSData: public QObject
QgsCoordinateReferenceSystem* srs,
QList<QgsFeature*> &features,
const QString& geometryAttribute,
const QSet<QString>& thematicAttributes,
const QMap<QString, QPair<int, QgsField> >& thematicAttributes,
QGis::WkbType* wkbType );
~QgsWFSData();

Expand Down Expand Up @@ -150,7 +151,7 @@ class QgsWFSData: public QObject
QList<QgsFeature*> &mFeatures;
/**Name of geometry attribute*/
QString mGeometryAttribute;
const QSet<QString> &mThematicAttributes;
const QMap<QString, QPair<int, QgsField> > &mThematicAttributes;
QGis::WkbType* mWkbType;
/**True if the request is finished*/
bool mFinished;
Expand All @@ -171,8 +172,6 @@ class QgsWFSData: public QObject
/**Similar to mCurrentWKB, but only the size*/
std::list< std::list<int> > mCurrentWKBFragmentSizes;
QString mAttributeName;
/**Index where the current attribute should be inserted*/
int mAttributeIndex;
QString mTypeName;
QgsApplication::endian_t mEndian;
/**Coordinate separator for coordinate strings. Usually "," */
Expand Down
25 changes: 20 additions & 5 deletions src/providers/wfs/qgswfsprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ int QgsWFSProvider::describeFeatureType( const QString& uri, QString& geometryAt

int QgsWFSProvider::getFeatureGET( const QString& uri, const QString& geometryAttribute )
{
#if 0
#if 0 //the old and slower method with DOM
//assemble request string
QString request = uri /*+ "&OUTPUTFORMAT=gml3"*/; //use gml2 as it is supported by most wfs servers
QByteArray result;
Expand Down Expand Up @@ -265,11 +265,13 @@ int QgsWFSProvider::getFeatureGET( const QString& uri, const QString& geometryAt
return 0;
#endif

//the new and faster method with the expat parser
QSet<QString> thematicAttributes;
//the new and faster method with the expat SAX parser

//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 )
{
thematicAttributes << it->name();
thematicAttributes.insert(it.value().name(), qMakePair(it.key(), it.value()));
}

QgsWFSData dataReader( uri, &mExtent, &mSourceCRS, mFeatures, geometryAttribute, thematicAttributes, &mWKBType );
Expand Down Expand Up @@ -512,7 +514,20 @@ int QgsWFSProvider::readAttributesFromSchema( QDomDocument& schemaDoc, QString&
}
else //todo: distinguish between numerical and non-numerical types
{
fields[fields.size()] = QgsField( name, QVariant::String, type );
QVariant::Type attributeType = QVariant::String; //string is default type
if(type.contains("double", Qt::CaseInsensitive) || type.contains("float", Qt::CaseInsensitive))
{
attributeType = QVariant::Double;
}
else if(type.contains("int", Qt::CaseInsensitive))
{
attributeType = QVariant::Int;
}
else if(type.contains("long", Qt::CaseInsensitive))
{
attributeType = QVariant::LongLong;
}
fields[fields.size()] = QgsField( name, attributeType, type );
}
}
return 0;
Expand Down

0 comments on commit 6373876

Please sign in to comment.