[mapserver-commits] r10467 - sandbox/sdlime/common-expressions/mapserver

svn at osgeo.org svn at osgeo.org
Tue Aug 24 09:18:16 EDT 2010


Author: sdlime
Date: 2010-08-24 13:18:16 +0000 (Tue, 24 Aug 2010)
New Revision: 10467

Modified:
   sandbox/sdlime/common-expressions/mapserver/maplayer.c
   sandbox/sdlime/common-expressions/mapserver/mapquery.c
   sandbox/sdlime/common-expressions/mapserver/mapserver.h
Log:
Basic version of msQueryByFilter() in place for shapefiles.

Modified: sandbox/sdlime/common-expressions/mapserver/maplayer.c
===================================================================
--- sandbox/sdlime/common-expressions/mapserver/maplayer.c	2010-08-24 03:03:18 UTC (rev 10466)
+++ sandbox/sdlime/common-expressions/mapserver/maplayer.c	2010-08-24 13:18:16 UTC (rev 10467)
@@ -104,6 +104,19 @@
 }
 
 /*
+** Returns MS_TRUE is a layer supports the common expression syntax (RFC 59) and MS_FALSE otherwise.
+*/
+int msLayerSupportsCommonExpressions(layerObj *layer)
+{
+  if ( ! layer->vtable) {
+    int rv =  msInitializeVirtualTable(layer);
+    if (rv != MS_SUCCESS)
+      return rv;
+  }
+  return layer->vtable->LayerSupportsCommonExpressions(layer);
+}
+
+/*
 ** Performs a spatial, and optionally an attribute based feature search. The function basically
 ** prepares things so that candidate features can be accessed by query or drawing functions. For
 ** OGR and shapefiles this sets an internal bit vector that indicates whether a particular feature
@@ -333,23 +346,21 @@
 extern char *msyytext;
 extern char *msyytext_esc;
 
-static int tokenizeExpression(expressionObj *expression, char **list, int *listsize)
+int msTokenizeExpression(expressionObj *expression, char **list, int *listsize)
 {
   int n=0;
   int token;
 
-  fprintf(stderr, "in tokenizeExression()\n");
-
   if(expression->type != MS_EXPRESSION) return MS_SUCCESS;
 
   msAcquireLock(TLOCK_PARSER);
   msyystate = MS_TOKENIZE_EXPRESSION;
   msyystring = expression->string; /* the thing we're tokenizing */
 
