[mapserver-commits] r9668 - trunk/mapserver
svn at osgeo.org
svn at osgeo.org
Tue Jan 5 09:54:35 EST 2010
Author: assefa
Date: 2010-01-05 09:54:33 -0500 (Tue, 05 Jan 2010)
New Revision: 9668
Modified:
trunk/mapserver/mapfile.c
trunk/mapserver/maplayer.c
trunk/mapserver/maporaclespatial.c
trunk/mapserver/mapserver.h
trunk/mapserver/mapwfs.c
Log:
wfs pagination support #2799
Modified: trunk/mapserver/mapfile.c
===================================================================
--- trunk/mapserver/mapfile.c 2010-01-05 11:56:00 UTC (rev 9667)
+++ trunk/mapserver/mapfile.c 2010-01-05 14:54:33 UTC (rev 9668)
@@ -2795,6 +2795,7 @@
layer->sizeunits = MS_PIXELS;
layer->maxfeatures = -1; /* no quota */
+ layer->startindex = -1; /*used for pagination*/
layer->template = layer->header = layer->footer = NULL;
Modified: trunk/mapserver/maplayer.c
===================================================================
--- trunk/mapserver/maplayer.c 2010-01-05 11:56:00 UTC (rev 9667)
+++ trunk/mapserver/maplayer.c 2010-01-05 14:54:33 UTC (rev 9668)
@@ -977,6 +977,14 @@
#endif
}
+int msLayerSupportsPaging(layerObj *layer)
+{
+ if (layer && layer->connectiontype == MS_ORACLESPATIAL)
+ return MS_TRUE;
+
+ return MS_FALSE;
+}
+
int
msLayerApplyPlainFilterToLayer(FilterEncodingNode *psNode, mapObj *map,
int iLayerIndex, int bOnlySpatialFilter)
Modified: trunk/mapserver/maporaclespatial.c
===================================================================
--- trunk/mapserver/maporaclespatial.c 2010-01-05 11:56:00 UTC (rev 9667)
+++ trunk/mapserver/maporaclespatial.c 2010-01-05 14:54:33 UTC (rev 9668)
@@ -1019,18 +1019,8 @@
sprintf( query_str2 + strlen(query_str2), " %s FROM %s", geom_column_name, table_name);
- osFilteritem(layer, FUNCTION_NONE, query_str2, 1);
+ osFilteritem(layer, FUNCTION_NONE, query_str2, 1);
- if (layer->maxfeatures > 0)
- {
- if(layer->filter.string != NULL)
- sprintf (query_str2 + strlen(query_str2), " AND ");
- else
- sprintf (query_str2 + strlen(query_str2), " WHERE ");
-
- sprintf( query_str2 + strlen(query_str2), " ROWNUM <= %d ", layer->maxfeatures);
- }
-
sprintf( query_str, "SELECT SDO_AGGR_MBR(%s) AS GEOM from %s)", geom_column_name, query_str2);
if (layer->debug)
@@ -1049,17 +1039,8 @@
sprintf( query_str2 + strlen(query_str2), " %s FROM %s", geom_column_name, table_name);
osFilteritem(layer, FUNCTION_NONE, query_str2, 1);
- if (layer->maxfeatures > 0)
- {
- if(layer->filter.string != NULL)
- sprintf (query_str2 + strlen(query_str2), " AND ");
- else
- sprintf (query_str2 + strlen(query_str2), " WHERE ");
-
- sprintf( query_str2 + strlen(query_str2), " ROWNUM <= %d ", layer->maxfeatures);
-
- }
+
sprintf( query_str, "SELECT SDO_GEOM.SDO_CONVEXHULL(%s, %f) AS GEOM from %s)", geom_column_name, TOLERANCE, query_str2);
}
@@ -1920,6 +1901,8 @@
int version = 0;
int existunique = MS_FALSE;
char query_str[6000];
+ char query_str2[256];
+ char *tmp_str=NULL, *tmp1_str=NULL;
char *table_name;
char geom_column_name[100], unique[100], srid[100];
OCIDefine *adtp = NULL;
@@ -1977,6 +1960,7 @@
if (strcmp(srid,"NULL") == 0)
strcpy(srid,"-1");
+
/* Check if the unique field is already in the items list */
for( i=0; i < layer->numitems; ++i ) {
if (strcmp(unique, layer->items[i])==0) {
@@ -1984,11 +1968,22 @@
break;
}
}
-
+
+ /*always select rownum to allow paging*/
if (existunique)
- sprintf( query_str, "SELECT ");
+ {
+ if (strcasecmp(unique, "rownum") == 0)
+ sprintf( query_str, "SELECT");
+ else
+ sprintf( query_str, "SELECT %s,", "rownum");
+ }
else
- sprintf( query_str, "SELECT %s, ", unique );
+ {
+ if (strcasecmp(unique, "rownum") == 0)
+ sprintf( query_str, "SELECT %s,", unique );
+ else
+ sprintf( query_str, "SELECT %s, %s,", "rownum", unique );
+ }
/* allocate enough space for items */
if (layer->numitems >= 0)
@@ -2013,14 +2008,17 @@
/* define SQL query */
for( i=0; i < layer->numitems; ++i )
+ {
sprintf( query_str + strlen(query_str), "%s, ", layer->items[i] );
-
+ }
sprintf( query_str + strlen(query_str), "%s FROM %s", geom_column_name, table_name );
osFilteritem(layer, function, query_str, 1);
- if (layer->maxfeatures > 0)
+ if (layer->maxfeatures > 0 && layer->startindex < 0)
{
+ if (function == FUNCTION_NONE)
+ sprintf( query_str + strlen(query_str), "%s"," WHERE ");
sprintf( query_str + strlen(query_str), " ROWNUM<=%d ", layer->maxfeatures);
if (function != FUNCTION_NONE)
sprintf (query_str + strlen(query_str), " AND ");
@@ -2032,6 +2030,34 @@
else
osNoGeodeticData(function, version, query_str, geom_column_name, srid, rect);
+
+ /*assuming startindex starts at 1*/
+ if (layer->startindex > 0)
+ {
+ tmp1_str = strdup("SELECT * from (SELECT atmp.*, ROWNUM rnum from (");
+ tmp_str = msStringConcatenate(tmp_str, tmp1_str);
+ msFree(tmp1_str);
+ tmp_str = msStringConcatenate(tmp_str, query_str);
+ /*oder by rowid does not seem to work with function using the spatial filter, at least
+ on layers loaded using ogr in a 11g database*/
+ if (function == FUNCTION_NONE || function == FUNCTION_RELATE || function == FUNCTION_GEOMRELATE)
+ tmp1_str = strdup( "order by rowid");
+ else
+ tmp1_str = strdup("");
+
+ if (layer->maxfeatures > 0)
+ sprintf(query_str2, " %s) atmp where ROWNUM<=%d) where rnum >=%d", tmp1_str,
+ layer->maxfeatures+layer->startindex-1, layer->startindex);
+ else
+ sprintf( query_str2, " %s) atmp) where rnum >=%d", tmp1_str, layer->startindex);
+ msFree(tmp1_str);
+
+ tmp_str = msStringConcatenate(tmp_str, query_str2);
+ sprintf (query_str, "%s", tmp_str);
+ msFree(tmp_str);
+ }
+
+
if (layer->debug)
msDebug("msOracleSpatialLayerWhichShapes. Using this Sql to retrieve the data: %s\n", query_str);
@@ -2069,7 +2095,7 @@
/* do the actual binding */
- if (success) {
+ if (success && function != FUNCTION_NONE) {
success = TRY( hand,
/* bind in srid */
OCIBindByName( sthand->stmthp, &bnd2p, hand->errhp, (text *) ":srid", strlen(":srid"),(ub1 *) srid, strlen(srid)+1, SQLT_STR,
Modified: trunk/mapserver/mapserver.h
===================================================================
--- trunk/mapserver/mapserver.h 2010-01-05 11:56:00 UTC (rev 9667)
+++ trunk/mapserver/mapserver.h 2010-01-05 14:54:33 UTC (rev 9668)
@@ -1229,7 +1229,8 @@
int sizeunits; /* applies to all classes */
- int maxfeatures;
+ int maxfeatures;
+ int startindex;
colorObj offsite; /* transparent pixel value for raster images */
@@ -1958,6 +1959,8 @@
/* maplayer.c */
MS_DLL_EXPORT int msLayerGetNumFeatures(layerObj *layer);
+MS_DLL_EXPORT int msLayerSupportsPaging(layerObj *layer);
+
/* These are special because SWF is using these */
int msOGRLayerNextShape(layerObj *layer, shapeObj *shape);
int msOGRLayerGetItems(layerObj *layer);
Modified: trunk/mapserver/mapwfs.c
===================================================================
--- trunk/mapserver/mapwfs.c 2010-01-05 11:56:00 UTC (rev 9667)
+++ trunk/mapserver/mapwfs.c 2010-01-05 14:54:33 UTC (rev 9668)
@@ -1026,6 +1026,8 @@
char **papszPropertyName = NULL;
int nPropertyNames = 0;
const char *pszMapSRS = NULL;
+ int nQueriedLayers=0;
+ layerObj *lpQueried=NULL;
/* Default filter is map extents */
bbox = map->extent;
@@ -1297,38 +1299,65 @@
maxfeatures = paramsObj->nMaxFeatures;
}
- if (paramsObj->nStartIndex >= 0)
+ nQueriedLayers=0;
+ for(j=0; j<map->numlayers; j++)
+ {
+ layerObj *lp;
+ lp = GET_LAYER(map, j);
+ if (lp->status == MS_ON)
+ {
+ lpQueried = GET_LAYER(map, j);
+ nQueriedLayers++;
+ }
+ }
+
+ 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)
+
+ /*maxfeatures set but no startindex*/
+ if (maxfeatures > 0 && startindex < 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++)
{
- for(j=0; j<map->numlayers; j++)
+ layerObj *lp;
+ lp = GET_LAYER(map, j);
+ if (lp->status == MS_ON)
{
- 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;
- }
+ /*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;
}
}
}
+
+ /*no maxfeatures set but startindex set*/
+ if (maxfeatures <=0 && startindex > 0)
+ {
+ if (nQueriedLayers == 1 && msLayerSupportsPaging(lpQueried))
+ {
+ lpQueried->startindex = startindex;
+ startindex = -1;
+ }
+ }
- /* if (strcasecmp(names[i], "FEATUREID") == 0) */
- /* { */
- /* */
- /* } */
+ /*maxfeatures set and startindex set*/
+ if (maxfeatures >0 && startindex > 0)
+ {
+ if (nQueriedLayers == 1 && msLayerSupportsPaging(lpQueried))
+ {
+ lpQueried->startindex = startindex;
+ if (lpQueried->maxfeatures <=0 ||
+ (lpQueried->maxfeatures > 0 && maxfeatures < lpQueried->maxfeatures))
+ lpQueried->maxfeatures = maxfeatures;
+
+ startindex = -1;
+ maxfeatures = -1;
+ }
+ }
+
+
if (paramsObj->pszFilter) {
bFilterSet = 1;
@@ -1859,7 +1888,7 @@
/*some validations on startindex, it should not be > that the total elements
TODO: should we send an exception?*/
- if (startindex >=0 && startindex >=iNumberOfFeatures)
+ if (startindex >0 && startindex >=iNumberOfFeatures)
{
msIO_printf(" <gml:boundedBy>\n");
msIO_printf(" <gml:null>missing</gml:null>\n");
@@ -1868,8 +1897,9 @@
else
{
/* handle case of maxfeatures = 0 */
+ /*internally use a start index that start with with 0 as the first index*/
if(maxfeatures != 0 && iResultTypeHits == 0)
- msGMLWriteWFSQuery(map, stdout, startindex, maxfeatures, pszNameSpace, outputformat);
+ msGMLWriteWFSQuery(map, stdout, startindex-1, maxfeatures, pszNameSpace, outputformat);
if (((iNumberOfFeatures==0) || (maxfeatures == 0)) && iResultTypeHits == 0) {
msIO_printf(" <gml:boundedBy>\n");
More information about the mapserver-commits
mailing list