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

svn at osgeo.org svn at osgeo.org
Fri Aug 26 07:28:36 EDT 2011


Author: tbonfort
Date: 2011-08-26 04:28:36 -0700 (Fri, 26 Aug 2011)
New Revision: 12462

Modified:
   trunk/mapserver/mapcache/Makefile.inc.in
   trunk/mapserver/mapcache/geocache.json
   trunk/mapserver/mapcache/include/geocache.h
   trunk/mapserver/mapcache/src/cache_sqlite.c
   trunk/mapserver/mapcache/src/configuration.c
   trunk/mapserver/mapcache/src/configuration_json.c
   trunk/mapserver/mapcache/src/configuration_xml.c
   trunk/mapserver/mapcache/src/dimension.c
   trunk/mapserver/mapcache/src/image.c
   trunk/mapserver/mapcache/src/imageio.c
   trunk/mapserver/mapcache/src/mod_geocache.c
   trunk/mapserver/mapcache/src/service_wms.c
   trunk/mapserver/mapcache/src/tileset.c
Log:


Modified: trunk/mapserver/mapcache/Makefile.inc.in
===================================================================
--- trunk/mapserver/mapcache/Makefile.inc.in	2011-08-26 11:28:26 UTC (rev 12461)
+++ trunk/mapserver/mapcache/Makefile.inc.in	2011-08-26 11:28:36 UTC (rev 12462)
@@ -54,7 +54,7 @@
 
 MISC_ENABLED=@MISC_ENABLED@ -DTHREADED_MPM=$(shell $(HTTPD) -V | grep "Server MPM" | grep -q "Prefork"; echo $$?)
 
-INCLUDES=-I../include $(MISC_ENABLED) $(CURL_CFLAGS) $(PNG_INC) $(JPEG_INC) $(GDAL_INC) $(GEOS_INC) $(APR_INC) $(APU_INC) $(MEMCACHE_ENABLED) $(PCRE_CFLAGS) $(PCRE_ENABLED) $(OGR_ENABLED) $(GEOS_ENABLED) $(SQLITE_ENABLED) $(SQLITE_INC) $(PIXMAN_ENABLED) $(PIXMAN_ENABLED) $(PIXMAN_INC)
+INCLUDES=-I../include $(MISC_ENABLED) $(CURL_CFLAGS) $(PNG_INC) $(JPEG_INC) $(GDAL_INC) $(GEOS_INC) $(APR_INC) $(APU_INC) $(MEMCACHE_ENABLED) $(PCRE_CFLAGS) $(PCRE_ENABLED) $(OGR_ENABLED) $(GEOS_ENABLED) $(SQLITE_ENABLED) $(SQLITE_INC) $(PIXMAN_ENABLED) $(PIXMAN_INC)
 LIBS=$(CURL_LIBS) $(PNG_LIB) $(JPEG_LIB) $(APR_LIBS) $(APU_LIBS) $(PCRE_LIBS) $(SQLITE_LIB) $(PIXMAN_LIB)
 SEEDER_EXTRALIBS=$(GDAL_LIB) $(GEOS_LIB)
 