-  fprintf(stderr, "string is %s\n", msyystring);
+  // fprintf(stderr, "string is %s\n", msyystring);
 
   while((token = msyylex()) != 0) { /* keep processing tokens until the end of the string (\0) */
-    fprintf(stderr, "%d: %d >> %s <<\n", n, token, msyytext);
+    // fprintf(stderr, "%d: %d >> %s <<\n", n, token, msyytext);
 
     switch(token) {
     case MS_TOKEN_LITERAL_NUMBER:
@@ -358,7 +369,7 @@
       break;
     case MS_TOKEN_LITERAL_STRING:
       expression->tokens[n].token = token;
-      fprintf(stderr, "    token value is: %s\n", msyytext_esc);
+      // fprintf(stderr, "    token value is: %s\n", msyytext_esc);
       expression->tokens[n].tokenval.strval = strdup(msyytext_esc);
       free(msyytext_esc); msyytext_esc=NULL;
       break;
@@ -366,7 +377,7 @@
       expression->tokens[n].token = token;
       msTimeInit(&(expression->tokens[n].tokenval.tmval));
       if(msParseTime(msyytext, &(expression->tokens[n].tokenval.tmval)) != MS_TRUE) {
-        msSetError(MS_PARSEERR, "Parsing time value failed.", "tokenizeExression()");
+        msSetError(MS_PARSEERR, "Parsing time value failed.", "msTokenizeExpression()");
         goto parse_error;
       }
       break;
@@ -383,12 +394,12 @@
       break;
     case MS_TOKEN_FUNCTION_FROMTEXT: /* we want to process a shape from WKT once and not for every feature being evaluated */
       if((token = msyylex()) != 40) { /* ( */
-        msSetError(MS_PARSEERR, "Parsing fromText function failed.", "tokenizeExression()");
+        msSetError(MS_PARSEERR, "Parsing fromText function failed.", "msTokenizeExpression()");
         goto parse_error;
       }
 
       if((token = msyylex()) != MS_TOKEN_LITERAL_STRING) {
-	msSetError(MS_PARSEERR, "Parsing fromText function failed.", "tokenizeExression()");
+	msSetError(MS_PARSEERR, "Parsing fromText function failed.", "msTokenizeExpression()");
         goto parse_error;
       }
 
@@ -397,14 +408,14 @@
       free(msyytext_esc);
 
       if(!expression->tokens[n].tokenval.shpval) {
-        msSetError(MS_PARSEERR, "Parsing fromText function failed, WKT processing failed.", "tokenizeExression()");
+        msSetError(MS_PARSEERR, "Parsing fromText function failed, WKT processing failed.", "msTokenizeExpression()");
         goto parse_error;
       }
 
       /* todo: perhaps process optional args (e.g. projection) */
 
       if((token = msyylex()) != 41) { /* ) */
-        msSetError(MS_PARSEERR, "Parsing fromText function failed.", "tokenizeExression()");
+        msSetError(MS_PARSEERR, "Parsing fromText function failed.", "msTokenizeExpression()");
         goto parse_error;
       }
       break;
@@ -492,7 +503,7 @@
     if(layer->filteritem) layer->filteritemindex = string2list(layer->items, &(layer->numitems), layer->filteritem);
 
     for(i=0; i<layer->numclasses; i++) {
-      if(layer->class[i]->expression.type == MS_EXPRESSION) tokenizeExpression(&(layer->class[i]->expression), layer->items, &(layer->numitems));
+      if(layer->class[i]->expression.type == MS_EXPRESSION) msTokenizeExpression(&(layer->class[i]->expression), layer->items, &(layer->numitems));
       for(j=0; j<layer->class[i]->numstyles; j++) {
         if(layer->class[i]->styles[j]->rangeitem) layer->class[i]->styles[j]->rangeitemindex = string2list(layer->items, &(layer->numitems), layer->class[i]->styles[j]->rangeitem);
         for(k=0; k<MS_STYLE_BINDING_LENGTH; k++)
@@ -500,11 +511,11 @@
       }
     }
 
-    if(layer->filter.type == MS_EXPRESSION) tokenizeExpression(&(layer->filter), layer->items, &(layer->numitems));
+    if(layer->filter.type == MS_EXPRESSION) msTokenizeExpression(&(layer->filter), layer->items, &(layer->numitems));
 
     if(layer->labelitem) layer->labelitemindex = string2list(layer->items, &(layer->numitems), layer->labelitem);
     for(i=0; i<layer->numclasses; i++) {
-      if(layer->class[i]->text.type == MS_EXPRESSION) tokenizeExpression(&(layer->class[i]->text), layer->items, &(layer->numitems));
+      if(layer->class[i]->text.type == MS_EXPRESSION) msTokenizeExpression(&(layer->class[i]->text), layer->items, &(layer->numitems));
       for(k=0; k<MS_LABEL_BINDING_LENGTH; k++)
         if(layer->class[i]->label.bindings[k].item) layer->class[i]->label.bindings[k].index = string2list(layer->items, &(layer->numitems), layer->class[i]->label.bindings[k].item);
     }

Modified: sandbox/sdlime/common-expressions/mapserver/mapquery.c
===================================================================
--- sandbox/sdlime/common-expressions/mapserver/mapquery.c	2010-08-24 03:03:18 UTC (rev 10466)
+++ sandbox/sdlime/common-expressions/mapserver/mapquery.c	2010-08-24 13:18:16 UTC (rev 10467)
@@ -55,6 +55,7 @@
   query->op = -1;
 
   query->item = query->str = NULL;
+  query->filter = NULL;
 
   return MS_SUCCESS;
 }
@@ -68,6 +69,7 @@
 
   if(query->item) free(query->item);
   if(query->str) free(query->str);
+  if(query->filter) freeExpression(query->filter);
 }
 
 /*
@@ -93,6 +95,9 @@
   case MS_QUERY_BY_ATTRIBUTE:
     status = msQueryByAttributes(map);
     break;
+  case MS_QUERY_BY_FILTER:
+    status = msQueryByFilter(map);
+    break;
   case MS_QUERY_BY_OPERATOR:
     status = msQueryByOperator(map);
     break;
@@ -135,7 +140,7 @@
   return MS_FALSE;
 }
 
-static int addResult(resultCacheObj *cache, int classindex, int shapeindex, int tileindex)
+static int addResult(resultCacheObj *cache, shapeObj *shape)
 {
   int i;
 
@@ -153,11 +158,16 @@
 
   i = cache->numresults;
 
-  cache->results[i].classindex = classindex;
-  cache->results[i].tileindex = tileindex;
-  cache->results[i].shapeindex = shapeindex;
+  cache->results[i].classindex = shape->classindex;
+  cache->results[i].tileindex = shape->tileindex;
+  cache->results[i].shapeindex = shape->index;
   cache->numresults++;
 
+  if(cache->numresults == 1)
+    cache->bounds = shape->bounds;
+  else
+    msMergeRect(&(cache->bounds), &shape->bounds);
+
   return(MS_SUCCESS);
 }
 
@@ -484,13 +494,9 @@
     return(MS_FAILURE);
   }
 
-  addResult(lp->resultcache, shape.classindex, shape.index, shape.tileindex);
-  if(lp->resultcache->numresults == 1)
-    lp->resultcache->bounds = shape.bounds;
-  else
-    msMergeRect(&(lp->resultcache->bounds), &shape.bounds);
-
+  addResult(lp->resultcache, &shape);
   msFreeShape(&shape);
+
   /* msLayerClose(lp); */
 
   return(MS_SUCCESS);
