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

svn at osgeo.org svn at osgeo.org
Fri Aug 26 07:05:49 EDT 2011


Author: tbonfort
Date: 2011-08-26 04:05:49 -0700 (Fri, 26 Aug 2011)
New Revision: 12192

Modified:
   trunk/mapserver/mapcache/geocache.xml
   trunk/mapserver/mapcache/include/geocache.h
   trunk/mapserver/mapcache/src/configuration.c
   trunk/mapserver/mapcache/src/geocache_seed.c
   trunk/mapserver/mapcache/src/image.c
   trunk/mapserver/mapcache/src/source_wms.c
   trunk/mapserver/mapcache/src/tileset.c
Log:
refactor capabilities into a function pointer of the geocache_service struct
polish wms-c capabilities
add tms capabilities
add a mimetype to image formats
thomas.bonfort | 2011-01-03 17:22:54 +0100 (Mon, 03 Jan 2011)

Modified: trunk/mapserver/mapcache/geocache.xml
===================================================================
--- trunk/mapserver/mapcache/geocache.xml	2011-08-26 11:05:43 UTC (rev 12191)
+++ trunk/mapserver/mapcache/geocache.xml	2011-08-26 11:05:49 UTC (rev 12192)
@@ -16,6 +16,15 @@
         	<LAYERS>basic</LAYERS>
         </wmsparams>
     </source>
+    <source name="osm" type="wms">
+        <url>http://localhost/cgi-bin/mapserv</url>
+        <srs>epsg:900913</srs>
+        <wmsparams>
+            <FORMAT>image/png</FORMAT>
+            <LAYERS>default</LAYERS>
+            <MAP>/Users/tbonfort/dev/mapserver-utils/osm-mapserver.map</MAP>
+        </wmsparams>
+    </source>
     <source name="nexrad" type="wms">
         <url>http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi</url>
         <srs>epsg:4326</srs>
@@ -36,34 +45,33 @@
     </source>
     <tileset name="test">
         <source>vmap0</source>
-        <srs>epsg:4326</srs>
         <cache>disk</cache>
-        <size>256 256</size>
         <format>PNG8</format>
-        <resolutions>0.703125 0.3515625 0.17578125 0.087890625 0.0439453125 0.02197265625 0.010986328125 0.0054931640625 0.00274658203125 0.001373291015625 0.0006866455078125 0.00034332275390625 0.000171661376953125 0.0000858306884765625 0.00004291534423828125</resolutions>
-        <extent>-180 -90 180 90</extent>
+        <grid>WGS84</grid>
         <expires>3600</expires>
     </tileset>
     <tileset name="test2">
         <source>nexrad</source>
-        <srs>epsg:4326</srs>
         <cache>disk</cache>
-        <size>256 256</size>
         <format>PNG</format>
-        <resolutions>0.703125 0.3515625 0.17578125 0.087890625 0.0439453125 0.02197265625 0.010986328125 0.0054931640625 0.00274658203125 0.001373291015625 0.0006866455078125 0.00034332275390625 0.000171661376953125 0.0000858306884765625 0.00004291534423828125</resolutions>
-        <extent>-180 -90 180 90</extent>
+        <grid>WGS84</grid>
     </tileset>
     <tileset name="test3">
         <source>basic</source>
-        <srs>epsg:4326</srs>
         <cache>disk</cache>
-        <size>256 256</size>
         <format>PNG8</format>
-        <resolutions>0.703125 0.3515625 0.17578125 0.087890625 0.0439453125 0.02197265625 0.010986328125 0.0054931640625 0.00274658203125 0.001373291015625 0.0006866455078125 0.00034332275390625 0.000171661376953125 0.0000858306884765625 0.00004291534423828125</resolutions>
-        <extent>-180 -90 180 90</extent>
+        <grid>WGS84</grid>
         <metatile>5 5</metatile>
         <metabuffer>30</metabuffer>
     </tileset>
+    <tileset name="osm">
+        <source>osm</source>
+        <cache>disk</cache>
+        <format>PNG</format>
+        <grid>google</grid>
+        <metatile>5 5</metatile>
+        <metabuffer>10</metabuffer>
+    </tileset>
     <merge_format>PNGQ_FAST</merge_format>
     
     <services>

Modified: trunk/mapserver/mapcache/include/geocache.h
===================================================================
--- trunk/mapserver/mapcache/include/geocache.h	2011-08-26 11:05:43 UTC (rev 12191)
+++ trunk/mapserver/mapcache/include/geocache.h	2011-08-26 11:05:49 UTC (rev 12192)
@@ -69,6 +69,7 @@
 typedef struct geocache_service_tms geocache_service_tms;
 typedef struct geocache_server_cfg geocache_server_cfg;
 typedef struct geocache_image geocache_image;
+typedef struct geocache_grid geocache_grid;
 typedef struct geocache_context geocache_context;
 
 
