[mapserver-commits] r12244 - in trunk/mapserver/mapcache: . include src

svn at osgeo.org svn at osgeo.org
Fri Aug 26 07:10:25 EDT 2011


Author: tbonfort
Date: 2011-08-26 04:10:25 -0700 (Fri, 26 Aug 2011)
New Revision: 12244

Modified:
   trunk/mapserver/mapcache/geocache.xml
   trunk/mapserver/mapcache/include/geocache.h
   trunk/mapserver/mapcache/src/cache_disk.c
   trunk/mapserver/mapcache/src/configuration.c
   trunk/mapserver/mapcache/src/service_wms.c
   trunk/mapserver/mapcache/src/tileset.c
Log:
add reconfigure script
thomas.bonfort | 2011-01-13 14:57:02 +0100 (Thu, 13 Jan 2011)

Modified: trunk/mapserver/mapcache/geocache.xml
===================================================================
--- trunk/mapserver/mapcache/geocache.xml	2011-08-26 11:10:19 UTC (rev 12243)
+++ trunk/mapserver/mapcache/geocache.xml	2011-08-26 11:10:25 UTC (rev 12244)
@@ -347,6 +347,38 @@
          after the creation date of the tile
       -->
       <expires>3600</expires>
+      
+      <!-- dimensions
+         optional dimensions that should be cached
+         the order of the <dimension> tags inside the <dimensions> is important as it is used
+         to create the directory structure for the disk cache. i.e. if you change the order of these
+         values, any tiles that have been previously cached are invalidated (but not removed from the 
+         cache, it's just they don't exist anymore for mod-geocache
+      -->
+      <dimensions>
+         <!-- dimension 
+            the example here creates a TIME dimension
+             * WMS and WMTS clients can now add a &TIME=value to their request string. If they don't
+            specify this key/value, the default will be to use TIME=foobar
+             * the allowed values for TIME= are foobar (it is important to add the default value to the
+               allowed values entry), foobarbaz, foo and bar.
+             * the value specified for TIME will be forwarded to the WMS source
+             * the produced tile will be stored in base/gridname/TIME/value/xx/xx/xx/xx/xx/xx.png
+               file. i.e. their are as many different caches created as their are values in the
+               <values> tag.
+         -->
+         <dimension name="TIME">
+            <!-- default
+                 the default value to pass on to the source if the client hasn't specified any dimension
+            -->
+            <default>foobar</default>
+
+            <!-- values
+               comma separated list of values that are allowed for the dimension
+            -->
+            <values>foobar,foobarbaz,foo,bar</values>
+         </dimension>
+      </dimensions>
    </tileset>
    <tileset name="test2">
       <source>nexrad</source>

Modified: trunk/mapserver/mapcache/include/geocache.h
===================================================================
--- trunk/mapserver/mapcache/include/geocache.h	2011-08-26 11:10:19 UTC (rev 12243)
+++ trunk/mapserver/mapcache/include/geocache.h	2011-08-26 11:10:25 UTC (rev 12244)
@@ -1025,7 +1025,7 @@
    char *name;
    apr_table_t *metadata;
    char *default_value;
-   int (*validate)(geocache_context *context, char *value);
+   int (*validate)(geocache_context *context, geocache_dimension *dimension, const char *value);
 };
 typedef struct geocache_dimension_values geocache_dimension_values;
 
@@ -1035,6 +1035,8 @@
    char **values;
 };
 