Modified: trunk/mapserver/mapcache/geocache.json
===================================================================
--- trunk/mapserver/mapcache/geocache.json	2011-08-26 11:28:26 UTC (rev 12461)
+++ trunk/mapserver/mapcache/geocache.json	2011-08-26 11:28:36 UTC (rev 12462)
@@ -53,11 +53,11 @@
   ],
   "sources": [
     {
-      "name":"test",
+      "name":"vmap0",
       "type":"wms",
       "props": {
         "http": {
-          "url":"http://localhost/xxxccv",
+          "url":"http://vmap0.tiles.osgeo.org/wms/vmap0",
           "headers": {
             "User-Agent":"mod-geocache/trunk",
             "Referer":"http://foosite"
@@ -65,7 +65,8 @@
         },
         "getmap": {
           "params":{
-            "LAYERS":"basic"
+            "LAYERS":"basic",
+            "FORMAT":"image/png"
           }
         },
         "getfeatureinfo": {
@@ -105,14 +106,14 @@
   "tilesets": [
     {
       "name": "test",
-      "source": "test",
+      "source": "vmap0",
       "grids": [
         "WGS84",
         { "ref":"g", "extent":[10,10,20,20]}
       ],
       "wgs84_extent":[-180,-90,180,90],
       "format": "png",
-      "cache": "disk",
+      "cache": "sqlite",
       "metatile": {
         "size":[5,5],
         "buffer":10
@@ -122,11 +123,13 @@
         "auto": false
       },
       "dimensions": [
-      ],
-      "watermark":"/path/to/logo.png"
+      ]
+      ,"watermark":"/home/tbonfort/dev/mod-geocache/static/watermark.png"
     }
   ],
   "services": [
+    { "type":"demo" },
+    { "type":"wms" }
   ],
   "config": {
     "error_reporting":"message",

Modified: trunk/mapserver/mapcache/include/geocache.h
===================================================================
--- trunk/mapserver/mapcache/include/geocache.h	2011-08-26 11:28:26 UTC (rev 12461)
+++ trunk/mapserver/mapcache/include/geocache.h	2011-08-26 11:28:36 UTC (rev 12462)
@@ -1155,7 +1155,10 @@
  */
 geocache_tileset* geocache_tileset_create(geocache_context *ctx);
 
+void geocache_tileset_configuration_check(geocache_context *ctx, geocache_tileset *tileset);
+void geocache_tileset_add_watermark(geocache_context *ctx, geocache_tileset *tileset, const char *filename);
 
+
 /**
  * lock the tile
  */
@@ -1307,6 +1310,7 @@
  */
 geocache_image* _geocache_imageio_png_decode(geocache_context *ctx, geocache_buffer *buffer);
 
+void geocache_image_create_empty(geocache_context *ctx, geocache_cfg *cfg);
 /**
  * @param r
  * @param buffer

Modified: trunk/mapserver/mapcache/src/cache_sqlite.c
===================================================================
--- trunk/mapserver/mapcache/src/cache_sqlite.c	2011-08-26 11:28:26 UTC (rev 12461)
+++ trunk/mapserver/mapcache/src/cache_sqlite.c	2011-08-26 11:28:36 UTC (rev 12462)
@@ -282,6 +282,7 @@
       geocache_cache *cache, geocache_cfg *cfg) {
    sqlite3 *db;
    char *errmsg;
+   int ret;
 
    apr_hash_index_t *tileindex_index = apr_hash_first(ctx->pool,cfg->tilesets);
 
@@ -297,10 +298,15 @@
             char *dbname = _get_dbname(ctx,(geocache_cache_sqlite*)cache,tileset,grid);
             sqlite3_open(dbname, &db);
             if(tileset->dimensions) {
-               sqlite3_exec(db, "create table if not exists tiles(x integer, y integer, z integer, data blob, dim text, ctime datetime, atime datetime, hitcount integer default 0, primary key(x,y,z,dim))", 0, 0, &errmsg);
+               ret = sqlite3_exec(db, "create table if not exists tiles(x integer, y integer, z integer, data blob, dim text, ctime datetime, atime datetime, hitcount integer default 0, primary key(x,y,z,dim))", 0, 0, &errmsg);
             } else {
-               sqlite3_exec(db, "create table if not exists tiles(x integer, y integer, z integer, data blob, ctime datetime, atime datetime, hitcount integer default 0, primary key (x,y,z))", 0, 0, &errmsg);
+               ret = sqlite3_exec(db, "create table if not exists tiles(x integer, y integer, z integer, data blob, ctime datetime, atime datetime, hitcount integer default 0, primary key (x,y,z))", 0, 0, &errmsg);
             }
+            if(ret != SQLITE_OK) {
+               ctx->set_error(ctx,500,"sqlite backend failed to create tiles table: %s",sqlite3_errmsg(db));
+               sqlite3_close(db);
+               return;
+            }
             sqlite3_close(db);
          }
       }

Modified: trunk/mapserver/mapcache/src/configuration.c
===================================================================
--- trunk/mapserver/mapcache/src/configuration.c	2011-08-26 11:28:26 UTC (rev 12461)
+++ trunk/mapserver/mapcache/src/configuration.c	2011-08-26 11:28:36 UTC (rev 12462)
@@ -24,6 +24,7 @@
    } else {
       geocache_configuration_parse_xml(ctx,filename,config);
    }
+   GC_CHECK_ERROR(ctx);
 
    if(!config->lockdir || !strlen(config->lockdir)) {
       config->lockdir = apr_pstrdup(ctx->pool, "/tmp");

Modified: trunk/mapserver/mapcache/src/configuration_json.c
===================================================================
--- trunk/mapserver/mapcache/src/configuration_json.c	2011-08-26 11:28:26 UTC (rev 12461)
+++ trunk/mapserver/mapcache/src/configuration_json.c	2011-08-26 11:28:36 UTC (rev 12462)
@@ -272,6 +272,59 @@
 
 
 }
+
+
+static void parse_dimension_json(geocache_context *ctx, cJSON *node, geocache_tileset *tileset) {
+   char *type = NULL;
+   cJSON *tmp;
+   geocache_dimension *dimension;
+
+   tmp = cJSON_GetObjectItem(node,"type");
+   if(tmp) type = tmp->valuestring;
+   if(!type || !strlen(type)) {
+      ctx->set_error(ctx, 400, "mandatory \"type\" not found in dimension for tileset %s", tileset->name);
+      return;
+   }
+   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;
+   }
+   
+   tmp = cJSON_GetObjectItem(node,"unit");
+   if(tmp &&tmp->valuestring) {
+      dimension->unit = apr_pstrdup(ctx->pool,tmp->valuestring);
+   }
+   tmp = cJSON_GetObjectItem(node,"name");
+   if(tmp && tmp->valuestring) {
+      dimension->name = apr_pstrdup(ctx->pool,tmp->valuestring);
+   }
+   tmp = cJSON_GetObjectItem(node,"default");
+   if(tmp && tmp->valuestring) {
+      dimension->default_value = apr_pstrdup(ctx->pool,tmp->valuestring);
+   }
+   
+
+   tmp = cJSON_GetObjectItem(node,"props");
+   if(!tmp || tmp->type != cJSON_Object) {
+      ctx->set_error(ctx, 400, "mandatory \"props\" not found in dimension %s for tileset %s",
+            dimension->name, tileset->name);
+      return;
+   } else {
+      dimension->configuration_parse_json(ctx,dimension,tmp);
+      GC_CHECK_ERROR(ctx);
+   }
+}
+
 static void parse_tileset_json(geocache_context *ctx, cJSON *node, geocache_cfg *cfg) {
    char *name = NULL;
    cJSON *tmp;
@@ -305,11 +358,156 @@
       GC_CHECK_ERROR(ctx);
    }
    
+   tmp = cJSON_GetObjectItem(node,"grids");
+   if(tmp && cJSON_GetArraySize(tmp)) {
+      tileset->grid_links = apr_array_make(ctx->pool,1,sizeof(geocache_grid_link*));
+      int i;
+      for(i=0;i<cJSON_GetArraySize(tmp);i++) {
+         cJSON *jgrid = cJSON_GetArrayItem(tmp,i);
+         cJSON *jchild;
+         char *gridname;
+         geocache_grid_link *gridlink = apr_pcalloc(ctx->pool,sizeof(geocache_grid_link));
+         switch(jgrid->type) {
+            case cJSON_String:
+               gridname = jgrid->valuestring;
+               break;
+            case cJSON_Object:
+               jchild = cJSON_GetObjectItem(jgrid,"ref");
+               if(!jchild || jchild->type != cJSON_String || !jchild->valuestring) {
+                  ctx->set_error(ctx, 400, "tileset \"%s\" references grid with no \"ref\"",name);
+                  return;
+               }
+               gridname = jchild->valuestring;
+               jchild = cJSON_GetObjectItem(jgrid,"extent");
+               if(jchild) {
+                  gridlink->restricted_extent = apr_pcalloc(ctx->pool,4*sizeof(double));
+                  parse_extent_json(ctx,jchild,gridlink->restricted_extent);
+                  GC_CHECK_ERROR(ctx);
+               }
+               break;
+            default:
+               ctx->set_error(ctx, 400, "tileset grid can either be a string or a {\"ref\":\"gridname\",\"extent\":{minx,miny,maxx,maxy} for tileset %s",name);
+               return;
+         }
+         geocache_grid *grid = geocache_configuration_get_grid(cfg,gridname);
+         if(!grid) {
+            ctx->set_error(ctx, 400, "tileset %s references unknown grid \"%s\"",name,gridname);
+            return;
+         }
+         
+         gridlink->grid = grid;
+         gridlink->grid_limits = apr_pcalloc(ctx->pool,grid->nlevels*sizeof(int*));
+         for(i=0;i<grid->nlevels;i++) {
+            gridlink->grid_limits[i] = apr_pcalloc(ctx->pool,4*sizeof(int));
+         }
+         double *extent;
+         if(gridlink->restricted_extent &&
+               gridlink->restricted_extent[2]>gridlink->restricted_extent[0] &&
+               gridlink->restricted_extent[3]>gridlink->restricted_extent[1]) {
+            extent = gridlink->restricted_extent;
+         } else {
+            extent = grid->extent;
+         }
+         geocache_grid_compute_limits(grid,extent,gridlink->grid_limits);
 
+         /* compute wgs84 bbox if it wasn't supplied already */
+         if(tileset->wgs84bbox[0] >= tileset->wgs84bbox[2] &&
+               !strcasecmp(grid->srs,"EPSG:4326")) {
+            tileset->wgs84bbox[0] = extent[0];
+            tileset->wgs84bbox[1] = extent[1];
+            tileset->wgs84bbox[2] = extent[2];
+            tileset->wgs84bbox[3] = extent[3];
+         }
+         APR_ARRAY_PUSH(tileset->grid_links,geocache_grid_link*) = gridlink;
+      }
+   } else {
+      ctx->set_error(ctx, 400, "tileset \"%s\" references no grids",name);
+      return;
+   }
+   tmp = cJSON_GetObjectItem(node,"cache");
+   if(!tmp || !tmp->valuestring) {
+      ctx->set_error(ctx, 400, "tileset \"%s\" references no cache",name);
+      return;
+   } else {
+      tileset->cache = geocache_configuration_get_cache(cfg,tmp->valuestring);
+      if(!tileset->cache) {
+         ctx->set_error(ctx, 400, "tileset \"%s\" references invalid cache \"%s\"",name,tmp->valuestring);
+         return;
+      }
+   }
+   tmp = cJSON_GetObjectItem(node,"source");
+   if(!tmp || !tmp->valuestring) {
+      ctx->set_error(ctx, 400, "tileset \"%s\" references no source",name);
+      return;
+   } else {
+      tileset->source = geocache_configuration_get_source(cfg,tmp->valuestring);
+      if(!tileset->source) {
+         ctx->set_error(ctx, 400, "tileset \"%s\" references invalid source \"%s\"",name,tmp->valuestring);
+         return;
+      }
+   }
+   tmp = cJSON_GetObjectItem(node,"format");
+   if(tmp && tmp->valuestring) {
+      tileset->format = geocache_configuration_get_image_format(cfg,tmp->valuestring);
+      if(!tileset->format) {
+         ctx->set_error(ctx, 400, "tileset \"%s\" references invalid format \"%s\"",name,tmp->valuestring);
+         return;
+      }
+   }
 
+   //dimensions
+   tmp = cJSON_GetObjectItem(node,"dimensions");
+   if(tmp) {
+      int i;
+      for(i=0;i<cJSON_GetArraySize(tmp);i++) {
+         cJSON *item = cJSON_GetArrayItem(tmp,i);
+         parse_dimension_json(ctx,item,tileset);
+         GC_CHECK_ERROR(ctx);
+      }
+   }
 
+   //metatile
+   tmp = cJSON_GetObjectItem(node,"metatile");
+   if(tmp && tmp->type == cJSON_Object) {
+      cJSON *e = cJSON_GetObjectItem(tmp,"size");
+      if(e->type == cJSON_Array && cJSON_GetArraySize(e) == 2 ) {
+         tileset->metasize_x = cJSON_GetArrayItem(e,0)->valueint;
+         tileset->metasize_y = cJSON_GetArrayItem(e,1)->valueint;
+      }
+      e = cJSON_GetObjectItem(tmp,"buffer");
+      if(e && e->type == cJSON_Number) {
+         tileset->metabuffer = e->valueint;
+      }
+   }
+   
+   //watermark
+   tmp = cJSON_GetObjectItem(node,"watermark");
+   if(tmp && tmp->valuestring) {
+      geocache_tileset_add_watermark(ctx,tileset,tmp->valuestring);
+      GC_CHECK_ERROR(ctx);
+   }
 
+   //expire and auto_expire
+   tmp = cJSON_GetObjectItem(node,"expires");
+   if(tmp && tmp->type == cJSON_Object) {
+      cJSON *e = cJSON_GetObjectItem(tmp,"delay");
+      if(e->type == cJSON_Number) {
+         tileset->expires = e->valueint;
+         e = cJSON_GetObjectItem(tmp,"auto");
+         if(e->type == cJSON_True) {
+            tileset->auto_expire = tileset->expires;
+         }
 
+      }
+   }
+   geocache_tileset_configuration_check(ctx,tileset);
+   GC_CHECK_ERROR(ctx);
+   
+   geocache_configuration_add_tileset(cfg,tileset,name);
+
+
+
+
 }
 static void parse_format_json(geocache_context *ctx, cJSON *node, geocache_cfg *cfg) {
    char *name = NULL, *type = NULL;
@@ -427,7 +625,55 @@
 
    geocache_configuration_add_image_format(cfg,format,name);
 }
-static void parse_service_json(geocache_context *ctx, cJSON *node, geocache_cfg *cfg) {
+static void parse_service_json(geocache_context *ctx, cJSON *node, geocache_cfg *config) {
+   cJSON *tmp = cJSON_GetObjectItem(node,"type");
+   char *type = NULL;
+   if(tmp) type = tmp->valuestring;
+   if(!type || !strlen(type)) {
+      ctx->set_error(ctx, 400, "mandatory attribute \"type\" not found in service");
+      return;
+   }
+   tmp = cJSON_GetObjectItem(node,"enabled");
+   if(tmp && tmp->type == cJSON_False) {
+      return;
+   }
+   
+   geocache_service *new_service;
+   if (!strcasecmp(type,"wms")) {
+      new_service = geocache_service_wms_create(ctx);
+      config->services[GEOCACHE_SERVICE_WMS] = new_service;
+   }
+   else if (!strcasecmp(type,"tms")) {
+      new_service = geocache_service_tms_create(ctx);
+      config->services[GEOCACHE_SERVICE_TMS] = new_service;
+   }
+   else if (!strcasecmp(type,"wmts")) {
+      new_service = geocache_service_wmts_create(ctx);
+      config->services[GEOCACHE_SERVICE_WMTS] = new_service;
+   }
+   else if (!strcasecmp(type,"kml")) {
+      new_service = geocache_service_kml_create(ctx);
+      config->services[GEOCACHE_SERVICE_KML] = new_service;
+   }
+   else if (!strcasecmp(type,"gmaps")) {
+      new_service = geocache_service_gmaps_create(ctx);
+      config->services[GEOCACHE_SERVICE_GMAPS] = new_service;
+   }
+   else if (!strcasecmp(type,"ve")) {
+      new_service = geocache_service_ve_create(ctx);
+      config->services[GEOCACHE_SERVICE_VE] = new_service;
+   }
+   else if (!strcasecmp(type,"demo")) {
+      new_service = geocache_service_demo_create(ctx);
+      config->services[GEOCACHE_SERVICE_DEMO] = new_service;
+   } else {
+      ctx->set_error(ctx,400,"unknown <service> type %s",type);
+   }
+   
+   tmp = cJSON_GetObjectItem(node,"props");
+   if(tmp && new_service->configuration_parse_json) {
+      new_service->configuration_parse_json(ctx,tmp,new_service);
+   }
 }
 
 
@@ -479,6 +725,14 @@
          if(GC_HAS_ERROR(ctx)) goto cleanup;
       }
    }
+   entry = cJSON_GetObjectItem(root,"formats");
+   if(entry) {
+      for(i=0;i<cJSON_GetArraySize(entry);i++) {
+         item = cJSON_GetArrayItem(entry,i);
+         parse_format_json(ctx,item,config);
+         if(GC_HAS_ERROR(ctx)) goto cleanup;
+      }
+   }
    entry = cJSON_GetObjectItem(root,"tilesets");
    if(entry) {
       for(i=0;i<cJSON_GetArraySize(entry);i++) {
@@ -492,14 +746,6 @@
       parse_keyvalues(ctx, entry, config->metadata);
       if(GC_HAS_ERROR(ctx)) goto cleanup;
    }
-   entry = cJSON_GetObjectItem(root,"formats");
-   if(entry) {
-      for(i=0;i<cJSON_GetArraySize(entry);i++) {
-         item = cJSON_GetArrayItem(entry,i);
-         parse_format_json(ctx,item,config);
-         if(GC_HAS_ERROR(ctx)) goto cleanup;
-      }
-   }
    entry = cJSON_GetObjectItem(root,"services");
    if(entry) {
       for(i=0;i<cJSON_GetArraySize(entry);i++) {
@@ -510,12 +756,46 @@
    }
    entry = cJSON_GetObjectItem(root,"config");
    if(entry) {
+
+      /* directory where to store temporary lock files */
+      cJSON *tmp = cJSON_GetObjectItem(entry,"lock_dir");
+      if(tmp && tmp->valuestring) {
+         config->lockdir = apr_pstrdup(ctx->pool,tmp->valuestring);
+      }
+
+      /* error reporting */
+      tmp = cJSON_GetObjectItem(entry,"errors");
+      if(tmp && tmp->valuestring) {
+         if(!strcmp(tmp->valuestring,"log")) {
+            config->reporting = GEOCACHE_REPORT_LOG;
+         } else if(!strcmp(tmp->valuestring,"report")) {
+            config->reporting = GEOCACHE_REPORT_MSG;
+         } else if(!strcmp(tmp->valuestring,"empty_img")) {
+            config->reporting = GEOCACHE_REPORT_EMPTY_IMG;
+            geocache_image_create_empty(ctx, config);
+            if(GC_HAS_ERROR(ctx)) goto cleanup;
+         } else if(!strcmp(tmp->valuestring, "report_img")) {
+            config->reporting = GEOCACHE_REPORT_ERROR_IMG;
+            ctx->set_error(ctx,501,"<errors>: report_img not implemented");
+            goto cleanup;
+         } else {
+            ctx->set_error(ctx,400,"<errors>: unknown value %s (allowed are log, report, empty_img, report_img)",
+                  tmp->valuestring);
+            goto cleanup;
+         }
+      }
+
       /* lock_dir, error_reporting */
    }
 
+   /* final checks */
+   if(!config->lockdir) {
+      config->lockdir = apr_pstrdup(ctx->pool,"/tmp");
+   }
 
+
 cleanup:
-   cJSON_Delete(root);
+   //cJSON_Delete(root);
    fclose(f);
-   free(filedata);
+   //free(filedata);
 }

Modified: trunk/mapserver/mapcache/src/configuration_xml.c
===================================================================
--- trunk/mapserver/mapcache/src/configuration_xml.c	2011-08-26 11:28:26 UTC (rev 12461)
+++ trunk/mapserver/mapcache/src/configuration_xml.c	2011-08-26 11:28:36 UTC (rev 12462)
@@ -569,31 +569,7 @@
              ctx->set_error(ctx,400, "watermark config entry empty");
              return;
          }
-         apr_file_t *f;
-         apr_finfo_t finfo;
-         int rv;
-         if(apr_file_open(&f, cur_node->txt, APR_FOPEN_READ|APR_FOPEN_BUFFERED|APR_FOPEN_BINARY,
-                APR_OS_DEFAULT, ctx->pool) != APR_SUCCESS) {
-             ctx->set_error(ctx,500, "failed to open watermark image %s",cur_node->txt);
-             return;
-         }
-         rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, f);
-         if(!finfo.size) {
-            ctx->set_error(ctx, 500, "watermark %s has no data",cur_node->txt);
-            return;
-         }
-
-         geocache_buffer *watermarkdata = geocache_buffer_create(finfo.size,ctx->pool);
-         //manually add the data to our buffer
-         apr_size_t size;
-         apr_file_read(f,(void*)watermarkdata->buf,&size);
-         watermarkdata->size = size;
-         if(size != finfo.size) {
-            ctx->set_error(ctx, 500,  "failed to copy watermark image data, got %d of %d bytes",(int)size, (int)finfo.size);
-            return;
-         }
-         apr_file_close(f);
-         tileset->watermark = geocache_imageio_decode(ctx,watermarkdata);
+         geocache_tileset_add_watermark(ctx,tileset,cur_node->txt);
          GC_CHECK_ERROR(ctx);
    }
       
