Permalink
Browse files

[OGR] Enable translation for maxfeatures/startindex to SQL LIMIT/OFFS…

…ET in Spatialite case
  • Loading branch information...
rouault committed Aug 29, 2016
1 parent 2a6ad64 commit 8ae17b3fd59b822f23b9276f7d53e418b8caf63b
Showing with 117 additions and 6 deletions.
  1. +74 −6 mapogr.cpp
  2. +41 −0 msautotest/wxs/expected/wfs_ogr_native_sql_37.xml
  3. +2 −0 msautotest/wxs/wfs_ogr_native_sql.map
View
@@ -72,6 +72,8 @@ typedef struct ms_ogr_file_info_t {
char *pszRowId;
int bIsOKForSQLCompose;
+ int bPaging;
+
} msOGRFileInfo;
static int msOGRLayerIsOpen(layerObj *layer);
@@ -1457,7 +1459,7 @@ msOGRFileOpen(layerObj *layer, const char *connection )
psInfo->dialect = NULL;
}
-
+ psInfo->bPaging = (psInfo->dialect != NULL);
return psInfo;
}
@@ -1858,7 +1860,10 @@ static int msOGRFileWhichShapes(layerObj *layer, rectObj rect, msOGRFileInfo *ps
// 2) ExecuteSQL (psInfo->hLayer is an SQL result OR sortBy was requested OR have native_string
// and start from the second
- if ( psInfo->bIsOKForSQLCompose && (psInfo->nLayerIndex == -1 || layer->sortBy.nProperties > 0 || layer->filter.native_string) ) {
+ if ( psInfo->bIsOKForSQLCompose && (psInfo->nLayerIndex == -1 ||
+ layer->sortBy.nProperties > 0 ||
+ layer->filter.native_string ||
+ (psInfo->bPaging && layer->maxfeatures > 0)) ) {
if( psInfo->nLayerIndex == -1 && select == NULL ) {
select = msStrdup(psInfo->pszLayerDef);
@@ -1914,8 +1919,7 @@ static int msOGRFileWhichShapes(layerObj *layer, rectObj rect, msOGRFileInfo *ps
if (psInfo->dialect) {
if (EQUAL(psInfo->dialect, "Spatialite") || EQUAL(psInfo->dialect, "PostgreSQL")) {
const char *sql = layer->filter.native_string;
- if (*sql == '\0') sql = NULL;
- if (sql) {
+ if (sql && *sql != '\0') {
if (filter) filter = msStringConcatenate(filter, "AND ");
filter = msStringConcatenate(filter, "(");
filter = msStringConcatenate(filter, sql);
@@ -2013,7 +2017,19 @@ static int msOGRFileWhichShapes(layerObj *layer, rectObj rect, msOGRFileInfo *ps
select = msStringConcatenate(select, sort);
msFree(sort);
}
-
+
+ if ( psInfo->bPaging && layer->maxfeatures >= 0 ) {
+ char szLimit[50];
+ snprintf(szLimit, sizeof(szLimit), " LIMIT %d", layer->maxfeatures);
+ select = msStringConcatenate(select, szLimit);
+ }
+
+ if ( psInfo->bPaging && layer->startindex > 0 ) {
+ char szOffset[50];
+ snprintf(szOffset, sizeof(szOffset), " OFFSET %d", layer->startindex);
+ select = msStringConcatenate(select, szOffset);
+ }
+
if( layer->debug )
msDebug("msOGRFileWhichShapes: SQL = %s.\n", select);
@@ -4274,6 +4290,57 @@ static int msOGRLayerSupportsCommonFilters(layerObj *layer)
return MS_FALSE;
}
+static void msOGREnablePaging(layerObj *layer, int value)
+{
+#ifdef USE_OGR
+ msOGRFileInfo *layerinfo = NULL;
+
+ if (layer->debug) {
+ msDebug("msOGREnablePaging(%d) called.\n", value);
+ }
+ if( value < 0 )
+ return;
+
+ if(!msOGRLayerIsOpen(layer))
+ msOGRLayerOpenVT(layer);
+
+ assert( layer->layerinfo != NULL);
+
+ layerinfo = (msOGRFileInfo *)layer->layerinfo;
+ layerinfo->bPaging = value;
+
+#else
+ msSetError( MS_MISCERR,
+ "OGR support is not available.",
+ "msOGREnablePaging()");
+#endif
+ return;
+}
+
+static int msOGRGetPaging(layerObj *layer)
+{
+#ifdef USE_POSTGIS
+ msOGRFileInfo *layerinfo = NULL;
+
+ if (layer->debug) {
+ msDebug("msOGRGetPaging called.\n");
+ }
+
+ if(!msOGRLayerIsOpen(layer))
+ return -1;
+
+ assert( layer->layerinfo != NULL);
+
+ layerinfo = (msOGRFileInfo *)layer->layerinfo;
+ return layerinfo->bPaging;
+#else
+ msSetError( MS_MISCERR,
+ "OGR support is not available.",
+ "msOGREnablePaging()");
+ return MS_FAILURE;
+#endif
+}
+
/************************************************************************/
/* msOGRLayerInitializeVirtualTable() */
/************************************************************************/
@@ -4305,7 +4372,8 @@ int msOGRLayerInitializeVirtualTable(layerObj *layer)
layer->vtable->LayerEscapeSQLParam = msOGREscapeSQLParam;
layer->vtable->LayerEscapePropertyName = msOGREscapePropertyName;
-
+ layer->vtable->LayerEnablePaging = msOGREnablePaging;
+ layer->vtable->LayerGetPaging = msOGRGetPaging;
return MS_SUCCESS;
}
@@ -0,0 +1,41 @@
+Content-Type: text/xml; subtype="gml/3.2.1"; charset=UTF-8
+
+<?xml version='1.0' encoding="UTF-8" ?>
+<wfs:FeatureCollection
+ xmlns:ms="http://mapserver.gis.umn.edu/mapserver"
+ xmlns:gml="http://www.opengis.net/gml/3.2"
+ xmlns:wfs="http://www.opengis.net/wfs/2.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://mapserver.gis.umn.edu/mapserver http://localhost/path/to/wfs_simple?SERVICE=WFS&amp;VERSION=2.0.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=towns&amp;OUTPUTFORMAT=application%2Fgml%2Bxml%3B%20version%3D3.2 http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd"
+ timeStamp="" numberMatched="unknown" numberReturned="1"
+ previous="http://localhost/path/to/wfs_simple?SERVICE=WFS&amp;VERSION=2.0.0&amp;REQUEST=GetFeature&amp;TYPENAMES=towns&amp;COUNT=1&amp;STARTINDEX=1"
+ next="http://localhost/path/to/wfs_simple?SERVICE=WFS&amp;VERSION=2.0.0&amp;REQUEST=GetFeature&amp;TYPENAMES=towns&amp;COUNT=1&amp;STARTINDEX=3">
+ <wfs:boundedBy>
+ <gml:Envelope srsName="urn:ogc:def:crs:EPSG::32632">
+ <gml:lowerCorner>656907.12000 4886687.84000</gml:lowerCorner>
+ <gml:upperCorner>656907.12000 4886687.84000</gml:upperCorner>
+ </gml:Envelope>
+ </wfs:boundedBy>
+<!-- WARNING: FeatureId item 'ID' not found in typename 'towns'. -->
+ <wfs:member>
+ <ms:towns>
+ <gml:boundedBy>
+ <gml:Envelope srsName="urn:ogc:def:crs:EPSG::32632">
+ <gml:lowerCorner>656907.12000 4886687.84000</gml:lowerCorner>
+ <gml:upperCorner>656907.12000 4886687.84000</gml:upperCorner>
+ </gml:Envelope>
+ </gml:boundedBy>
+ <ms:msGeometry>
+ <gml:Point gml:id=".1" srsName="urn:ogc:def:crs:EPSG::32632">
+ <gml:pos>656907.12000 4886687.84000</gml:pos>
+ </gml:Point>
+ </ms:msGeometry>
+ <ms:name>Granaglione</ms:name>
+ <ms:peoples>2116</ms:peoples>
+ <ms:localcounc>1</ms:localcounc>
+ <ms:county>0</ms:county>
+ <ms:region>0</ms:region>
+ </ms:towns>
+ </wfs:member>
+</wfs:FeatureCollection>
+
@@ -74,6 +74,8 @@
# Same as wfs_ogr_native_sql_02 on a SELECT too complex to be edited, so falling back to client side evaluation
# RUN_PARMS: wfs_ogr_native_sql_36.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=select_too_complex_for_optim&OUTPUTFORMAT=GML2&FILTER=<Filter><AND><BBOX><PropertyName>Geometry</PropertyName><Box srsName='EPSG:32632'><coordinates>643159,4877386 696879,4898059</coordinates></Box></BBOX><PropertyIsEqualTo><PropertyName>name</PropertyName><Literal>Fanano</Literal></PropertyIsEqualTo></AND></Filter>" > [RESULT]
#
+# Test COUNT, STARTINDEX
+# RUN_PARMS: wfs_ogr_native_sql_37.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&TYPENAMES=towns&COUNT=1&STARTINDEX=2" > [RESULT_DEVERSION]
MAP

0 comments on commit 8ae17b3

Please sign in to comment.