+geocache_dimension_values* geocache_dimension_values_create(apr_pool_t *pool);
+
 typedef struct geocache_dimension_regexp geocache_dimension_regexp;
 
 struct geocache_dimension_regexp {

Modified: trunk/mapserver/mapcache/src/cache_disk.c
===================================================================
--- trunk/mapserver/mapcache/src/cache_disk.c	2011-08-26 11:10:19 UTC (rev 12243)
+++ trunk/mapserver/mapcache/src/cache_disk.c	2011-08-26 11:10:25 UTC (rev 12244)
@@ -20,9 +20,10 @@
 #include <apr_file_io.h>
 
 void _geocache_cache_disk_blank_tile_key(geocache_context *ctx, geocache_tile *tile, unsigned char *color, char **path) {
-   *path = apr_psprintf(ctx->pool,"%s/%s/blanks/%02X%02X%02X%02X.%s",
+   *path = apr_psprintf(ctx->pool,"%s/%s/%s/blanks/%02X%02X%02X%02X.%s",
          ((geocache_cache_disk*)tile->tileset->cache)->base_directory,
          tile->tileset->name,
+         tile->tileset->grid->name,
          color[0],
          color[1],
          color[2],
@@ -53,6 +54,8 @@
       while(i--) {
          apr_table_entry_t *entry = &(APR_ARRAY_IDX(elts,i,apr_table_entry_t));
          start = apr_pstrcat(ctx->pool,start,"/",entry->key,"/",entry->val,NULL);
+         ctx->log(ctx,GEOCACHE_DEBUG,"tile dim %s",start);
+
       }
    }
    *path = apr_psprintf(ctx->pool,"%s/%02d/%03d/%03d/%03d/%03d/%03d/%03d.%s",
@@ -156,6 +159,7 @@
    GC_CHECK_ERROR(ctx);
 
    /* find the location of the last '/' in the string */
+   ctx->log(ctx,GEOCACHE_DEBUG,"filename is %s",filename);
    hackptr1 = filename;
    while(*hackptr1) {
       if(*hackptr1 == '/')
@@ -182,9 +186,11 @@
          if(apr_file_open(&f, blankname, APR_FOPEN_READ, APR_OS_DEFAULT, ctx->pool) != APR_SUCCESS) {
             /* create the blank file */
             if(APR_SUCCESS != apr_dir_make_recursive(
-                  apr_psprintf(ctx->pool, "%s/%s/blanks",
-                        ((geocache_cache_disk*)tile->tileset->cache)->base_directory,tile->tileset->name),
-                        APR_OS_DEFAULT,ctx->pool)) {
+                  apr_psprintf(ctx->pool, "%s/%s/%s/blanks",
+                        ((geocache_cache_disk*)tile->tileset->cache)->base_directory,
+                        tile->tileset->name,
+                        tile->tileset->grid->name),
+                  APR_OS_DEFAULT,ctx->pool)) {
                ctx->set_error(ctx, GEOCACHE_DISK_ERROR,  "failed to create directory for blank tiles");
                ctx->global_lock_release(ctx);
                return;
@@ -211,8 +217,9 @@
 #endif
          }
          ctx->global_lock_release(ctx);
-         if(apr_file_link(blankname,filename) != GEOCACHE_SUCCESS) {
-            ctx->set_error(ctx, GEOCACHE_DISK_ERROR,  "failed to link tile %s to %s",filename, blankname);
+         int errno;
+         if(errno = apr_file_link(blankname,filename) != GEOCACHE_SUCCESS) {
+            ctx->set_error(ctx, GEOCACHE_DISK_ERROR,  "failed to link tile %s to %s: %s",filename, blankname, strerror(errno));
             return; /* we could not create the file */
          }
 #ifdef DEBUG        

Modified: trunk/mapserver/mapcache/src/configuration.c
===================================================================
--- trunk/mapserver/mapcache/src/configuration.c	2011-08-26 11:10:19 UTC (rev 12243)
+++ trunk/mapserver/mapcache/src/configuration.c	2011-08-26 11:10:25 UTC (rev 12244)
@@ -20,6 +20,7 @@
 #include <stdlib.h>
 #include <apr_strings.h>
 #include <apr_hash.h>
+#include <apr_tables.h>
 #include <apr_file_io.h>
 #include <apr_file_info.h>
 
@@ -202,14 +203,6 @@
    apr_hash_set(config->image_formats, key, APR_HASH_KEY_STRING, (void*)format);
 }
 
-void extractNameAndTypeAttributes(apr_pool_t *pool, ezxml_t doc, char **name, char **type) {
-   *name = (char*)ezxml_attr(doc,"name");
-   *type = (char*)ezxml_attr(doc,"type");
-   if(*name) *name = apr_pstrdup(pool, *name);
-   if(*type) *type = apr_pstrdup(pool, *type);
-
-}
-
 void parseMetadata(geocache_context *ctx, ezxml_t node, apr_table_t *metadata) {
    ezxml_t cur_node;
    for(cur_node = node->child; cur_node; cur_node = cur_node->sibling) {
@@ -217,18 +210,72 @@
    }
 }
 
+void parseDimensions(geocache_context *ctx, ezxml_t node, geocache_tileset *tileset) {
+   ezxml_t dimension_node;
+   apr_array_header_t *dimensions = apr_array_make(ctx->pool,1,sizeof(geocache_dimension*));
+   for(dimension_node = ezxml_child(node,"dimension"); dimension_node; dimension_node = dimension_node->next) {
+      char *name = (char*)ezxml_attr(dimension_node,"name");
+      char *default_value, *values, *key, *last;
+      int count = 1;
+      ezxml_t dchild_node;
+      if(!name || !strlen(name)) {
+         ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "mandatory attribute \"name\" not found in <dimension>");
+         return;
+      }
+      name = apr_pstrdup(ctx->pool,name);
+
+      dchild_node = ezxml_child(dimension_node,"default");
+      if(!dchild_node || !dchild_node->txt) {
+         ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "<dimension> \"%s\" has no default value",name);
+         return;
+      }
+      default_value = apr_pstrdup(ctx->pool,dchild_node->txt);
+      
+      dchild_node = ezxml_child(dimension_node,"values");
+      if(!dchild_node || !dchild_node->txt) {
+         ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "<dimension> \"%s\" has no values",name);
+         return;
+      }
+      values = apr_pstrdup(ctx->pool,dchild_node->txt);
+      geocache_dimension_values *dimension = geocache_dimension_values_create(ctx->pool);
+      dimension->dimension.name = name;
+      dimension->dimension.default_value = default_value;
+      for(key=values;*key;key++) if(*key == ',') count++;
+
+      dimension->values = (char**)apr_pcalloc(ctx->pool,count*sizeof(char*));
+
+      for (key = apr_strtok(values, ",", &last); key != NULL;
+            key = apr_strtok(NULL, ",", &last)) {
+         dimension->values[dimension->nvalues]=key;
+         dimension->nvalues++;
+      }
+      if(!dimension->nvalues) {
+         ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "<dimension> \"%s\" has no values",name);
+         return;
+      }
+      APR_ARRAY_PUSH(dimensions,geocache_dimension*) = (geocache_dimension*)dimension;
+   }
+   if(apr_is_empty_array(dimensions)) {
+      ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "<dimensions> for tileset \"%s\" has no dimensions defined (expecting <dimension> children)",tileset->name);
+      return;
+   }
+   tileset->dimensions = dimensions;
+}
+
 void parseGrid(geocache_context *ctx, ezxml_t node, geocache_cfg *config) {
-   char *name = NULL, *type = NULL;
+   char *name;
    double extent[4] = {0,0,0,0};
    geocache_grid *grid;
    ezxml_t cur_node;
    char *value;
-   extractNameAndTypeAttributes(ctx->pool, node, &name, &type);
+
+   name = (char*)ezxml_attr(node,"name");
    if(!name || !strlen(name)) {
       ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "mandatory attribute \"name\" not found in <grid>");
       return;
    }
    else {
+      name = apr_pstrdup(ctx->pool, name);
       /* check we don't already have a grid defined with this name */
       if(geocache_configuration_get_grid(config, name)) {
          ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "duplicate grid with name \"%s\"",name);
@@ -332,13 +379,15 @@
    ezxml_t cur_node;
    char *name = NULL, *type = NULL;
 
-   extractNameAndTypeAttributes(ctx->pool, node, &name, &type);
 
+   name = (char*)ezxml_attr(node,"name");
+   type = (char*)ezxml_attr(node,"type");
    if(!name || !strlen(name)) {
       ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "mandatory attribute \"name\" not found in <source>");
       return;
    }
    else {
+      name = apr_pstrdup(ctx->pool, name);
       /* check we don't already have a source defined with this name */
       if(geocache_configuration_get_source(config, name)) {
          ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "duplicate source with name \"%s\"",name);
@@ -384,11 +433,13 @@
    char *name = NULL,  *type = NULL;
    geocache_image_format *format = NULL;
    ezxml_t cur_node;
-   extractNameAndTypeAttributes(ctx->pool, node, &name, &type);
+   name = (char*)ezxml_attr(node,"name");
+   type = (char*)ezxml_attr(node,"type");
    if(!name || !strlen(name)) {
       ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "mandatory attribute \"name\" not found in <format>");
       return;
    }
