[mapserver-commits] r8719 - sandbox/single-pass/mapserver

svn at osgeo.org svn at osgeo.org
Mon Mar 9 15:00:40 EDT 2009


Author: sdlime
Date: 2009-03-09 15:00:40 -0400 (Mon, 09 Mar 2009)
New Revision: 8719

Modified:
   sandbox/single-pass/mapserver/mapdraw.c
   sandbox/single-pass/mapserver/mapfile.c
   sandbox/single-pass/mapserver/maplayer.c
   sandbox/single-pass/mapserver/mapquery.c
   sandbox/single-pass/mapserver/mapserver.h
   sandbox/single-pass/mapserver/mapshape.c
   sandbox/single-pass/mapserver/maptemplate.c
Log:
Improved query processing, rect query only, template presentation only...

Modified: sandbox/single-pass/mapserver/mapdraw.c
===================================================================
--- sandbox/single-pass/mapserver/mapdraw.c	2009-03-09 18:46:33 UTC (rev 8718)
+++ sandbox/single-pass/mapserver/mapdraw.c	2009-03-09 19:00:40 UTC (rev 8719)
@@ -881,7 +881,7 @@
   if (layer->classgroup && layer->numclasses > 0)
       classgroup = msAllocateValidClassGroups(layer, &nclasses);
 
