[mapserver-commits] r9584 - trunk/mapserver

svn at osgeo.org svn at osgeo.org
Mon Dec 7 08:51:55 EST 2009


Author: assefa
Date: 2009-12-07 08:51:53 -0500 (Mon, 07 Dec 2009)
New Revision: 9584

Modified:
   trunk/mapserver/HISTORY.TXT
   trunk/mapserver/mapogcfilter.c
   trunk/mapserver/mapogcfilter.h
   trunk/mapserver/mapogcsld.c
   trunk/mapserver/mapogcsld.h
Log:
Filter encoding: simple filters using propertyislike not applied properly

Modified: trunk/mapserver/HISTORY.TXT
===================================================================
--- trunk/mapserver/HISTORY.TXT	2009-12-04 22:42:00 UTC (rev 9583)
+++ trunk/mapserver/HISTORY.TXT	2009-12-07 13:51:53 UTC (rev 9584)
@@ -14,6 +14,8 @@
 Current Version (SVN trunk):
 ----------------------------
 
+- Filter encoding: simple filters using propertyislike not applied properly
+  #2720, #2840
 
 Version 5.6.0 (2009-12-04):
 ---------------------------

Modified: trunk/mapserver/mapogcfilter.c
===================================================================
--- trunk/mapserver/mapogcfilter.c	2009-12-04 22:42:00 UTC (rev 9583)
+++ trunk/mapserver/mapogcfilter.c	2009-12-07 13:51:53 UTC (rev 9584)
@@ -223,7 +223,6 @@
     char *szEPSG = NULL;
     rectObj sQueryRect = map->extent;
     layerObj *lp = NULL;
-    char *szClassItem = NULL;
     projectionObj sProjTmp;
     int bPointQuery = 0, bShapeQuery=0;
     shapeObj *psQueryShape = NULL;
@@ -273,13 +272,18 @@
 
     if (szExpression)
     {
-        szClassItem = FLTGetMapserverExpressionClassItem(psNode);
-        
-        /* TODO: Doesn't this code leak the contents of any pre-existing class
-         * in the layer???
-         */
-        if (lp->numclasses == 0 &&
-            msGrowLayerClasses(lp) == NULL)
+        for(i=0;i<lp->numclasses;i++) 
+        {
+            if (lp->class[i] != NULL) {
+                lp->class[i]->layer=NULL;
+                if ( freeClass(lp->class[i]) == MS_SUCCESS ) {
+                    msFree(lp->class[i]);
+                    lp->class[i] = NULL;
+                }
+            }
+        }
+        lp->numclasses = 0;
+        if (msGrowLayerClasses(lp) == NULL)
             return MS_FAILURE;
        	initClass(lp->class[0]);
 
@@ -287,46 +291,7 @@
         lp->numclasses = 1;
         msLoadExpressionString(&lp->class[0]->expression, 
                                szExpression);
-/* -------------------------------------------------------------------- */
-/*      classitems are necessary for filter type PropertyIsLike         */
-/* -------------------------------------------------------------------- */
-        if (szClassItem)
-        {
-            if (lp->classitem)
-              free (lp->classitem);
-            lp->classitem = strdup(szClassItem);
 
-/* ==================================================================== */
-/*      If there is a case where PorprtyIsLike is combined with an      */
-/*      Or, then we need to create a second class with the              */
-/*      PrpertyIsEqual expression. Note that the first expression       */
-/*      returned does not include the IslikePropery.                    */
-/* ==================================================================== */
-            if (!FLTIsOnlyPropertyIsLike(psNode))
-            {
-                szExpression = 
-                  FLTGetMapserverIsPropertyExpression(psNode, lp);
-                if (szExpression)
-                {
-                    /* TODO: Doesn't this code leak the contents of any 
-                     * pre-existing class in the layer???
-                     */
-                    if (lp->numclasses <2 &&
-                        msGrowLayerClasses(lp) == NULL)
-                        return MS_FAILURE;
-                    initClass(lp->class[1]);
-                    
-                    lp->class[1]->type = lp->type;
-                    /* TODO: if numclasses was already > 1 then this increment is wrong and leaves class[numclasses] non-initialized */
-                    lp->numclasses++;
-                    msLoadExpressionString(&lp->class[1]->expression, 
-                                         szExpression);
-                    if (!lp->class[1]->template)
-                      lp->class[1]->template = strdup("ttt.html");
-                }
-            }
-        }
-
         if (!lp->class[0]->template)
           lp->class[0]->template = strdup("ttt.html");
 /* -------------------------------------------------------------------- */
@@ -976,7 +941,7 @@
     char *pszBuffer = NULL;
     int bConcatWhere = 0;
     int bHasAWhere =0;
-    char *pszFilterItem=NULL;
+    char *pszTmp = NULL;
 
     lp = (GET_LAYER(map, iLayerIndex));
 
@@ -1026,9 +991,6 @@
 #endif
     }
 