@@ -642,55 +618,9 @@
          }
          tileset->format = format;
    }
-   if(!tileset->format && tileset->source->type == GEOCACHE_SOURCE_GDAL) {
-      ctx->set_error(ctx,400, "tileset \"%s\" references a gdal source. <format> tag is missing and mandatory in this case",
-            tileset->name);
-      return;
-   }
-   
-   /* check we have all we want */
-   if(tileset->cache == NULL) {
-      /* TODO: we should allow tilesets with no caches */
-      ctx->set_error(ctx, 400, "tileset \"%s\" has no cache configured."
-            " You must add a <cache> tag.", tileset->name);
-      return;
-   }
-   if(tileset->source == NULL) {
-      ctx->set_error(ctx, 400, "tileset \"%s\" has no source configured."
-            " You must add a <source> tag.", tileset->name);
-      return;
-   } 
 
-   if(apr_is_empty_array(tileset->grid_links)) {
-      ctx->set_error(ctx, 400, "tileset \"%s\" has no grids configured."
-            " You must add a <grid> tag.", tileset->name);
-      return;
-   } else if(!havewgs84bbox) {
-#ifdef USE_PROJ
-      geocache_grid_link *sgrid = APR_ARRAY_IDX(tileset->grid_links,0,geocache_grid_link*);
-      double *extent = sgrid->grid->extent;
-      if(sgrid->restricted_extent) {
-         extent = sgrid->restricted_extent;
-      }
-#endif
-   }
-
-   if(!tileset->format && (
-         tileset->metasize_x != 1 ||
-         tileset->metasize_y != 1 ||
-         tileset->metabuffer != 0 ||
-         tileset->watermark)) {
-       if(tileset->watermark) {
-          ctx->set_error(ctx,400,"tileset \"%s\" has no <format> configured, but it is needed for the watermark",
-                   tileset->name);
-          return;
-       } else {
-          ctx->set_error(ctx,400,"tileset \"%s\" has no <format> configured, but it is needed for metatiling",
-                   tileset->name);
-          return;
-       }
-   }
-
+   geocache_tileset_configuration_check(ctx,tileset);
+   GC_CHECK_ERROR(ctx);
    geocache_configuration_add_tileset(config,tileset,name);
    return;
 }
