Skip to content

Commit e53f4a8

Browse files
committed
[BUGFIX][Server] WFS GeoJSON: QGIS Server 2.18 much slower than 2.14
Fixed #18249 The JsonExporter was generated for each feature exported to GeoJSON.
1 parent 3f31100 commit e53f4a8

File tree

2 files changed

+68
-40
lines changed

2 files changed

+68
-40
lines changed

src/server/qgswfsserver.cpp

Lines changed: 59 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -516,13 +516,13 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
516516

517517
//Using pending attributes and pending fields
518518
QgsAttributeList attrIndexes = layer->pendingAllAttributesList();
519+
QgsFields fields = layer->pendingFields();
519520

520521
QDomNodeList queryChildNodes = queryElem.childNodes();
521522
if ( queryChildNodes.size() )
522523
{
523524
QStringList::const_iterator alstIt;
524525
QList<int> idxList;
525-
QgsFields fields = layer->pendingFields();
526526
// build corresponding propertyname
527527
QList<QString> propertynames;
528528
for ( int idx = 0; idx < fields.count(); ++idx )
@@ -548,9 +548,17 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
548548
}
549549
}
550550
}
551-
if ( !idxList.isEmpty() )
551+
attrIndexes = idxList;
552+
}
553+
if ( !attrIndexes.isEmpty() && !layerExcludedAttributes.isEmpty() )
554+
{
555+
foreach ( const QString &excludedAttribute, layerExcludedAttributes )
552556
{
553-
attrIndexes = idxList;
557+
int fieldNameIdx = fields.fieldNameIndex( excludedAttribute );
558+
if ( fieldNameIdx > -1 && attrIndexes.contains( fieldNameIdx ) )
559+
{
560+
attrIndexes.removeOne( fieldNameIdx );
561+
}
554562
}
555563
}
556564

@@ -609,7 +617,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
609617
if ( featureCounter == 0 )
610618
startGetFeature( request, format, layerPrec, layerCrs, &searchRect );
611619

612-
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, layerExcludedAttributes, provider->pkAttributeIndexes() );
620+
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, provider->pkAttributeIndexes() );
613621

614622
fid = "";
615623
++featCounter;
@@ -648,7 +656,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
648656

649657
if ( featureCounter >= startIndex )
650658
{
651-
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, layerExcludedAttributes, provider->pkAttributeIndexes() );
659+
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, provider->pkAttributeIndexes() );
652660
++featCounter;
653661
}
654662
++featureCounter;
@@ -702,7 +710,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
702710

703711
if ( featureCounter >= startIndex )
704712
{
705-
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, layerExcludedAttributes, provider->pkAttributeIndexes() );
713+
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, provider->pkAttributeIndexes() );
706714
++featCounter;
707715
}
708716
++featureCounter;
@@ -720,7 +728,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
720728

721729
if ( featureCounter >= startIndex )
722730
{
723-
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, layerExcludedAttributes, provider->pkAttributeIndexes() );
731+
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, provider->pkAttributeIndexes() );
724732
++featCounter;
725733
}
726734
++featureCounter;
@@ -933,14 +941,14 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
933941

934942
//Using pending attributes and pending fields
935943
QgsAttributeList attrIndexes = layer->pendingAllAttributesList();
944+
QgsFields fields = layer->pendingFields();
936945
if ( mPropertyName != "*" )
937946
{
938947
QStringList attrList = mPropertyName.split( "," );
939948
if ( !attrList.isEmpty() )
940949
{
941950
QStringList::const_iterator alstIt;
942951
QList<int> idxList;
943-
QgsFields fields = layer->pendingFields();
944952
// build corresponding propertyname
945953
QList<QString> propertynames;
946954
for ( int idx = 0; idx < fields.count(); ++idx )
@@ -957,9 +965,17 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
957965
idxList.append( fieldNameIdx );
958966
}
959967
}
960-
if ( !idxList.isEmpty() )
968+
attrIndexes = idxList;
969+
}
970+
}
971+
if ( !attrIndexes.isEmpty() && !layerExcludedAttributes.isEmpty() )
972+
{
973+
foreach ( const QString &excludedAttribute, layerExcludedAttributes )
974+
{
975+
int fieldNameIdx = fields.fieldNameIndex( excludedAttribute );
976+
if ( fieldNameIdx > -1 && attrIndexes.contains( fieldNameIdx ) )
961977
{
962-
attrIndexes = idxList;
978+
attrIndexes.removeOne( fieldNameIdx );
963979
}
964980
}
965981
}
@@ -989,7 +1005,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
9891005
if ( featureCounter == 0 )
9901006
startGetFeature( request, format, layerPrec, layerCrs, &searchRect );
9911007

