Skip to content

Commit 30b3b68

Browse files
committed
[FEATURE][QGIS Server] STARTINDEX param in WFS GetFeature Request
STARTINDEX is standard in WFS 2.0, but it's an extension for WFS 1.0 implemented in QGIS Server. STARTINDEX can be used to skip some features in the result set and in combination with MAXFEATURES provides for the ability to use WFS GetFeature to page through results. Note that STARTINDEX=0 means start with the first feature, skipping none.
1 parent cf60ddb commit 30b3b68

File tree

1 file changed

+67
-30
lines changed

1 file changed

+67
-30
lines changed

src/server/qgswfsserver.cpp

Lines changed: 67 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
411411

412412
long maxFeat = 0;
413413
long maxFeatures = -1;
414+
long startIndex = 0;
414415
long featureCounter = 0;
415416
int layerPrec = 8;
416417

@@ -426,6 +427,8 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
426427

427428
if ( docElem.hasAttribute( "maxFeatures" ) )
428429
maxFeatures = docElem.attribute( "maxFeatures" ).toLong();
430+
if ( docElem.hasAttribute( "startIndex" ) )
431+
startIndex = docElem.attribute( "startIndex" ).toLong();
429432

430433
QDomNodeList queryNodes = docElem.elementsByTagName( "Query" );
431434
QDomElement queryElem;
@@ -624,13 +627,16 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
624627
req.setSubsetOfAttributes( attrIndexes );
625628

626629
QgsFeatureIterator fit = layer->getFeatures( req );
627-
while ( fit.nextFeature( feature ) && ( maxFeatures == -1 || featureCounter < maxFeat ) )
630+
while ( fit.nextFeature( feature ) && ( maxFeatures == -1 || featureCounter < maxFeat + startIndex ) )
628631
{
629-
if ( featureCounter == 0 )
632+
if ( featureCounter == startIndex )
630633
startGetFeature( request, format, layerPrec, layerCrs, &searchRect );
631634

632-
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, layerExcludedAttributes );
633-
++featCounter;
635+
if ( featureCounter >= startIndex )
636+
{
637+
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, layerExcludedAttributes );
638+
++featCounter;
639+
}
634640
++featureCounter;
635641
}
636642
}
@@ -643,7 +649,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
643649
{
644650
throw QgsMapServiceException( "RequestNotWellFormed", filter->parserErrorString() );
645651
}
646-
while ( fit.nextFeature( feature ) && ( maxFeatures == -1 || featureCounter < maxFeat ) )
652+
while ( fit.nextFeature( feature ) && ( maxFeatures == -1 || featureCounter < maxFeat + startIndex ) )
647653
{
648654
expressionContext.setFeature( feature );
649655

@@ -654,26 +660,32 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
654660
}
655661
if ( res.toInt() != 0 )
656662
{
657-
if ( featureCounter == 0 )
663+
if ( featureCounter == startIndex )
658664
startGetFeature( request, format, layerPrec, layerCrs, &searchRect );
659665

660-
setGetFeature( request, format, &feature, featureCounter, layerPrec, layerCrs, attrIndexes, layerExcludedAttributes );
666+
if ( featureCounter >= startIndex )
667+
{
668+
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, layerExcludedAttributes );
669+
++featCounter;
670+
}
661671
++featureCounter;
662-
++featCounter;
663672
}
664673
}
665674
}
666675
}
667676
}
668677
else
669678
{
670-
while ( fit.nextFeature( feature ) && ( maxFeatures == -1 || featureCounter < maxFeat ) )
679+
while ( fit.nextFeature( feature ) && ( maxFeatures == -1 || featureCounter < maxFeat + startIndex ) )
671680
{
672-
if ( featureCounter == 0 )
681+
if ( featureCounter == startIndex )
673682
startGetFeature( request, format, layerPrec, layerCrs, &searchRect );
674683

675-
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, layerExcludedAttributes );
676-
++featCounter;
684+
if ( featureCounter >= startIndex )
685+
{
686+
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, layerExcludedAttributes );
687+
++featCounter;
688+
}
677689
++featureCounter;
678690
}
679691
}
@@ -692,7 +704,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
692704
QgsMessageLog::logMessage( mErrors.join( "\n" ) );
693705

694706
QgsMapLayerRegistry::instance()->removeAllMapLayers();
695-
if ( featureCounter == 0 )
707+
if ( featureCounter <= startIndex )
696708
startGetFeature( request, format, layerPrec, layerCrs, &searchRect );
697709
endGetFeature( request, format );
698710
return 0;
@@ -806,6 +818,15 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
806818
maxFeat = mfString.toLong( &mfOk, 10 );
807819
}
808820