@@ -749,15 +679,6 @@
    }
 }
 
-static void createEmptyImages(geocache_context *ctx, geocache_cfg *cfg) {
-   unsigned int color=0;
-   if(!strstr(cfg->merge_format->mime_type,"png")) {
-      color = 0xffffffff;
-   }
-   cfg->empty_image = cfg->merge_format->create_empty_image(ctx, cfg->merge_format,
-         256,256, color);
-   GC_CHECK_ERROR(ctx);
-}
 
 void geocache_configuration_parse_xml(geocache_context *ctx, const char *filename, geocache_cfg *config) {
    ezxml_t doc, node;
@@ -895,7 +816,7 @@
          config->reporting = GEOCACHE_REPORT_MSG;
       } else if(!strcmp(node->txt,"empty_img")) {
          config->reporting = GEOCACHE_REPORT_EMPTY_IMG;
-         createEmptyImages(ctx, config);
+         geocache_image_create_empty(ctx, config);
          if(GC_HAS_ERROR(ctx)) goto cleanup;
       } else if(!strcmp(node->txt, "report_img")) {
          config->reporting = GEOCACHE_REPORT_ERROR_IMG;

Modified: trunk/mapserver/mapcache/src/dimension.c
===================================================================
--- trunk/mapserver/mapcache/src/dimension.c	2011-08-26 11:28:26 UTC (rev 12461)
+++ trunk/mapserver/mapcache/src/dimension.c	2011-08-26 11:28:36 UTC (rev 12462)
@@ -54,6 +54,10 @@
    return ret;
 }
 
