[mapserver-commits] r9590 - trunk/mapserver

svn at osgeo.org svn at osgeo.org
Mon Dec 7 13:28:50 EST 2009


Author: assefa
Date: 2009-12-07 13:28:49 -0500 (Mon, 07 Dec 2009)
New Revision: 9590

Modified:
   trunk/mapserver/HISTORY.TXT
   trunk/mapserver/mapgml.c
   trunk/mapserver/mapows.h
   trunk/mapserver/mapwfs.c
Log:
 WFS paging support (#2799)

Modified: trunk/mapserver/HISTORY.TXT
===================================================================
--- trunk/mapserver/HISTORY.TXT	2009-12-07 17:18:29 UTC (rev 9589)
+++ trunk/mapserver/HISTORY.TXT	2009-12-07 18:28:49 UTC (rev 9590)
@@ -14,6 +14,8 @@
 Current Version (SVN trunk):
 ----------------------------
 
+- WFS paging support (#2799)
+
 - Fixed joins do not accept crypted passwords (#2912)
 
 - Fixed HTML legend image samples truncated (#2636)

Modified: trunk/mapserver/mapgml.c
===================================================================
--- trunk/mapserver/mapgml.c	2009-12-07 17:18:29 UTC (rev 9589)
+++ trunk/mapserver/mapgml.c	2009-12-07 18:28:49 UTC (rev 9590)
@@ -1414,7 +1414,7 @@
 **
 ** Similar to msGMLWriteQuery() but tuned for use with WFS 1.0.0
 */
-int msGMLWriteWFSQuery(mapObj *map, FILE *stream, int maxfeatures, char *default_namespace_prefix, int outputformat)
+int msGMLWriteWFSQuery(mapObj *map, FILE *stream, int startindex, int maxfeatures, char *default_namespace_prefix, int outputformat)
 {
 #ifdef USE_WFS_SVR
   int status;
@@ -1423,7 +1423,8 @@
   shapeObj shape;
   rectObj  resultBounds = {-1.0,-1.0,-1.0,-1.0};
   int features = 0;
-  
+  int currentfeature =0;
+
   gmlGroupListObj *groupList=NULL;
   gmlItemListObj *itemList=NULL;
   gmlConstantListObj *constantList=NULL;
@@ -1478,6 +1479,7 @@
       const char *value;
       int featureIdIndex=-1; /* no feature id */
 
+      
       /* setup namespace, a layer can override the default */
       namespace_prefix = (char*) msOWSLookupMetadata(&(lp->metadata), "OFG", "namespace_prefix");
       if(!namespace_prefix) namespace_prefix = default_namespace_prefix;
@@ -1510,6 +1512,13 @@
       }
 
       for(j=0; j<lp->resultcache->numresults; j++) {
+
+        if (startindex > 0 && currentfeature < startindex)
+        {
+            currentfeature++;
+            continue;
+        }
+
         status = msLayerResultsGetShape(lp, &shape, lp->resultcache->results[j].tileindex, lp->resultcache->results[j].shapeindex);
         if(status != MS_SUCCESS) 
             return(status);

Modified: trunk/mapserver/mapows.h
===================================================================
--- trunk/mapserver/mapows.h	2009-12-07 17:18:29 UTC (rev 9589)
+++ trunk/mapserver/mapows.h	2009-12-07 18:28:49 UTC (rev 9590)
@@ -109,6 +109,7 @@
   char *pszSrs;
   char *pszResultType;
   char *pszPropertyName;
+  int nStartIndex;
 } wfsParamsObj;
 
 /*
@@ -399,7 +400,8 @@
 
 
 #ifdef USE_WFS_SVR
-MS_DLL_EXPORT int msGMLWriteWFSQuery(mapObj *map, FILE *stream, int maxfeatures, char *wfs_namespace, int outputformat);
+MS_DLL_EXPORT int msGMLWriteWFSQuery(mapObj *map, FILE *stream, int startindex, int maxfeatures, char *wfs_namespace, 
+                                     int outputformat);
 #endif
 
 

Modified: trunk/mapserver/mapwfs.c
===================================================================
--- trunk/mapserver/mapwfs.c	2009-12-07 17:18:29 UTC (rev 9589)
+++ trunk/mapserver/mapwfs.c	2009-12-07 18:28:49 UTC (rev 9590)
@@ -989,7 +989,8 @@
 int msWFSGetFeature(mapObj *map, wfsParamsObj *paramsObj, cgiRequestObj *req)
   /* const char *wmtver, char **names, char **values, int numentries) */
 {
-  int         i, j, maxfeatures=-1;
+  int   i, j; 
+  int   maxfeatures=-1,startindex=-1;
   const char *typename="";
   char       *script_url=NULL, *script_url_encoded;
   rectObj     bbox;
@@ -1318,6 +1319,34 @@
       maxfeatures = paramsObj->nMaxFeatures;
   }
 
+  if (paramsObj->nStartIndex >= 0)
+    startindex = paramsObj->nStartIndex;
+
+  /* set the max features to each layer that is available. Note that maxfeatures is
+     the total number of features that is returned and setting this for each layer
+     is not entirely exact (it is only exact if we query one layer) but overall it
+     should be better */
+  if (maxfeatures > 0)
+  {
+      /*if startindex is specified, do not set the maxfeatures on the layers. What we want is to retreive all
+        features that meet the criteria and then filter it when writing the gml (msGMLWriteWFSQuery)*/
+      if (startindex < 0)
+      {
+          for(j=0; j<map->numlayers; j++) 
+          {
+              layerObj *lp;
+              lp = GET_LAYER(map, j);
+              if (lp->status == MS_ON)
+              {
+                  /*over-ride the value only if it is unset or wfs maxfeattures is
+                    lower that what is currently set*/
+                  if (lp->maxfeatures <=0 || lp->maxfeatures > 0 && maxfeatures < lp->maxfeatures)
+                    lp->maxfeatures = maxfeatures;
+              }
+          }
+      }
+  }
+
   /* if (strcasecmp(names[i], "FEATUREID") == 0) */
   /* { */
   /*  */
@@ -1802,14 +1831,25 @@
     msFree(encoded_schema);
     msFree(encoded_typename);
 
-    /* handle case of maxfeatures = 0 */
-    if(maxfeatures != 0 && iResultTypeHits == 0)
-      msGMLWriteWFSQuery(map, stdout, maxfeatures, pszNameSpace, outputformat);
+    /*some validations on startindex, it should not be > that the total elements
+     TODO: should we send an exception?*/
+    if (startindex >=0 && startindex >=iNumberOfFeatures)
+    {   
+        msIO_printf("   <gml:boundedBy>\n"); 
+        msIO_printf("      <gml:null>missing</gml:null>\n");
+        msIO_printf("   </gml:boundedBy>\n"); 
+    }
+    else
+    {
+        /* handle case of maxfeatures = 0 */
+        if(maxfeatures != 0 && iResultTypeHits == 0)
+          msGMLWriteWFSQuery(map, stdout, startindex, maxfeatures, pszNameSpace, outputformat);
 
-    if (((iNumberOfFeatures==0) || (maxfeatures == 0)) && iResultTypeHits == 0) {
-      msIO_printf("   <gml:boundedBy>\n"); 
-      msIO_printf("      <gml:null>missing</gml:null>\n");
-      msIO_printf("   </gml:boundedBy>\n"); 
+        if (((iNumberOfFeatures==0) || (maxfeatures == 0)) && iResultTypeHits == 0) {
+          msIO_printf("   <gml:boundedBy>\n"); 
+          msIO_printf("      <gml:null>missing</gml:null>\n");
+          msIO_printf("   </gml:boundedBy>\n"); 
+        }
     }
 
     if(outputformat == OWS_GML2)
@@ -2017,6 +2057,7 @@
     if (paramsObj)
     {
         paramsObj->nMaxFeatures = -1;
+        paramsObj->nStartIndex = -1;
     }
 
     return paramsObj;
@@ -2089,6 +2130,9 @@
              
                 else if (strcasecmp(request->ParamNames[i], "MAXFEATURES") == 0)
                   wfsparams->nMaxFeatures = atoi(request->ParamValues[i]);
+
+                else if (strcasecmp(request->ParamNames[i], "STARTINDEX") == 0)
+                  wfsparams->nStartIndex = atoi(request->ParamValues[i]);
                 
                 else if (strcasecmp(request->ParamNames[i], "BBOX") == 0)
                   wfsparams->pszBbox = strdup(request->ParamValues[i]);
@@ -2219,6 +2263,11 @@
                 if (pszValue)
                   wfsparams->nMaxFeatures = atoi(pszValue);
 
+                 pszValue = (char*)CPLGetXMLValue(psGetFeature,  "startIndex", 
+                                                 NULL);
+                if (pszValue)
+                  wfsparams->nStartIndex = atoi(pszValue);
+
                 psQuery = CPLGetXMLNode(psGetFeature, "Query");
                 if (psQuery)
                 {



More information about the mapserver-commits mailing list