Skip to content

Commit b9f20b0

Browse files
authoredSep 27, 2018
Merge pull request #7902 from rldhont/server-wfs-format-field
[Bugfix][Server][WFS] Server wfs format field
2 parents 3a70f88 + 68ba754 commit b9f20b0

File tree

3 files changed

+149
-10
lines changed

3 files changed

+149
-10
lines changed
 

‎src/server/services/wfs/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ INCLUDE_DIRECTORIES(
4545
../../../core/raster
4646
../../../core/symbology
4747
../../../core/layertree
48+
../../../core/fieldformatter
4849
../..
4950
..
5051
.

‎src/server/services/wfs/qgswfsdescribefeaturetype.cpp

Lines changed: 68 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
#include "qgsvectordataprovider.h"
3131
#include "qgsmapserviceexception.h"
3232
#include "qgscoordinatereferencesystem.h"
33+
#include "qgsfieldformatterregistry.h"
34+
#include "qgsfieldformatter.h"
35+
#include "qgsdatetimefieldformatter.h"
3336

3437
#include <QStringList>
3538

@@ -251,8 +254,8 @@ namespace QgsWfs
251254
const QSet<QString> &layerExcludedAttributes = layer->excludeAttributesWfs();
252255
for ( int idx = 0; idx < fields.count(); ++idx )
253256
{
254-
255-
QString attributeName = fields.at( idx ).name();
257+
const QgsField field = fields.at( idx );
258+
QString attributeName = field.name();
256259
//skip attribute if excluded from WFS publication
257260
if ( layerExcludedAttributes.contains( attributeName ) )
258261
{
@@ -262,27 +265,86 @@ namespace QgsWfs
262265
//xsd:element
263266
QDomElement attElem = doc.createElement( QStringLiteral( "element" )/*xsd:element*/ );
264267
attElem.setAttribute( QStringLiteral( "name" ), attributeName.replace( ' ', '_' ).replace( cleanTagNameRegExp, QString() ) );
265-
QVariant::Type attributeType = fields.at( idx ).type();
268+
QVariant::Type attributeType = field.type();
266269
if ( attributeType == QVariant::Int )
267-
attElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "integer" ) );
270+
{
271+
attElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "int" ) );
272+
}
273+
else if ( attributeType == QVariant::UInt )
274+
{
275+
attElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "unsignedInt" ) );
276+
}
268277
else if ( attributeType == QVariant::LongLong )
278+
{
269279
attElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "long" ) );
280+
}
281+
else if ( attributeType == QVariant::ULongLong )
282+
{
283+
attElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "unsignedLong" ) );
284+
}
270285
else if ( attributeType == QVariant::Double )
271-
attElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "double" ) );
286+
{
287+
if ( field.length() != 0 && field.precision() == 0 )
288+
attElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "integer" ) );
289+
else
290+
attElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "decimal" ) );
291+
}
272292
else if ( attributeType == QVariant::Bool )
293+
{
273294
attElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "boolean" ) );
295+
}
274296
else if ( attributeType == QVariant::Date )
297+
{
275298
attElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "date" ) );
299+
}
276300
else if ( attributeType == QVariant::Time )
301+
{
277302
attElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "time" ) );
303+
}
278304
else if ( attributeType == QVariant::DateTime )
305+
{
279306
attElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "dateTime" ) );
307+
}
280308
else
309+
{
281310
attElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "string" ) );
311+
}
312+
313+
const QgsEditorWidgetSetup setup = field.editorWidgetSetup();
314+
if ( setup.type() == QStringLiteral( "DateTime" ) )
315+
{
316+
QgsDateTimeFieldFormatter fieldFormatter;
317+
const QVariantMap config = setup.config();
318+
const QString fieldFormat = config.value( QStringLiteral( "field_format" ), fieldFormatter.defaultFormat( field.type() ) ).toString();
319+
if ( fieldFormat == QStringLiteral( "yyyy-MM-dd" ) )
320+
attElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "date" ) );
321+
else if ( fieldFormat == QStringLiteral( "HH:mm:ss" ) )
322+
attElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "time" ) );
323+
else
324+
attElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "dateTime" ) );
325+
}
326+
else if ( setup.type() == QStringLiteral( "Range" ) )
327+
{
328+
const QVariantMap config = setup.config();
329+
if ( config.contains( QStringLiteral( "Precision" ) ) )
330+
{
331+
// if precision in range config is not the same as the attributePrec
332+
// we need to update type
333+
bool ok;
334+
int configPrec( config[ QStringLiteral( "Precision" ) ].toInt( &ok ) );
335+
if ( ok && configPrec != field.precision() )
336+
{
337+
if ( configPrec == 0 )
338+
attElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "integer" ) );
339+
else
340+
attElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "decimal" ) );
341+
}
342+
}
343+
}
282344

283345
sequenceElem.appendChild( attElem );
284346