+static void _geocache_dimension_intervals_parse_json(geocache_context *ctx, geocache_dimension *dim,
+      cJSON *node) {
+}
+
 static void _geocache_dimension_intervals_parse_xml(geocache_context *ctx, geocache_dimension *dim,
       ezxml_t node) {
    const char *entry = node->txt;
@@ -123,6 +127,38 @@
    return ret;
 }
 
+static void _geocache_dimension_regex_parse_json(geocache_context *ctx, geocache_dimension *dim,
+      cJSON *node) {
+   geocache_dimension_regex *dimension = (geocache_dimension_regex*)dim;
+   cJSON *tmp = cJSON_GetObjectItem(node,"regex");
+   if(tmp && tmp->valuestring && *(tmp->valuestring)) {
+      dimension->regex_string = apr_pstrdup(ctx->pool,tmp->valuestring);
+#ifdef USE_PCRE
+      const char *pcre_err;
+      int pcre_offset;
+      dimension->pcregex = pcre_compile(dimension->regex_string,0,&pcre_err, &pcre_offset,0);
+      if(!dimension->pcregex) {
+         ctx->set_error(ctx,400,"failed to compile regular expression \"%s\" for dimension \"%s\": %s",
+               dimension->regex_string,dim->name,pcre_err);
+         return;
+      }
+#else
+      int rc = regcomp(dimension->regex, dimension->regex_string, 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",
+               dimension->regex_string,dim->name,errmsg);
+         return;
+      }
+#endif
+   }
+   if(!dimension->regex_string) {
+      ctx->set_error(ctx,400,"failed to parse dimension \"%s\" regex: none supplied", dim->name);
+      return;
+   }
+}
+
 static void _geocache_dimension_regex_parse_xml(geocache_context *ctx, geocache_dimension *dim,
       ezxml_t node) {
    const char *entry = node->txt;
@@ -180,6 +216,33 @@
    return ret;
 }
 
