[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