@@ -467,6 +468,11 @@
     apr_hash_t *image_formats;
 
     /**
+     * hashtable containing (pre)defined grids
+     */
+    apr_hash_t *grids;
+
+    /**
      * the format to use when merging multiple tiles
      */
     geocache_image_format *merge_format;
@@ -493,10 +499,12 @@
 geocache_cfg* geocache_configuration_create(apr_pool_t *pool);
 geocache_source* geocache_configuration_get_source(geocache_cfg *config, const char *key);
 geocache_cache* geocache_configuration_get_cache(geocache_cfg *config, const char *key);
+geocache_grid *geocache_configuration_get_grid(geocache_cfg *config, const char *key);
 geocache_tileset* geocache_configuration_get_tileset(geocache_cfg *config, const char *key);
 geocache_image_format *geocache_configuration_get_image_format(geocache_cfg *config, const char *key);
 void geocache_configuration_add_image_format(geocache_cfg *config, geocache_image_format *format, const char * key);
 void geocache_configuration_add_source(geocache_cfg *config, geocache_source *source, const char * key);
+void geocache_configuration_add_grid(geocache_cfg *config, geocache_grid *grid, const char * key);
 void geocache_configuration_add_tileset(geocache_cfg *config, geocache_tileset *tileset, const char * key);
 void geocache_configuration_add_cache(geocache_cfg *config, geocache_cache *cache, const char * key);
 
@@ -561,6 +569,15 @@
     geocache_tile *tiles; /**< the list of geocache_tile s contained in this metatile */
 };
 
+struct geocache_grid {
+   char *name;
+   int levels;
+   char *srs;
+   int tile_sx, tile_sy; /**<width and height of a tile in pixels */
+   double *resolutions;
+   double **extents; /**< array of extents (one for each resolution) */
+};
+
 /**\class geocache_tileset
  * \brief a set of tiles that can be requested by a client, created from a geocache_source
  *        stored by a geocache_cache in a geocache_format
@@ -573,41 +590,16 @@
     char *name;
 
     /**
-     * the extent of the tileset.
+     * the extent of the tileset that can be cached
      */
-    double extent[4];
+    double restricted_extent[4];
 
     /**
-     * the SRS of the tileset
+     * definition of the gridset
      */
-    char *srs;
+    geocache_grid *grid;
 
     /**
-     * the unit of measure of the tileset
-     */
-    geocache_unit units;
-
-    /**
-     * width of a tile in pixels
-     */
-    int tile_sx;
-
-    /**
-     * height of a tile in pixels
-     */
-    int tile_sy;
-
-    /**
-     * number of resolutions
-     */
-    int levels;
-
-    /**
-     * resolutions of the tiles
-     */
-    double *resolutions;
-
-    /**
      * size of the metatile that should be requested to the geocache_tileset::source
      */
     int metasize_x, metasize_y;
@@ -739,6 +731,9 @@
 /** @} */
 
 
+geocache_grid* geocache_grid_create(apr_pool_t *pool);
+
+
 /* in util.c */
 int geocache_util_extract_int_list(geocache_context *ctx, char* args, const char sep, int **numbers,
         int *numbers_count);