@@ -643,13 +649,7 @@
       lp->project = MS_FALSE;
 #endif
 
-    addResult(lp->resultcache, shape.classindex, shape.index, shape.tileindex);
-    
-    if(lp->resultcache->numresults == 1)
-      lp->resultcache->bounds = shape.bounds;
-    else
-      msMergeRect(&(lp->resultcache->bounds), &shape.bounds);
-    
+    addResult(lp->resultcache, &shape);
     msFreeShape(&shape);
 
     if(map->query.mode == MS_QUERY_SINGLE) { /* no need to look any further */
@@ -678,168 +678,158 @@
 }
 
 /*
-**
+** Query using common expression syntax.
 */
 int msQueryByFilter(mapObj *map)
 {
+  int l;
+  int start, stop=0;
+
   layerObj *lp;
-  int status;
+
+  char status;
   
-  int old_filtertype=-1;
-  char *old_filterstring=NULL, *old_filteritem=NULL;
+  expressionObj old_filter;
 
-  rectObj searchrect;
+  rectObj search_rect;
 
   shapeObj shape;
   
   int nclasses = 0;
   int *classgroup = NULL;
 
-  if(map->query.type != MS_QUERY_BY_ATTRIBUTE) {
-    msSetError(MS_QUERYERR, "The query is not properly defined.", "msQueryByAttribute()");
+  if(map->query.type != MS_QUERY_BY_FILTER) {
+    msSetError(MS_QUERYERR, "The query is not properly defined.", "msQueryByFilter()");
     return(MS_FAILURE);
   }
-
-  if(map->query.layer < 0 || map->query.layer >= map->numlayers) {
-    msSetError(MS_MISCERR, "No query layer defined.", "msQueryByAttributes()"); 
+  if(!map->query.filter) { // TODO: check filter type too
+    msSetError(MS_QUERYERR, "Filter is not set.", "msQueryByFilter()");
     return(MS_FAILURE);
   }
+  
+  msInitShape(&shape);
 
-  lp = (GET_LAYER(map, map->query.layer));
+  if(map->query.layer < 0 || map->query.layer >= map->numlayers)
+    start = map->numlayers-1;
+  else
+    start = stop = map->query.layer;
 
-  /* conditions may have changed since this layer last drawn, so set 
-     layer->project true to recheck projection needs (Bug #673) */ 
-  lp->project = MS_TRUE; 
+  for(l=start; l>=stop; l--) {
+    lp = (GET_LAYER(map, l));
 
-  /* free any previous search results, do now in case one of the following tests fails */
-  if(lp->resultcache) {
-    if(lp->resultcache->results) free(lp->resultcache->results);
-    free(lp->resultcache);
-    lp->resultcache = NULL;
-  }
+    /* conditions may have changed since this layer last drawn, so set 
+       layer->project true to recheck projection needs (Bug #673) */ 
+    lp->project = MS_TRUE; 
 
-  if(!msIsLayerQueryable(lp)) {
-    msSetError(MS_QUERYERR, "Requested layer has no templates defined so is not queryable.", "msQueryByAttributes()"); 
-    return(MS_FAILURE);
-  }
+    /* free any previous search results, do it now in case one of the next few tests fail */
+    if(lp->resultcache) {
+      if(lp->resultcache->results) free(lp->resultcache->results);
+      free(lp->resultcache);
+      lp->resultcache = NULL;
+    }
 
-  if(!map->query.str) {
-    msSetError(MS_QUERYERR, "No query expression defined.", "msQueryByAttributes()"); 
-    return(MS_FAILURE);
-  }
+    if(!msIsLayerQueryable(lp)) continue;
+    if(lp->status == MS_OFF) continue;
+    if(lp->type == MS_LAYER_RASTER) continue; /* ok to skip? */
 
-  /* save any previously defined filter */
-  if(lp->filter.string) {
-    old_filtertype = lp->filter.type;
-    old_filterstring = strdup(lp->filter.string);
-    if(lp->filteritem) 
-      old_filteritem = strdup(lp->filteritem);
-  }
+    if(map->scaledenom > 0) {
+      if((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) continue;
+      if((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) continue;
+    }
 
-  /* apply the passed query parameters */
-  if(map->query.item && map->query.item[0] != '\0') 
-    lp->filteritem = strdup(map->query.item);
-  else
-    lp->filteritem = NULL;
-  msLoadExpressionString(&(lp->filter), map->query.str);
+    if (lp->maxscaledenom <= 0 && lp->minscaledenom <= 0) {
+      if((lp->maxgeowidth > 0) && ((map->extent.maxx - map->extent.minx) > lp->maxgeowidth)) continue;
+      if((lp->mingeowidth > 0) && ((map->extent.maxx - map->extent.minx) < lp->mingeowidth)) continue;
+    }
 
-  msInitShape(&shape);
+    msCopyExpression(&old_filter, &lp->filter); /* save existing filter */
+    if(msLayerSupportsCommonExpressions(lp)) {
+      msCopyExpression(&lp->filter, map->query.filter); /* apply new filter */
+    } else {
+      freeExpression(&lp->filter); /* clear existing filter */
+      status = msTokenizeExpression(map->query.filter, NULL, NULL);
+      if(status != MS_SUCCESS) goto query_error;
+    }
 
-  /* open this layer */
-  status = msLayerOpen(lp);
-  if(status != MS_SUCCESS) {
-    msRestoreOldFilter(lp, old_filtertype, old_filteritem, old_filterstring); /* manually reset the filter */
-    return(MS_FAILURE);
-  }
-  
-  /* build item list, we want *all* items */
-  status = msLayerWhichItems(lp, MS_TRUE, NULL);
-  if(status != MS_SUCCESS) {
-    msRestoreOldFilter(lp, old_filtertype, old_filteritem, old_filterstring); /* manually reset the filter */
-    return(MS_FAILURE);
-  }
+    status = msLayerOpen(lp);
+    if(status != MS_SUCCESS) goto query_error;
 
-  /* identify candidate shapes */
-  searchrect = map->query.rect;
-#ifdef USE_PROJ  
-  if(lp->project && msProjectionsDiffer(&(lp->projection), &(map->projection)))  
-    msProjectRect(&(map->projection), &(lp->projection), &searchrect); /* project the searchrect to source coords */
-  else
-    lp->project = MS_FALSE;
+    /* build item list, we want *all* items */
+    status = msLayerWhichItems(lp, MS_TRUE, NULL);
+    if(status != MS_SUCCESS) goto query_error;
+
+    search_rect = map->query.rect;
+#ifdef USE_PROJ
+    if(lp->project && msProjectionsDiffer(&(lp->projection), &(map->projection)))
+      msProjectRect(&(map->projection), &(lp->projection), &search_rect); /* project the searchrect to source coords */
+    else
+      lp->project = MS_FALSE;
 #endif
 
-  status = msLayerWhichShapes(lp, searchrect);
-  if(status == MS_DONE) { /* no overlap */
-    msRestoreOldFilter(lp, old_filtertype, old_filteritem, old_filterstring); /* manually reset the filter */
-    msLayerClose(lp);
-    msSetError(MS_NOTFOUND, "No matching record(s) found, layer and area of interest do not overlap.", "msQueryByAttributes()");
-    return(MS_FAILURE);
-  } else if(status != MS_SUCCESS) {
-    msRestoreOldFilter(lp, old_filtertype, old_filteritem, old_filterstring); /* manually reset the filter */
-    msLayerClose(lp);
-    return(MS_FAILURE);
-  }
+    status = msLayerWhichShapes(lp, search_rect);
+    if(status == MS_DONE) { /* no overlap */
+      msLayerClose(lp);
+      continue;
+    } else if(status != MS_SUCCESS) goto query_error;
 
-  lp->resultcache = (resultCacheObj *)malloc(sizeof(resultCacheObj)); /* allocate and initialize the result cache */
-  initResultCache( lp->resultcache);
-  
-  nclasses = 0;
-  classgroup = NULL;
-  if (lp->classgroup && lp->numclasses > 0)
-    classgroup = msAllocateValidClassGroups(lp, &nclasses);
+    lp->resultcache = (resultCacheObj *)malloc(sizeof(resultCacheObj)); /* allocate and initialize the result cache */
+    initResultCache( lp->resultcache);
 
-  while((status = msLayerNextShape(lp, &shape)) == MS_SUCCESS) { /* step through the shapes */
+    nclasses = 0;
+    classgroup = NULL;
+    if (lp->classgroup && lp->numclasses > 0)
+      classgroup = msAllocateValidClassGroups(lp, &nclasses);
 
-    shape.classindex = msShapeGetClass(lp, &shape, map->scaledenom, classgroup, nclasses);
-    if(!(lp->template) && ((shape.classindex == -1) || (lp->class[shape.classindex]->status == MS_OFF))) { /* not a valid shape */
-      msFreeShape(&shape);
-      continue;
-    }
+    while((status = msLayerNextShape(lp, &shape)) == MS_SUCCESS) { /* step through the shapes */
 
-    if(!(lp->template) && !(lp->class[shape.classindex]->template)) { /* no valid template */
-      msFreeShape(&shape);
-      continue;
-    }
+      if(!msLayerSupportsCommonExpressions(lp)) { /* we have to apply the filter here instead of within the driver */
+        // TODO!
+      }
 
+      shape.classindex = msShapeGetClass(lp, &shape, map->scaledenom, classgroup, nclasses);
+      if(!(lp->template) && ((shape.classindex == -1) || (lp->class[shape.classindex]->status == MS_OFF))) { /* not a valid shape */
+        msFreeShape(&shape);
+        continue;
+      }
+
+      if(!(lp->template) && !(lp->class[shape.classindex]->template)) { /* no valid template */
+        msFreeShape(&shape);
+        continue;
+      }
+
 #ifdef USE_PROJ
-    if(lp->project && msProjectionsDiffer(&(lp->projection), &(map->projection)))
-      msProjectShape(&(lp->projection), &(map->projection), &shape);
-    else
-      lp->project = MS_FALSE;
+      if(lp->project && msProjectionsDiffer(&(lp->projection), &(map->projection)))
+        msProjectShape(&(lp->projection), &(map->projection), &shape);
+      else
+        lp->project = MS_FALSE;
 #endif
 
-    addResult(lp->resultcache, shape.classindex, shape.index, shape.tileindex);
-    
-    if(lp->resultcache->numresults == 1)
-      lp->resultcache->bounds = shape.bounds;
-    else
-      msMergeRect(&(lp->resultcache->bounds), &shape.bounds);
-    
-    msFreeShape(&shape);
+      addResult(lp->resultcache, &shape);
+      msFreeShape(&shape);
+    } /* next shape */
 
-    if(map->query.mode == MS_QUERY_SINGLE) { /* no need to look any further */
-      status = MS_DONE;
-      break;
-    }
-  }
+    if(classgroup) msFree(classgroup);
 
-  if (classgroup)
-    msFree(classgroup);
+    // restore filter...
 
-  msRestoreOldFilter(lp, old_filtertype, old_filteritem, old_filterstring); /* manually reset the filter */
+    if(status != MS_DONE) goto query_error;
+    if(lp->resultcache->numresults == 0) msLayerClose(lp); /* no need to keep the layer open */
 
-  if(status != MS_DONE) {
-    msLayerClose(lp);
-    return(MS_FAILURE);
+  } /* next layer */
+
+  /* was anything found? */
+  for(l=start; l>=stop; l--) {    
+    if(GET_LAYER(map, l)->resultcache && GET_LAYER(map, l)->resultcache->numresults > 0)
+      return MS_SUCCESS;
   }
 
-  /* was anything found? (if yes, don't close the layer) */
-  if(lp->resultcache && lp->resultcache->numresults > 0)
-    return(MS_SUCCESS);
+  msSetError(MS_NOTFOUND, "No matching record(s) found.", "msQueryByFilter()"); 
+  return MS_FAILURE;
 
-  msLayerClose(lp);
-  msSetError(MS_NOTFOUND, "No matching record(s) found.", "msQueryByAttributes()"); 
-  return(MS_FAILURE);
+  query_error:
+    // restore filter...
+    msLayerClose(lp);
+    return MS_FAILURE;
 }
 
 int msQueryByRect(mapObj *map) 
@@ -977,15 +967,8 @@
 	}
       }	
 
-      if(status == MS_TRUE) {
-	addResult(lp->resultcache, shape.classindex, shape.index, shape.tileindex);
-	
-	if(lp->resultcache->numresults == 1)
-	  lp->resultcache->bounds = shape.bounds;
-	else
-	  msMergeRect(&(lp->resultcache->bounds), &shape.bounds);
-      }
-
+      if(status == MS_TRUE)
+	addResult(lp->resultcache, &shape);
       msFreeShape(&shape);
     } /* next shape */
       
@@ -1264,15 +1247,8 @@
 	  break; /* should never get here as we test for selection shape type explicitly earlier */
 	}
 
-	if(status == MS_TRUE) {
-	  addResult(lp->resultcache, shape.classindex, shape.index, shape.tileindex);
-
-	  if(lp->resultcache->numresults == 1)
-	    lp->resultcache->bounds = shape.bounds;
-	  else
-	    msMergeRect(&(lp->resultcache->bounds), &shape.bounds);
-	}
-
+	if(status == MS_TRUE)
+          addResult(lp->resultcache, &shape);
 	msFreeShape(&shape);
       } /* next shape */
 