+   name = apr_pstrdup(ctx->pool, name);
    if(!type || !strlen(type)) {
       ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "mandatory attribute \"type\" not found in <format>");
       return;
@@ -457,12 +508,14 @@
 void parseCache(geocache_context *ctx, ezxml_t node, geocache_cfg *config) {
    char *name = NULL,  *type = NULL;
    geocache_cache *cache = NULL;
-   extractNameAndTypeAttributes(ctx->pool, node, &name, &type);
+   name = (char*)ezxml_attr(node,"name");
+   type = (char*)ezxml_attr(node,"type");
    if(!name || !strlen(name)) {
       ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "mandatory attribute \"name\" not found in <cache>");
       return;
    }
    else {
+      name = apr_pstrdup(ctx->pool, name);
       /* check we don't already have a cache defined with this name */
       if(geocache_configuration_get_cache(config, name)) {
          ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "duplicate cache with name \"%s\"",name);
@@ -496,16 +549,17 @@
 
 
 void parseTileset(geocache_context *ctx, ezxml_t node, geocache_cfg *config) {
-   char *name = NULL, *type = NULL;
+   char *name = NULL;
    geocache_tileset *tileset = NULL;
    ezxml_t cur_node;
    char* value;
-   extractNameAndTypeAttributes(ctx->pool, node, &name, &type);
+   name = (char*)ezxml_attr(node,"name");
    if(!name || !strlen(name)) {
       ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "mandatory attribute \"name\" not found in <tileset>");
       return;
    }
    else {
+      name = apr_pstrdup(ctx->pool, name);
       /* check we don't already have a cache defined with this name */
       if(geocache_configuration_get_tileset(config, name)) {
          ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "duplicate tileset with name \"%s\"",name);
@@ -529,6 +583,11 @@
       parseMetadata(ctx, cur_node, tileset->metadata);
       GC_CHECK_ERROR(ctx);
    }
+   
+   if ((cur_node = ezxml_child(node,"dimensions")) != NULL) {
+      parseDimensions(ctx, cur_node, tileset);
+      GC_CHECK_ERROR(ctx);
+   }
 
 
    if ((cur_node = ezxml_child(node,"cache")) != NULL) {

Modified: trunk/mapserver/mapcache/src/service_wms.c
===================================================================
--- trunk/mapserver/mapcache/src/service_wms.c	2011-08-26 11:10:19 UTC (rev 12243)
+++ trunk/mapserver/mapcache/src/service_wms.c	2011-08-26 11:10:25 UTC (rev 12244)
@@ -322,7 +322,15 @@
                geocache_dimension *dimension = APR_ARRAY_IDX(tileset->dimensions,i,geocache_dimension*);
                const char *value;
                if((value = apr_table_get(params,dimension->name)) != NULL) {
-                  apr_table_setn(tile->dimensions,dimension->name,value);
+                  int ok = dimension->validate(ctx,dimension,value);
+                  GC_CHECK_ERROR(ctx);
+                  if(ok == GEOCACHE_SUCCESS)
+                     apr_table_setn(tile->dimensions,dimension->name,value);
+                  else {
+                     ctx->set_error(ctx,GEOCACHE_REQUEST_ERROR,"dimension \"%s\" value \"%s\" fails to validate",
+                           dimension->name, value);
+                     return;
+                  }
                } else {
                   apr_table_setn(tile->dimensions,dimension->name,dimension->default_value);
                }

Modified: trunk/mapserver/mapcache/src/tileset.c
===================================================================
--- trunk/mapserver/mapcache/src/tileset.c	2011-08-26 11:10:19 UTC (rev 12243)
+++ trunk/mapserver/mapcache/src/tileset.c	2011-08-26 11:10:25 UTC (rev 12244)
@@ -122,6 +122,7 @@
    mt->tile.sy =  mt->tile.tileset->metasize_y * tile->sy + 2 * mt->tile.tileset->metabuffer;
    mt->tile.z = tile->z;
    mt->tile.x = tile->x / mt->tile.tileset->metasize_x;
+   mt->tile.dimensions = tile->dimensions;
    if(tile->x < 0)
       mt->tile.x --;
    mt->tile.y = tile->y / mt->tile.tileset->metasize_y;
@@ -142,6 +143,7 @@
    for(i=0; i<mt->tile.tileset->metasize_x; i++) {
       for(j=0; j<mt->tile.tileset->metasize_y; j++) {
          geocache_tile *t = &(mt->tiles[i*mt->tile.tileset->metasize_x+j]);
+         t->dimensions = tile->dimensions;
          t->z = tile->z;
          t->x = blx + i;
          t->y = bly + j;



More information about the mapserver-commits mailing list