[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