@@ -1453,16 +1429,9 @@
       if( d <= t ) { /* found one */
 	if(map->query.mode == MS_QUERY_SINGLE) {
 	  lp->resultcache->numresults = 0;
-	  addResult(lp->resultcache, shape.classindex, shape.index, shape.tileindex);
-	  lp->resultcache->bounds = shape.bounds;
 	  t = d; /* next one must be closer */
-	} else {
-	  addResult(lp->resultcache, shape.classindex, shape.index, shape.tileindex);
-	  if(lp->resultcache->numresults == 1)
-	    lp->resultcache->bounds = shape.bounds;
-	  else
-	    msMergeRect(&(lp->resultcache->bounds), &shape.bounds);
 	}
+        addResult(lp->resultcache, &shape);
       }
  
       msFreeShape(&shape);
@@ -1711,15 +1680,8 @@
 	break; /* should never get here as we test for selection shape type explicitly earlier */
       }
 
-      if(status == MS_TRUE) {
-	addResult(lp->resultcache, shape.classindex, shape.index, shape.tileindex);
-	
-	if(lp->resultcache->numresults == 1)
-	  lp->resultcache->bounds = shape.bounds;
-	else
-	  msMergeRect(&(lp->resultcache->bounds), &shape.bounds);
-      }
-
+      if(status == MS_TRUE)
+	addResult(lp->resultcache, &shape);
       msFreeShape(&shape);
     } /* next shape */
 
