[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