992-
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, layerExcludedAttributes, provider->pkAttributeIndexes() );
1008+
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, provider->pkAttributeIndexes() );
9931009
++featCounter;
9941010
++featureCounter;
9951011
}
@@ -1038,7 +1054,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
10381054

10391055
if ( featureCounter >= startIndex )
10401056
{
1041-
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, layerExcludedAttributes, provider->pkAttributeIndexes() );
1057+
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, provider->pkAttributeIndexes() );
10421058
++featCounter;
10431059
}
10441060
++featureCounter;
@@ -1075,7 +1091,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
10751091
if ( featureCounter == 0 )
10761092
startGetFeature( request, format, layerPrec, layerCrs, &searchRect );
10771093

1078-
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, layerExcludedAttributes, provider->pkAttributeIndexes() );
1094+
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, provider->pkAttributeIndexes() );
10791095

10801096
fid = "";
10811097
++featCounter;
@@ -1114,7 +1130,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
11141130

11151131
if ( featureCounter >= startIndex )
11161132
{
1117-
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, layerExcludedAttributes, provider->pkAttributeIndexes() );
1133+
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, provider->pkAttributeIndexes() );
11181134
++featCounter;
11191135
}
11201136
++featureCounter;
@@ -1163,7 +1179,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
11631179

11641180
if ( featureCounter >= startIndex )
11651181
{
1166-
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, layerExcludedAttributes, provider->pkAttributeIndexes() );
1182+
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, provider->pkAttributeIndexes() );
11671183
++featCounter;
11681184
}
11691185
++featureCounter;
@@ -1202,7 +1218,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
12021218

12031219
if ( featureCounter >= startIndex )
12041220
{
1205-
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, layerExcludedAttributes, provider->pkAttributeIndexes() );
1221+
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, provider->pkAttributeIndexes() );
12061222
++featCounter;
12071223
}
12081224
++featureCounter;
@@ -1375,7 +1391,7 @@ void QgsWFSServer::startGetFeature( QgsRequestHandler& request, const QString& f
13751391
fcString = "";
13761392
}
13771393