Modified: trunk/mapserver/mapcache/src/configuration.c
===================================================================
--- trunk/mapserver/mapcache/src/configuration.c	2011-08-26 11:05:43 UTC (rev 12191)
+++ trunk/mapserver/mapcache/src/configuration.c	2011-08-26 11:05:49 UTC (rev 12192)
@@ -24,10 +24,54 @@
 #include <apr_file_io.h>
 
 geocache_cfg* geocache_configuration_create(apr_pool_t *pool) {
+   geocache_grid *grid;
+   int i;
+   double wgs84_resolutions[16]={
+         1.40625,
+         0.703125,
+         0.3515625,
+         0.17578125,
+         0.087890625,
+         0.0439453125,
+         0.02197265625,
+         0.010986328125,
+         0.0054931640625,
+         0.00274658203125,
+         0.001373291015625,
+         0.0006866455078125,
+         0.00034332275390625,
+         0.000171661376953125,
+         0.0000858306884765625,
+         0.00004291534423828125};
+   double google_resolutions[19] = {
+         156543.0339,
+         78271.51695,
+         39135.758475,
+         19567.8792375,
+         9783.93961875,
+         4891.96980938,
+         2445.98490469,
+         1222.99245234,
+         611.496226172,
+         305.748113086,
+         152.874056543,
+         76.4370282715,
+         38.2185141357,
+         19.1092570679,
+         9.55462853394,
+         4.77731426697,
+         2.38865713348,
+         1.19432856674,
+         0.597164283371
+   };
+   double wgs84_extent[4]={-180,-90,180,90};
+   double google_extent[4]={-20037508.3392,-20037508.3392,20037508.3392,20037508.3392};
+
    geocache_cfg *cfg = (geocache_cfg*)apr_pcalloc(pool, sizeof(geocache_cfg));
    cfg->caches = apr_hash_make(pool);
    cfg->sources = apr_hash_make(pool);
    cfg->tilesets = apr_hash_make(pool);
+   cfg->grids = apr_hash_make(pool);
    cfg->image_formats = apr_hash_make(pool);
 
    geocache_configuration_add_image_format(cfg,
@@ -42,6 +86,40 @@
    cfg->merge_format = geocache_configuration_get_image_format(cfg,"PNG");
    cfg->lockdir = "/tmp/geocache_locks";
    cfg->reporting = GEOCACHE_REPORT_MSG;
+
+   grid = geocache_grid_create(pool);
+   grid->name = "WGS84";
+   grid->srs = "epsg:4326";
+   grid->tile_sx = grid->tile_sy = 256;
+   grid->resolutions = wgs84_resolutions;
+   grid->levels = 16;
+   grid->extents = (double**)apr_pcalloc(pool,grid->levels*sizeof(double*));
+   grid->resolutions = (double*)apr_pcalloc(pool,grid->levels*sizeof(double));
+   for(i=0; i<grid->levels; i++) {
+      grid->extents[i] = (double*)apr_pcalloc(pool,4*sizeof(double));
+      grid->extents[i][0] = wgs84_extent[0];
+      grid->extents[i][1] = wgs84_extent[1];
+      grid->extents[i][2] = wgs84_extent[2];
+      grid->extents[i][3] = wgs84_extent[3];
+      grid->resolutions[i] = wgs84_resolutions[i];
+   }
+   geocache_configuration_add_grid(cfg,grid,"WGS84");
+
+   grid = geocache_grid_create(pool);
+   grid->name = "google";
+   grid->srs = "epsg:900913";
+   grid->tile_sx = grid->tile_sy = 256;
+   grid->resolutions = google_resolutions;
+   grid->levels = 19;
+   grid->extents = (double**)apr_pcalloc(pool,grid->levels*sizeof(double*));
+   grid->resolutions = (double*)apr_pcalloc(pool,grid->levels*sizeof(double));
+   for(i=0; i<grid->levels; i++) {
+      grid->extents[i] = google_extent;
+      grid->resolutions[i] = google_resolutions[i];
+   }
+   geocache_configuration_add_grid(cfg,grid,"google");
+
+
    return cfg;
 }
 
@@ -53,6 +131,10 @@
    return (geocache_cache*)apr_hash_get(config->caches, (void*)key, APR_HASH_KEY_STRING);
 }
 
+geocache_grid *geocache_configuration_get_grid(geocache_cfg *config, const char *key) {
+   return (geocache_grid*)apr_hash_get(config->grids, (void*)key, APR_HASH_KEY_STRING);
+}
+
 geocache_tileset *geocache_configuration_get_tileset(geocache_cfg *config, const char *key) {
    return (geocache_tileset*)apr_hash_get(config->tilesets, (void*)key, APR_HASH_KEY_STRING);
 }
@@ -65,6 +147,10 @@
    apr_hash_set(config->sources, key, APR_HASH_KEY_STRING, (void*)source);
 }
 
+void geocache_configuration_add_grid(geocache_cfg *config, geocache_grid *grid, const char * key) {
+   apr_hash_set(config->grids, key, APR_HASH_KEY_STRING, (void*)grid);
+}
+
 void geocache_configuration_add_tileset(geocache_cfg *config, geocache_tileset *tileset, const char * key) {
    tileset->config = config;
    apr_hash_set(config->tilesets, key, APR_HASH_KEY_STRING, (void*)tileset);
@@ -97,6 +183,116 @@
    }
 }
 