+static void _geocache_dimension_values_parse_json(geocache_context *ctx, geocache_dimension *dim,
+      cJSON *node) {
+   cJSON *tmp;
+   geocache_dimension_values *dimension = (geocache_dimension_values*)dim;
+   tmp = cJSON_GetObjectItem(node,"values");
+   if(tmp) {
+      int i;
+      dimension->values = (char**)apr_pcalloc(ctx->pool,cJSON_GetArraySize(tmp)*sizeof(char*));
+      for(i=0;i<cJSON_GetArraySize(tmp);i++) {
+         if(!tmp->valuestring || !*(tmp->valuestring)) {
+            ctx->set_error(ctx,400,"invalid value for dimension %s",dim->name);
+            return;
+         }
+         dimension->values[dimension->nvalues]=apr_pstrdup(ctx->pool,tmp->valuestring);
+         dimension->nvalues++;
+      }
+   }
+   tmp = cJSON_GetObjectItem(node,"case_sensitive");
+   if(tmp && tmp->type == cJSON_True) {
+      dimension->case_sensitive = 1;
+   }
+   if(!dimension->nvalues) {
+      ctx->set_error(ctx, 400, "dimension \"%s\" has no values",dim->name);
+      return;
+   }
+}
+
 static void _geocache_dimension_values_parse_xml(geocache_context *ctx, geocache_dimension *dim,
       ezxml_t node) {
    int count = 1;
@@ -218,6 +281,7 @@
    dimension->nvalues = 0;
    dimension->dimension.validate = _geocache_dimension_values_validate;
    dimension->dimension.configuration_parse_xml = _geocache_dimension_values_parse_xml;
+   dimension->dimension.configuration_parse_json = _geocache_dimension_values_parse_json;
    dimension->dimension.print_ogc_formatted_values = _geocache_dimension_values_print;
    return (geocache_dimension*)dimension;
 }
@@ -238,6 +302,7 @@
    dimension->nintervals = 0;
    dimension->dimension.validate = _geocache_dimension_intervals_validate;
    dimension->dimension.configuration_parse_xml = _geocache_dimension_intervals_parse_xml;
+   dimension->dimension.configuration_parse_json = _geocache_dimension_intervals_parse_json;
    dimension->dimension.print_ogc_formatted_values = _geocache_dimension_intervals_print;
    return (geocache_dimension*)dimension;
 }