@@ -1940,15 +1902,8 @@
           return(MS_FAILURE);
       }
 
-      if(status == MS_TRUE) {
-        addResult(lp->resultcache, shape.classindex, shape.index, shape.tileindex);
-	
-        if(lp->resultcache->numresults == 1)
-          lp->resultcache->bounds = shape.bounds;
-        else
-          msMergeRect(&(lp->resultcache->bounds), &shape.bounds);
-      }
-
+      if(status == MS_TRUE)
+        addResult(lp->resultcache, &shape);
       msFreeShape(&shape);
     } /* next shape */
 

Modified: sandbox/sdlime/common-expressions/mapserver/mapserver.h
===================================================================
--- sandbox/sdlime/common-expressions/mapserver/mapserver.h	2010-08-24 03:03:18 UTC (rev 10466)
+++ sandbox/sdlime/common-expressions/mapserver/mapserver.h	2010-08-24 13:18:16 UTC (rev 10467)
@@ -405,7 +405,7 @@
 #define MS_MULTIPLE 1
 
 enum MS_QUERY_MODE {MS_QUERY_SINGLE, MS_QUERY_MULTIPLE};
-enum MS_QUERY_TYPE {MS_QUERY_IS_NULL, MS_QUERY_BY_POINT, MS_QUERY_BY_RECT, MS_QUERY_BY_SHAPE, MS_QUERY_BY_ATTRIBUTE, MS_QUERY_BY_INDEX, MS_QUERY_BY_OPERATOR};
+enum MS_QUERY_TYPE {MS_QUERY_IS_NULL, MS_QUERY_BY_POINT, MS_QUERY_BY_RECT, MS_QUERY_BY_SHAPE, MS_QUERY_BY_ATTRIBUTE, MS_QUERY_BY_INDEX, MS_QUERY_BY_OPERATOR, MS_QUERY_BY_FILTER};
 
 enum MS_ALIGN_VALUE {MS_ALIGN_LEFT, MS_ALIGN_CENTER, MS_ALIGN_RIGHT}; 
 