-  while((status = msLayerNextShape(layer, &shape)) == MS_SUCCESS) {
+  while((status = msLayerNextShape(layer, &shape, NULL)) == MS_SUCCESS) {
 
       shape.classindex = msShapeGetClass(layer, &shape, map->scaledenom, classgroup, nclasses);
     if((shape.classindex == -1) || (layer->class[shape.classindex]->status == MS_OFF)) {

Modified: sandbox/single-pass/mapserver/mapfile.c
===================================================================
--- sandbox/single-pass/mapserver/mapfile.c	2009-03-09 18:46:33 UTC (rev 8718)
+++ sandbox/single-pass/mapserver/mapfile.c	2009-03-09 19:00:40 UTC (rev 8719)
@@ -2826,6 +2826,7 @@
   if(layer->features)
     freeFeatureList(layer->features);
 
+  /* TODO use a freeResultCache in the mapquery.c */
   if(layer->resultcache) {    
     if(layer->resultcache->results) free(layer->resultcache->results);
     msFree(layer->resultcache);

Modified: sandbox/single-pass/mapserver/maplayer.c
===================================================================
--- sandbox/single-pass/mapserver/maplayer.c	2009-03-09 18:46:33 UTC (rev 8718)
+++ sandbox/single-pass/mapserver/maplayer.c	2009-03-09 19:00:40 UTC (rev 8719)
@@ -1,3 +1,4 @@
+
 /******************************************************************************
  * $Id$
  *
@@ -167,6 +168,20 @@
 }
 
 /*
+** Resets a layer to the beginning of its feature stack
+*/
+int msLayerRewind(layerObj *layer)
+{
+  if ( ! layer->vtable) {
+    int rv =  msInitializeVirtualTable(layer);
+    if (rv != MS_SUCCESS)
+      return rv;
+  }
+
+  return layer->vtable->LayerRewind(layer);
+}
+
+/*
 ** Closes resources used by a particular layer.
 */
 void msLayerClose(layerObj *layer) 
@@ -203,6 +218,7 @@
 int msLayerGetItems(layerObj *layer) 
 {
   const char *itemNames;
+
   /* clean up any previously allocated instances */
   msLayerFreeItemInfo(layer);
   if(layer->items) {
@@ -222,12 +238,10 @@
    */
   /* TO DO! Need to add any joined itemd on to the core layer items, one long list!  */
   itemNames = msLayerGetProcessingKey( layer, "ITEMS" );
-  if (itemNames)
-  {
+  if (itemNames) {
     layer->items = msStringSplit(itemNames, ',', &layer->numitems);
     return MS_SUCCESS;
-  }
-  else
+  } else
     return layer->vtable->LayerGetItems(layer);
 }
 
@@ -281,18 +295,30 @@
 
   for(i=0; i<(*listsize); i++)
     if(strcasecmp(list[i], string) == 0) { 
-        /* printf("string2list (duplicate): %s %d\n", string, i); */
       return(i);
     }
 
   list[i] = strdup(string);
   (*listsize)++;
 
-  /* printf("string2list: %s %d\n", string, i); */
-
   return(i);
 }
 
+static void expression2list_new(char **items, int numitems, char **list, int *listsize, expressionObj *expression) 
+{
+  int i;
+  char *tag;
+
+  for(i=0; i<numitems; i++) {
+    tag = (char *) malloc(sizeof(char)*strlen(items[i])+3);
+    snprintf(tag, strlen(items[i])+2, "[%s]", items[i]);
+    if(strcasecmp(tag, expression->string) == 0) { 
+      string2list(list, listsize, items[i]); /* add to overall list */
+      string2list(expression->items, &(expression->numitems), items[i]); /* add to expression list */
+    }
+  }
+}
+
 /* TO DO: this function really needs to use the lexer */
 static void expression2list(char **list, int *listsize, expressionObj *expression) 
 {
@@ -337,35 +363,159 @@
   }
 }
 
-int msLayerWhichItemsNew(layerObj *layer, int classify, int annotate, char *metadata) 
+int msLayerWhichItemsNew(layerObj *layer, int classify, int annotate, int all, char *metadata) 
 {
-  int status;
-  int numchars;
-/* int i; */
+  char **items;
+  int numitems;
+  int i, j, k, rv;
+  int freeitems=MS_FALSE;
 
-  status = msLayerGetItems(layer); /* get a list of all attributes available for this layer (including JOINs) */
-  if(status != MS_SUCCESS) return(status);
+  if (!layer->vtable) {
+    rv =  msInitializeVirtualTable(layer);
+    if (rv != MS_SUCCESS) {
+      return rv;
+    }
+  }
 
-  /* allocate space for the various item lists */
-  if(classify && layer->filter.type == MS_EXPRESSION) { 
-    numchars = msCountChars(layer->filter.string, '[');
-    if(numchars > 0) {
-      layer->filter.items = (char **)calloc(numchars, sizeof(char *)); /* should be more than enough space */
+  /* 1) call msLayerGetItems to get a complete list (including joins) */
+  /* 2) loop though item-based parameters and expressions to identify items to keep */
+  /* 3) based on 2) build a list of items */
+
+  rv = msLayerGetItems(layer); /* get a list of all attributes available for this layer (including JOINs) */
+  if(rv != MS_SUCCESS) return(rv);
+
+  printf("Items (which code):\n");
+  for(i=0;i<layer->numitems;i++)
+    printf("  %d: %s\n", i, layer->items[i]);
+
+  items = layer->items; /* save for later */
+  numitems = layer->numitems;
+
+  /* 
+  ** Allocate space for the various item lists (if necessary), worse case is all items will be required. 
+  */
+  if(annotate) {
+    for(i=0; i<layer->numclasses; i++) {
+      if(layer->class[i]->text.type == MS_EXPRESSION) {
+        layer->class[i]->text.items = (char **) calloc(numitems, sizeof(char *));
+        if(!(layer->class[i]->text.items)) {
+          msSetError(MS_MEMERR, NULL, "msLayerWhichItems()");
+          return(MS_FAILURE);
+        }
+        layer->class[i]->text.indexes = (int *) malloc(numitems*sizeof(int));
+        if(!(layer->class[i]->text.indexes)) {
+          msSetError(MS_MEMERR, NULL, "msLayerWhichItems()");
+          return(MS_FAILURE);
+        }
+        layer->class[i]->text.numitems = 0; /* initially empty */
+      }
+    }
+  }
+
+  if(classify || all) {
+    /* filters with logical expressions */
+    if(layer->filter.type == MS_EXPRESSION) { 
+      layer->filter.items = (char **) calloc(numitems, sizeof(char *));
       if(!(layer->filter.items)) {
-	msSetError(MS_MEMERR, NULL, "msLayerWhichItems()");
-	return(MS_FAILURE);
+        msSetError(MS_MEMERR, NULL, "msLayerWhichItems()");
+        return(MS_FAILURE);
       }
-      layer->filter.indexes = (int *)malloc(numchars*sizeof(int));
+      layer->filter.indexes = (int *) malloc(numitems*sizeof(int));
       if(!(layer->filter.indexes)) {
-	msSetError(MS_MEMERR, NULL, "msLayerWhichItems()");
-	return(MS_FAILURE);
+        msSetError(MS_MEMERR, NULL, "msLayerWhichItems()");
+        return(MS_FAILURE);
       }
-      layer->filter.numitems = 0;     
+      layer->filter.numitems = 0; /* initially empty */
     }
+
+    /* classes with logical expressions */
+    for(i=0; i<layer->numclasses; i++) {
+      if(layer->class[i]->expression.type == MS_EXPRESSION) {
+        layer->class[i]->expression.items = (char **) calloc(numitems, sizeof(char *));
+        if(!(layer->class[i]->expression.items)) {
+	  msSetError(MS_MEMERR, NULL, "msLayerWhichItems()");
+          return(MS_FAILURE);
+	}
+	layer->class[i]->expression.indexes = (int *) malloc(numitems*sizeof(int));
+	if(!(layer->class[i]->expression.indexes)) {
+          msSetError(MS_MEMERR, NULL, "msLayerWhichItems()");
+	  return(MS_FAILURE);
+	}
+	layer->class[i]->expression.numitems = 0; /* initially empty */
+      }
+    }
   }
 
-  /* for(i=0; i<layer->numitems; i++) { } */
+  /*
+  ** Reset things (if necessary)
+  **   Note: if we don't reset then the items array is fully populated will ALL items
+  */
+  if(!all || (layer->connectiontype == MS_INLINE)) {
+    rv = layer->vtable->LayerCreateItems(layer, numitems);
+    if (rv != MS_SUCCESS) return rv;
+    freeitems = MS_TRUE;
+  }
 
+  /*
+  ** Now assign index values (and build lists)
+  */
+  if(classify) {
+    if(layer->classitem) layer->classitemindex = string2list(layer->items, &(layer->numitems), layer->classitem);
+    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) expression2list_new(items, numitems, layer->items, &(layer->numitems), &(layer->class[i]->expression));
+      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++)
+	  if(layer->class[i]->styles[j]->bindings[k].item) layer->class[i]->styles[j]->bindings[k].index = string2list(layer->items, &(layer->numitems), layer->class[i]->styles[j]->bindings[k].item);
+      }
+    }
+
+    if(layer->filter.type == MS_EXPRESSION) expression2list(layer->items, &(layer->numitems), &(layer->filter));      
+  }
+
+  if(annotate) {
+    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) expression2list_new(items, numitems, layer->items, &(layer->numitems), &(layer->class[i]->text));
+      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);
+    }
+  }
+
+  if(metadata) {
+    char **tokens;
+    int n = 0;
+    int j;
+    int bFound = 0;
+
+    tokens = msStringSplit(metadata, ',', &n);
+    if(tokens) {
+      for(i=0; i<n; i++) {
+        bFound = 0;
+        for(j=0; j<layer->numitems; j++) {
+          if(strcmp(tokens[i], layer->items[j]) == 0) {
+            bFound = 1;
+            break;
+          }
+        }
+
+        if(!bFound) {
+          layer->numitems++;
+          layer->items =  (char **)realloc(layer->items, sizeof(char *)*(layer->numitems));
+          layer->items[layer->numitems-1] = strdup(tokens[i]);
+        }
+      }
+      msFreeCharArray(tokens, n);
+    }
+  }
+
+  /*
+  ** Clean up
+  */
+  if(freeitems) msFreeCharArray(items, numitems);
+
   return(MS_SUCCESS);
 }
 
