mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-25 00:58:06 -05:00
added support for QGIS mapserver GetFeatureInfo GML flavour
This commit is contained in:
parent
be318fe6b2
commit
c00bcb1bd0
@ -296,7 +296,18 @@ void QgsGml::startElement( const XML_Char* el, const XML_Char** attr )
|
||||
mAttributeName = localName;
|
||||
mStringCash.clear();
|
||||
}
|
||||
|
||||
// QGIS server (2.2) is using:
|
||||
// <Attribute value="My description" name="desc"/>
|
||||
else if ( theParseMode == feature
|
||||
&& localName.compare( "attribute", Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
QString name = readAttribute( "name", attr );
|
||||
if ( mThematicAttributes.contains( name ) )
|
||||
{
|
||||
QString value = readAttribute( "value", attr );
|
||||
setAttribute( name, value );
|
||||
}
|
||||
}
|
||||
|
||||
if ( mEpsg == 0 && ( localName == "Point" || localName == "MultiPoint" ||
|
||||
localName == "LineString" || localName == "MultiLineString" ||
|
||||
@ -332,29 +343,7 @@ void QgsGml::endElement( const XML_Char* el )
|
||||
{
|
||||
mParseModeStack.pop();
|
||||
|
||||
//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;
|
||||
}
|
||||
Q_ASSERT( mCurrentFeature );
|
||||
mCurrentFeature->setAttribute( att_it.value().first, QVariant( mStringCash ) );
|
||||
}
|
||||
setAttribute( mAttributeName, mStringCash );
|
||||
}
|
||||
else if ( theParseMode == geometry && localName == mGeometryAttribute )
|
||||
{
|
||||
@ -550,6 +539,33 @@ void QgsGml::characters( const XML_Char* chars, int len )
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGml::setAttribute( const QString& name, const QString& value )
|
||||
{
|
||||
//find index with attribute name
|
||||
QMap<QString, QPair<int, QgsField> >::const_iterator att_it = mThematicAttributes.find( name );
|
||||
if ( att_it != mThematicAttributes.constEnd() )
|
||||
{
|
||||
QVariant var;
|
||||
switch ( att_it.value().second.type() )
|
||||
{
|
||||
case QVariant::Double:
|
||||
var = QVariant( value.toDouble() );
|
||||
break;
|
||||
case QVariant::Int:
|
||||
var = QVariant( value.toInt() );
|
||||
break;
|
||||
case QVariant::LongLong:
|
||||
var = QVariant( value.toLongLong() );
|
||||
break;
|
||||
default: //string type is default
|
||||
var = QVariant( value );
|
||||
break;
|
||||
}
|
||||
Q_ASSERT( mCurrentFeature );
|
||||
mCurrentFeature->setAttribute( att_it.value().first, var );
|
||||
}
|
||||
}
|
||||
|
||||
int QgsGml::readEpsgFromAttribute( int& epsgNr, const XML_Char** attr ) const
|
||||
{
|
||||
int i = 0;
|
||||
@ -590,7 +606,7 @@ QString QgsGml::readAttribute( const QString& attributeName, const XML_Char** at
|
||||
{
|
||||
return QString( attr[i+1] );
|
||||
}
|
||||
++i;
|
||||
i += 2;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
@ -121,6 +121,9 @@ class CORE_EXPORT QgsGml : public QObject
|
||||
static_cast<QgsGml*>( data )->characters( chars, len );
|
||||
}
|
||||
|
||||
// Set current feature attribute
|
||||
void setAttribute( const QString& name, const QString& value );
|
||||
|
||||
//helper routines
|
||||
|
||||
/**Reads attribute srsName="EpsgCrsId:..."
|
||||
|
@ -79,7 +79,7 @@ QString QgsGmlSchema::readAttribute( const QString& attributeName, const XML_Cha
|
||||
{
|
||||
return QString( attr[i+1] );
|
||||
}
|
||||
++i;
|
||||
i += 2;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
@ -374,6 +374,7 @@ void QgsGmlSchema::startElement( const XML_Char* el, const XML_Char** attr )
|
||||
//QgsDebugMsg( "ns = " + ns + " localName = " + localName );
|
||||
|
||||
ParseMode parseMode = modeStackTop();
|
||||
//QgsDebugMsg ( QString("localName = %1 parseMode = %2").arg(localName).arg(parseMode) );
|
||||
|
||||
if ( ns == GML_NAMESPACE && localName == "boundedBy" )
|
||||
{
|
||||
@ -388,6 +389,7 @@ void QgsGmlSchema::startElement( const XML_Char* el, const XML_Char** attr )
|
||||
// with 'Member' apart standard gml:featureMember, but it is quite usual to
|
||||
// that the names ends with 'Member', e.g.: osgb:topographicMember, cityMember,...
|
||||
// so this is really fail if the name does not contain 'Member'
|
||||
|
||||
else if ( localName.endsWith( "member", Qt::CaseInsensitive ) )
|
||||
{
|
||||
mParseModeStack.push( QgsGmlSchema::featureMember );
|
||||
@ -398,12 +400,15 @@ void QgsGmlSchema::startElement( const XML_Char* el, const XML_Char** attr )
|
||||
// do nothing, we catch _feature children
|
||||
}
|
||||
// UMN Mapserver simple GetFeatureInfo response feature element (ends with _feature)
|
||||
// or featureMember children
|
||||
// or featureMember children.
|
||||
// QGIS mapserver 2.2 GetFeatureInfo is using <Feature id="###"> for feature member,
|
||||
// without any feature class distinction.
|
||||
else if ( elementName.endsWith( "_feature" )
|
||||
|| parseMode == QgsGmlSchema::featureMember
|
||||
|| parseMode == QgsGmlSchema::featureMembers )
|
||||
|| parseMode == QgsGmlSchema::featureMembers
|
||||
|| localName.compare( "feature", Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
//QgsDebugMsg ( "is feature path = " + path );
|
||||
QgsDebugMsg( "is feature path = " + path );
|
||||
if ( mFeatureClassMap.count( localName ) == 0 )
|
||||
{
|
||||
mFeatureClassMap.insert( localName, QgsGmlFeatureClass( localName, path ) );
|
||||
@ -425,9 +430,26 @@ void QgsGmlSchema::startElement( const XML_Char* el, const XML_Char** attr )
|
||||
{
|
||||
// An element in feature should be ordinary or geometry attribute
|
||||
//QgsDebugMsg( "is attribute");
|
||||
mParseModeStack.push( QgsGmlSchema::attribute );
|
||||
mAttributeName = localName;
|
||||
mStringCash.clear();
|
||||
|
||||
// Usually localName is attribute name, e.g.
|
||||
// <gml:desc>My description</gml:desc>
|
||||
// but QGIS server (2.2) is using:
|
||||
// <Attribute value="My description" name="desc"/>
|
||||
QString name = readAttribute( "name", attr );
|
||||
//QgsDebugMsg ( "attribute name = " + name );
|
||||
if ( localName.compare( "attribute", Qt::CaseInsensitive ) == 0
|
||||
&& !name.isEmpty() )
|
||||
{
|
||||
QString value = readAttribute( "value", attr );
|
||||
//QgsDebugMsg ( "attribute value = " + value );
|
||||
addAttribute( name, value );
|
||||
}
|
||||
else
|
||||
{
|
||||
mAttributeName = localName;
|
||||
mParseModeStack.push( QgsGmlSchema::attribute );
|
||||
mStringCash.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -466,41 +488,7 @@ void QgsGmlSchema::endElement( const XML_Char* el )
|
||||
|
||||
if ( mFeatureClassMap[mCurrentFeatureName].geometryAttributes().count( mAttributeName ) == 0 )
|
||||
{
|
||||
// It is not geometry attribute -> analyze value
|
||||
bool ok;
|
||||
mStringCash.toInt( &ok );
|
||||
QVariant::Type type = QVariant::String;
|
||||
if ( ok )
|
||||
{
|
||||
type = QVariant::Int;
|
||||
}
|
||||
else
|
||||
{
|
||||
mStringCash.toDouble( &ok );
|
||||
if ( ok )
|
||||
{
|
||||
type = QVariant::Double;
|
||||
}
|
||||
}
|
||||
//QgsDebugMsg( "mStringCash = " + mStringCash + " type = " + QVariant::typeToName( type ) );
|
||||
//QMap<QString, QgsField> & fields = mFeatureClassMap[mCurrentFeatureName].fields();
|
||||
QList<QgsField> & fields = mFeatureClassMap[mCurrentFeatureName].fields();
|
||||
int fieldIndex = mFeatureClassMap[mCurrentFeatureName].fieldIndex( mAttributeName );
|
||||
if ( fieldIndex == -1 )
|
||||
{
|
||||
QgsField field( mAttributeName, type );
|
||||
fields.append( field );
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsField &field = fields[fieldIndex];
|
||||
// check if type is sufficient
|
||||
if (( field.type() == QVariant::Int && ( type == QVariant::String || type == QVariant::Double ) ) ||
|
||||
( field.type() == QVariant::Double && type == QVariant::String ) )
|
||||
{
|
||||
field.setType( type );
|
||||
}
|
||||
}
|
||||
addAttribute( mAttributeName, mStringCash );
|
||||
}
|
||||
}
|
||||
else if ( ns == GML_NAMESPACE && localName == "boundedBy" )
|
||||
@ -531,6 +519,45 @@ void QgsGmlSchema::characters( const XML_Char* chars, int len )
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGmlSchema::addAttribute( const QString& name, const QString& value )
|
||||
{
|
||||
// It is not geometry attribute -> analyze value
|
||||
bool ok;
|
||||
value.toInt( &ok );
|
||||
QVariant::Type type = QVariant::String;
|
||||
if ( ok )
|
||||
{
|
||||
type = QVariant::Int;
|
||||
}
|
||||
else
|
||||
{
|
||||
value.toDouble( &ok );
|
||||
if ( ok )
|
||||
{
|
||||
type = QVariant::Double;
|
||||
}
|
||||
}
|
||||
//QgsDebugMsg( "mStringCash = " + mStringCash + " type = " + QVariant::typeToName( type ) );
|
||||
//QMap<QString, QgsField> & fields = mFeatureClassMap[mCurrentFeatureName].fields();
|
||||
QList<QgsField> & fields = mFeatureClassMap[mCurrentFeatureName].fields();
|
||||
int fieldIndex = mFeatureClassMap[mCurrentFeatureName].fieldIndex( name );
|
||||
if ( fieldIndex == -1 )
|
||||
{
|
||||
QgsField field( name, type );
|
||||
fields.append( field );
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsField &field = fields[fieldIndex];
|
||||
// check if type is sufficient
|
||||
if (( field.type() == QVariant::Int && ( type == QVariant::String || type == QVariant::Double ) ) ||
|
||||
( field.type() == QVariant::Double && type == QVariant::String ) )
|
||||
{
|
||||
field.setType( type );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QStringList QgsGmlSchema::typeNames() const
|
||||
{
|
||||
return mFeatureClassMap.keys();
|
||||
|
@ -131,6 +131,8 @@ class CORE_EXPORT QgsGmlSchema : public QObject
|
||||
{
|
||||
static_cast<QgsGmlSchema*>( data )->characters( chars, len );
|
||||
}
|
||||
// Add attribute or reset its type according to value of current feature
|
||||
void addAttribute( const QString& name, const QString& value );
|
||||
|
||||
//helper routines
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user