1378-
void QgsWFSServer::setGetFeature( QgsRequestHandler& request, const QString& format, QgsFeature* feat, int featIdx, int prec, QgsCoordinateReferenceSystem& crs, const QgsAttributeList& attrIndexes, const QSet<QString>& excludedAttributes,
1394+
void QgsWFSServer::setGetFeature( QgsRequestHandler& request, const QString& format, QgsFeature* feat, int featIdx, int prec, QgsCoordinateReferenceSystem& crs, const QgsAttributeList& attrIndexes,
13791395
const QgsAttributeList& pkAttributes ) /*const*/
13801396
{
13811397
if ( !feat->isValid() )
@@ -1389,7 +1405,11 @@ void QgsWFSServer::setGetFeature( QgsRequestHandler& request, const QString& for
13891405
fcString += " ";
13901406
else
13911407
fcString += " ,";
1392-
fcString += createFeatureGeoJSON( feat, prec, crs, attrIndexes, excludedAttributes, pkAttributes );
1408+
mJsonExporter.setSourceCrs( crs );
1409+
mJsonExporter.setIncludeGeometry( false );
1410+
mJsonExporter.setIncludeAttributes( !attrIndexes.isEmpty() );
1411+
mJsonExporter.setAttributes( attrIndexes );
1412+
fcString += createFeatureGeoJSON( feat, prec, crs, attrIndexes, pkAttributes );
13931413
fcString += "\n";
13941414

13951415
result = fcString.toUtf8();
@@ -1402,12 +1422,12 @@ void QgsWFSServer::setGetFeature( QgsRequestHandler& request, const QString& for
14021422
QDomElement featureElement;
14031423
if ( format == "GML3" )
14041424
{
1405-
featureElement = createFeatureGML3( feat, gmlDoc, prec, crs, attrIndexes, excludedAttributes, pkAttributes );
1425+
featureElement = createFeatureGML3( feat, gmlDoc, prec, crs, attrIndexes, pkAttributes );
14061426
gmlDoc.appendChild( featureElement );
14071427
}
14081428
else
14091429
{
1410-
featureElement = createFeatureGML2( feat, gmlDoc, prec, crs, attrIndexes, excludedAttributes, pkAttributes );
1430+
featureElement = createFeatureGML2( feat, gmlDoc, prec, crs, attrIndexes, pkAttributes );
14111431
gmlDoc.appendChild( featureElement );
14121432
}
14131433

@@ -1952,13 +1972,14 @@ QgsFeatureIds QgsWFSServer::getFeatureIdsFromFilter( const QDomElement& filterEl
19521972
return fids;
19531973
}
19541974

1955-
QString QgsWFSServer::createFeatureGeoJSON( QgsFeature* feat, int prec, QgsCoordinateReferenceSystem& crs, const QgsAttributeList& attrIndexes, const QSet<QString>& excludedAttributes,
1975+
QString QgsWFSServer::createFeatureGeoJSON( QgsFeature* feat, int prec, QgsCoordinateReferenceSystem& crs, const QgsAttributeList& attrIndexes,
19561976
const QgsAttributeList& pkAttributes ) /*const*/
19571977
{
19581978
QString id = QString( "%1.%2" ).arg( mTypeName, featureGmlId( feat, pkAttributes ) );
19591979

1960-
QgsJSONExporter exporter;
1961-
exporter.setSourceCrs( crs );
1980+
//QgsJSONExporter exporter;
1981+
//exporter.setSourceCrs( crs );
1982+
Q_UNUSED( crs );
19621983
//QgsJSONExporter force transform geometry to ESPG:4326
19631984
//and the RFC 7946 GeoJSON specification recommends limiting coordinate precision to 6
19641985
Q_UNUSED( prec );
@@ -1967,10 +1988,11 @@ QString QgsWFSServer::createFeatureGeoJSON( QgsFeature* feat, int prec, QgsCoord
19671988
//copy feature so we can modify its geometry as required
19681989
QgsFeature f( *feat );
19691990
const QgsGeometry* geom = feat->constGeometry();
1970-
exporter.setIncludeGeometry( false );
1991+
//exporter.setIncludeGeometry( false );
19711992
if ( geom && mWithGeom && mGeometryName != "NONE" )
19721993
{
1973-
exporter.setIncludeGeometry( true );
1994+
//exporter.setIncludeGeometry( true );
1995+
mJsonExporter.setIncludeGeometry( true );
19741996
if ( mGeometryName == "EXTENT" )
19751997
{
19761998
QgsRectangle box = geom->boundingBox();
@@ -1984,7 +2006,7 @@ QString QgsWFSServer::createFeatureGeoJSON( QgsFeature* feat, int prec, QgsCoord
19842006
}
19852007
}
19862008

1987-
const QgsFields* fields = feat->fields();
2009+
/*const QgsFields* fields = feat->fields();
19882010
QgsAttributeList attrsToExport;
19892011
for ( int i = 0; i < attrIndexes.count(); ++i )
19902012
{
@@ -2001,15 +2023,16 @@ QString QgsWFSServer::createFeatureGeoJSON( QgsFeature* feat, int prec, QgsCoord
20012023
}
20022024
20032025
attrsToExport << idx;
2004-
}
2026+
}*/
2027+
Q_UNUSED( attrIndexes );
20052028

2006-
exporter.setIncludeAttributes( !attrsToExport.isEmpty() );
2007-
exporter.setAttributes( attrsToExport );
2029+
//exporter.setIncludeAttributes( !attrsToExport.isEmpty() );
2030+
//exporter.setAttributes( attrsToExport );
20082031

2009-
return exporter.exportFeature( f, QVariantMap(), id );
2032+
return mJsonExporter.exportFeature( f, QVariantMap(), id );
20102033
}
20112034

2012-
QDomElement QgsWFSServer::createFeatureGML2( QgsFeature* feat, QDomDocument& doc, int prec, QgsCoordinateReferenceSystem& crs, const QgsAttributeList& attrIndexes, const QSet<QString>& excludedAttributes,
2035+
QDomElement QgsWFSServer::createFeatureGML2( QgsFeature* feat, QDomDocument& doc, int prec, QgsCoordinateReferenceSystem& crs, const QgsAttributeList& attrIndexes,
20132036
const QgsAttributeList& pkAttributes ) /*const*/
20142037
{
20152038
//gml:FeatureMember
@@ -2079,10 +2102,10 @@ QDomElement QgsWFSServer::createFeatureGML2( QgsFeature* feat, QDomDocument& doc
20792102
}
20802103
QString attributeName = fields->at( idx ).name();
20812104
//skip attribute if it is excluded from WFS publication
2082-
if ( excludedAttributes.contains( attributeName ) )
2105+
/*if ( excludedAttributes.contains( attributeName ) )
20832106
{
20842107
continue;
2085-
}
2108+
}*/
20862109

20872110
QDomElement fieldElem = doc.createElement( "qgs:" + attributeName.replace( " ", "_" ) );
20882111
QDomText fieldText = doc.createTextNode( featureAttributes[idx].toString() );
@@ -2093,7 +2116,7 @@ QDomElement QgsWFSServer::createFeatureGML2( QgsFeature* feat, QDomDocument& doc
20932116
return featureElement;
20942117
}
20952118

2096-
QDomElement QgsWFSServer::createFeatureGML3( QgsFeature* feat, QDomDocument& doc, int prec, QgsCoordinateReferenceSystem& crs, const QgsAttributeList& attrIndexes, const QSet<QString>& excludedAttributes,
2119+
QDomElement QgsWFSServer::createFeatureGML3( QgsFeature* feat, QDomDocument& doc, int prec, QgsCoordinateReferenceSystem& crs, const QgsAttributeList& attrIndexes,
20972120
const QgsAttributeList& pkAttributes ) /*const*/
20982121
{
20992122
//gml:FeatureMember
@@ -2163,10 +2186,10 @@ QDomElement QgsWFSServer::createFeatureGML3( QgsFeature* feat, QDomDocument& doc
21632186
}
21642187
QString attributeName = fields->at( idx ).name();
21652188
//skip attribute if it is excluded from WFS publication
2166-
if ( excludedAttributes.contains( attributeName ) )
2189+
/*if ( excludedAttributes.contains( attributeName ) )
21672190
{
21682191
continue;
2169-
}
2192+
}*/
21702193

21712194
QDomElement fieldElem = doc.createElement( "qgs:" + attributeName.replace( " ", "_" ) );
21722195
QDomText fieldText = doc.createTextNode( featureAttributes[idx].toString() );

src/server/qgswfsserver.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "qgsowsserver.h"
2727
#include "qgsvectorlayer.h"
2828
#include "qgswfsprojectparser.h"
29+
#include "qgsjsonutils.h"
2930

3031
class QgsCoordinateReferenceSystem;
3132
class QgsComposerLayerItem;
@@ -45,6 +46,7 @@ class QgsRectangle;
4546
class QgsGeometry;
4647
class QgsSymbol;
4748
class QgsRequestHandler;
49+
class QgsJSONExporter;
4850
class QFile;
4951
class QFont;
5052
class QImage;
@@ -107,28 +109,31 @@ class QgsWFSServer: public QgsOWSServer
107109
/* Error messages */
108110
QStringList mErrors;
109111

112+
/* GeoJSON Exporter */
113+
QgsJSONExporter mJsonExporter;
114+
/* WFS configParser */
110115
QgsWFSProjectParser* mConfigParser;
111116

112117
protected:
113118

114119
void startGetFeature( QgsRequestHandler& request, const QString& format, int prec, QgsCoordinateReferenceSystem& crs, QgsRectangle* rect );
115-
void setGetFeature( QgsRequestHandler& request, const QString& format, QgsFeature* feat, int featIdx, int prec, QgsCoordinateReferenceSystem& crs, const QgsAttributeList& attrIndexes, const QSet<QString>& excludedAttributes,
120+
void setGetFeature( QgsRequestHandler& request, const QString& format, QgsFeature* feat, int featIdx, int prec, QgsCoordinateReferenceSystem& crs, const QgsAttributeList& attrIndexes,
116121
const QgsAttributeList& pkAttributes = QgsAttributeList() );
117122
void endGetFeature( QgsRequestHandler& request, const QString& format );
118123

119124
//method for transaction
120125
QgsFeatureIds getFeatureIdsFromFilter( const QDomElement& filter, QgsVectorLayer* layer );
121126

122127
//methods to write GeoJSON
123-
QString createFeatureGeoJSON( QgsFeature* feat, int prec, QgsCoordinateReferenceSystem& crs, const QgsAttributeList& attrIndexes, const QSet<QString>& excludedAttributes,
128+
QString createFeatureGeoJSON( QgsFeature* feat, int prec, QgsCoordinateReferenceSystem& crs, const QgsAttributeList& attrIndexes,
124129
const QgsAttributeList& pkAttributes = QgsAttributeList() ) /*const*/;
125130

126131
//methods to write GML2
127-
QDomElement createFeatureGML2( QgsFeature* feat, QDomDocument& doc, int prec, QgsCoordinateReferenceSystem& crs, const QgsAttributeList& attrIndexes, const QSet<QString>& excludedAttributes,
132+
QDomElement createFeatureGML2( QgsFeature* feat, QDomDocument& doc, int prec, QgsCoordinateReferenceSystem& crs, const QgsAttributeList& attrIndexes,
128133
const QgsAttributeList& pkAttributes = QgsAttributeList() ) /*const*/;
129134

130135
//methods to write GML3
131-
QDomElement createFeatureGML3( QgsFeature* feat, QDomDocument& doc, int prec, QgsCoordinateReferenceSystem& crs, const QgsAttributeList& attrIndexes, const QSet<QString>& excludedAttributes,
136+
QDomElement createFeatureGML3( QgsFeature* feat, QDomDocument& doc, int prec, QgsCoordinateReferenceSystem& crs, const QgsAttributeList& attrIndexes,
132137
const QgsAttributeList& pkAttributes = QgsAttributeList() ) /*const*/;
133138

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

0 commit comments

Comments
 (0)