@@ -1110,6 +1260,11 @@
     return MS_FAILURE;
 }
 
+int LayerDefaultRewind(layerObj *layer)
+{
+  return MS_SUCCESS;
+}
+
 /*
  * msConnectLayer
  *
@@ -1167,6 +1322,8 @@
     
     vtable->LayerGetNumFeatures = LayerDefaultGetNumFeatures;
 
+    vtable->LayerRewind = LayerDefaultRewind;
+
     return MS_SUCCESS;
 }
 

Modified: sandbox/single-pass/mapserver/mapquery.c
===================================================================
--- sandbox/single-pass/mapserver/mapquery.c	2009-03-09 18:46:33 UTC (rev 8718)
+++ sandbox/single-pass/mapserver/mapquery.c	2009-03-09 19:00:40 UTC (rev 8719)
@@ -1,3 +1,4 @@
+
 /******************************************************************************
  * $Id$
  *
@@ -31,6 +32,28 @@
 
 MS_CVSID("$Id$")
 
+static void freeResults(layerObj *layer) 
+{
+  if(layer->resultcache->results) free(layer->resultcache->results);
+  free(layer->resultcache);
+  layer->resultcache = NULL;
+}
+
+int initResults(layerObj *layer) 
+{
+  layer->resultcache = (resultCacheObj *) malloc(sizeof(resultCacheObj));
+  if(!(layer->resultcache)) {
+    msSetError(MS_MEMERR, "Malloc() error allocating memory for results.", "initResults()");
+    return MS_FAILURE;
+  }
+
+  layer->resultcache->results = NULL;
+  layer->resultcache->numresults = layer->resultcache->cachesize = layer->resultcache->maxcachesize = 0;
+  layer->resultcache->bounds.minx = layer->resultcache->bounds.miny = layer->resultcache->bounds.maxx = layer->resultcache->bounds.maxy = -1;
+
+  return MS_SUCCESS;
+}
+
 /*
 ** msIsLayerQueryable()  returns MS_TRUE/MS_FALSE
 */
@@ -51,12 +74,17 @@
   return MS_FALSE;
 }
 