@@ -249,6 +314,7 @@
 #endif
    dimension->dimension.validate = _geocache_dimension_regex_validate;
    dimension->dimension.configuration_parse_xml = _geocache_dimension_regex_parse_xml;
+   dimension->dimension.configuration_parse_json = _geocache_dimension_regex_parse_json;
    dimension->dimension.print_ogc_formatted_values = _geocache_dimension_regex_print;
    return (geocache_dimension*)dimension;
 }

Modified: trunk/mapserver/mapcache/src/image.c
===================================================================
--- trunk/mapserver/mapcache/src/image.c	2011-08-26 11:28:26 UTC (rev 12461)
+++ trunk/mapserver/mapcache/src/image.c	2011-08-26 11:28:36 UTC (rev 12462)
@@ -61,7 +61,7 @@
          pixman_int_to_fixed(-startj),
          pixman_int_to_fixed(-starti));
    pixman_image_set_filter(si,PIXMAN_FILTER_NEAREST, NULL, 0);
-   pixman_image_composite32 (PIXMAN_OP_OVER, si, si, bi,
+   pixman_image_composite (PIXMAN_OP_OVER, si, si, bi,
                             0, 0, 0, 0, 0, 0, base->w,base->h);
    pixman_image_unref(si);
    pixman_image_unref(bi);

Modified: trunk/mapserver/mapcache/src/imageio.c
===================================================================
--- trunk/mapserver/mapcache/src/imageio.c	2011-08-26 11:28:26 UTC (rev 12461)
+++ trunk/mapserver/mapcache/src/imageio.c	2011-08-26 11:28:36 UTC (rev 12462)
@@ -57,6 +57,17 @@
    }
 }
 
+
+void geocache_image_create_empty(geocache_context *ctx, geocache_cfg *cfg) {
+   unsigned int color=0;
+   if(!strstr(cfg->merge_format->mime_type,"png")) {
+      color = 0xffffffff;
+   }
+   cfg->empty_image = cfg->merge_format->create_empty_image(ctx, cfg->merge_format,
+         256,256, color);
+   GC_CHECK_ERROR(ctx);
+}
+
 void geocache_imageio_decode_to_image(geocache_context *ctx, geocache_buffer *buffer,
       geocache_image *image) {
    geocache_image_format_type type = geocache_imageio_header_sniff(ctx,buffer);

Modified: trunk/mapserver/mapcache/src/mod_geocache.c
===================================================================
--- trunk/mapserver/mapcache/src/mod_geocache.c	2011-08-26 11:28:26 UTC (rev 12461)
+++ trunk/mapserver/mapcache/src/mod_geocache.c	2011-08-26 11:28:36 UTC (rev 12462)
@@ -421,13 +421,12 @@
       config->mutex = cfg->mutex;
    }
    
