[mapserver-commits] r12295 - in trunk/mapserver/mapcache: . include
src
svn at osgeo.org
svn at osgeo.org
Fri Aug 26 07:14:40 EDT 2011
Author: tbonfort
Date: 2011-08-26 04:14:40 -0700 (Fri, 26 Aug 2011)
New Revision: 12295
Modified:
trunk/mapserver/mapcache/Makefile.inc.in
trunk/mapserver/mapcache/configure.in
trunk/mapserver/mapcache/geocache.xml
trunk/mapserver/mapcache/include/geocache.h
trunk/mapserver/mapcache/src/configuration.c
trunk/mapserver/mapcache/src/dimension.c
trunk/mapserver/mapcache/src/lock.c
trunk/mapserver/mapcache/src/service_wms.c
trunk/mapserver/mapcache/src/service_wmts.c
Log:
use correct value for WMS capabilities LatLonBoundingBox
add WMTS capabilities WGS84BoundingBox
latlon bounding box can be added/overriden in a tileset by setting the "wgs84boundingbox" metadata entry
thomas.bonfort | 2011-02-05 15:08:46 +0100 (Sat, 05 Feb 2011)
Modified: trunk/mapserver/mapcache/Makefile.inc.in
===================================================================
--- trunk/mapserver/mapcache/Makefile.inc.in 2011-08-26 11:14:32 UTC (rev 12294)
+++ trunk/mapserver/mapcache/Makefile.inc.in 2011-08-26 11:14:40 UTC (rev 12295)
@@ -15,6 +15,9 @@
APR_INC=@APR_INC@
APR_LIBS=@APR_LIBS@
+PCRE_LIBS=@PCRE_LIBS@
+PCRE_CFLAGS=@PCRE_CFLAGS@
+PCRE_ENABLED=@PCRE_ENABLED@
PNG_INC=@PNG_INC@
PNG_LIB=@PNG_LIB@
@@ -31,8 +34,8 @@
GDAL_LIB=@GDAL_LIB@
GDAL_ENABLED=@GDAL_ENABLED@
-INCLUDES=-I../include $(CURL_CFLAGS) $(PNG_INC) $(JPEG_INC) $(GDAL_INC) $(GDAL_ENABLED) $(APR_INC)
-LIBS=$(CURL_LIBS) $(PNG_LIB) $(JPEG_LIB) $(GDAL_LIB) $(APR_LIBS)
+INCLUDES=-I../include $(CURL_CFLAGS) $(PNG_INC) $(JPEG_INC) $(GDAL_INC) $(GDAL_ENABLED) $(APR_INC) $(PCRE_CFLAGS) $(PCRE_ENABLED)
+LIBS=$(CURL_LIBS) $(PNG_LIB) $(JPEG_LIB) $(GDAL_LIB) $(APR_LIBS) $(PCRE_LIBS)
Modified: trunk/mapserver/mapcache/configure.in
===================================================================
--- trunk/mapserver/mapcache/configure.in 2011-08-26 11:14:32 UTC (rev 12294)
+++ trunk/mapserver/mapcache/configure.in 2011-08-26 11:14:40 UTC (rev 12295)
@@ -159,6 +159,47 @@
AC_SUBST(LIBTOOL, `$APRCONFIG --apr-libtool`)
])
+AC_DEFUN([PCRE_CHECK],[
+ AC_MSG_CHECKING([pcre library])
+ AC_ARG_WITH(pcre,
+ [ --with-pcre[[=prefix]] use pcre instead of posix regular expressions],,
+ with_pcre="yes")
+ if test "x$with_pcre" = "xno" ; then
+ AC_MSG_RESULT([disabled])
+ else
+ AC_MSG_RESULT([(testing)])
+ AC_CHECK_LIB(pcre, pcre_study)
+ if test "$ac_cv_lib_pcre_pcre_study" = "yes" ; then
+ PCRE_LIBS="-lpcre"
+ AC_MSG_CHECKING([lib pcre])
+ AC_MSG_RESULT([$PCRE_LIBS])
+ PCRE_ENABLED="-DUSE_PCRE"
+ else
+ OLDLDFLAGS="$LDFLAGS" ; LDFLAGS="$LDFLAGS -L$with_pcre/lib"
+ OLDCPPFLAGS="$CPPFLAGS" ; CPPFLAGS="$CPPFLAGS -I$with_pcre/include"
+ AC_CHECK_LIB(pcre, pcre_compile)
+ CPPFLAGS="$OLDCPPFLAGS"
+ LDFLAGS="$OLDLDFLAGS"
+ if test "$ac_cv_lib_pcre_pcre_compile" = "yes" ; then
+ AC_MSG_RESULT(.setting PCRE_LIBS -L$with_pcre/lib -lpcre)
+ PCRE_LIBS="-L$with_pcre/lib -lpcre"
+ test -d "$with_pcre/include" && PCRE_CFLAGS="-I$with_pcre/include"
+ AC_MSG_CHECKING([lib pcre])
+ AC_MSG_RESULT([$PCRE_LIBS])
+ PCRE_ENABLED="-DUSE_PCRE"
+ else
+ AC_MSG_CHECKING([lib pcre])
+ AC_MSG_RESULT([no, (WARNING)])
+ fi
+ fi
+ fi
+ AC_SUBST([PCRE_ENABLED])
+ AC_SUBST([PCRE_LIBS])
+ AC_SUBST([PCRE_CFLAGS])
+])
+
+
+
AC_DEFUN([DEBUG_CHECK],[
AC_ARG_ENABLE(debug,
AC_HELP_STRING([--enable-debug],[Enable debug build]),
@@ -403,6 +444,7 @@
JPEG_CHECK
+PCRE_CHECK
# disable gdal building for now
#GDAL_CHECK
Modified: trunk/mapserver/mapcache/geocache.xml
===================================================================
--- trunk/mapserver/mapcache/geocache.xml 2011-08-26 11:14:32 UTC (rev 12294)
+++ trunk/mapserver/mapcache/geocache.xml 2011-08-26 11:14:40 UTC (rev 12295)
@@ -388,21 +388,9 @@
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>
- <dimension name="ELEVATION">
- <default>0</default>
- <values>0,1000,2000,3000,4000</values>
- </dimension>
+ <dimension type="regex" name="MAPFILE" default="/path/to/mapfile.map">^[a-zA-Z0-9\./]*\.map$</dimension>
+ <dimension type="values" name="TIME" default="foobar" unit="ISO8601">foobar,foobarbaz,foo,bar</dimension>
+ <dimension name="ELEVATION" type="intervals" default="0">0/5000/1000</dimension>
</dimensions>
</tileset>
<tileset name="test2">
Modified: trunk/mapserver/mapcache/include/geocache.h
===================================================================
--- trunk/mapserver/mapcache/include/geocache.h 2011-08-26 11:14:32 UTC (rev 12294)
+++ trunk/mapserver/mapcache/include/geocache.h 2011-08-26 11:14:40 UTC (rev 12295)
@@ -34,7 +34,12 @@
#endif
#include <assert.h>
#include <apr_time.h>
+
+#ifdef USE_PCRE
+#include <pcre.h>
+#else
#include <regex.h>
+#endif
#define GEOCACHE_SUCCESS 0
#define GEOCACHE_FAILURE 1
@@ -88,6 +93,10 @@
typedef struct geocache_grid_link geocache_grid_link;
typedef struct geocache_context geocache_context;
typedef struct geocache_dimension geocache_dimension;
+typedef struct geocache_dimension_time geocache_dimension_time;
+typedef struct geocache_dimension_intervals geocache_dimension_intervals;
+typedef struct geocache_dimension_values geocache_dimension_values;
+typedef struct geocache_dimension_regex geocache_dimension_regex;
/** \defgroup utility Utility */
/** @{ */
@@ -1088,18 +1097,82 @@
/** @} */
+typedef struct {
+ double start;
+ double end;
+ double resolution;
+} geocache_interval;
+
+typedef enum {
+ GEOCACHE_DIMENSION_VALUES,
+ GEOCACHE_DIMENSION_REGEX,
+ GEOCACHE_DIMENSION_INTERVALS,
+ GEOCACHE_DIMENSION_TIME
+} geocache_dimension_type;
+
struct geocache_dimension {
+ geocache_dimension_type type;
char *name;
char *unit;
apr_table_t *metadata;
char *default_value;
+
+ /**
+ * \brief validate the given value
+ *
+ * \param value is updated in case the given value is correct but has to be represented otherwise,
+ * e.g. to round off a value
+ * \returns GEOCACHE_SUCCESS if the given value is correct for the current dimension
+ * \returns GEOCACHE_FAILURE if not
+ */
+ int (*validate)(geocache_context *context, geocache_dimension *dimension, char **value);
+
+ /**
+ * \brief returns a list of values that are authorized for this dimension
+ *
+ * \returns a list of character strings that will be included in the capabilities <dimension> element
+ */
+ const char** (*print_ogc_formatted_values)(geocache_context *context, geocache_dimension *dimension);
+
+ /**
+ * \brief parse the value given in the configuration
+ */
+ void (*parse)(geocache_context *context, geocache_dimension *dim, const char *entry);
+};
+
+struct geocache_dimension_values {
+ geocache_dimension dimension;
int nvalues;
char **values;
- int (*validate)(geocache_context *context, geocache_dimension *dimension, const char *value);
};
-geocache_dimension* geocache_dimension_create(apr_pool_t *pool);
+struct geocache_dimension_regex {
+ geocache_dimension dimension;
+ char *regex_string;
+#ifdef USE_PCRE
+ pcre *pcregex;
+#else
+ regex_t *regex;
+#endif
+};
+struct geocache_dimension_intervals {
+ geocache_dimension dimension;
+ int nintervals;
+ geocache_interval *intervals;
+};
+
+struct geocache_dimension_time {
+ geocache_dimension dimension;
+ int nintervals;
+ geocache_interval *intervals;
+};
+
+geocache_dimension* geocache_dimension_values_create(apr_pool_t *pool);
+geocache_dimension* geocache_dimension_regex_create(apr_pool_t *pool);
+geocache_dimension* geocache_dimension_intervals_create(apr_pool_t *pool);
+geocache_dimension* geocache_dimension_time_create(apr_pool_t *pool);
+
#endif /* GEOCACHE_H_ */
/* vim: ai ts=3 sts=3 et sw=3
*/
Modified: trunk/mapserver/mapcache/src/configuration.c
===================================================================
--- trunk/mapserver/mapcache/src/configuration.c 2011-08-26 11:14:32 UTC (rev 12294)
+++ trunk/mapserver/mapcache/src/configuration.c 2011-08-26 11:14:40 UTC (rev 12295)
@@ -218,48 +218,53 @@
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 *key, *last, *values;
- int count = 1;
- geocache_dimension *dimension = geocache_dimension_create(ctx->pool);
- ezxml_t dchild_node;
+ char *type = (char*)ezxml_attr(dimension_node,"type");
+ char *unit = (char*)ezxml_attr(dimension_node,"unit");
+ char *default_value = (char*)ezxml_attr(dimension_node,"default");
+
+ geocache_dimension *dimension = NULL;
+
if(!name || !strlen(name)) {
ctx->set_error(ctx, 400, "mandatory attribute \"name\" not found in <dimension>");
return;
}
- dimension->name = apr_pstrdup(ctx->pool,name);
-
- dchild_node = ezxml_child(dimension_node,"unit");
- if(dchild_node && dchild_node->txt) {
- dimension->unit = apr_pstrdup(ctx->pool,dchild_node->txt);
- }
-
- dchild_node = ezxml_child(dimension_node,"default");
- if(!dchild_node || !dchild_node->txt) {
- ctx->set_error(ctx, 400, "<dimension> \"%s\" has no default value",name);
+ if(type && *type) {
+ if(!strcmp(type,"values")) {
+ dimension = geocache_dimension_values_create(ctx->pool);
+ } else if(!strcmp(type,"regex")) {
+ dimension = geocache_dimension_regex_create(ctx->pool);
+ } else if(!strcmp(type,"intervals")) {
+ dimension = geocache_dimension_intervals_create(ctx->pool);
+ } else if(!strcmp(type,"time")) {
+ ctx->set_error(ctx,501,"time dimension type not implemented yet");
+ return;
+ dimension = geocache_dimension_time_create(ctx->pool);
+ } else {
+ ctx->set_error(ctx,400,"unknown dimension type \"%s\"",type);
+ return;
+ }
+ } else {
+ ctx->set_error(ctx,400, "mandatory attribute \"type\" not found in <dimensions>");
return;
}
- dimension->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, 400, "<dimension> \"%s\" has no values",name);
- return;
- }
- values = apr_pstrdup(ctx->pool,dchild_node->txt);
- for(key=values;*key;key++) if(*key == ',') count++;
- dimension->values = (char**)apr_pcalloc(ctx->pool,count*sizeof(char*));
+ dimension->name = apr_pstrdup(ctx->pool,name);
- for (key = apr_strtok(values, ",", &last); key != NULL;
- key = apr_strtok(NULL, ",", &last)) {
- dimension->values[dimension->nvalues]=key;
- dimension->nvalues++;
+ if(unit && *unit) {
+ dimension->unit = apr_pstrdup(ctx->pool,unit);
}
- if(!dimension->nvalues) {
- ctx->set_error(ctx, 400, "<dimension> \"%s\" has no values",name);
+
+ if(default_value && *default_value) {
+ dimension->default_value = apr_pstrdup(ctx->pool,default_value);
+ } else {
+ ctx->set_error(ctx,400,"dimension \"%s\" has no \"default\" attribute",dimension->name);
return;
}
+
+ dimension->parse(ctx,dimension,dimension_node->txt);
+ GC_CHECK_ERROR(ctx);
+
APR_ARRAY_PUSH(dimensions,geocache_dimension*) = dimension;
}
if(apr_is_empty_array(dimensions)) {
Modified: trunk/mapserver/mapcache/src/dimension.c
===================================================================
--- trunk/mapserver/mapcache/src/dimension.c 2011-08-26 11:14:32 UTC (rev 12294)
+++ trunk/mapserver/mapcache/src/dimension.c 2011-08-26 11:14:40 UTC (rev 12295)
@@ -15,34 +15,225 @@
*/
#include "geocache.h"
+#include <apr_strings.h>
+#include <math.h>
+#include <sys/types.h>
-int _geocache_dimension_validate(geocache_context *ctx, geocache_dimension *dim, const char *value) {
+
+static int _geocache_dimension_intervals_validate(geocache_context *ctx, geocache_dimension *dim, char **value) {
int i;
- if(dim->unit && !strcmp(dim->unit,"ISO8601")) {
- for(i=0;i<dim->nvalues;i++) {
- if(!strcmp(value,dim->values[i]))
- return GEOCACHE_SUCCESS;
+ char *endptr;
+ double val = strtod(*value,&endptr);
+ *value = apr_psprintf(ctx->pool,"%g",val);
+ if(*endptr != 0) {
+ return GEOCACHE_FAILURE;
+ }
+ geocache_dimension_intervals *dimension = (geocache_dimension_intervals*)dim;
+ for(i=0;i<dimension->nintervals;i++) {
+ geocache_interval *interval = &dimension->intervals[i];
+ if(val<interval->start || val>interval->end)
+ continue;
+ if(interval->resolution == 0)
+ return GEOCACHE_SUCCESS;
+ double diff = fmod((val - interval->start),interval->resolution);
+ if(diff == 0.0)
+ return GEOCACHE_SUCCESS;
+ }
+ return GEOCACHE_FAILURE;
+}
+
+static const char** _geocache_dimension_intervals_print(geocache_context *ctx, geocache_dimension *dim) {
+ geocache_dimension_intervals *dimension = (geocache_dimension_intervals*)dim;
+ const char **ret = (const char**)apr_pcalloc(ctx->pool,(dimension->nintervals+1)*sizeof(const char*));
+ int i;
+ for(i=0;i<dimension->nintervals;i++) {
+ geocache_interval *interval = &dimension->intervals[i];
+ ret[i] = apr_psprintf(ctx->pool,"%g/%g/%g",interval->start,interval->end,interval->resolution);
+ }
+ ret[i]=NULL;
+ return ret;
+}
+
+static void _geocache_dimension_intervals_parse(geocache_context *ctx, geocache_dimension *dim, const char *entry) {
+ int count = 1;
+ if(!entry || !*entry) {
+ ctx->set_error(ctx,400,"failed to parse dimension values: none supplied");
+ return;
+ }
+ geocache_dimension_intervals *dimension = (geocache_dimension_intervals*)dim;
+ char *values = apr_pstrdup(ctx->pool,entry);
+ char *key,*last;
+ for(key=values;*key;key++) if(*key == ',') count++;
+
+ dimension->intervals = (geocache_interval*)apr_pcalloc(ctx->pool,count*sizeof(geocache_interval));
+
+ for (key = apr_strtok(values, ",", &last); key != NULL;
+ key = apr_strtok(NULL, ",", &last)) {
+ char *endptr;
+ geocache_interval *interval = &dimension->intervals[dimension->nintervals];
+ interval->start = strtod(key,&endptr);
+ if(*endptr != '/') {
+ ctx->set_error(ctx,400,"failed to parse min dimension value \"%s\" in \"%s\" for dimension %s",key,entry,dim->name);
+ return;
}
- } else if(dim->unit && !strcmp(dim->unit,"m")) {
- for(i=0;i<dim->nvalues;i++) {
- if(!strcmp(value,dim->values[i]))
- return GEOCACHE_SUCCESS;
+ key = endptr+1;
+
+ interval->end = strtod(key,&endptr);
+ if(*endptr != '/') {
+ ctx->set_error(ctx,400,"failed to parse max dimension value \"%s\" in \"%s\" for dimension %s",key,entry,dim->name);
+ return;
}
- } else {
- for(i=0;i<dim->nvalues;i++) {
- if(!strcmp(value,dim->values[i]))
- return GEOCACHE_SUCCESS;
+ key = endptr+1;
+ interval->resolution = strtod(key,&endptr);
+ if(*endptr != '\0') {
+ ctx->set_error(ctx,400,"failed to parse resolution dimension value \"%s\" in \"%s\" for dimension %s",key,entry,dim->name);
+ return;
}
+ dimension->nintervals++;
}
+
+ if(!dimension->nintervals) {
+ ctx->set_error(ctx, 400, "<dimension> \"%s\" has no intervals",dim->name);
+ return;
+ }
+}
+
+static int _geocache_dimension_regex_validate(geocache_context *ctx, geocache_dimension *dim, char **value) {
+ geocache_dimension_regex *dimension = (geocache_dimension_regex*)dim;
+#ifdef USE_PCRE
+ int ovector[30];
+ int rc = pcre_exec(dimension->pcregex,NULL,*value,strlen(*value),0,0,ovector,30);
+ if(rc>0)
+ return GEOCACHE_SUCCESS;
+#else
+ if(!regexec(dimension->regex,*value,0,0,0)) {
+ return GEOCACHE_SUCCESS;
+ }
+#endif
return GEOCACHE_FAILURE;
}
-geocache_dimension* geocache_dimension_create(apr_pool_t *pool) {
- geocache_dimension *dimension = apr_pcalloc(pool, sizeof(geocache_dimension));
+static const char** _geocache_dimension_regex_print(geocache_context *ctx, geocache_dimension *dim) {
+ geocache_dimension_regex *dimension = (geocache_dimension_regex*)dim;
+ const char **ret = (const char**)apr_pcalloc(ctx->pool,2*sizeof(const char*));
+ ret[0]=dimension->regex_string;
+ ret[1]=NULL;
+ return ret;
+}
+
+static void _geocache_dimension_regex_parse(geocache_context *ctx, geocache_dimension *dim, const char *entry) {
+ if(!entry || !*entry) {
+ ctx->set_error(ctx,400,"failed to parse dimension regex: none supplied");
+ return;
+ }
+ geocache_dimension_regex *dimension = (geocache_dimension_regex*)dim;
+ dimension->regex_string = apr_pstrdup(ctx->pool,entry);
+#ifdef USE_PCRE
+ const char *pcre_err;
+ int pcre_offset;
+ dimension->pcregex = pcre_compile(entry,0,&pcre_err, &pcre_offset,0);
+ if(!dimension->pcregex) {
+ ctx->set_error(ctx,400,"failed to compile regular expression \"%s\" for dimension \"%s\": %s",
+ entry,dim->name,pcre_err);
+ return;
+ }
+#else
+ int rc = regcomp(dimension->regex, entry, REG_EXTENDED);
+ if(rc) {
+ char errmsg[200];
+ regerror(rc,dimension->regex,errmsg,200);
+ ctx->set_error(ctx,400,"failed to compile regular expression \"%s\" for dimension \"%s\": %s",
+ entry,dim->name,errmsg);
+ return;
+ }
+#endif
+
+}
+
+static int _geocache_dimension_values_validate(geocache_context *ctx, geocache_dimension *dim, char **value) {
+ int i;
+ geocache_dimension_values *dimension = (geocache_dimension_values*)dim;
+ for(i=0;i<dimension->nvalues;i++) {
+ if(!strcmp(*value,dimension->values[i]))
+ return GEOCACHE_SUCCESS;
+ }
+ return GEOCACHE_FAILURE;
+}
+
+static const char** _geocache_dimension_values_print(geocache_context *ctx, geocache_dimension *dim) {
+ geocache_dimension_values *dimension = (geocache_dimension_values*)dim;
+ const char **ret = (const char**)apr_pcalloc(ctx->pool,(dimension->nvalues+1)*sizeof(const char*));
+ int i;
+ for(i=0;i<dimension->nvalues;i++) {
+ ret[i] = dimension->values[i];
+ }
+ ret[i]=NULL;
+ return ret;
+}
+
+static void _geocache_dimension_values_parse(geocache_context *ctx, geocache_dimension *dim, const char *entry) {
+ int count = 1;
+ if(!entry || !*entry) {
+ ctx->set_error(ctx,400,"failed to parse dimension values: none supplied");
+ return;
+ }
+ geocache_dimension_values *dimension = (geocache_dimension_values*)dim;
+ char *values = apr_pstrdup(ctx->pool,entry);
+ char *key,*last;
+ 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, 400, "<dimension> \"%s\" has no values",dim->name);
+ return;
+ }
+}
+
+geocache_dimension* geocache_dimension_values_create(apr_pool_t *pool) {
+ geocache_dimension_values *dimension = apr_pcalloc(pool, sizeof(geocache_dimension_values));
+ dimension->dimension.type = GEOCACHE_DIMENSION_VALUES;
dimension->nvalues = 0;
- dimension->validate = _geocache_dimension_validate;
- return dimension;
+ dimension->dimension.validate = _geocache_dimension_values_validate;
+ dimension->dimension.parse = _geocache_dimension_values_parse;
+ dimension->dimension.print_ogc_formatted_values = _geocache_dimension_values_print;
+ return (geocache_dimension*)dimension;
}
+geocache_dimension* geocache_dimension_time_create(apr_pool_t *pool) {
+ geocache_dimension_time *dimension = apr_pcalloc(pool, sizeof(geocache_dimension_time));
+ dimension->dimension.type = GEOCACHE_DIMENSION_TIME;
+ dimension->nintervals = 0;
+// dimension->dimension.validate = _geocache_dimension_time_validate;
+// dimension->dimension.parse = _geocache_dimension_time_parse;
+// dimension->dimension.print_ogc_formatted_values = _geocache_dimension_time_print;
+ return (geocache_dimension*)dimension;
+}
+
+geocache_dimension* geocache_dimension_intervals_create(apr_pool_t *pool) {
+ geocache_dimension_intervals *dimension = apr_pcalloc(pool, sizeof(geocache_dimension_intervals));
+ dimension->dimension.type = GEOCACHE_DIMENSION_INTERVALS;
+ dimension->nintervals = 0;
+ dimension->dimension.validate = _geocache_dimension_intervals_validate;
+ dimension->dimension.parse = _geocache_dimension_intervals_parse;
+ dimension->dimension.print_ogc_formatted_values = _geocache_dimension_intervals_print;
+ return (geocache_dimension*)dimension;
+}
+geocache_dimension* geocache_dimension_regex_create(apr_pool_t *pool) {
+ geocache_dimension_regex *dimension = apr_pcalloc(pool, sizeof(geocache_dimension_regex));
+ dimension->dimension.type = GEOCACHE_DIMENSION_REGEX;
+#ifndef USE_PCRE
+ dimension->regex = (regex_t*)apr_pcalloc(pool, sizeof(regex_t));
+#endif
+ dimension->dimension.validate = _geocache_dimension_regex_validate;
+ dimension->dimension.parse = _geocache_dimension_regex_parse;
+ dimension->dimension.print_ogc_formatted_values = _geocache_dimension_regex_print;
+ return (geocache_dimension*)dimension;
+}
/* vim: ai ts=3 sts=3 et sw=3
*/
Modified: trunk/mapserver/mapcache/src/lock.c
===================================================================
--- trunk/mapserver/mapcache/src/lock.c 2011-08-26 11:14:32 UTC (rev 12294)
+++ trunk/mapserver/mapcache/src/lock.c 2011-08-26 11:14:40 UTC (rev 12295)
@@ -60,7 +60,13 @@
int i;
for(i=0;i<elts->nelts;i++) {
apr_table_entry_t entry = APR_ARRAY_IDX(elts,i,apr_table_entry_t);
- lockname = apr_pstrcat(ctx->pool,lockname,entry.val,NULL);
+ char *dimvalue = apr_pstrdup(ctx->pool,entry.val);
+ char *iter = dimvalue;
+ while(*iter) {
+ if(*iter == '/') *iter='_';
+ iter++;
+ }
+ lockname = apr_pstrcat(ctx->pool,lockname,dimvalue,NULL);
}
}
Modified: trunk/mapserver/mapcache/src/service_wms.c
===================================================================
--- trunk/mapserver/mapcache/src/service_wms.c 2011-08-26 11:14:32 UTC (rev 12294)
+++ trunk/mapserver/mapcache/src/service_wms.c 2011-08-26 11:14:40 UTC (rev 12295)
@@ -164,12 +164,14 @@
dimension->default_value);
if(dimension->unit) {
dimensions = apr_pstrcat(ctx->pool,dimensions,
- " units=\"%s\"",dimension->unit,NULL);
+ " units=\"",dimension->unit,"\"",NULL);
}
- dimensions = apr_pstrcat(ctx->pool,dimensions,">",dimension->values[0],NULL);
- int j;
- for(j=1;j<dimension->nvalues;j++) {
- dimensions = apr_pstrcat(ctx->pool,dimensions,",",dimension->values[j],NULL);
+ const char **value = dimension->print_ogc_formatted_values(ctx,dimension);
+ dimensions = apr_pstrcat(ctx->pool,dimensions,">",*value,NULL);
+ value++;
+ while(*value) {
+ dimensions = apr_pstrcat(ctx->pool,dimensions,",",*value,NULL);
+ value++;
}
dimensions = apr_pstrcat(ctx->pool,dimensions,"</Dimension>\n",NULL);
}
@@ -341,11 +343,12 @@
for(i=0;i<tileset->dimensions->nelts;i++) {
geocache_dimension *dimension = APR_ARRAY_IDX(tileset->dimensions,i,geocache_dimension*);
const char *value;
- if((value = apr_table_get(params,dimension->name)) != NULL) {
- int ok = dimension->validate(ctx,dimension,value);
+ if((value = (char*)apr_table_get(params,dimension->name)) != NULL) {
+ char *tmpval = apr_pstrdup(ctx->pool,value);
+ int ok = dimension->validate(ctx,dimension,&tmpval);
GC_CHECK_ERROR(ctx);
if(ok == GEOCACHE_SUCCESS)
- apr_table_setn(tile->dimensions,dimension->name,value);
+ apr_table_setn(tile->dimensions,dimension->name,tmpval);
else {
ctx->set_error(ctx,400,"dimension \"%s\" value \"%s\" fails to validate",
dimension->name, value);
Modified: trunk/mapserver/mapcache/src/service_wmts.c
===================================================================
--- trunk/mapserver/mapcache/src/service_wmts.c 2011-08-26 11:14:32 UTC (rev 12294)
+++ trunk/mapserver/mapcache/src/service_wmts.c 2011-08-26 11:14:40 UTC (rev 12295)
@@ -141,12 +141,14 @@
dimension->name,
dimension->default_value);
if(dimension->unit) {
- dimensions = apr_pstrcat(ctx->pool,dimension,
+ dimensions = apr_pstrcat(ctx->pool,dimensions,
" <UOM>",dimension->unit,"</UOM>\n",NULL);
}
- int i = dimension->nvalues;
- while(i--) {
- dimensions = apr_pstrcat(ctx->pool,dimensions," <Value>",dimension->values[i],"</Value>\n",NULL);
+ const char **values = dimension->print_ogc_formatted_values(ctx,dimension);
+ const char **value = values;
+ while(*value) {
+ dimensions = apr_pstrcat(ctx->pool,dimensions," <Value>",*value,"</Value>\n",NULL);
+ value++;
}
dimensions = apr_pstrcat(ctx->pool,dimensions," </Dimension>\n",NULL);
@@ -423,17 +425,30 @@
/*validate dimensions*/
if(tileset->dimensions) {
+ if(!dimtable) {
+ ctx->set_error(ctx,404, "received request with no dimensions");
+ return;
+ }
int i;
for(i=0;i<tileset->dimensions->nelts;i++) {
geocache_dimension *dimension = APR_ARRAY_IDX(tileset->dimensions,i,geocache_dimension*);
const char *value = apr_table_get(dimtable,dimension->name);
- int ok = dimension->validate(ctx,dimension,value);
+ if(!value) {
+ ctx->set_error(ctx,404,"received request with no value for dimension \"%s\"",dimension->name);
+ return;
+ }
+ char *tmpval = apr_pstrdup(ctx->pool,value);
+ int ok = dimension->validate(ctx,dimension,&tmpval);
GC_CHECK_ERROR(ctx);
if(ok != GEOCACHE_SUCCESS) {
ctx->set_error(ctx,404,"dimension \"%s\" value \"%s\" fails to validate",
dimension->name, value);
return;
}
+
+ /* re-set the eventually modified value in the dimension table */
+ apr_table_set(dimtable,dimension->name,tmpval);
+
}
}
More information about the mapserver-commits
mailing list