-static int addResult(resultCacheObj *cache, int classindex, int shapeindex, int tileindex)
+static int addResult(resultCacheObj *cache, shapeObj *shape, int status)
 {
   int i;
 
-  if(cache->numresults == cache->cachesize) { /* just add it to the end */
-    if(cache->cachesize == 0)
+  if(!cache || !shape) {
+    msSetError(MS_MISCERR, "Unallocated cache or shape objects.", "addResult()");
+    return(MS_FAILURE);
+  }
+
+  if(cache->cachesize == cache->maxcachesize) { /* expand the cache */
+    if(cache->maxcachesize == 0)
       cache->results = (resultCacheMemberObj *) malloc(sizeof(resultCacheMemberObj)*MS_RESULTCACHEINCREMENT);
     else
       cache->results = (resultCacheMemberObj *) realloc(cache->results, sizeof(resultCacheMemberObj)*(cache->cachesize+MS_RESULTCACHEINCREMENT));
@@ -64,16 +92,25 @@
       msSetError(MS_MEMERR, "Realloc() error.", "addResult()");
       return(MS_FAILURE);
     }   
-    cache->cachesize += MS_RESULTCACHEINCREMENT;
+    cache->maxcachesize += MS_RESULTCACHEINCREMENT;
   }
 
-  i = cache->numresults;
+  i = cache->cachesize;
+  cache->cachesize++;
 
-  cache->results[i].classindex = classindex;
-  cache->results[i].tileindex = tileindex;
-  cache->results[i].shapeindex = shapeindex;
-  cache->numresults++;
+  cache->results[i].status = status;
+  cache->results[i].classindex = shape->classindex;
+  cache->results[i].tileindex = shape->tileindex;
+  cache->results[i].shapeindex = shape->index;
 
+  if(cache->results[i].status == MS_TRUE) {
+    cache->numresults++;
+    if(cache->numresults == 1)
+      cache->bounds = shape->bounds;
+    else
+      msMergeRect(&(cache->bounds), &shape->bounds);
+  }
+
   return(MS_SUCCESS);
 }
 
@@ -139,7 +176,8 @@
     }
     
     /* inialize the results for this layer */
-    GET_LAYER(map, j)->resultcache = (resultCacheObj *)malloc(sizeof(resultCacheObj)); /* allocate and initialize the result cache */
+    // GET_LAYER(map, j)->resultcache = (resultCacheObj *)malloc(sizeof(resultCacheObj)); /* allocate and initialize the result cache */
+    if(initResults(GET_LAYER(map, j)) != MS_SUCCESS) return(MS_FAILURE);
 
     fread(&(GET_LAYER(map, j)->resultcache->numresults), sizeof(int), 1, stream); /* number of results    */
     GET_LAYER(map, j)->resultcache->cachesize = GET_LAYER(map, j)->resultcache->numresults;
@@ -157,8 +195,7 @@
 }
 
 
-int _msQueryByIndex(mapObj *map, int qlayer, int tileindex, int shapeindex, 
-                    int addtoquery)
+int _msQueryByIndex(mapObj *map, int qlayer, int tileindex, int shapeindex, int addtoquery)
 {
   layerObj *lp;
   int status;
@@ -179,13 +216,8 @@
 
   msInitShape(&shape);
 
-  if (!addtoquery) {  
-    if(lp->resultcache) {
-      if(lp->resultcache->results) free(lp->resultcache->results);
-      free(lp->resultcache);
-      lp->resultcache = NULL;
-    }
-  }
+  if(!addtoquery && lp->resultcache)
+    freeResults(lp);
 
   /* open this layer */
   status = msLayerOpen(lp);
@@ -195,11 +227,8 @@
   status = msLayerWhichItems(lp, MS_TRUE, MS_FALSE, NULL);
   if(status != MS_SUCCESS) return(MS_FAILURE);
 
-  if (!addtoquery || lp->resultcache == NULL) {
-    lp->resultcache = (resultCacheObj *)malloc(sizeof(resultCacheObj)); /* allocate and initialize the result cache */
-    lp->resultcache->results = NULL;
-    lp->resultcache->numresults = lp->resultcache->cachesize = 0;
-    lp->resultcache->bounds.minx = lp->resultcache->bounds.miny = lp->resultcache->bounds.maxx = lp->resultcache->bounds.maxy = -1;
+  if(!addtoquery || lp->resultcache == NULL) {
+    if(initResults(lp) != MS_SUCCESS) return(MS_FAILURE);
   }
 
   status = msLayerGetShape(lp, &shape, tileindex, shapeindex);
@@ -221,7 +250,7 @@
     return(MS_FAILURE);
   }
 
-  addResult(lp->resultcache, shape.classindex, shape.index, shape.tileindex);
+  addResult(lp->resultcache, &shape, MS_TRUE);
   if(lp->resultcache->numresults == 1)
     lp->resultcache->bounds = shape.bounds;
   else
@@ -335,15 +364,12 @@
     return(MS_FAILURE);
   }
 