-#ifdef EXPERIMENTAL_POST_CONFIG
    /* fork a child process to let it accomplish post-configuration tasks with the uid of the runtime user */
    apr_proc_t proc;
    rv = apr_proc_fork(&proc, ptemp);
    if (rv == APR_INCHILD) {
       ap_unixd_setup_child();
-      geocache_context *ctx = (geocache_context*)apache_server_context_create(s,ptemp);
+      geocache_context *ctx = (geocache_context*)apache_server_context_create(s,p);
       for (sconf = s; sconf; sconf = sconf->next) {
          geocache_server_cfg* config = ap_get_module_config(sconf->module_config, &geocache_module);
          if(config->aliases) {
@@ -443,7 +442,7 @@
                if(GC_HAS_ERROR(ctx)) {
                   ap_log_error(APLOG_MARK, APLOG_CRIT, APR_EGENERAL, s, "post config for %s failed: %s", alias,
                         ctx->get_error_message(ctx));
-                  exit(0);
+                  exit(APR_EGENERAL);
                }
                entry = apr_hash_next(entry);
             }
@@ -456,6 +455,7 @@
       apr_proc_wait(&proc,&exitcode,&exitwhy,APR_WAIT);
       if(exitwhy != APR_PROC_EXIT) {
          ap_log_error(APLOG_MARK, APLOG_CRIT, APR_EGENERAL, s, "geocache post-config child terminated abnormally");
+         return APR_EGENERAL;
       } else {
          if(exitcode != 0) {
             return APR_EGENERAL;
@@ -466,9 +466,6 @@
       ap_log_error(APLOG_MARK, APLOG_CRIT, APR_EGENERAL, s, "failed to fork geocache post-config child");
       return APR_EGENERAL;
    }
-#else
-   return OK;
-#endif
 }
 
 static void mod_geocache_child_init(apr_pool_t *pool, server_rec *s) {
@@ -604,12 +601,6 @@
    if(GC_HAS_ERROR(ctx)) {
       return ctx->get_error_message(ctx);
    }
-#ifndef EXPERIMENTAL_POST_CONFIG
-   geocache_configuration_post_config(ctx,config);
-   if(GC_HAS_ERROR(ctx)) {
-      return ctx->get_error_message(ctx);
-   }
-#endif
    ap_log_error(APLOG_MARK, APLOG_INFO, 0, cmd->server, "loaded geocache configuration file from %s on alias %s", config->configFile, alias);
    if(!sconfig->aliases) {
       sconfig->aliases = apr_hash_make(cmd->pool);

Modified: trunk/mapserver/mapcache/src/service_wms.c
===================================================================
--- trunk/mapserver/mapcache/src/service_wms.c	2011-08-26 11:28:26 UTC (rev 12461)
+++ trunk/mapserver/mapcache/src/service_wms.c	2011-08-26 11:28:36 UTC (rev 12462)
@@ -767,6 +767,11 @@
 #endif
 }
 
+void _configuration_parse_wms_json(geocache_context *ctx, cJSON *node, geocache_service *gservice) {
+   assert(gservice->type == GEOCACHE_SERVICE_WMS);
+   geocache_service_wms *wms = (geocache_service_wms*)gservice;
+}
+
 void _configuration_parse_wms_xml(geocache_context *ctx, ezxml_t node, geocache_service *gservice) {
    assert(gservice->type == GEOCACHE_SERVICE_WMS);
    geocache_service_wms *wms = (geocache_service_wms*)gservice;
@@ -842,6 +847,7 @@
    service->service.parse_request = _geocache_service_wms_parse_request;
    service->service.create_capabilities_response = _create_capabilities_wms;
    service->service.configuration_parse_xml = _configuration_parse_wms_xml;
+   service->service.configuration_parse_json = _configuration_parse_wms_json;
    return (geocache_service*)service;
 }
 

Modified: trunk/mapserver/mapcache/src/tileset.c
===================================================================
--- trunk/mapserver/mapcache/src/tileset.c	2011-08-26 11:28:26 UTC (rev 12461)
+++ trunk/mapserver/mapcache/src/tileset.c	2011-08-26 11:28:36 UTC (rev 12462)
@@ -18,7 +18,90 @@
 #include <apr_strings.h>
 #include <math.h>
 
+void geocache_tileset_configuration_check(geocache_context *ctx, geocache_tileset *tileset) {
+   
+   /* check we have all we want */
+   if(tileset->cache == NULL) {
+      /* TODO: we should allow tilesets with no caches */
+      ctx->set_error(ctx, 400, "tileset \"%s\" has no cache configured.", tileset->name);
+      return;
+   }
+   if(tileset->source == NULL) {
+      ctx->set_error(ctx, 400, "tileset \"%s\" has no source configured.", tileset->name);
+      return;
+   } 
 
+   if(apr_is_empty_array(tileset->grid_links)) {
+      ctx->set_error(ctx, 400, "tileset \"%s\" has no grids configured", tileset->name);
+      return;
+   } 
+#ifdef USE_PROJ
+   /* not implemented yet, will be used to automatically calculate wgs84bbox with proj */
+   else if(tileset->wgs84bbox[0]>=tileset->wgs84bbox[2]) {
+      geocache_grid_link *sgrid = APR_ARRAY_IDX(tileset->grid_links,0,geocache_grid_link*);
+      double *extent = sgrid->grid->extent;
+      if(sgrid->restricted_extent) {
+         extent = sgrid->restricted_extent;
+      }
+   }
+#endif
+   if(!tileset->format && tileset->source->type == GEOCACHE_SOURCE_GDAL) {
+      ctx->set_error(ctx,400, "tileset \"%s\" references a gdal source. <format> tag is missing and mandatory in this case",
+            tileset->name);
+      return;
+   }
+
+   if(tileset->metabuffer < 0 || tileset->metasize_x < 1 || tileset->metasize_y < 1) {
+      ctx->set_error(ctx,400,"tileset \"%s\" has invalid metasize %d,%d or metabuffer %d",
+            tileset->name,tileset->metasize_x,tileset->metasize_y,tileset->metabuffer);
+      return;
+   }
+
+   if(!tileset->format && (
+         tileset->metasize_x != 1 ||
+         tileset->metasize_y != 1 ||
+         tileset->metabuffer != 0 ||
+         tileset->watermark)) {
+       if(tileset->watermark) {
+          ctx->set_error(ctx,400,"tileset \"%s\" has no <format> configured, but it is needed for the watermark",
+                   tileset->name);
+          return;
+       } else {
+          ctx->set_error(ctx,400,"tileset \"%s\" has no <format> configured, but it is needed for metatiling",
+                   tileset->name);
+          return;
+       }
+   }
+}
+
+void geocache_tileset_add_watermark(geocache_context *ctx, geocache_tileset *tileset, const char *filename) {
+   apr_file_t *f;
+   apr_finfo_t finfo;
+   int rv;
+   if(apr_file_open(&f, filename, APR_FOPEN_READ|APR_FOPEN_BUFFERED|APR_FOPEN_BINARY,
+            APR_OS_DEFAULT, ctx->pool) != APR_SUCCESS) {
+      ctx->set_error(ctx,500, "failed to open watermark image %s",filename);
+      return;
+   }
+   rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, f);
+   if(!finfo.size) {
+      ctx->set_error(ctx, 500, "watermark %s has no data",filename);
+      return;
+   }
+
+   geocache_buffer *watermarkdata = geocache_buffer_create(finfo.size,ctx->pool);
+   //manually add the data to our buffer
+   apr_size_t size = finfo.size;
+   apr_file_read(f,watermarkdata->buf,&size);
+   watermarkdata->size = size;
+   if(size != finfo.size) {
+      ctx->set_error(ctx, 500,  "failed to copy watermark image data, got %d of %d bytes",(int)size, (int)finfo.size);
+      return;
+   }
+   apr_file_close(f);
+   tileset->watermark = geocache_imageio_decode(ctx,watermarkdata);
+}
+
 void geocache_tileset_tile_validate(geocache_context *ctx, geocache_tile *tile) {
    if(tile->z < 0 || tile->z >= tile->grid_link->grid->nlevels) {
       ctx->set_error(ctx,404,"invalid tile z level");



More information about the mapserver-commits mailing list