-    /* TODO: Doesn't this code leak the contents of any pre-existing class
-     * in the layer???
-     */
     /* make sure that the layer can be queried*/
     if (!lp->template)
       lp->template = strdup("ttt.html");
@@ -1046,7 +1008,17 @@
     bHasAWhere = 0;
     if (lp->connectiontype == MS_POSTGIS || lp->connectiontype ==  MS_ORACLESPATIAL ||
         lp->connectiontype == MS_SDE || lp->connectiontype == MS_PLUGIN)
-      szExpression = FLTGetSQLExpression(psNode, lp);
+    {
+        szExpression = FLTGetSQLExpression(psNode, lp);
+        if (szExpression)
+        {
+            pszTmp = strdup("(");
+            pszTmp = msStringConcatenate(pszTmp, szExpression);
+            pszTmp = msStringConcatenate(pszTmp, ")");
+            msFree(szExpression);
+            szExpression = pszTmp;
+        }
+    }
     /* concatenates the WHERE clause for OGR layers. This only applies if
        the expression was empty or not of an expression string. If there
        is an sql type expression, it is assumed to have the WHERE clause. 
@@ -1076,15 +1048,7 @@
     else
     {
       szExpression = FLTGetMapserverExpression(psNode, lp);
-        /*if there is a filter item set it (this is only for propertislike with 
-          non db layers*/
-        pszFilterItem = FLTGetMapserverExpressionClassItem(psNode);
-        if (pszFilterItem)
-        {
-            if (lp->filteritem)
-              free (lp->filteritem);
-            lp->filteritem = strdup(pszFilterItem);
-        }
+        
     }
    
 
@@ -1125,6 +1089,7 @@
     map->query.mode = MS_QUERY_MULTIPLE;
     map->query.layer = lp->index;
     map->query.rect = sQueryRect;
+
     return msQueryByRect(map);
 
     /* return MS_SUCCESS; */