-  lp->resultcache = (resultCacheObj *)malloc(sizeof(resultCacheObj)); /* allocate and initialize the result cache */
-  lp->resultcache->results = NULL;
-  lp->resultcache->numresults = lp->resultcache->cachesize = 0;
-  lp->resultcache->bounds.minx = lp->resultcache->bounds.miny = lp->resultcache->bounds.maxx = lp->resultcache->bounds.maxy = -1;
+  if(initResults(lp) != MS_SUCCESS) return(MS_FAILURE);
   
   nclasses = 0;
   classgroup = NULL;
-  if (lp->classgroup && lp->numclasses > 0)
-      classgroup = msAllocateValidClassGroups(lp, &nclasses);
+  if(lp->classgroup && lp->numclasses > 0)
+    classgroup = msAllocateValidClassGroups(lp, &nclasses);
 
   while((status = msLayerNextShape(lp, &shape)) == MS_SUCCESS) { /* step through the shapes */
 
@@ -365,13 +391,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, MS_TRUE);
     msFreeShape(&shape);
 
     if(mode == MS_SINGLE) { /* no need to look any further */
@@ -446,11 +466,7 @@
     lp->project = MS_TRUE; 
 
     /* 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(lp->resultcache) freeResults(lp);
 
     if(!msIsLayerQueryable(lp)) continue;
     if(lp->status == MS_OFF) continue;
@@ -469,7 +485,6 @@
     if( lp->type == MS_LAYER_RASTER ) {
       if( msRasterQueryByRect( map, lp, rect ) == MS_FAILURE)
         return MS_FAILURE;
-
       continue;
     }
 
@@ -477,8 +492,8 @@
     status = msLayerOpen(lp);
     if(status != MS_SUCCESS) return(MS_FAILURE);
 
-    /* build item list (no annotation) */
-    status = msLayerWhichItems(lp, MS_TRUE, MS_FALSE, NULL);
+    /* build item list, we need all items */
+    status = msLayerWhichItemsNew(lp, MS_TRUE, MS_FALSE, MS_TRUE, NULL);
     if(status != MS_SUCCESS) return(MS_FAILURE);
 
     /* identify target shapes */
@@ -498,10 +513,7 @@
       return(MS_FAILURE);
     }
 
-    lp->resultcache = (resultCacheObj *)malloc(sizeof(resultCacheObj)); /* allocate and initialize the result cache */
-    lp->resultcache->results = NULL;
-    lp->resultcache->numresults = lp->resultcache->cachesize = 0;
-    lp->resultcache->bounds.minx = lp->resultcache->bounds.miny = lp->resultcache->bounds.maxx = lp->resultcache->bounds.maxy = -1;
+    if(initResults(lp) != MS_SUCCESS) return(MS_FAILURE);
 
     nclasses = 0;
     classgroup = NULL;
@@ -512,13 +524,15 @@
 
       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;
+        addResult(lp->resultcache, &shape, MS_FALSE);
+        msFreeShape(&shape);
+        continue;
       }
 
       if(!(lp->template) && !(lp->class[shape.classindex]->template)) { /* no valid template */
+        addResult(lp->resultcache, &shape, MS_FALSE);
         msFreeShape(&shape);
-	      continue;
+        continue;
       }
 
 #ifdef USE_PROJ
@@ -529,7 +543,7 @@
 #endif
 
       if(msRectContained(&shape.bounds, &rect) == MS_TRUE) { /* if the whole shape is in, don't intersect */	
-	      status = MS_TRUE;
+        status = MS_TRUE;
       } else {
 	switch(shape.type) { /* make sure shape actually intersects the rect (ADD FUNCTIONS SPECIFIC TO RECTOBJ) */
 	case MS_SHAPE_POINT:
@@ -546,15 +560,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, status);
       msFreeShape(&shape);
     } /* next shape */
       
@@ -563,7 +570,7 @@
 
     if(status != MS_DONE) return(MS_FAILURE);
 
-    msLayerClose(lp);
+    // msLayerClose(lp);
   } /* next layer */
  
   msFreeShape(&searchshape);
@@ -605,7 +612,7 @@
   msInitShape(&selectshape);
 
   if( map->debug )