821+
//read STARTINDEX
822+
QMap<QString, QString>::const_iterator siIt = mParameters.find( "STARTINDEX" );
823+
if ( siIt != mParameters.end() )
824+
{
825+
QString siString = siIt.value();
826+
bool siOk;
827+
startIndex = siString.toLong( &siOk, 10 );
828+
}
829+
809830
//read PROPERTYNAME
810831
mWithGeom = true;
811832
mPropertyName = "*";
@@ -959,7 +980,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
959980
{
960981
throw QgsMapServiceException( "RequestNotWellFormed", QString( "Expression filter error message: %1." ).arg( filter->parserErrorString() ) );
961982
}
962-
while ( fit.nextFeature( feature ) && ( maxFeatures == -1 || featureCounter < maxFeat ) )
983+
while ( fit.nextFeature( feature ) && ( maxFeatures == -1 || featureCounter < maxFeat + startIndex ) )
963984
{
964985
expressionContext.setFeature( feature );
965986
QVariant res = filter->evaluate( &expressionContext );
@@ -969,11 +990,14 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
969990
}
970991
if ( res.toInt() != 0 )
971992
{
972-
if ( featureCounter == 0 )
993+
if ( featureCounter == startIndex )
973994
startGetFeature( request, format, layerPrec, layerCrs, &searchRect );
974995

975-
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, layerExcludedAttributes );
976-
++featCounter;
996+
if ( featureCounter >= startIndex )
997+
{
998+
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, layerExcludedAttributes );
999+
++featCounter;
1000+
}
9771001
++featureCounter;
9781002
}
9791003
}
@@ -1040,13 +1064,16 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
10401064
req.setSubsetOfAttributes( attrIndexes );
10411065

10421066
QgsFeatureIterator fit = layer->getFeatures( req );
1043-
while ( fit.nextFeature( feature ) && ( maxFeatures == -1 || featureCounter < maxFeat ) )
1067+
while ( fit.nextFeature( feature ) && ( maxFeatures == -1 || featureCounter < maxFeat + startIndex ) )
10441068
{
1045-
if ( featureCounter == 0 )
1069+
if ( featureCounter == startIndex )
10461070
startGetFeature( request, format, layerPrec, layerCrs, &searchRect );
10471071

1048-
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, layerExcludedAttributes );
1049-
++featCounter;
1072+
if ( featureCounter >= startIndex )
1073+
{
1074+
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, layerExcludedAttributes );
1075+
++featCounter;
1076+
}
10501077
++featureCounter;
10511078
}
10521079
}
@@ -1078,7 +1105,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
10781105
}
10791106
req.setSubsetOfAttributes( attrIndexes );
10801107
QgsFeatureIterator fit = layer->getFeatures( req );
1081-
while ( fit.nextFeature( feature ) && ( maxFeatures == -1 || featureCounter < maxFeat ) )
1108+
while ( fit.nextFeature( feature ) && ( maxFeatures == -1 || featureCounter < maxFeat + startIndex ) )
10821109
{
10831110
expressionContext.setFeature( feature );
10841111
QVariant res = filter->evaluate( &expressionContext );
@@ -1088,12 +1115,15 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
10881115
}
10891116
if ( res.toInt() != 0 )
10901117
{
1091-
if ( featureCounter == 0 )
1118+
if ( featureCounter == startIndex )
10921119
startGetFeature( request, format, layerPrec, layerCrs, &searchRect );
10931120

1094-
setGetFeature( request, format, &feature, featureCounter, layerPrec, layerCrs, attrIndexes, layerExcludedAttributes );
1121+
if ( featureCounter >= startIndex )
1122+
{
1123+
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, layerExcludedAttributes );
1124+
++featCounter;
1125+
}
10951126
++featureCounter;
1096-
++featCounter;
10971127
}
10981128
}
10991129
}
@@ -1121,14 +1151,17 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
11211151
}
11221152
req.setSubsetOfAttributes( attrIndexes );
11231153
QgsFeatureIterator fit = layer->getFeatures( req );
1124-
while ( fit.nextFeature( feature ) && ( maxFeatures == -1 || featureCounter < maxFeat ) )
1154+
while ( fit.nextFeature( feature ) && ( maxFeatures == -1 || featureCounter < maxFeat + startIndex ) )
11251155
{
11261156
mErrors << QString( "The feature %2 of layer for the TypeName '%1'" ).arg( tnStr ).arg( featureCounter );
1127-
if ( featureCounter == 0 )
1157+
if ( featureCounter == startIndex )
11281158
startGetFeature( request, format, layerPrec, layerCrs, &searchRect );
11291159

1130-
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, layerExcludedAttributes );
1131-
++featCounter;
1160+
if ( featureCounter >= startIndex )
1161+
{
1162+
setGetFeature( request, format, &feature, featCounter, layerPrec, layerCrs, attrIndexes, layerExcludedAttributes );
1163+
++featCounter;
1164+
}
11321165
++featureCounter;
11331166
}
11341167
}
@@ -1142,7 +1175,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
11421175
}
11431176

11441177
QgsMapLayerRegistry::instance()->removeAllMapLayers();
1145-
if ( featureCounter == 0 )
1178+
if ( featureCounter <= startIndex )
11461179
startGetFeature( request, format, layerPrec, layerCrs, &searchRect );
11471180
endGetFeature( request, format );
11481181

@@ -1217,6 +1250,10 @@ void QgsWFSServer::startGetFeature( QgsRequestHandler& request, const QString& f
12171250
{
12181251
mapUrl.removeQueryItem( queryIt->first );
12191252
}
1253+
else if ( queryIt->first.compare( "STARTINDEX", Qt::CaseInsensitive ) == 0 )
1254+
{
1255+
mapUrl.removeQueryItem( queryIt->first );
1256+
}
12201257
else if ( queryIt->first.compare( "PROPERTYNAME", Qt::CaseInsensitive ) == 0 )
12211258
{
12221259
mapUrl.removeQueryItem( queryIt->first );

0 commit comments

Comments
 (0)