@@ -1132,7 +1097,7 @@
 
 int FLTIsSimpleFilter(FilterEncodingNode *psNode)
 {
-  if (FLTValidForBBoxFilter(psNode) && FLTValidForPropertyIsLikeFilter(psNode))
+    if (FLTValidForBBoxFilter(psNode))
     {
         if (FLTNumberOfFilterType(psNode, "DWithin") == 0 &&
             FLTNumberOfFilterType(psNode, "Intersect") == 0 &&
@@ -2031,7 +1996,8 @@
                     CPLSearchXMLNode(psXMLNode,  "PropertyName") &&
                     CPLGetXMLValue(psXMLNode, "wildCard", "") &&
                     CPLGetXMLValue(psXMLNode, "singleChar", "") &&
-                    CPLGetXMLValue(psXMLNode, "escape", ""))
+                    (CPLGetXMLValue(psXMLNode, "escape", "") || 
+                     CPLGetXMLValue(psXMLNode, "escapeChar", "")))
                   /*
                     psXMLNode->psChild &&  
                     strcasecmp(psXMLNode->psChild->pszValue, "wildCard") == 0 &&
@@ -2061,10 +2027,16 @@
                       ((FEPropertyIsLike *)psFilterNode->pOther)->pszSingleChar = 
                         strdup(pszTmp);
                     pszTmp = (char *)CPLGetXMLValue(psXMLNode, "escape", "");
-                    if (pszTmp)
+                    if (pszTmp && strlen(pszTmp)>0)
                       ((FEPropertyIsLike *)psFilterNode->pOther)->pszEscapeChar = 
                         strdup(pszTmp);
-
+                    else
+                    {
+                        pszTmp = (char *)CPLGetXMLValue(psXMLNode, "escapeChar", "");
+                        if (pszTmp)
+                          ((FEPropertyIsLike *)psFilterNode->pOther)->pszEscapeChar = 
+                            strdup(pszTmp);
+                    }
                     pszTmp = (char *)CPLGetXMLValue(psXMLNode, "matchCase", "");
                     if (pszTmp && strlen(pszTmp) > 0 && 
                         strcasecmp(pszTmp, "false") == 0)
@@ -2339,96 +2311,9 @@
 }
     
 
-/************************************************************************/
-/*                     FLTValidForPropertyIsLikeFilter                  */
-/*                                                                      */
-/*      Check if there is only none or one PropertyIsLikeFilter.        */
-/************************************************************************/
-int FLTValidForPropertyIsLikeFilter(FilterEncodingNode *psFilterNode)
-{
-    int nCount = 0;
-   
-    if (!psFilterNode)
-      return 1;
 
-    nCount = FLTNumberOfFilterType(psFilterNode, "PropertyIsLike");
 
-    if (nCount == 0)
-       return 1;
-
-    if (nCount > 1)
-      return 0;
-
-    /*make sure that if there is properyisequal, it is the only one*/
-    if (psFilterNode->psLeftNode == NULL && psFilterNode->psRightNode == NULL)
-      return 1;
-
-    return 0;
-}
-
-int FLTIsPropertyIsLikeFilter(FilterEncodingNode *psFilterNode)
-{
-    if (!psFilterNode || !psFilterNode->pszValue)
-      return 0;
-    
-    if (strcasecmp(psFilterNode->pszValue, "PropertyIsLike") == 0)
-      return 1;
-
-    if (strcasecmp(psFilterNode->pszValue, "OR") == 0)
-    {
-      if (strcasecmp(psFilterNode->psLeftNode->pszValue, "PropertyIsLike") ==0 ||
-          strcasecmp(psFilterNode->psRightNode->pszValue, "PropertyIsLike") ==0)
-        return 1;
-    }
-
-    return 0;
-}       
- 
-
 /************************************************************************/
-/*                         FLTIsOnlyPropertyIsLike                      */
-/*                                                                      */
-/*      Check if the only expression expression in the node tree is     */
-/*      of type PropertyIsLIke. 2 cases :                               */
-/*        - one node with PropertyIsLike                                */
-/*        - or PropertyIsLike combined with BBOX                        */
-/************************************************************************/
-int FLTIsOnlyPropertyIsLike(FilterEncodingNode *psFilterNode)
-{
-    if (psFilterNode && psFilterNode->pszValue)
-    {
-        
-        if (strcmp(psFilterNode->pszValue, "PropertyIsLike") ==0)
-          return 1;
-        else if (FLTNumberOfFilterType(psFilterNode, "PropertyIsLike") == 1 &&
-                 FLTNumberOfFilterType(psFilterNode, "BBOX") == 1)
-          return 1;
-    }
-    return 0;
-}
-
-char *FLTGetMapserverIsPropertyExpression(FilterEncodingNode *psFilterNode, layerObj *lp)
-{
-    char *pszExpression = NULL;
-
-    if (psFilterNode && psFilterNode->pszValue && 
-         strcmp(psFilterNode->pszValue, "PropertyIsLike") ==0)
-      return FLTGetMapserverExpression(psFilterNode, lp);
-    else
-    {
-        if (psFilterNode->psLeftNode)
-          pszExpression = 
-            FLTGetMapserverIsPropertyExpression(psFilterNode->psLeftNode, lp);
-        if (!pszExpression && psFilterNode->psRightNode)
-          pszExpression = 
-            FLTGetMapserverIsPropertyExpression(psFilterNode->psRightNode, lp);
-    }
-
-    return pszExpression;
-}
-
-
-/************************************************************************/
 /*                          FLTValidForBBoxFilter                       */
 /*                                                                      */
 /*      Validate if there is only one BBOX filter node. Here is waht    */
@@ -2666,38 +2551,7 @@
 
     return pszReturn;
 }