-      msDebug( "in msQueryByFeatures()\n" );
+    msDebug( "in msQueryByFeatures()\n" );
 
   /* is the selection layer valid and has it been queried */
   if(slayer < 0 || slayer >= map->numlayers) {
@@ -640,13 +647,9 @@
     lp->project = MS_TRUE; 
 
     /* 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(lp->resultcache) freeResults(lp);
 
-    if(!msIsLayerQueryable(lp)) continue;    
+    if(!msIsLayerQueryable(lp)) continue;
     if(lp->status == MS_OFF) continue;
     
     if(map->scaledenom > 0) {
@@ -682,7 +685,7 @@
     status = msLayerWhichItems(lp, MS_TRUE, MS_FALSE, NULL);
     if(status != MS_SUCCESS) return(MS_FAILURE);
     
-    /* for each selection shape */
+    /* for each selection shape (TODO: use cached features if they exist) */
     for(i=0; i<slp->resultcache->numresults; i++) {
 
       status = msLayerGetShape(slp, &selectshape, slp->resultcache->results[i].tileindex, slp->resultcache->results[i].shapeindex);
@@ -733,11 +736,8 @@
       }
 
       if(i == 0) {
-	lp->resultcache = (resultCacheObj *)malloc(sizeof(resultCacheObj)); /* allocate and initialize the result cache */
-	lp->resultcache->results = NULL;
-	lp->resultcache->numresults = lp->resultcache->cachesize = 0;
-	lp->resultcache->bounds.minx = lp->resultcache->bounds.miny = lp->resultcache->bounds.maxx = lp->resultcache->bounds.maxy = -1;    
-      }      
+        if(initResults(lp) != MS_SUCCESS) return(MS_FAILURE);        
+      }
 
       nclasses = 0;
       classgroup = NULL;
@@ -835,15 +835,9 @@
 	  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(status == MS_TRUE)
+	  addResult(lp->resultcache, &shape, MS_TRUE);
 
-	  if(lp->resultcache->numresults == 1)
-	    lp->resultcache->bounds = shape.bounds;
-	  else
-	    msMergeRect(&(lp->resultcache->bounds), &shape.bounds);
-	}
-
 	msFreeShape(&shape);
       } /* next shape */
 
@@ -917,11 +911,7 @@
     lp->project = MS_TRUE; 
 
     /* 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(lp->resultcache) freeResults(lp);
 
     if(!msIsLayerQueryable(lp)) continue;
     if(lp->status == MS_OFF) continue;
@@ -938,21 +928,20 @@
 
     /* Raster layers are handled specially.  */
     if( lp->type == MS_LAYER_RASTER ) {
-        if( msRasterQueryByPoint( map, lp, mode, p, buffer )
-            == MS_FAILURE )
-            return MS_FAILURE;
-        continue;
+      if( msRasterQueryByPoint( map, lp, mode, p, buffer) == MS_FAILURE )
+        return MS_FAILURE;
+      continue;
     }
 
     /* Get the layer tolerance
        default is 3 for point and line layers, 0 for others */
-    if(lp->tolerance == -1)
-        if(lp->status == MS_LAYER_POINT || lp->status == MS_LAYER_LINE)
-            layer_tolerance = 3;
-        else
-            layer_tolerance = 0;
-    else
-        layer_tolerance = lp->tolerance;
+    if(lp->tolerance == -1) {
+      if(lp->status == MS_LAYER_POINT || lp->status == MS_LAYER_LINE)
+        layer_tolerance = 3;
+      else
+        layer_tolerance = 0;
+    } else
+      layer_tolerance = lp->tolerance;
 
     if(buffer <= 0) { /* use layer tolerance */
       if(lp->toleranceunits == MS_PIXELS)
@@ -992,11 +981,10 @@
       return(MS_FAILURE);
     }
 
-    lp->resultcache = (resultCacheObj *)malloc(sizeof(resultCacheObj)); /* allocate and initialize the result cache */
-    lp->resultcache->results = NULL;
-    lp->resultcache->numresults = lp->resultcache->cachesize = 0;
-    lp->resultcache->bounds.minx = lp->resultcache->bounds.miny = lp->resultcache->bounds.maxx = lp->resultcache->bounds.maxy = -1;
+    if(initResults(lp) != MS_SUCCESS) return(MS_FAILURE);
 
+    /* YOU LEFT OFF HERE! */
+
     nclasses = 0;
     classgroup = NULL;
     if (lp->classgroup && lp->numclasses > 0)
@@ -1026,15 +1014,11 @@
       if( d <= t ) { /* found one */
 	if(mode == MS_SINGLE) {
 	  lp->resultcache->numresults = 0;
-	  addResult(lp->resultcache, shape.classindex, shape.index, shape.tileindex);
+	  addResult(lp->resultcache, &shape, MS_TRUE);
 	  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, MS_TRUE);
 	}
       }
  
