Skip to content

Commit

Permalink
Merge pull request #7870 from rldhont/server-wfs-format-field-218
Browse files Browse the repository at this point in the history
[Bugfix][Server][WFS] correctly define field type and encode values
  • Loading branch information
rldhont committed Sep 18, 2018
2 parents ff5bd09 + f427577 commit 018fd07
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 8 deletions.
42 changes: 36 additions & 6 deletions src/server/qgswfsprojectparser.cpp
Expand Up @@ -455,8 +455,8 @@ void QgsWFSProjectParser::describeFeatureType( const QString& aTypeName, QDomEle
const QgsFields& fields = layer->pendingFields();
for ( int idx = 0; idx < fields.count(); ++idx )
{

QString attributeName = fields.at( idx ).name();
const QgsField field = fields.at( idx );
QString attributeName = field.name();
//skip attribute if excluded from WFS publication
if ( layerExcludedAttributes.contains( attributeName ) )
{
Expand All @@ -466,27 +466,57 @@ void QgsWFSProjectParser::describeFeatureType( const QString& aTypeName, QDomEle
//xsd:element
QDomElement attElem = doc.createElement( "element"/*xsd:element*/ );
attElem.setAttribute( "name", attributeName.replace( " ", "_" ).replace( mCleanTagNameRegExp, "" ) );
QVariant::Type attributeType = fields[idx].type();
QVariant::Type attributeType = field.type();
if ( attributeType == QVariant::Int )
attElem.setAttribute( "type", "integer" );
{
attElem.setAttribute( "type", "int" );
}
else if ( attributeType == QVariant::UInt )
{
attElem.setAttribute( "type", "unsignedInt" );
}
else if ( attributeType == QVariant::LongLong )
{
attElem.setAttribute( "type", "long" );
}
else if ( attributeType == QVariant::ULongLong )
{
attElem.setAttribute( "type", "unsignedLong" );
}
else if ( attributeType == QVariant::Double )
attElem.setAttribute( "type", "double" );
{
// if the size is well known, it may be an integer
// else a decimal
// in sqlite the length is unknown but int type can be used
if ( field.length() != 0 && field.precision() == 0 )
attElem.setAttribute( "type", "integer" );
else
attElem.setAttribute( "type", "decimal" );
}
else if ( attributeType == QVariant::Bool )
{
attElem.setAttribute( "type", "boolean" );
}
else if ( attributeType == QVariant::Date )
{
attElem.setAttribute( "type", "date" );
}
else if ( attributeType == QVariant::Time )
{
attElem.setAttribute( "type", "time" );
}
else if ( attributeType == QVariant::DateTime )
{
attElem.setAttribute( "type", "dateTime" );
}
else
{
attElem.setAttribute( "type", "string" );
}

sequenceElem.appendChild( attElem );

QString alias = fields.at( idx ).alias();
QString alias = field.alias();
if ( !alias.isEmpty() )
{
attElem.setAttribute( "alias", alias );
Expand Down
52 changes: 50 additions & 2 deletions src/server/qgswfsserver.cpp
Expand Up @@ -2129,7 +2129,7 @@ QDomElement QgsWFSServer::createFeatureGML2( QgsFeature* feat, QDomDocument& doc
}*/

QDomElement fieldElem = doc.createElement( "qgs:" + attributeName.replace( " ", "_" ).replace( mConfigParser->getCleanTagNameRegExp(), "" ) );
QDomText fieldText = doc.createTextNode( featureAttributes[idx].toString() );
QDomText fieldText = doc.createTextNode( encodeValueToText( featureAttributes[idx] ) );
fieldElem.appendChild( fieldText );
typeNameElement.appendChild( fieldElem );
}
Expand Down Expand Up @@ -2213,14 +2213,62 @@ QDomElement QgsWFSServer::createFeatureGML3( QgsFeature* feat, QDomDocument& doc
}*/

QDomElement fieldElem = doc.createElement( "qgs:" + attributeName.replace( " ", "_" ).replace( mConfigParser->getCleanTagNameRegExp(), "" ) );
QDomText fieldText = doc.createTextNode( featureAttributes[idx].toString() );
QDomText fieldText = doc.createTextNode( encodeValueToText( featureAttributes[idx] ) );
fieldElem.appendChild( fieldText );
typeNameElement.appendChild( fieldElem );
}

return featureElement;
}

QString QgsWFSServer::encodeValueToText( const QVariant& value )
{
if ( value.isNull() )
return "null";

switch ( value.type() )
{
case QVariant::Int:
case QVariant::UInt:
case QVariant::LongLong:
case QVariant::ULongLong:
case QVariant::Double:
return value.toString();

case QVariant::Bool:
return value.toBool() ? "true" : "false";

case QVariant::StringList:
case QVariant::List:
case QVariant::Map:
{
QString v = QgsJSONUtils::encodeValue( value );

//do we need CDATA
if ( v.indexOf( '<' ) != -1 || v.indexOf( '&' ) != -1 )
{
v.prepend( "<![CDATA[" ).append( "]]>" );
}

return v;
}

default:
case QVariant::String:
{
QString v = value.toString();

//do we need CDATA
if ( v.indexOf( '<' ) != -1 || v.indexOf( '&' ) != -1 )
{
v.prepend( "<![CDATA[" ).append( "]]>" );
}

return v;
}
}
}

QString QgsWFSServer::serviceUrl() const
{
QUrl mapUrl( getenv( "REQUEST_URI" ) );
Expand Down
3 changes: 3 additions & 0 deletions src/server/qgswfsserver.h
Expand Up @@ -136,6 +136,9 @@ class QgsWFSServer: public QgsOWSServer
QDomElement createFeatureGML3( QgsFeature* feat, QDomDocument& doc, int prec, QgsCoordinateReferenceSystem& crs, const QgsAttributeList& attrIndexes,
const QgsAttributeList& pkAttributes = QgsAttributeList() ) /*const*/;

//methods to encode value to string for text node
QString encodeValueToText( const QVariant& value );

void addTransactionResult( QDomDocument& responseDoc, QDomElement& responseElem, const QString& status, const QString& locator, const QString& message );
};

Expand Down

0 comments on commit 018fd07

Please sign in to comment.