-/************************************************************************/
-/*                     GetMapserverExpressionClassItem                  */
-/*                                                                      */
-/*      Check if one of the node is a PropertyIsLike filter node. If    */
-/*      that is the case return the value that will be used as a        */
-/*      ClassItem in mapserver.                                         */
-/*      NOTE : only the first one is used.                              */
-/************************************************************************/
-char *FLTGetMapserverExpressionClassItem(FilterEncodingNode *psFilterNode)
-{
-    char *pszReturn = NULL;
 
-    if (!psFilterNode)
-      return NULL;
-
-    if (psFilterNode->pszValue && 
-        strcasecmp(psFilterNode->pszValue, "PropertyIsLike") == 0)
-    {
-        if (psFilterNode->psLeftNode)
-          return psFilterNode->psLeftNode->pszValue;
-    }
-    else
-    {
-        pszReturn = FLTGetMapserverExpressionClassItem(psFilterNode->psLeftNode);
-        if (pszReturn)
-          return pszReturn;
-        else
-          return  FLTGetMapserverExpressionClassItem(psFilterNode->psRightNode);
-    }
-
-    return pszReturn;
-}
 /************************************************************************/
 /*                          GetMapserverExpression                      */
 /*                                                                      */
@@ -2912,6 +2766,7 @@
 #endif
 
     }
+    
     return pszExpression;
 }
   
@@ -3079,37 +2934,19 @@
         
         pszBuffer = (char *)malloc(sizeof(char) * (strlen(pszTmp) + 3));
         pszBuffer[0] = '\0';
+        /*
         if (strcasecmp(psFilterNode->psLeftNode->pszValue, "PropertyIsLike") == 0 ||
             strcasecmp(psFilterNode->psRightNode->pszValue, "PropertyIsLike") == 0)
           sprintf(pszBuffer, "%s", pszTmp);
         else
-          sprintf(pszBuffer, "(%s)", pszTmp);
+        */
+        sprintf(pszBuffer, "(%s)", pszTmp);
         
         
         return pszBuffer;
     }
 
-/* ==================================================================== */
-/*      special case for PropertyIsLike.                                */
-/* ==================================================================== */
-    if (psFilterNode->psLeftNode && psFilterNode->psRightNode &&
-        ((strcasecmp(psFilterNode->psLeftNode->pszValue, "PropertyIsLike") == 0) ||
-         (strcasecmp(psFilterNode->psRightNode->pszValue, "PropertyIsLike") == 0)))
-    {
-        if (strcasecmp(psFilterNode->psLeftNode->pszValue, "PropertyIsLike") != 0)
-          pszTmp = FLTGetNodeExpression(psFilterNode->psLeftNode, lp);
-        else
-          pszTmp = FLTGetNodeExpression(psFilterNode->psRightNode, lp);
-
-        if (!pszTmp)
-          return NULL;
-        pszBuffer = (char *)malloc(sizeof(char) * (strlen(pszTmp) + 1));
-        pszBuffer[0] = '\0';
-        sprintf(pszBuffer, "%s", pszTmp);
-        
-
-        return pszBuffer;
-    }
+    
 /* -------------------------------------------------------------------- */
 /*      OR and AND                                                      */
 /* -------------------------------------------------------------------- */