@@ -1237,14 +1221,8 @@
 	break;
       }
 
-      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, MS_TRUE);
 
       msFreeShape(&shape);
     } /* next shape */
@@ -1474,14 +1452,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, MS_TRUE);
 
         msFreeShape(&shape);
       } /* next shape */

Modified: sandbox/single-pass/mapserver/mapserver.h
===================================================================
--- sandbox/single-pass/mapserver/mapserver.h	2009-03-09 18:46:33 UTC (rev 8718)
+++ sandbox/single-pass/mapserver/mapserver.h	2009-03-09 19:00:40 UTC (rev 8719)
@@ -885,6 +885,7 @@
 /*                         resultCacheMemberObj                         */
 /************************************************************************/
 typedef struct {
+  int status; /* TRUE/FALSE */
   long shapeindex;
   int tileindex;
   int classindex;
@@ -901,7 +902,7 @@
 
 #ifndef SWIG
   resultCacheMemberObj *results;
-  int cachesize;
+  int cachesize, maxcachesize;
 #endif /* not SWIG */
 
 #ifdef SWIG
@@ -1440,6 +1441,7 @@
 
     int (*LayerCreateItems)(layerObj *layer, int nt);
     int (*LayerGetNumFeatures)(layerObj *layer);
+    int (*LayerRewind)(layerObj *layer);
 };
 #endif /*SWIG*/
 
@@ -1546,7 +1548,6 @@
 MS_DLL_EXPORT int msMapIgnoreMissingData( mapObj *map );
 
 /* mapfile.c */
-
 MS_DLL_EXPORT int msValidateParameter(char *value, char *pattern1, char *pattern2, char *pattern3, char *pattern4);
 MS_DLL_EXPORT int msGetLayerIndex(mapObj *map, char *name);
 MS_DLL_EXPORT int msGetSymbolIndex(symbolSetObj *set, char *name, int try_addimage_if_notfound);
@@ -1784,8 +1785,10 @@
 MS_DLL_EXPORT int msLayerOpen(layerObj *layer); /* in maplayer.c */
 MS_DLL_EXPORT int msLayerIsOpen(layerObj *layer);
 MS_DLL_EXPORT void msLayerClose(layerObj *layer);
+MS_DLL_EXPORT int msLayerRewind(layerObj *layer);
 MS_DLL_EXPORT int msLayerWhichShapes(layerObj *layer, rectObj rect);
 MS_DLL_EXPORT int msLayerWhichItems(layerObj *layer, int classify, int annotate, char *metadata);
+MS_DLL_EXPORT int msLayerWhichItemsNew(layerObj *layer, int classify, int annotate, int all, char *metadata);
 MS_DLL_EXPORT int msLayerNextShape(layerObj *layer, shapeObj *shape);
 MS_DLL_EXPORT int msLayerGetItems(layerObj *layer);
 MS_DLL_EXPORT int msLayerSetItems(layerObj *layer, char **items, int numitems);

Modified: sandbox/single-pass/mapserver/mapshape.c
===================================================================
--- sandbox/single-pass/mapserver/mapshape.c	2009-03-09 18:46:33 UTC (rev 8718)
+++ sandbox/single-pass/mapserver/mapshape.c	2009-03-09 19:00:40 UTC (rev 8719)
@@ -2059,6 +2059,13 @@
   return(MS_FAILURE); /* should *never* get here */
 }
 