+void parseGrid(geocache_context *ctx, xmlNode *node, geocache_cfg *config) {
+   char *name = NULL, *type = NULL;
+   double extent[4] = {0,0,0,0};
+   geocache_grid *grid;
+   xmlNode *cur_node;
+   char *value;
+   if(xmlStrcmp(node->name, BAD_CAST "grid")) {
+      ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "SEVERE: <%s> is not a grid tag",node->name);
+      return;
+   }
+   extractNameAndTypeAttributes(node->doc, node->properties, &name, &type);
+   if(!name || !strlen(name)) {
+      ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "mandatory attribute \"name\" not found in <grid>");
+      return;
+   }
+   else {
+      /* 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);
+         return;
+      }
+   }
+   grid = geocache_grid_create(ctx->pool);
+   grid->name = name;
+   for(cur_node = node->children; cur_node; cur_node = cur_node->next) {
+      if(cur_node->type != XML_ELEMENT_NODE) continue;
+      if(!xmlStrcmp(cur_node->name, BAD_CAST "extent")) {
+         value = (char*)xmlNodeGetContent(cur_node);
+         int nvalues;
+         double *values;
+         if(GEOCACHE_SUCCESS != geocache_util_extract_double_list(ctx, value, ' ', &values, &nvalues) ||
+               nvalues != 4) {
+            ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "failed to parse extent array %s."
+                  "(expecting 4 space separated numbers, got %d (%f %f %f %f)"
+                  "eg <extent>-180 -90 180 90</extent>",
+                  value,nvalues,values[0],values[1],values[2],values[3]);
+            return;
+         }
+         extent[0] = values[0];
+         extent[1] = values[1];
+         extent[2] = values[2];
+         extent[3] = values[3];
+         xmlFree(value);
+      } else if(!xmlStrcmp(cur_node->name, BAD_CAST "srs")) {
+         value = (char*)xmlNodeGetContent(cur_node);
+         grid->srs = value;
+      } else if(!xmlStrcmp(cur_node->name, BAD_CAST "size")) {
+         value = (char*)xmlNodeGetContent(cur_node);
+         int *sizes, nsizes;
+         if(GEOCACHE_SUCCESS != geocache_util_extract_int_list(ctx, value, ' ', &sizes, &nsizes) ||
+               nsizes != 2) {
+            ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "failed to parse size array %s in  grid %s"
+                  "(expecting two space separated integers, eg <size>256 256</size>",
+                  value, grid->name);
+            return;
+         }
+         grid->tile_sx = sizes[0];
+         grid->tile_sy = sizes[1];
+         xmlFree(value);
+      } else if(!xmlStrcmp(cur_node->name, BAD_CAST "resolutions")) {
+         value = (char*)xmlNodeGetContent(cur_node);
+         int nvalues;
+         double *values;
+         if(GEOCACHE_SUCCESS != geocache_util_extract_double_list(ctx, value, ' ', &values, &nvalues) ||
+               !nvalues) {
+            ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "failed to parse resolutions array %s."
+                  "(expecting space separated numbers, "
+                  "eg <resolutions>1 2 4 8 16 32</resolutions>",
+                  value);
+            return;
+         }
+         grid->resolutions = values;
+         grid->levels = nvalues;
+         xmlFree(value);
+      }
+   }
+
+   if(grid->srs == NULL) {
+      ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "grid \"%s\" has no srs configured."
+            " You must add a <srs> tag.", grid->name);
+      return;
+   }
+   if(extent[0] >= extent[2] || extent[1] >= extent[3]) {
+      ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "grid \"%s\" has no (or invalid) extent configured"
+            " You must add/correct a <extent> tag.", grid->name);
+      return;
+   }
+   if(grid->tile_sx <= 0 || grid->tile_sy <= 0) {
+      ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "grid \"%s\" has no (or invalid) tile size configured"
+            " You must add/correct a <size> tag.", grid->name);
+      return;
+   }
+   if(!grid->levels) {
+      ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "grid \"%s\" has no resolutions configured."
+            " You must add a <resolutions> tag.", grid->name);
+      return;
+   } else {
+      int i;
+      grid->extents = apr_pcalloc(ctx->pool, grid->levels * sizeof(double*));
+      for(i=0;i<grid->levels;i++) {
+         grid->extents[i] = apr_pcalloc(ctx->pool, 4 * sizeof(double*));
+         grid->extents[i][0] = extent[0];
+         grid->extents[i][1] = extent[1];
+         grid->extents[i][2] = extent[2];
+         grid->extents[i][3] = extent[3];
+      }
+   }
+   geocache_configuration_add_grid(config,grid,name);
+}
+
 void parseSource(geocache_context *ctx, xmlNode *node, geocache_cfg *config) {
    if(xmlStrcmp(node->name, BAD_CAST "source")) {
       ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "SEVERE: found tag %s instead of <source>",node->name);
@@ -306,10 +502,21 @@
    }
    tileset = geocache_tileset_create(ctx);
    tileset->name = name;
+
    for(cur_node = node->children; cur_node; cur_node = cur_node->next) {
       if(cur_node->type != XML_ELEMENT_NODE) continue;
-      if(!xmlStrcmp(cur_node->name, BAD_CAST "cache")) {
+      if(!xmlStrcmp(cur_node->name, BAD_CAST "grid")) {
          value = (char*)xmlNodeGetContent(cur_node);
+         geocache_grid *grid = geocache_configuration_get_grid(config, value);
+         if(!grid) {
+            ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "tileset \"%s\" references grid \"%s\","
+                  " but it is not configured", name, value);
+            return;
+         }
+         tileset->grid = grid;
+         xmlFree(BAD_CAST value);
+      } else if(!xmlStrcmp(cur_node->name, BAD_CAST "cache")) {
+         value = (char*)xmlNodeGetContent(cur_node);
          geocache_cache *cache = geocache_configuration_get_cache(config, value);
          if(!cache) {
             ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "tileset \"%s\" references cache \"%s\","
@@ -328,54 +535,6 @@
          }
          tileset->source = source;
          xmlFree(value);
-      } else if(!xmlStrcmp(cur_node->name, BAD_CAST "srs")) {
-         value = (char*)xmlNodeGetContent(cur_node);
-         tileset->srs = value;
-      } else if(!xmlStrcmp(cur_node->name, BAD_CAST "size")) {
-         value = (char*)xmlNodeGetContent(cur_node);
-         int *sizes, nsizes;
-         if(GEOCACHE_SUCCESS != geocache_util_extract_int_list(ctx, value, ' ', &sizes, &nsizes) ||
-               nsizes != 2) {
-            ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "failed to parse size array %s."
-                  "(expecting two space separated integers, eg <size>256 256</size>",
-                  value);
-            return;
-         }
-         tileset->tile_sx = sizes[0];
-         tileset->tile_sy = sizes[1];
-         xmlFree(value);
-      } else if(!xmlStrcmp(cur_node->name, BAD_CAST "extent")) {
-         value = (char*)xmlNodeGetContent(cur_node);
-         int nvalues;
-         double *values;
-         if(GEOCACHE_SUCCESS != geocache_util_extract_double_list(ctx, value, ' ', &values, &nvalues) ||
-               nvalues != 4) {
-            ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "failed to parse extent array %s."
-                  "(expecting 4 space separated numbers, got %d (%f %f %f %f)"
-                  "eg <extent>-180 -90 180 90</extent>",
-                  value,nvalues,values[0],values[1],values[2],values[3]);
-            return;
-         }
-         tileset->extent[0] = values[0];
-         tileset->extent[1] = values[1];
-         tileset->extent[2] = values[2];
-         tileset->extent[3] = values[3];
-         xmlFree(value);
-      } else if(!xmlStrcmp(cur_node->name, BAD_CAST "resolutions")) {
-         value = (char*)xmlNodeGetContent(cur_node);
-         int nvalues;
-         double *values;
-         if(GEOCACHE_SUCCESS != geocache_util_extract_double_list(ctx, value, ' ', &values, &nvalues) ||
-               !nvalues) {
-            ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "failed to parse resolutions array %s."
-                  "(expecting space separated numbers, "
-                  "eg <resolutions>1 2 4 8 16 32</resolutions>",
-                  value);
-            return;
-         }
-         tileset->resolutions = values;
-         tileset->levels = nvalues;
-         xmlFree(value);
       } else if(!xmlStrcmp(cur_node->name, BAD_CAST "metatile")) {
          value = (char*)xmlNodeGetContent(cur_node);
          int *values, nvalues;
@@ -424,6 +583,10 @@
          }
          tileset->format = format;
          xmlFree(value);
+      } else {
+         ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "tileset \"%s\" contains unknown tag \"%s\","
+               " but it is not configured",name,cur_node->name);
+         return;
       }
    }
    /* check we have all we want */
@@ -438,22 +601,13 @@
             " You must add a <source> tag.", tileset->name);
       return;
    }