@@ -3571,6 +3408,7 @@
 char *FLTGetIsLikeComparisonExpression(FilterEncodingNode *psFilterNode)
 {
     char szBuffer[1024];
+    char szTmp[256];
     char *pszValue = NULL;
     
     char *pszWild = NULL;
@@ -3578,7 +3416,7 @@
     char *pszEscape = NULL;
     int  bCaseInsensitive = 0;
 
-    int nLength=0, i=0, iBuffer = 0;
+    int nLength=0, i=0, iTmp=0;
 
 
     if (!psFilterNode || !psFilterNode->pOther || !psFilterNode->psLeftNode ||
@@ -3597,23 +3435,34 @@
 
  
 /* -------------------------------------------------------------------- */
-/*      Use only the right node (which is the value), to build the      */
-/*      regular expresssion. The left node will be used to build the    */
-/*      classitem.                                                      */
+/*      Use operand with regular expressions.                           */
 /* -------------------------------------------------------------------- */
-    iBuffer = 0;
-    szBuffer[iBuffer++] = '/';
-    szBuffer[iBuffer] = '\0';
-    /*szBuffer[1] = '^';*/
+    szBuffer[0] = '\0';
+    sprintf(szTmp, "%s", " (\"[");
+    szTmp[4] = '\0';
+
+    strcat(szBuffer, szTmp);
+
+    /* attribute */
+    strcat(szBuffer, psFilterNode->psLeftNode->pszValue);
+    szBuffer[strlen(szBuffer)] = '\0';
+
+    sprintf(szTmp, "%s", "]\" =~ /");
+    szTmp[7] = '\0';
+    strcat(szBuffer, szTmp);
+    szBuffer[strlen(szBuffer)] = '\0';
+
+
     pszValue = psFilterNode->psRightNode->pszValue;
     nLength = strlen(pszValue);
     
+    iTmp =0;
     if (nLength > 0 && pszValue[0] != pszWild[0] && 
         pszValue[0] != pszSingle[0] &&
         pszValue[0] != pszEscape[0])
     {
-        szBuffer[iBuffer++] = '^';
-        szBuffer[iBuffer] = '\0';
+      szTmp[iTmp]= '^';
+      iTmp++;
     }
     for (i=0; i<nLength; i++)
     {
@@ -3621,40 +3470,41 @@
             pszValue[i] != pszSingle[0] &&
             pszValue[i] != pszEscape[0])
         {
-            szBuffer[iBuffer] = pszValue[i];
-            iBuffer++;
-            szBuffer[iBuffer] = '\0';
+            szTmp[iTmp] = pszValue[i];
+            iTmp++;
+            szTmp[iTmp] = '\0';
         }
         else if  (pszValue[i] == pszSingle[0])
         {
-             szBuffer[iBuffer] = '.';
-             iBuffer++;
-             szBuffer[iBuffer] = '\0';
+             szTmp[iTmp] = '.';
+             iTmp++;
+             szTmp[iTmp] = '\0';
         }
         else if  (pszValue[i] == pszEscape[0])
         {
-            szBuffer[iBuffer] = '\\';
-            iBuffer++;
-            szBuffer[iBuffer] = '\0';
+            szTmp[iTmp] = '\\';
+            iTmp++;
+            szTmp[iTmp] = '\0';
 
         }
         else if (pszValue[i] == pszWild[0])
         {
             /* strcat(szBuffer, "[0-9,a-z,A-Z,\\s]*"); */
             /* iBuffer+=17; */
-            strcat(szBuffer, ".*");
-            iBuffer+=2;
-            szBuffer[iBuffer] = '\0';
+            szTmp[iTmp++] = '.';
+            szTmp[iTmp++] = '*';
+            szTmp[iTmp] = '\0';
         }
     }   
-    szBuffer[iBuffer] = '/';
+    szTmp[iTmp] = '/';
     if (bCaseInsensitive == 1)
     {
-      szBuffer[++iBuffer] = 'i';
+      szTmp[++iTmp] = 'i';
     } 
-    szBuffer[++iBuffer] = '\0';
+    szTmp[++iTmp] = '\0';
     
-        
+    strcat(szBuffer, szTmp);
+    strcat(szBuffer, ")");     
     return strdup(szBuffer);
 }
 
@@ -4057,6 +3907,12 @@
 }
 
 