285-
QString alias = fields.at( idx ).alias();
347+
QString alias = field.alias();
286348
if ( !alias.isEmpty() )
287349
{
288350
attElem.setAttribute( QStringLiteral( "alias" ), alias );

‎src/server/services/wfs/qgswfsgetfeature.cpp

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
#include "qgswfsutils.h"
2323
#include "qgsserverprojectutils.h"
2424
#include "qgsfields.h"
25+
#include "qgsfieldformatterregistry.h"
26+
#include "qgsfieldformatter.h"
27+
#include "qgsdatetimefieldformatter.h"
2528
#include "qgsexpression.h"
2629
#include "qgsgeometry.h"
2730
#include "qgsmaplayer.h"
@@ -62,6 +65,8 @@ namespace QgsWfs
6265

6366
QString createFeatureGeoJSON( QgsFeature *feat, const createFeatureParams &params );
6467

68+
QString encodeValueToText( const QVariant &value, const QgsEditorWidgetSetup &setup );
69+
6570
QDomElement createFeatureGML2( QgsFeature *feat, QDomDocument &doc, const createFeatureParams &params, const QgsProject *project );
6671

6772
QDomElement createFeatureGML3( QgsFeature *feat, QDomDocument &doc, const createFeatureParams &params, const QgsProject *project );
@@ -1335,10 +1340,12 @@ namespace QgsWfs
13351340
{
13361341
continue;
13371342
}
1338-
QString attributeName = fields.at( idx ).name();
1343+
const QgsField field = fields.at( idx );
1344+
const QgsEditorWidgetSetup setup = field.editorWidgetSetup();
1345+
QString attributeName = field.name();
13391346

13401347
QDomElement fieldElem = doc.createElement( "qgs:" + attributeName.replace( ' ', '_' ).replace( cleanTagNameRegExp, QString() ) );
1341-
QDomText fieldText = doc.createTextNode( featureAttributes[idx].toString() );
1348+
QDomText fieldText = doc.createTextNode( encodeValueToText( featureAttributes[idx], setup ) );
13421349
fieldElem.appendChild( fieldText );
13431350
typeNameElement.appendChild( fieldElem );
13441351
}
@@ -1430,18 +1437,87 @@ namespace QgsWfs
14301437
{
14311438
continue;
14321439
}
1433-
QString attributeName = fields.at( idx ).name();
1440+
const QgsField field = fields.at( idx );
1441+
const QgsEditorWidgetSetup setup = field.editorWidgetSetup();
1442+
QString attributeName = field.name();
14341443

14351444
QDomElement fieldElem = doc.createElement( "qgs:" + attributeName.replace( ' ', '_' ).replace( cleanTagNameRegExp, QString() ) );
1436-
QDomText fieldText = doc.createTextNode( featureAttributes[idx].toString() );
1445+
QDomText fieldText = doc.createTextNode( encodeValueToText( featureAttributes[idx], setup ) );
14371446
fieldElem.appendChild( fieldText );
14381447
typeNameElement.appendChild( fieldElem );
14391448
}
14401449

14411450
return featureElement;
14421451
}
14431452

1453+
QString encodeValueToText( const QVariant &value, const QgsEditorWidgetSetup &setup )
1454+
{
1455+
if ( value.isNull() )
1456+
return QStringLiteral( "null" );
1457+
1458+
if ( setup.type() == QStringLiteral( "DateTime" ) )
1459+
{
1460+
QgsDateTimeFieldFormatter fieldFormatter;
1461+
const QVariantMap config = setup.config();
1462+
const QString fieldFormat = config.value( QStringLiteral( "field_format" ), fieldFormatter.defaultFormat( value.type() ) ).toString();
1463+
QDateTime date = value.toDateTime();
1464+
1465+
if ( date.isValid() )
1466+
{
1467+
return date.toString( fieldFormat );
1468+
}
1469+
}
1470+
else if ( setup.type() == QStringLiteral( "Range" ) )
1471+
{
1472+
const QVariantMap config = setup.config();
1473+
if ( config.contains( QStringLiteral( "Precision" ) ) )
1474+
{
1475+
// if precision is defined, use it
1476+
bool ok;
1477+
int precision( config[ QStringLiteral( "Precision" ) ].toInt( &ok ) );
1478+
if ( ok )
1479+
return QString::number( value.toDouble(), 'f', precision );
1480+
}
1481+
}
1482+
1483+
switch ( value.type() )
1484+
{
1485+
case QVariant::Int:
1486+
case QVariant::UInt:
1487+
case QVariant::LongLong:
1488+
case QVariant::ULongLong:
1489+
case QVariant::Double:
1490+
return value.toString();
1491+
1492+
case QVariant::Bool:
1493+
return value.toBool() ? QStringLiteral( "true" ) : QStringLiteral( "false" );
1494+
1495+
case QVariant::StringList:
1496+
case QVariant::List:
1497+
case QVariant::Map:
1498+
{
1499+
QString v = QgsJsonUtils::encodeValue( value );
1500+
1501+
//do we need CDATA
1502+
if ( v.indexOf( '<' ) != -1 || v.indexOf( '&' ) != -1 )
1503+
v.prepend( QStringLiteral( "<![CDATA[" ) ).append( QStringLiteral( "]]>" ) );
1504+
1505+
return v;
1506+
}
1507+
1508+
default:
1509+
case QVariant::String:
1510+
{
1511+
QString v = value.toString();
1512+
1513+
//do we need CDATA
1514+
if ( v.indexOf( '<' ) != -1 || v.indexOf( '&' ) != -1 )
1515+
v.prepend( QStringLiteral( "<![CDATA[" ) ).append( QStringLiteral( "]]>" ) );
14441516

1517+
return v;
1518+
}
1519+
}
1520+
}
14451521

14461522

14471523
} // namespace

0 commit comments

Comments
 (0)
Please sign in to comment.