-   if(tileset->srs == NULL) {
-      ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "tileset \"%s\" has no srs configured."
-            " You must add a <srs> tag.", tileset->name);
+
+   if(tileset->grid == NULL) {
+      ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "tileset \"%s\" has no grid configured."
+            " You must add a <grid> tag.", tileset->name);
       return;
    }
-   if(tileset->extent[0] == tileset->extent[2] ||
-         tileset->extent[1] == tileset->extent[3]) {
-      ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "tileset \"%s\" has no (or invalid) extent configured"
-            " You must add/correct a <extent> tag.", tileset->name);
-      return;
-   }
-   if(!tileset->levels) {
-      ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "tileset \"%s\" has no resolutions configured."
-            " You must add a <resolutions> tag.", tileset->name);
-      return;
-   }
+
    if(!tileset->format && (
          tileset->metasize_x != 1 ||
          tileset->metasize_y != 1 ||
@@ -489,14 +643,14 @@
          } else if(!xmlStrcmp(cur_node->name, BAD_CAST "cache")) {
             parseCache(ctx, cur_node, config);
             GC_CHECK_ERROR(ctx);
-         } 
-         else if(!xmlStrcmp(cur_node->name, BAD_CAST "format")) {
+         } else if(!xmlStrcmp(cur_node->name, BAD_CAST "format")) {
             parseFormat(ctx, cur_node, config);
             GC_CHECK_ERROR(ctx);
-         }
-         else if(!xmlStrcmp(cur_node->name, BAD_CAST "tileset")) {
-            parseTileset(ctx, cur_node, config);
+         } else if(!xmlStrcmp(cur_node->name, BAD_CAST "grid")) {
+            parseGrid(ctx, cur_node, config);
             GC_CHECK_ERROR(ctx);
+         } else if(!xmlStrcmp(cur_node->name, BAD_CAST "tileset")) {
+            continue; //we'll parse it in a second loop
          }  else if(!xmlStrcmp(cur_node->name, BAD_CAST "services")) {
             xmlNode *service_node;
             for(service_node = cur_node->children; service_node; service_node = service_node->next) {
@@ -536,6 +690,14 @@
          }
 
       }
+      /* second loop to parse the tilesets */
+      for(cur_node = children; cur_node; cur_node = cur_node->next) {
+         if(cur_node->type != XML_ELEMENT_NODE) continue;
+         else if(!xmlStrcmp(cur_node->name, BAD_CAST "tileset")) {
+            parseTileset(ctx,cur_node,config);
+            GC_CHECK_ERROR(ctx);
+         }
+      }
 
    } else {
       ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, 

Modified: trunk/mapserver/mapcache/src/geocache_seed.c
===================================================================
--- trunk/mapserver/mapcache/src/geocache_seed.c	2011-08-26 11:05:43 UTC (rev 12191)
+++ trunk/mapserver/mapcache/src/geocache_seed.c	2011-08-26 11:05:49 UTC (rev 12192)
@@ -271,22 +271,22 @@
         if(!zooms) {
             zooms = (int*)apr_pcalloc(gctx->pool,2*sizeof(int));
             zooms[0] = 1;
-            zooms[1] = tileset->levels;
+            zooms[1] = tileset->grid->levels;
         }
         if(!extent) {
             extent = (double*)apr_pcalloc(gctx->pool,4*sizeof(double));
-            extent[0] = tileset->extent[0];
-            extent[1] = tileset->extent[1];
-            extent[2] = tileset->extent[2];
-            extent[3] = tileset->extent[3];
+            extent[0] = tileset->grid->extents[0][0];
+            extent[1] = tileset->grid->extents[0][1];
+            extent[2] = tileset->grid->extents[0][2];
+            extent[3] = tileset->grid->extents[0][3];
         }
     }
 
     geocache_context_seeding_init(&ctx,cfg,tileset,zooms[0],zooms[1],extent);
     for(n=zooms[0];n<=zooms[1];n++) {
-        geocache_tileset_get_xy(gctx,tileset,tileset->extent[0],tileset->extent[1],
+        geocache_tileset_get_xy(gctx,tileset,tileset->grid->extents[n][0],tileset->grid->extents[n][1],
                 n,&seed_tiles[n].firstx,&seed_tiles[n].firsty);
-        geocache_tileset_get_xy(gctx,tileset,tileset->extent[2],tileset->extent[3],
+        geocache_tileset_get_xy(gctx,tileset,tileset->grid->extents[n][2],tileset->grid->extents[n][3],
                 n,&seed_tiles[n].lastx,&seed_tiles[n].lasty);
     }
     ctx.nextz = zooms[0];

Modified: trunk/mapserver/mapcache/src/image.c
===================================================================
--- trunk/mapserver/mapcache/src/image.c	2011-08-26 11:05:43 UTC (rev 12191)
+++ trunk/mapserver/mapcache/src/image.c	2011-08-26 11:05:49 UTC (rev 12192)
@@ -96,8 +96,8 @@
       geocache_image *metatile;
       int i,j;
       int sx,sy;
-      tileimg.w = mt->tile.tileset->tile_sx;
-      tileimg.h = mt->tile.tileset->tile_sy;
+      tileimg.w = mt->tile.tileset->grid->tile_sx;
+      tileimg.h = mt->tile.tileset->grid->tile_sy;
       metatile = geocache_imageio_decode(ctx, mt->tile.data);
       if(!metatile) {
          ctx->set_error(ctx, GEOCACHE_IMAGE_ERROR, "failed to load image data from metatile");

Modified: trunk/mapserver/mapcache/src/source_wms.c
===================================================================
--- trunk/mapserver/mapcache/src/source_wms.c	2011-08-26 11:05:43 UTC (rev 12191)
+++ trunk/mapserver/mapcache/src/source_wms.c	2011-08-26 11:05:49 UTC (rev 12192)
@@ -31,7 +31,7 @@
    apr_table_setn(params,"WIDTH",apr_psprintf(ctx->pool,"%d",tile->tile.sx));
    apr_table_setn(params,"HEIGHT",apr_psprintf(ctx->pool,"%d",tile->tile.sy));
    apr_table_setn(params,"FORMAT","image/png");
-   apr_table_setn(params,"SRS",tile->tile.tileset->srs);
+   apr_table_setn(params,"SRS",tile->tile.tileset->grid->srs);
    
    apr_table_overlap(params,wms->wms_params,0);
         

Modified: trunk/mapserver/mapcache/src/tileset.c
===================================================================
--- trunk/mapserver/mapcache/src/tileset.c	2011-08-26 11:05:43 UTC (rev 12191)
+++ trunk/mapserver/mapcache/src/tileset.c	2011-08-26 11:05:49 UTC (rev 12192)
@@ -19,17 +19,17 @@
 #include <math.h>
 
 static double _geocache_tileset_get_resolution(geocache_tileset *tileset, double *bbox) {
-   double rx = (bbox[2] - bbox[0]) / (double)tileset->tile_sx;
-   double ry = (bbox[3] - bbox[1]) / (double)tileset->tile_sy;
+   double rx = (bbox[2] - bbox[0]) / (double)tileset->grid->tile_sx;
+   double ry = (bbox[3] - bbox[1]) / (double)tileset->grid->tile_sy;
    return GEOCACHE_MAX(rx,ry);
 }
 
 void geocache_tileset_get_level(geocache_context *ctx, geocache_tileset *tileset, double *resolution, int *level) {
-   double max_diff = *resolution / (double)GEOCACHE_MAX(tileset->tile_sx, tileset->tile_sy);
+   double max_diff = *resolution / (double)GEOCACHE_MAX(tileset->grid->tile_sx, tileset->grid->tile_sy);
    int i;
-   for(i=0; i<tileset->levels; i++) {
-      if(fabs(tileset->resolutions[i] - *resolution) < max_diff) {
-         *resolution = tileset->resolutions[i];
+   for(i=0; i<tileset->grid->levels; i++) {
+      if(fabs(tileset->grid->resolutions[i] - *resolution) < max_diff) {
+         *resolution = tileset->grid->resolutions[i];
          *level = i;
          return;
       }
@@ -52,20 +52,20 @@
                         % (minx, miny, self.bbox))
                return None
     */
-   tile->x = (int)round((bbox[0] - tile->tileset->extent[0]) / (res * tile->tileset->tile_sx));
-   tile->y = (int)round((bbox[1] - tile->tileset->extent[1]) / (res * tile->tileset->tile_sy));
+   tile->x = (int)round((bbox[0] - tile->tileset->grid->extents[tile->z][0]) / (res * tile->tileset->grid->tile_sx));
+   tile->y = (int)round((bbox[1] - tile->tileset->grid->extents[tile->z][1]) / (res * tile->tileset->grid->tile_sy));
 
-   if((fabs(bbox[0] - (tile->x * res * tile->tileset->tile_sx) - tile->tileset->extent[0] ) / res > 1) ||
-         (fabs(bbox[1] - (tile->y * res * tile->tileset->tile_sy) - tile->tileset->extent[1] ) / res > 1)) {
+   if((fabs(bbox[0] - (tile->x * res * tile->tileset->grid->tile_sx) - tile->tileset->grid->extents[tile->z][0] ) / res > 1) ||
+         (fabs(bbox[1] - (tile->y * res * tile->tileset->grid->tile_sy) - tile->tileset->grid->extents[tile->z][1] ) / res > 1)) {
       ctx->set_error(ctx, GEOCACHE_TILESET_ERROR, "tileset %s: supplied bbox not aligned on configured grid",tile->tileset->name);
    }
 }
 
 void geocache_tileset_get_xy(geocache_context *ctx, geocache_tileset *tileset, double dx, double dy,
         int z, int *x, int *y) {
-    double res = tileset->resolutions[z];
-    *x = (int)((dx - tileset->extent[0]) / (res * tileset->tile_sx));
-    *y = (int)((dy - tileset->extent[1]) / (res * tileset->tile_sy));
+    double res = tileset->grid->resolutions[z];
+    *x = (int)((dx - tileset->grid->extents[z][0]) / (res * tileset->grid->tile_sx));
+    *y = (int)((dy - tileset->grid->extents[z][1]) / (res * tileset->grid->tile_sy));
 }
 
 /*
@@ -104,7 +104,7 @@
 static geocache_metatile* _geocache_tileset_metatile_get(geocache_context *ctx, geocache_tile *tile) {
    geocache_metatile *mt = (geocache_metatile*)apr_pcalloc(ctx->pool, sizeof(geocache_metatile));
    int i,j,blx,bly;
-   double res = tile->tileset->resolutions[tile->z];
+   double res = tile->tileset->grid->resolutions[tile->z];
    double gbuffer,gwidth,gheight;
    mt->tile.tileset = tile->tileset;
    mt->ntiles = mt->tile.tileset->metasize_x * mt->tile.tileset->metasize_y;
@@ -123,8 +123,8 @@
    gbuffer = res * mt->tile.tileset->metabuffer;
    gwidth = res * mt->tile.tileset->metasize_x * tile->sx;
    gheight = res * mt->tile.tileset->metasize_y * tile->sy;
-   mt->bbox[0] = mt->tile.tileset->extent[0] + mt->tile.x * gwidth - gbuffer;
-   mt->bbox[1] = mt->tile.tileset->extent[1] + mt->tile.y * gheight - gbuffer;
+   mt->bbox[0] = mt->tile.tileset->grid->extents[tile->z][0] + mt->tile.x * gwidth - gbuffer;
+   mt->bbox[1] = mt->tile.tileset->grid->extents[tile->z][1] + mt->tile.y * gheight - gbuffer;
    mt->bbox[2] = mt->bbox[0] + gwidth + 2 * gbuffer;
    mt->bbox[3] = mt->bbox[1] + gheight + 2 * gbuffer;
 
@@ -168,11 +168,11 @@
  * compute the bounding box of a given tile
  */
 void geocache_tileset_tile_bbox(geocache_tile *tile, double *bbox) {
-   double res  = tile->tileset->resolutions[tile->z];
-   bbox[0] = tile->tileset->extent[0] + (res * tile->x * tile->sx);
-   bbox[1] = tile->tileset->extent[1] + (res * tile->y * tile->sy);
-   bbox[2] = tile->tileset->extent[0] + (res * (tile->x + 1) * tile->sx);
-   bbox[3] = tile->tileset->extent[1] + (res * (tile->y + 1) * tile->sy);
+   double res  = tile->tileset->grid->resolutions[tile->z];
+   bbox[0] = tile->tileset->grid->extents[tile->z][0] + (res * tile->x * tile->sx);
+   bbox[1] = tile->tileset->grid->extents[tile->z][1] + (res * tile->y * tile->sy);
+   bbox[2] = tile->tileset->grid->extents[tile->z][0] + (res * (tile->x + 1) * tile->sx);
+   bbox[3] = tile->tileset->grid->extents[tile->z][1] + (res * (tile->y + 1) * tile->sy);
 }
 
 /*
@@ -182,12 +182,10 @@
    geocache_tileset* tileset = (geocache_tileset*)apr_pcalloc(ctx->pool, sizeof(geocache_tileset));
    tileset->metasize_x = tileset->metasize_y = 1;
    tileset->metabuffer = 0;
-   tileset->units = GEOCACHE_UNIT_UNSET;
    tileset->expires = 0;
-   tileset->tile_sx = tileset->tile_sy = 256;
-   tileset->extent[0]=tileset->extent[1]=tileset->extent[2]=tileset->extent[3]=0;
    tileset->forwarded_params = apr_table_make(ctx->pool,1);
    tileset->format = NULL;
+   tileset->grid = NULL;
    tileset->config = NULL;
    return tileset;
 }
@@ -199,16 +197,16 @@
    geocache_tile *tile = (geocache_tile*)apr_pcalloc(pool, sizeof(geocache_tile));
    tile->tileset = tileset;
    tile->expires = tileset->expires;
-   tile->sx = tileset->tile_sx;
-   tile->sy = tileset->tile_sy;
+   tile->sx = tileset->grid->tile_sx;
+   tile->sy = tileset->grid->tile_sy;
    return tile;
 }
 
 
 void geocache_tileset_tile_lookup(geocache_context *ctx, geocache_tile *tile, double *bbox) {
-   if(tile->sx != tile->tileset->tile_sx || tile->sy != tile->tileset->tile_sy) {
+   if(tile->sx != tile->tileset->grid->tile_sx || tile->sy != tile->tileset->grid->tile_sy) {
       ctx->set_error(ctx, GEOCACHE_TILESET_ERROR, "tileset %s: wrong size. found %dx%d instead of %dx%d",
-            tile->tileset->name,tile->sx,tile->sy,tile->tileset->tile_sx,tile->tileset->tile_sy);
+            tile->tileset->name,tile->sx,tile->sy,tile->tileset->grid->tile_sx,tile->tileset->grid->tile_sy);
       return;
    }
    _geocache_tileset_tile_get_cell(ctx, tile,bbox);
@@ -235,10 +233,10 @@
 void geocache_tileset_tile_get(geocache_context *ctx, geocache_tile *tile) {
    int isLocked,ret;
    geocache_metatile *mt=NULL;
-   if(tile->sx != tile->tileset->tile_sx || tile->sy != tile->tileset->tile_sy) {
+   if(tile->sx != tile->tileset->grid->tile_sx || tile->sy != tile->tileset->grid->tile_sy) {
       ctx->set_error(ctx, GEOCACHE_TILESET_ERROR, 
             "tileset %s: asked for a %dx%d tile from a %dx%d tileset",tile->tileset->name,
-            tile->sx, tile->sy, tile->tileset->tile_sx, tile->tileset->tile_sy);
+            tile->sx, tile->sy, tile->tileset->grid->tile_sx, tile->tileset->grid->tile_sy);
       return;
    }
    ret = tile->tileset->cache->tile_get(ctx, tile);
@@ -264,7 +262,6 @@
          mt = _geocache_tileset_metatile_get(ctx, tile);
          _geocache_tileset_metatile_lock(ctx, mt);
       }
-
       ctx->global_lock_release(ctx);
       if(GC_HAS_ERROR(ctx))
          return;



More information about the mapserver-commits mailing list