+/************************************************************************/
+/*                        FLTPreParseFilterForAlias                     */
+/*                                                                      */
+/*      Utility function to replace aliased' attributes with their      */
+/*      real name.                                                      */
+/************************************************************************/
 void FLTPreParseFilterForAlias(FilterEncodingNode *psFilterNode, 
                                mapObj *map, int i, const char *namespaces)
 {

Modified: trunk/mapserver/mapogcfilter.h
===================================================================
--- trunk/mapserver/mapogcfilter.h	2009-12-04 22:42:00 UTC (rev 9583)
+++ trunk/mapserver/mapogcfilter.h	2009-12-07 13:51:53 UTC (rev 9584)
@@ -92,7 +92,6 @@
 MS_DLL_EXPORT int FLTIsSupportedFilterType(CPLXMLNode *psXMLNode);
 
 MS_DLL_EXPORT char *FLTGetMapserverExpression(FilterEncodingNode *psFilterNode, layerObj *lp);
-MS_DLL_EXPORT char *FLTGetMapserverExpressionClassItem(FilterEncodingNode *psFilterNode);
 MS_DLL_EXPORT char *FLTGetNodeExpression(FilterEncodingNode *psFilterNode, layerObj *lp);
 MS_DLL_EXPORT char *FLTGetBBOX(FilterEncodingNode *psFilterNode, rectObj *psRect);
 

Modified: trunk/mapserver/mapogcsld.c
===================================================================
--- trunk/mapserver/mapogcsld.c	2009-12-04 22:42:00 UTC (rev 9583)
+++ trunk/mapserver/mapogcsld.c	2009-12-07 13:51:53 UTC (rev 9584)
@@ -74,7 +74,7 @@
     char *pszSLDbuf=NULL;
     FILE *fp = NULL;               
     int nStatus = MS_FAILURE;
-
+    
     if (map && szURL)
     {
         pszSLDTmpFile = msTmpFile(map->mappath, map->web.imagepath, "sld.xml");
@@ -154,10 +154,15 @@
     /*const char *pszSLDNotSupported = NULL;*/
     char *tmpfilename = NULL;
     const char *pszFullName = NULL; 
-    char szTmp[256]; 
+    char szTmp[512]; 
     char *pszTmp1=NULL;
     char *pszTmp2 = NULL; 
-
+    char *pszBuffer = NULL;
+    layerObj *lp = NULL;
+    char *pszSqlExpression=NULL;
+    FilterEncodingNode *psExpressionNode =NULL;
+    int bFailedExpression=0;
+ 
     pasLayers = msSLDParseSLD(map, psSLDXML, &nLayers);
 
     if (pasLayers && nLayers > 0)
@@ -203,7 +208,19 @@
                     {
                         GET_LAYER(map, i)->type = pasLayers[j].type;
 
-                        /* TODO: Setting numclasses=0 here results in leaking the contents of any pre-existing classes!?! */
+                        for(k=0;k<GET_LAYER(map, i)->numclasses;k++) 
+                        {
+                            if (GET_LAYER(map, i)->class[k] != NULL) 
+                            {
+                                GET_LAYER(map, i)->class[k]->layer=NULL;
+                                if (freeClass(GET_LAYER(map, i)->class[k]) == MS_SUCCESS )
+                                {
+                                    msFree(GET_LAYER(map, i)->class[k]);
+                                    GET_LAYER(map, i)->class[k] = NULL;
+                                }
+                            }
+                        }
+
                         GET_LAYER(map, i)->numclasses = 0;
 
                         /*unset the classgroup on the layer if it was set. This allows the layer to render
@@ -360,6 +377,75 @@
                             GET_LAYER(map, i)->template = NULL;
                         }
                     }
+                    else
+                    {
+                        /*in some cases it would make sense to concatenate all the class
+                          expressions and use it to set the filter on the layer. This   
+                          could increase performace. Will do it for db types layers #2840*/
+                        lp = GET_LAYER(map, i);
+                        if (lp->filter.string == NULL || 
+                            (lp->filter.string && lp->filter.type == MS_EXPRESSION))
+                        {
+                            if (lp->connectiontype == MS_POSTGIS || lp->connectiontype ==  MS_ORACLESPATIAL ||
+                                lp->connectiontype == MS_SDE || lp->connectiontype == MS_PLUGIN)
+                            {
+                                if (lp->numclasses > 0)
+                                {
+                                    /*check first that all classes have an expression type. That is
+                                      the only way we can concatenate them and set the filter 
+                                      expression*/
+                                    for (k=0;k<lp->numclasses;k++)
+                                    {
+                                        if (lp->class[k]->expression.type != MS_EXPRESSION)
+                                          break;
+                                    }
+                                    if (k == lp->numclasses)
+                                    {
+                                        bFailedExpression = 0;
+                                        for (k=0;k<lp->numclasses;k++)
+                                        {
+                                            if (pszBuffer == NULL)
+                                              sprintf(szTmp, "%s", "((");
+                                            else
+                                               sprintf(szTmp, "%s", " OR ");
+
+                                            pszBuffer =msStringConcatenate(pszBuffer, szTmp);
+                                            psExpressionNode = BuildExpressionTree(lp->class[k]->expression.string,NULL);
+                                            if (psExpressionNode)
+                                            {
+                                                pszSqlExpression = FLTGetSQLExpression(psExpressionNode,lp);
+                                                if (pszSqlExpression)
+                                                {
+                                                    pszBuffer =
+                                                      msStringConcatenate(pszBuffer, pszSqlExpression);
+                                                    msFree(pszSqlExpression);
+                                                }
+                                                else
+                                                {
+                                                    bFailedExpression =1;
+                                                    break;
+                                                }
+                                                FLTFreeFilterEncodingNode(psExpressionNode);
+                                            }
+                                            else
+                                            {
+                                                bFailedExpression =1;
+                                                break;
+                                            }
+                                        }
+                                        if (!bFailedExpression)
+                                        {
+                                            sprintf(szTmp, "%s", "))");
+                                            pszBuffer =msStringConcatenate(pszBuffer, szTmp);
+                                            msLoadExpressionString(&lp->filter, pszBuffer);
+                                        }
+                                        msFree(pszBuffer);
+                                    }
+                                }    
+                            }       
+                        }
+                        
+                    }
                     break;
                 }
             }
