[mapserver-commits] r10916 - trunk/mapserver
svn at osgeo.org
svn at osgeo.org
Wed Jan 26 14:29:02 EST 2011
Author: assefa
Date: 2011-01-26 11:29:02 -0800 (Wed, 26 Jan 2011)
New Revision: 10916
Added:
trunk/mapserver/mapogcfiltercommon.c
Modified:
trunk/mapserver/Makefile.in
trunk/mapserver/Makefile.vc
trunk/mapserver/maplayer.c
trunk/mapserver/mapogcfilter.c
trunk/mapserver/mapogcfilter.h
trunk/mapserver/mapserver.h
trunk/mapserver/mapwfs.c
Log:
use new parser for wfs filter #3613
Modified: trunk/mapserver/Makefile.in
===================================================================
--- trunk/mapserver/Makefile.in 2011-01-26 10:50:08 UTC (rev 10915)
+++ trunk/mapserver/Makefile.in 2011-01-26 19:29:02 UTC (rev 10916)
@@ -286,7 +286,7 @@
maprasterquery.o mapobject.o mapgeos.o classobject.o layerobject.o mapio.o mappool.o \
mapregex.o mappluginlayer.o mapogcsos.o mappostgresql.o mapcrypto.o mapowscommon.o \
maplibxml2.o mapdebug.o mapchart.o maptclutf.o mapxml.o mapkml.o mapkmlrenderer.o \
- mapogroutput.o mapwcs20.o
+ mapogroutput.o mapwcs20.o mapogcfiltercommon.o
EXE_LIST = shp2img shp2pdf legend mapserv shptree shptreevis \
shptreetst scalebar sortshp mapscriptvars tile4ms \
Modified: trunk/mapserver/Makefile.vc
===================================================================
--- trunk/mapserver/Makefile.vc 2011-01-26 10:50:08 UTC (rev 10915)
+++ trunk/mapserver/Makefile.vc 2011-01-26 19:29:02 UTC (rev 10916)
@@ -47,7 +47,8 @@
maprendering.obj mapimageio.obj mapcairo.obj \
mapoglrenderer.obj mapoglcontext.obj mapogl.obj \
maptile.obj $(EPPL_OBJ) $(REGEX_OBJ) mapgeomtransform.obj \
- mapkmlrenderer.obj mapkml.obj mapdummyrenderer.obj mapgeomutil.obj mapquantization.obj $(AGG_OBJ)
+ mapkmlrenderer.obj mapkml.obj mapdummyrenderer.obj mapgeomutil.obj mapquantization.obj \
+ mapogcfiltercommon.obj $(AGG_OBJ)
MS_HDRS = mapserver.h mapfile.h
Modified: trunk/mapserver/maplayer.c
===================================================================
--- trunk/mapserver/maplayer.c 2011-01-26 10:50:08 UTC (rev 10915)
+++ trunk/mapserver/maplayer.c 2011-01-26 19:29:02 UTC (rev 10916)
@@ -1093,11 +1093,11 @@
int
msLayerApplyCondSQLFilterToLayer(FilterEncodingNode *psNode, mapObj *map,
- int iLayerIndex, int bOnlySpatialFilter)
+ int iLayerIndex)
{
#if USE_OGR
- return FLTLayerApplyCondSQLFilterToLayer(psNode, map, iLayerIndex,
- bOnlySpatialFilter);
+ return FLTLayerApplyCondSQLFilterToLayer(psNode, map, iLayerIndex);
+
#else
return MS_FAILURE;
#endif
@@ -1113,11 +1113,10 @@
int
msLayerApplyPlainFilterToLayer(FilterEncodingNode *psNode, mapObj *map,
- int iLayerIndex, int bOnlySpatialFilter)
+ int iLayerIndex)
{
#if USE_OGR
- return FLTLayerApplyPlainFilterToLayer(psNode, map, iLayerIndex,
- bOnlySpatialFilter);
+ return FLTLayerApplyPlainFilterToLayer(psNode, map, iLayerIndex);
#else
return MS_FAILURE;
#endif
Modified: trunk/mapserver/mapogcfilter.c
===================================================================
--- trunk/mapserver/mapogcfilter.c 2011-01-26 10:50:08 UTC (rev 10915)
+++ trunk/mapserver/mapogcfilter.c 2011-01-26 19:29:02 UTC (rev 10916)
@@ -44,7 +44,7 @@
return (*(int*)a) - (*(int*)b);
}
-static int FLTIsNumeric(char *pszValue)
+int FLTIsNumeric(char *pszValue)
{
if (pszValue)
{
@@ -1267,11 +1267,6 @@
return status;
}
-int FLTApplySpatialFilterToLayer(FilterEncodingNode *psNode, mapObj *map,
- int iLayerIndex)
-{
- return FLTApplyFilterToLayer(psNode, map, iLayerIndex, MS_TRUE);
-}
/************************************************************************/
/* FLTApplyFilterToLayer */
@@ -1280,7 +1275,7 @@
/* and apply it to the layer. */
/************************************************************************/
int FLTApplyFilterToLayer(FilterEncodingNode *psNode, mapObj *map,
- int iLayerIndex, int bOnlySpatialFilter)
+ int iLayerIndex)
{
layerObj *layer = GET_LAYER(map, iLayerIndex);
@@ -1289,9 +1284,8 @@
if (rv != MS_SUCCESS)
return rv;
}
- return layer->vtable->LayerApplyFilterToLayer(psNode, map,
- iLayerIndex,
- bOnlySpatialFilter);
+ return layer->vtable->LayerApplyFilterToLayer(psNode, map, iLayerIndex);
+
}
/************************************************************************/
@@ -1300,19 +1294,19 @@
/* Helper function for layer virtual table architecture */
/************************************************************************/
int FLTLayerApplyCondSQLFilterToLayer(FilterEncodingNode *psNode, mapObj *map,
- int iLayerIndex, int bOnlySpatialFilter)
+ int iLayerIndex)
{
/* ==================================================================== */
/* Check here to see if it is a simple filter and if that is */
/* the case, we are going to use the FILTER element on */
/* the layer. */
/* ==================================================================== */
- if (!bOnlySpatialFilter && FLTIsSimpleFilter(psNode))
+ if (FLTIsSimpleFilter(psNode))
{
return FLTApplySimpleSQLFilter(psNode, map, iLayerIndex);
}
- return FLTLayerApplyPlainFilterToLayer(psNode, map, iLayerIndex, bOnlySpatialFilter);
+ return FLTLayerApplyPlainFilterToLayer(psNode, map, iLayerIndex);
}
/************************************************************************/
@@ -1321,46 +1315,18 @@
/* Helper function for layer virtual table architecture */
/************************************************************************/
int FLTLayerApplyPlainFilterToLayer(FilterEncodingNode *psNode, mapObj *map,
- int iLayerIndex, int bOnlySpatialFilter)
+ int iLayerIndex)
{
- int *panResults = NULL;
- int nResults = 0;
- layerObj *psLayer = NULL;
- int status;
+ char *pszExpression =NULL;
+ int status =MS_FALSE;
-/* ==================================================================== */
-/* Check here to see if it is a simple filter and if that is */
-/* the case, we are going to use the FILTER element on */
-/* the layer. */
-/* ==================================================================== */
- if (!bOnlySpatialFilter && FLTIsSimpleFilter(psNode))
+ pszExpression = FLTGetCommonExpression(psNode, GET_LAYER(map, iLayerIndex));
+ if (pszExpression)
{
- return FLTApplySimpleSQLFilter(psNode, map, iLayerIndex);
- }
-
-
- psLayer = (GET_LAYER(map, iLayerIndex));
- status = FLTGetQueryResults(psNode, map, iLayerIndex,
- &panResults, &nResults, bOnlySpatialFilter);
- if (panResults)
- FLTAddToLayerResultCache(panResults, nResults, map, iLayerIndex);
- /* clear the cache if the results is NULL to make sure there aren't */
- /* any left over from intermediate queries. */
- else
- {
- if (psLayer && psLayer->resultcache)
- {
- if (psLayer->resultcache->results)
- free (psLayer->resultcache->results);
- free(psLayer->resultcache);
-
- psLayer->resultcache = NULL;
- }
+ status = FLTApplyFilterToLayerCommonExpression(map, iLayerIndex, pszExpression);
+ msFree(pszExpression);
}
- if (panResults)
- free(panResults);
-
return status;
}
Modified: trunk/mapserver/mapogcfilter.h
===================================================================
--- trunk/mapserver/mapogcfilter.h 2011-01-26 10:50:08 UTC (rev 10915)
+++ trunk/mapserver/mapogcfilter.h 2011-01-26 19:29:02 UTC (rev 10916)
@@ -56,16 +56,13 @@
MS_DLL_EXPORT FilterEncodingNode *FLTParseFilterEncoding(char *szXMLString);
MS_DLL_EXPORT FilterEncodingNode *FLTCreateFilterEncodingNode(void);
MS_DLL_EXPORT int FLTApplyFilterToLayer(FilterEncodingNode *psNode, mapObj *map,
- int iLayerIndex, int bOnlySpatialFilter);
+ int iLayerIndex);
MS_DLL_EXPORT int FLTLayerApplyCondSQLFilterToLayer(FilterEncodingNode *psNode, mapObj *map,
- int iLayerIndex, int bOnlySpatialFilter);
+ int iLayerIndex);
MS_DLL_EXPORT int FLTLayerApplyPlainFilterToLayer(FilterEncodingNode *psNode, mapObj *map,
- int iLayerIndex, int bOnlySpatialFilter);
+ int iLayerIndex);
-MS_DLL_EXPORT int FLTApplySpatialFilterToLayer(FilterEncodingNode *psNode, mapObj *map,
- int iLayerIndex);
-
MS_DLL_EXPORT void FLTFreeFilterEncodingNode(FilterEncodingNode *psFilterNode);
MS_DLL_EXPORT int FLTValidFilterNode(FilterEncodingNode *psFilterNode);
@@ -123,6 +120,13 @@
MS_DLL_EXPORT int FLTParseGMLEnvelope(CPLXMLNode *psRoot, rectObj *psBbox, char **ppszSRS);
MS_DLL_EXPORT int FLTParseGMLBox(CPLXMLNode *psBox, rectObj *psBbox, char **ppszSRS);
+MS_DLL_EXPORT int FLTIsNumeric(char *pszValue);
+/*common-expressions*/
+MS_DLL_EXPORT char *FLTGetBinaryComparisonCommonExpression(FilterEncodingNode *psFilterNode, layerObj *lp);
+MS_DLL_EXPORT char *FLTGetCommonExpression(FilterEncodingNode *psFilterNode, layerObj *lp);
+MS_DLL_EXPORT int FLTApplyFilterToLayerCommonExpression(mapObj *map, int iLayerIndex, char *pszExpression);
+
+
#ifdef USE_LIBXML2
MS_DLL_EXPORT xmlNodePtr FLTGetCapabilities(xmlNsPtr psNsParent, xmlNsPtr psNsOgc, int bTemporal);
#endif
Added: trunk/mapserver/mapogcfiltercommon.c
===================================================================
--- trunk/mapserver/mapogcfiltercommon.c (rev 0)
+++ trunk/mapserver/mapogcfiltercommon.c 2011-01-26 19:29:02 UTC (rev 10916)
@@ -0,0 +1,622 @@
+/**********************************************************************
+ * $Id: mapogcfilter.c 10508 2010-09-17 20:52:33Z assefa $
+ *
+ * Project: MapServer
+ * Purpose: OGC Filter Encoding implementation
+ * Author: Y. Assefa, DM Solutions Group (assefa at dmsolutions.ca)
+ *
+ **********************************************************************
+ * Copyright (c) 2003, Y. Assefa, DM Solutions Group Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies of this Software or works derived from this Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ ****************************************************************************/
+
+#ifdef USE_OGR
+#include "cpl_minixml.h"
+#endif
+
+#include "mapogcfilter.h"
+#include "mapserver.h"
+#include "mapowscommon.h"
+
+MS_CVSID("$Id: $")
+
+#ifdef USE_OGR
+
+static int FTLParseEpsgString(char *pszEpsg, projectionObj *psProj)
+{
+ int nStatus = MS_FALSE;
+ int nTokens = 0;
+ char **tokens = NULL;
+ int nEpsgTmp=0;
+
+#ifdef USE_PROJ
+ if (pszEpsg && psProj)
+ {
+ nTokens = 0;
+ tokens = msStringSplit(pszEpsg,'#', &nTokens);
+ if (tokens && nTokens == 2)
+ {
+ char szTmp[32];
+ sprintf(szTmp, "init=epsg:%s",tokens[1]);
+ msInitProjection(psProj);
+ if (msLoadProjectionString(psProj, szTmp) == 0)
+ nStatus = MS_TRUE;
+ }
+ else if (tokens && nTokens == 1)
+ {
+ if (tokens)
+ msFreeCharArray(tokens, nTokens);
+ nTokens = 0;
+
+ tokens = msStringSplit(pszEpsg,':', &nTokens);
+ nEpsgTmp = -1;
+ if (tokens && nTokens == 1)
+ {
+ nEpsgTmp = atoi(tokens[0]);
+
+ }
+ else if (tokens && nTokens == 2)
+ {
+ nEpsgTmp = atoi(tokens[1]);
+ }
+ if (nEpsgTmp > 0)
+ {
+ char szTmp[32];
+ sprintf(szTmp, "init=epsg:%d",nEpsgTmp);
+ msInitProjection(psProj);
+ if (msLoadProjectionString(psProj, szTmp) == 0)
+ nStatus = MS_TRUE;
+ }
+ }
+ if (tokens)
+ msFreeCharArray(tokens, nTokens);
+ }
+#endif
+ return nStatus;
+}
+
+char *FLTGetIsBetweenComparisonCommonExpresssion(FilterEncodingNode *psFilterNode,
+ layerObj *lp)
+{
+ const size_t bufferSize = 1024;
+ char szBuffer[1024];
+ char **aszBounds = NULL;
+ int nBounds = 0;
+ int bString=0;
+ char *pszExpression=NULL;
+
+ if (!psFilterNode ||
+ !(strcasecmp(psFilterNode->pszValue, "PropertyIsBetween") == 0))
+ return NULL;
+
+ if (psFilterNode->psLeftNode == NULL || psFilterNode->psRightNode == NULL )
+ return NULL;
+
+/* -------------------------------------------------------------------- */
+/* Get the bounds value which are stored like boundmin;boundmax */
+/* -------------------------------------------------------------------- */
+ aszBounds = msStringSplit(psFilterNode->psRightNode->pszValue, ';', &nBounds);
+ if (nBounds != 2)
+ {
+ if (aszBounds)
+ msFreeCharArray(aszBounds, nBounds);
+ return NULL;
+ }
+/* -------------------------------------------------------------------- */
+/* check if the value is a numeric value or alphanumeric. If it */
+/* is alphanumeric, add quotes around attribute and values. */
+/* -------------------------------------------------------------------- */
+ bString = 0;
+ if (aszBounds[0])
+ {
+ snprintf(szBuffer, bufferSize, "%s_type", psFilterNode->psLeftNode->pszValue);
+ if (msOWSLookupMetadata(&(lp->metadata), "OFG", szBuffer) != NULL &&
+ (strcasecmp(msOWSLookupMetadata(&(lp->metadata), "G", szBuffer), "Character") == 0))
+ bString = 1;
+ else if (FLTIsNumeric(aszBounds[0]) == MS_FALSE)
+ bString = 1;
+ }
+ if (!bString)
+ {
+ if (aszBounds[1])
+ {
+ if (FLTIsNumeric(aszBounds[1]) == MS_FALSE)
+ bString = 1;
+ }
+ }
+
+
+/* -------------------------------------------------------------------- */
+/* build expresssion. */
+/* -------------------------------------------------------------------- */
+ /* attribute */
+ if (bString)
+ sprintf(szBuffer, "%s", " (\"[");
+ else
+ sprintf(szBuffer, "%s", " ([");
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+ pszExpression = msStringConcatenate(pszExpression, psFilterNode->psLeftNode->pszValue);
+
+ if (bString)
+ sprintf(szBuffer, "%s", "]\" ");
+ else
+ sprintf(szBuffer, "%s", "] ");
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+
+ sprintf(szBuffer, "%s", " >= ");
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+
+ if (bString)
+ {
+ sprintf(szBuffer,"%s", "\"");
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+ }
+
+ snprintf(szBuffer, bufferSize, "%s", aszBounds[0]);
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+ if (bString)
+ {
+ sprintf(szBuffer, "%s", "\"");
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+ }
+
+ sprintf(szBuffer, "%s", " AND ");
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+
+ if (bString)
+ sprintf(szBuffer, "%s", " \"[");
+ else
+ sprintf(szBuffer, "%s", " [");
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+
+ /* attribute */
+ pszExpression = msStringConcatenate(pszExpression, psFilterNode->psLeftNode->pszValue);
+
+ if (bString)
+ sprintf(szBuffer, "%s", "]\" ");
+ else
+ sprintf(szBuffer, "%s", "] ");
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+
+ sprintf(szBuffer, "%s", " <= ");
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+ if (bString)
+ {
+ sprintf(szBuffer,"%s", "\"");
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+ }
+ snprintf(szBuffer, bufferSize, "%s", aszBounds[1]);
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+
+ if (bString)
+ {
+ sprintf(szBuffer,"\"");
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+ }
+ sprintf(szBuffer, "%s", ")");
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+
+ if (aszBounds)
+ msFreeCharArray(aszBounds, nBounds);
+
+ return pszExpression;
+}
+
+char *FLTGetBinaryComparisonCommonExpression(FilterEncodingNode *psFilterNode, layerObj *lp)
+{
+ char szTmp[1024];
+ char *pszExpression = NULL;
+ int bString;
+
+ if (psFilterNode == NULL)
+ return NULL;
+
+/* -------------------------------------------------------------------- */
+/* check if the value is a numeric value or alphanumeric. If it */
+/* is alphanumeric, add quotes around attribute and values. */
+/* -------------------------------------------------------------------- */
+ bString = 0;
+ if (psFilterNode->psRightNode->pszValue)
+ {
+ snprintf(szTmp, sizeof(szTmp), "%s_type", psFilterNode->psLeftNode->pszValue);
+ if (msOWSLookupMetadata(&(lp->metadata), "OFG", szTmp) != NULL &&
+ (strcasecmp(msOWSLookupMetadata(&(lp->metadata), "G", szTmp), "Character") == 0))
+ bString = 1;
+ else if (FLTIsNumeric(psFilterNode->psRightNode->pszValue) == MS_FALSE)
+ bString = 1;
+ }
+
+ /* specical case to be able to have empty strings in the expression. */
+ /*propertyislike is always treated as string*/
+ if (psFilterNode->psRightNode->pszValue == NULL ||
+ strcasecmp(psFilterNode->pszValue, "PropertyIsLike") == 0)
+ bString = 1;
+
+
+
+ /* attribute */
+ if (bString)
+ sprintf(szTmp, "%s", " (\"[");
+ else
+ sprintf(szTmp, "%s"," ([");
+ pszExpression = msStringConcatenate(pszExpression, szTmp);
+ pszExpression = msStringConcatenate(pszExpression, psFilterNode->psLeftNode->pszValue);
+ if (bString)
+ sprintf(szTmp, "%s","]\" ");
+ else
+ sprintf(szTmp, "%s", "] ");
+ pszExpression = msStringConcatenate(pszExpression, szTmp);
+
+ if (strcasecmp(psFilterNode->pszValue,
+ "PropertyIsEqualTo") == 0)
+ {
+ /*case insensitive set ? */
+ if (psFilterNode->psRightNode->pOther &&
+ (*(int *)psFilterNode->psRightNode->pOther) == 1)
+ {
+ sprintf(szTmp, "%s", "=="); /*TODO what should this be ??*/
+ }
+ else
+ sprintf(szTmp, "%s", "==");
+
+ }
+ else if (strcasecmp(psFilterNode->pszValue,
+ "PropertyIsNotEqualTo") == 0)
+ sprintf(szTmp, "%s", " != ");
+ else if (strcasecmp(psFilterNode->pszValue,
+ "PropertyIsLessThan") == 0)
+ sprintf(szTmp, "%s", " < ");
+ else if (strcasecmp(psFilterNode->pszValue,
+ "PropertyIsGreaterThan") == 0)
+ sprintf(szTmp, "%s", " > ");
+ else if (strcasecmp(psFilterNode->pszValue,
+ "PropertyIsLessThanOrEqualTo") == 0)
+ sprintf(szTmp, "%s", " <= ");
+ else if (strcasecmp(psFilterNode->pszValue,
+ "PropertyIsGreaterThanOrEqualTo") == 0)
+ sprintf(szTmp, "%s", " >= ");
+ else if (strcasecmp(psFilterNode->pszValue,
+ "PropertyIsLike") == 0)
+ sprintf(szTmp, "%s", " ~* ");
+
+ pszExpression = msStringConcatenate(pszExpression, szTmp);
+
+ /* value */
+ if (bString)
+ {
+ sprintf(szTmp, "%s", "\"");
+ pszExpression = msStringConcatenate(pszExpression, szTmp);
+ }
+
+ if (psFilterNode->psRightNode->pszValue)
+ pszExpression = msStringConcatenate(pszExpression, psFilterNode->psRightNode->pszValue);
+
+ if (bString)
+ {
+ sprintf(szTmp, "%s", "\"");
+ pszExpression = msStringConcatenate(pszExpression, szTmp);
+ }
+
+ sprintf(szTmp, "%s", ")");
+ pszExpression = msStringConcatenate(pszExpression, szTmp);
+
+ return pszExpression;
+}
+
+
+
+char *FLTGetLogicalComparisonCommonExpression(FilterEncodingNode *psFilterNode, layerObj *lp)
+{
+ char *pszExpression = NULL;
+ char *pszTmp = NULL;
+ char szBuffer[256];
+
+ if (!psFilterNode || !FLTIsLogicalFilterType(psFilterNode->pszValue))
+ return NULL;
+
+/* -------------------------------------------------------------------- */
+/* OR and AND */
+/* -------------------------------------------------------------------- */
+ if (psFilterNode->psLeftNode && psFilterNode->psRightNode)
+ {
+ pszTmp = FLTGetCommonExpression(psFilterNode->psLeftNode, lp);
+ if (!pszTmp)
+ return NULL;
+
+ sprintf(szBuffer, "%s", " (");
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+
+ pszExpression = msStringConcatenate(pszExpression, pszTmp);
+ msFree(pszTmp);
+
+ sprintf(szBuffer, "%s", " ");
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+
+ pszExpression = msStringConcatenate(pszExpression, psFilterNode->pszValue);
+ sprintf(szBuffer, "%s", " ");
+
+
+ pszTmp = FLTGetCommonExpression(psFilterNode->psRightNode, lp);
+ if (!pszTmp)
+ return NULL;
+
+ pszExpression = msStringConcatenate(pszExpression, pszTmp);
+ msFree(pszTmp);
+
+ sprintf(szBuffer, "%s", ") ");
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+ }
+/* -------------------------------------------------------------------- */
+/* NOT */
+/* -------------------------------------------------------------------- */
+ else if (psFilterNode->psLeftNode &&
+ strcasecmp(psFilterNode->pszValue, "NOT") == 0)
+ {
+ pszTmp = FLTGetCommonExpression(psFilterNode->psLeftNode, lp);
+ if (!pszTmp)
+ return NULL;
+
+ sprintf(szBuffer, "%s", " (NOT ");
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+
+ pszExpression = msStringConcatenate(pszExpression, pszTmp);
+ msFree(pszTmp);
+
+ sprintf(szBuffer, "%s", ") ");
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+
+ }
+
+
+ return pszExpression;
+}
+
+
+char *FLTGetSpatialComparisonCommonExpression(FilterEncodingNode *psNode, layerObj *lp)
+{
+ char *pszExpression = NULL;
+ shapeObj *psQueryShape = NULL;
+ double dfDistance = -1;
+ int nUnit = -1;
+ char *pszWktText = NULL;
+ char szBuffer[256];
+ char *pszTmp=NULL;
+ projectionObj sProjTmp;
+ char *pszEPSG= NULL;
+ rectObj sQueryRect;
+ shapeObj *psTmpShape=NULL, *psBufferShape=NULL;
+ int bBBoxQuery = 0;
+
+ if (psNode == NULL || lp == NULL)
+ return NULL;
+
+ if (psNode->eType != FILTER_NODE_TYPE_SPATIAL)
+ return NULL;
+
+ /* get the shape*/
+ /*BBOX case: replace it with NOT DISJOINT.*/
+ if(FLTIsBBoxFilter(psNode))
+ {
+ pszEPSG = FLTGetBBOX(psNode, &sQueryRect);
+ /*this should be removed and bbox should parse and strore the srs properly,
+ using now legacy code*/
+ if (pszEPSG)
+ psNode->pszSRS = msStrdup(pszEPSG);
+
+ psTmpShape = (shapeObj *)malloc(sizeof(shapeObj));
+ msInitShape(psTmpShape);
+ msRectToPolygon(sQueryRect, psTmpShape);
+ bBBoxQuery = 1;
+
+ }
+ else
+ {
+ /*other geos type operations*/
+
+ /*project shape to layer projection. If the proj is not part of the filter query,
+ assume that the cooredinates are in the map projection*/
+
+ psQueryShape = FLTGetShape(psNode, &dfDistance, &nUnit);
+
+ if ((strcasecmp(psNode->pszValue, "DWithin") == 0 ||
+ strcasecmp(psNode->pszValue, "Beyond") == 0 ) &&
+ dfDistance > 0)
+ {
+ if (nUnit >=0 && nUnit != lp->map->units)
+ dfDistance *= msInchesPerUnit(nUnit,0)/msInchesPerUnit(lp->map->units,0);
+
+ psBufferShape = msGEOSBuffer(psQueryShape, dfDistance);
+ }
+ if (psBufferShape)
+ psTmpShape = psBufferShape;
+ else
+ psTmpShape = psQueryShape;
+ }
+
+ if (psTmpShape)
+ {
+ if( lp->projection.numargs > 0)
+ {
+ if (psNode->pszSRS && FTLParseEpsgString(psNode->pszSRS, &sProjTmp))
+ msProjectShape(&sProjTmp, &lp->projection, psTmpShape);
+ else if (lp->map->projection.numargs > 0)
+ msProjectShape(&lp->map->projection, &lp->projection, psTmpShape);
+ }
+ if (bBBoxQuery)
+ sprintf(szBuffer, "%s", " (NOT ([shape] ");
+ else
+ sprintf(szBuffer, "%s", " ([shape] ");
+
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+
+
+ if (strcasecmp(psNode->pszValue, "intersect") == 0)
+ pszTmp = msStrdup(psNode->pszValue);
+ else
+ pszTmp = msStrdup(psNode->pszValue);
+ msStringToLower(pszTmp);
+ if (bBBoxQuery)
+ sprintf(szBuffer, " %s ", "disjoint");
+ else
+ sprintf(szBuffer, " %s ", pszTmp);
+
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+ msFree(pszTmp);
+
+ pszWktText = msGEOSShapeToWKT(psTmpShape);
+ sprintf(szBuffer, "%s", " fromText('");
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+ pszExpression = msStringConcatenate(pszExpression, pszWktText);
+ sprintf(szBuffer, "%s", "')");
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+
+ }
+ if (psBufferShape)
+ msFreeShape(psBufferShape);
+
+
+ sprintf(szBuffer, "%s", ")");
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+
+ if (bBBoxQuery)
+ {
+ sprintf(szBuffer, "%s", ")");
+ pszExpression = msStringConcatenate(pszExpression, szBuffer);
+ }
+ return pszExpression;
+}
+
+char *FLTGetFeatureIdCommonExpression(FilterEncodingNode *psFilterNode, layerObj *lp)
+{
+
+ char *pszExpression = NULL;
+ int nTokens = 0, i=0, bString=0;
+ char **tokens = NULL;
+ const char *pszAttribute=NULL;
+
+#if defined(USE_WMS_SVR) || defined (USE_WFS_SVR) || defined (USE_WCS_SVR) || defined(USE_SOS_SVR)
+ if (psFilterNode->pszValue)
+ {
+ pszAttribute = msOWSLookupMetadata(&(lp->metadata), "OFG", "featureid");
+ if (pszAttribute)
+ {
+ tokens = msStringSplit(psFilterNode->pszValue,',', &nTokens);
+ if (tokens && nTokens > 0)
+ {
+ for (i=0; i<nTokens; i++)
+ {
+ char *pszTmp = NULL;
+ int bufferSize = 0;
+
+ if (i == 0)
+ {
+ if(FLTIsNumeric(tokens[0]) == MS_FALSE)
+ bString = 1;
+ }
+
+
+ if (bString)
+ {
+ bufferSize = 11+strlen(tokens[i])+strlen(pszAttribute)+1;
+ pszTmp = (char *)malloc(bufferSize);
+ snprintf(pszTmp, bufferSize, "(\"[%s]\" ==\"%s\")" , pszAttribute, tokens[i]);
+ }
+ else
+ {
+ bufferSize = 7+strlen(tokens[i])+strlen(pszAttribute)+1;
+ pszTmp = (char *)malloc(bufferSize);
+ snprintf(pszTmp, bufferSize, "([%s] == %s)" , pszAttribute, tokens[i]);
+ }
+
+ if (pszExpression != NULL)
+ pszExpression = msStringConcatenate(pszExpression, " OR ");
+ else
+ pszExpression = msStringConcatenate(pszExpression, "(");
+ pszExpression = msStringConcatenate(pszExpression, pszTmp);
+ msFree(pszTmp);
+ }
+
+ msFreeCharArray(tokens, nTokens);
+ }
+ }
+ /*opening and closing brackets are needed for mapserver expressions*/
+ if (pszExpression)
+ pszExpression = msStringConcatenate(pszExpression, ")");
+ }
+#endif
+
+ return pszExpression;
+}
+
+char *FLTGetCommonExpression(FilterEncodingNode *psFilterNode, layerObj *lp)
+{
+ char *pszExpression = NULL;
+
+ if (!psFilterNode)
+ return NULL;
+
+ if (psFilterNode->eType == FILTER_NODE_TYPE_COMPARISON)
+ {
+ if ( psFilterNode->psLeftNode && psFilterNode->psRightNode)
+ {
+ if (FLTIsBinaryComparisonFilterType(psFilterNode->pszValue) ||
+ strcasecmp(psFilterNode->pszValue, "PropertyIsLike") == 0)
+ pszExpression = FLTGetBinaryComparisonCommonExpression(psFilterNode, lp);
+
+ else if (strcasecmp(psFilterNode->pszValue, "PropertyIsBetween") == 0)
+ pszExpression = FLTGetIsBetweenComparisonCommonExpresssion(psFilterNode, lp);
+ }
+ }
+ else if (psFilterNode->eType == FILTER_NODE_TYPE_LOGICAL)
+ pszExpression = FLTGetLogicalComparisonCommonExpression(psFilterNode, lp);
+
+ else if (psFilterNode->eType == FILTER_NODE_TYPE_SPATIAL)
+ pszExpression = FLTGetSpatialComparisonCommonExpression(psFilterNode, lp);
+
+ else if (psFilterNode->eType == FILTER_NODE_TYPE_FEATUREID)
+ pszExpression = FLTGetFeatureIdCommonExpression(psFilterNode, lp);
+
+ return pszExpression;
+}
+
+
+int FLTApplyFilterToLayerCommonExpression(mapObj *map, int iLayerIndex, char *pszExpression)
+{
+ int retval;
+
+ msFreeQuery(&(map->query));
+ msInitQuery(&(map->query));
+
+ map->query.type = MS_QUERY_BY_FILTER;
+
+ map->query.filter = (expressionObj *) malloc(sizeof(expressionObj));
+ initExpression( map->query.filter);
+ map->query.filter->string = msStrdup(pszExpression);
+ map->query.filter->type = 2000;
+ map->query.layer = iLayerIndex;
+
+ /*TODO: if there is a bbox in the node, get it and set the map extent*/
+ map->query.rect = map->extent;
+
+ retval = msQueryByFilter(map);
+
+ return retval;
+}
+
+#endif
Property changes on: trunk/mapserver/mapogcfiltercommon.c
___________________________________________________________________
Added: svn:executable
+ *
Modified: trunk/mapserver/mapserver.h
===================================================================
--- trunk/mapserver/mapserver.h 2011-01-26 10:50:08 UTC (rev 10915)
+++ trunk/mapserver/mapserver.h 2011-01-26 19:29:02 UTC (rev 10916)
@@ -1623,7 +1623,7 @@
int (*LayerGetAutoStyle)(mapObj *map, layerObj *layer, classObj *c, int tile, long record);
int (*LayerCloseConnection)(layerObj *layer);
int (*LayerSetTimeFilter)(layerObj *layer, const char *timestring, const char *timefield);
- int (*LayerApplyFilterToLayer)(FilterEncodingNode *psNode, mapObj *map, int iLayerIndex, int bOnlySpatialFilter);
+ int (*LayerApplyFilterToLayer)(FilterEncodingNode *psNode, mapObj *map, int iLayerIndex);
int (*LayerCreateItems)(layerObj *layer, int nt);
int (*LayerGetNumFeatures)(layerObj *layer);
int (*LayerGetAutoProjection)(layerObj *layer, projectionObj *projection);
@@ -2058,10 +2058,10 @@
const char *timefield);
MS_DLL_EXPORT int msLayerApplyCondSQLFilterToLayer(FilterEncodingNode *psNode, mapObj *map,
- int iLayerIndex, int bOnlySpatialFilter);
+ int iLayerIndex);
MS_DLL_EXPORT int msLayerApplyPlainFilterToLayer(FilterEncodingNode *psNode, mapObj *map,
- int iLayerIndex, int bOnlySpatialFilter);
+ int iLayerIndex);
/* maplayer.c */
Modified: trunk/mapserver/mapwfs.c
===================================================================
--- trunk/mapserver/mapwfs.c 2011-01-26 10:50:08 UTC (rev 10915)
+++ trunk/mapserver/mapwfs.c 2011-01-26 19:29:02 UTC (rev 10916)
@@ -2225,7 +2225,7 @@
/* run filter. If no results are found, do not throw exception */
/* this is a null result */
- if( FLTApplyFilterToLayer(psNode, map, iLayerIndex, MS_FALSE) != MS_SUCCESS )
+ if( FLTApplyFilterToLayer(psNode, map, iLayerIndex) != MS_SUCCESS )
{
ms_error = msGetErrorObj();
@@ -2326,7 +2326,7 @@
}
psNode = FLTCreateFeatureIdFilterEncoding(aFIDValues[j]);
- if( FLTApplyFilterToLayer(psNode, map, lp->index, MS_FALSE) != MS_SUCCESS ) {
+ if( FLTApplyFilterToLayer(psNode, map, lp->index) != MS_SUCCESS ) {
msSetError(MS_WFSERR, "FLTApplyFilterToLayer() failed", "msWFSGetFeature");
return msWFSException(map, "mapserv", "NoApplicableCode", paramsObj->pszVersion);
}
@@ -2381,7 +2381,7 @@
*/
/* __TODO__ Using a rectangle query may not be the most efficient way */
/* to do things here. */
- if (!bFilterSet) {
+ if (!bFilterSet && !bFeatureIdSet) {
if (!bBBOXSet)
{
More information about the mapserver-commits
mailing list