@@ -668,6 +668,8 @@
   char *item; /* by attribute */
   char *str;
 
+  expressionObj *filter; /* by filter */
+
   int op; /* by GEOS operator */
 
   int slayer; /* selection layer, used for msQueryByFeatures() (note this is not a query mode per se) */
@@ -1783,6 +1785,7 @@
 
 MS_DLL_EXPORT int msQueryByIndex(mapObj *map); /* various query methods, all rely on the queryObj hung off the mapObj */
 MS_DLL_EXPORT int msQueryByAttributes(mapObj *map);
+MS_DLL_EXPORT int msQueryByFilter(mapObj *map);
 MS_DLL_EXPORT int msQueryByPoint(mapObj *map);
 MS_DLL_EXPORT int msQueryByRect(mapObj *map);
 MS_DLL_EXPORT int msQueryByFeatures(mapObj *map);
@@ -1995,6 +1998,9 @@
 MS_DLL_EXPORT int msLayerClearProcessing( layerObj *layer );
 MS_DLL_EXPORT char* msLayerGetFilterString( layerObj *layer );
 
+MS_DLL_EXPORT int msLayerSupportsCommanExpressions(layerObj *layer);
+MS_DLL_EXPORT int msTokenizeExpression(expressionObj *expression, char **list, int *listsize);
+
 MS_DLL_EXPORT int msLayerSetTimeFilter(layerObj *lp, const char *timestring, 
                                        const char *timefield);
 /* Helper functions for layers */ 
@@ -2385,6 +2391,7 @@
 MS_DLL_EXPORT int msCopyClass(classObj *dst, classObj *src, layerObj *layer);
 MS_DLL_EXPORT int msCopyStyle(styleObj *dst, styleObj *src);
 MS_DLL_EXPORT int msCopyLabel(labelObj *dst, labelObj *src);
+MS_DLL_EXPORT int msCopyExpression(expressionObj *dst, expressionObj *src);
 
 /* ==================================================================== */
 /*      end prototypes for functions in mapcopy                         */



More information about the mapserver-commits mailing list