@@ -634,7 +720,6 @@
     CPLXMLNode *psTmpNode = NULL;
     FilterEncodingNode *psNode = NULL;
     char *szExpression = NULL;
-    char *szClassItem = NULL;
     int i=0, nNewClasses=0, nClassBeforeFilter=0, nClassAfterFilter=0;
     int nClassAfterRule=0, nClassBeforeRule=0;
     char *pszTmpFilter = NULL;
@@ -755,8 +840,6 @@
 
                                 if (szExpression)
                                 {
-                                    szClassItem = 
-                                      FLTGetMapserverExpressionClassItem(psNode);
                                     nNewClasses = 
                                       nClassAfterFilter - nClassBeforeFilter;
                                     for (i=0; i<nNewClasses; i++)
@@ -765,8 +848,6 @@
                                                              class[psLayer->numclasses-1-i]->
                                                              expression, szExpression);
                                     }
-                                    if (szClassItem)
-                                      psLayer->classitem = strdup(szClassItem);
                                 }
                             }
                         }
@@ -2737,15 +2818,17 @@
             if (nValues == nThresholds+1)
             {
                 /*free existing classes*/
-                for(i=0;i<psLayer->maxclasses;i++) {
+                for(i=0;i<psLayer->numclasses;i++) {
                     if (psLayer->class[i] != NULL) 
                     {
                         psLayer->class[i]->layer=NULL;
                         if ( freeClass(psLayer->class[i]) == MS_SUCCESS ) {
                             msFree(psLayer->class[i]);
+                            psLayer->class[i]=NULL;
                         }
                     }
                 }
+                psLayer->numclasses=0;
                 for (i=0; i<nValues; i++)
                 {
                     pszTmp = (papszValues[i]);
@@ -4593,6 +4676,8 @@
 
     if (strstr(pszExpression, "<=") || strstr(pszExpression, " le "))
       pszValue = strdup("PropertyIsLessThanOrEqualTo");
+     else if (strstr(pszExpression, "=~"))
+      pszValue = strdup("PropertyIsLike");
     else if (strstr(pszExpression, ">=") || strstr(pszExpression, " ge "))
       pszValue = strdup("PropertyIsGreaterThanOrEqualTo");
     else if (strstr(pszExpression, "!=") || strstr(pszExpression, " ne "))
@@ -4603,6 +4688,7 @@
       pszValue = strdup("PropertyIsLessThan");
     else if (strstr(pszExpression, ">") || strstr(pszExpression, " gt "))
       pszValue = strdup("PropertyIsGreaterThan");
+   
 
     return pszValue;
 }
@@ -4864,6 +4950,18 @@
 
         bOneCharCompare =0;
     }
+    else if (strcasecmp(pszComparionValue, "PropertyIsLike") == 0)
+    {
+        szCompare[0] = '=';
+        szCompare[1] = '~';
+        szCompare[2] = '\0';
+
+        szCompare2[0] = '=';
+        szCompare2[1] = '~';
+        szCompare2[2] = '\0';
+
+        bOneCharCompare =0;
+    }
     else if (strcasecmp(pszComparionValue, "PropertyIsLessThan") == 0)
     {
         cCompare = '<';
@@ -4941,6 +5039,8 @@
                 }
                 pszAttributeName[iValue] = '\0';
             }