+int msTiledSHPLayerRewind(layerObj *layer) 
+{
+  msTiledSHPLayerInfo *tSHP=layer->layerinfo;
+  tSHP->shpfile->lastshape = 0;
+  return MS_SUCCESS;
+}
+
 int msTiledSHPNextShape(layerObj *layer, shapeObj *shape) 
 {
   int i, status, filter_passed = MS_FALSE;
@@ -2070,7 +2077,6 @@
   
   if ( msCheckParentPointer(layer->map,"map")==MS_FAILURE )
 	return MS_FAILURE;
-  
 
   tSHP = layer->layerinfo;
   if(!tSHP) {
@@ -2102,8 +2108,8 @@
           if(!layer->data) /* assume whole filename is in attribute field */
             filename = (char *) msDBFReadStringAttribute(tSHP->tileshpfile->hDBF, tshape.index, layer->tileitemindex);
           else {
-	        sprintf(tilename,"%s/%s", msDBFReadStringAttribute(tSHP->tileshpfile->hDBF, tshape.index, layer->tileitemindex) , layer->data);
-	        filename = tilename;
+	    sprintf(tilename,"%s/%s", msDBFReadStringAttribute(tSHP->tileshpfile->hDBF, tshape.index, layer->tileitemindex) , layer->data);
+	    filename = tilename;
           }
 
           if(strlen(filename) == 0) continue; /* check again */
@@ -2116,12 +2122,11 @@
 
           status = msShapefileWhichShapes(tSHP->shpfile, tSHP->tileshpfile->statusbounds, layer->debug);
           if(status == MS_DONE) {
-              /* Close and continue to next tile */
+            /* Close and continue to next tile */
+            msShapefileClose(tSHP->shpfile);
+            continue;
+          } else if(status != MS_SUCCESS) {
               msShapefileClose(tSHP->shpfile);
-              continue;
-          }
-          else if(status != MS_SUCCESS) {
-              msShapefileClose(tSHP->shpfile);
               return(MS_FAILURE);
           }
 
@@ -2387,6 +2392,7 @@
 	layer->vtable->LayerSetTimeFilter = msLayerMakeBackticsTimeFilter;
 	/* layer->vtable->LayerCreateItems, use default */
   /* layer->vtable->LayerGetNumFeatures, use default */
+  layer->vtable->LayerRewind = msTiledSHPLayerRewind;
 
 	return MS_SUCCESS;
 }
@@ -2492,6 +2498,14 @@
   return MS_SUCCESS;
 }
 
+int msShapeFileLayerRewind(layerObj *layer) 
+{
+  shapefileObj *shpfile = layer->layerinfo;
+  shpfile->lastshape = 0;
+  printf("msShapeFileLayerRewind()\n");
+  return MS_SUCCESS;
+}
+
 int msShapeFileLayerNextShape(layerObj *layer, shapeObj *shape) 
 {
   int i, filter_passed;
@@ -2617,6 +2631,7 @@
   /* layer->vtable->LayerApplyFilterToLayer, use default */
   /* layer->vtable->LayerCreateItems, use default */
   /* layer->vtable->LayerGetNumFeatures, use default */
+  layer->vtable->LayerRewind = msShapeFileLayerRewind;
     
   return MS_SUCCESS;
 }

Modified: sandbox/single-pass/mapserver/maptemplate.c
===================================================================
--- sandbox/single-pass/mapserver/maptemplate.c	2009-03-09 18:46:33 UTC (rev 8718)
+++ sandbox/single-pass/mapserver/maptemplate.c	2009-03-09 19:00:40 UTC (rev 8719)
@@ -834,12 +834,16 @@
 
   /* we know the layer has query results or we wouldn't be in this code */
 
-  status = msLayerOpen(layer); /* open the layer */
-  if(status != MS_SUCCESS) return status;
-  
-  status = msLayerGetItems(layer); /* retrieve all the item names */
-  if(status != MS_SUCCESS) return status;
+  // status = msLayerOpen(layer); /* open the layer */
+  // if(status != MS_SUCCESS) return status;
+    
+  // status = msLayerGetItems(layer); /* retrieve all the item names */
+  // if(status != MS_SUCCESS) return status;
 
+  printf("Items (template code):\n");
+  for(i=0;i<layer->numitems;i++) 
+    printf("  %d: %s\n", i, layer->items[i]);
+
   if(layer->numjoins > 0) { /* initialize necessary JOINs here */
     for(j=0; j<layer->numjoins; j++) {
       status = msJoinConnect(layer, &(layer->joins[j]));
@@ -856,10 +860,12 @@
   else
     limit = MS_MIN(limit, layer->resultcache->numresults);
 
-  for(i=0; i<limit; i++) {
-    status = msLayerGetShape(layer, &(mapserv->resultshape), layer->resultcache->results[i].tileindex, layer->resultcache->results[i].shapeindex);
-    if(status != MS_SUCCESS) return status;
+  i=0;
+  msLayerRewind(layer);
+  while(((status = msLayerNextShape(layer, &(mapserv->resultshape))) == MS_SUCCESS) && (i <= limit)) {
 
+    if(layer->resultcache->results[i].status != MS_TRUE) continue; /* don't present */
+
     /* prepare any necessary JOINs here (one-to-one only) */
     if(layer->numjoins > 0) {
       for(j=0; j<layer->numjoins; j++) {
@@ -886,11 +892,12 @@
     free(tagInstance);
     msFreeShape(&(mapserv->resultshape)); /* init too */
 
-    mapserv->RN++; /* increment counters */
+    i++; /* increment counters */
+    mapserv->RN++;
     mapserv->LRN++;
   }
 
-  msLayerClose(layer);
+  // msLayerClose(layer);
   mapserv->resultlayer = NULL; /* necessary? */
 
   *line = msStringConcatenate(*line, postTag);



More information about the mapserver-commits mailing list