+
+            
         }
     }
     else if (bOneCharCompare == 0)
@@ -5052,7 +5152,23 @@
             }
             pszFinalAttributeValue[iAtt] = '\0';
         }
-            
+         
+        /*trim  for regular expressions*/
+        if (pszFinalAttributeValue && strlen(pszFinalAttributeValue) > 2 && 
+            strcasecmp(pszComparionValue, "PropertyIsLike") == 0)
+        {
+            msStringTrimBlanks(pszFinalAttributeValue);
+            if (pszFinalAttributeValue[0] == '/' &&  pszFinalAttributeValue[strlen(pszFinalAttributeValue)-1] == '/')
+            {
+                pszFinalAttributeValue[strlen(pszFinalAttributeValue)-1] = '\0';
+                pszFinalAttributeValue = pszFinalAttributeValue++;
+                if (pszFinalAttributeValue[0] == '^')
+                  pszFinalAttributeValue++;
+
+                /*replace wild card string .* with * */
+                pszFinalAttributeValue = msReplaceSubstring(pszFinalAttributeValue, ".*", "*");
+            }
+        }
         return pszFinalAttributeValue;
     }
 }
@@ -5115,7 +5231,7 @@
 
 /* -------------------------------------------------------------------- */
 /*      First we check how many logical operators are there :           */
-/*       - if none : It means It is a coamrision operator (like =,      */
+/*       - if none : It means It is a comparision operator (like =,      */
 /*      >, >= .... We get the comparison value as well as the           */
 /*      attribute and the attribut's value and assign it to the node    */
 /*      passed in argument.                                             */
@@ -5144,6 +5260,14 @@
             psNode->psRightNode->eType = FILTER_NODE_TYPE_LITERAL;
             psNode->psRightNode->pszValue = strdup(pszAttibuteValue);
 
+            if (strcasecmp(pszComparionValue, "PropertyIsLike") == 0)
+            {
+                psNode->pOther = (FEPropertyIsLike *)malloc(sizeof(FEPropertyIsLike));
+                ((FEPropertyIsLike *)psNode->pOther)->bCaseInsensitive = 0;
+                ((FEPropertyIsLike *)psNode->pOther)->pszWildCard = strdup("*");
+                 ((FEPropertyIsLike *)psNode->pOther)->pszSingleChar = strdup("#");
+                 ((FEPropertyIsLike *)psNode->pOther)->pszEscapeChar = strdup("!");
+            }
             free(pszComparionValue);
             free(pszAttibuteName);
             free(pszAttibuteValue);
@@ -5636,7 +5760,7 @@
 /************************************************************************/
 /*                              msSLDGetFilter                          */
 /*                                                                      */
-/*      Get the correspondinf ogc Filter based on the class             */
+/*      Get the corresponding ogc Filter based on the class             */
 /*      expression. TODO : move function to mapogcfilter.c when         */
 /*      finished.                                                       */
 /************************************************************************/

Modified: trunk/mapserver/mapogcsld.h
===================================================================
--- trunk/mapserver/mapogcsld.h	2009-12-04 22:42:00 UTC (rev 9583)
+++ trunk/mapserver/mapogcsld.h	2009-12-07 13:51:53 UTC (rev 9584)
@@ -86,6 +86,6 @@
 char *msSLDGeneratePolygonSLD(styleObj *psStyle, layerObj *psLayer, int nVersion);
 char *msSLDGeneratePointSLD(styleObj *psStyle, layerObj *psLayer, int nVersion);
 char *msSLDGenerateTextSLD(classObj *psClass, layerObj *psLayer, int nVersion);
+FilterEncodingNode *BuildExpressionTree(char *pszExpression, FilterEncodingNode *psNode);
 
-
 #endif



More information about the mapserver-commits mailing list