[mapserver-commits] r13271 - in trunk/mapserver/mapcache: include lib

svn at osgeo.org svn at osgeo.org
Fri Mar 16 10:22:43 EDT 2012


Author: tbonfort
Date: 2012-03-16 07:22:43 -0700 (Fri, 16 Mar 2012)
New Revision: 13271

Modified:
   trunk/mapserver/mapcache/include/mapcache.h
   trunk/mapserver/mapcache/lib/cache_disk.c
Log:
add arcgis disk cache layout (#4248)


Modified: trunk/mapserver/mapcache/include/mapcache.h
===================================================================
--- trunk/mapserver/mapcache/include/mapcache.h	2012-03-16 13:03:53 UTC (rev 13270)
+++ trunk/mapserver/mapcache/include/mapcache.h	2012-03-16 14:22:43 UTC (rev 13271)
@@ -385,6 +385,12 @@
     char *filename_template;
     int symlink_blank;
     int creation_retry;
+
+    /**
+     * Set filename for a given tile
+     * \memberof mapcache_cache_disk
+     */
+    void (*tile_key)(mapcache_context *ctx, mapcache_tile *tile, char **path);
 };
 
 #ifdef USE_TIFF

Modified: trunk/mapserver/mapcache/lib/cache_disk.c
===================================================================
--- trunk/mapserver/mapcache/lib/cache_disk.c	2012-03-16 13:03:53 UTC (rev 13270)
+++ trunk/mapserver/mapcache/lib/cache_disk.c	2012-03-16 14:22:43 UTC (rev 13271)
@@ -39,6 +39,30 @@
 #include <unistd.h>
 #endif
 
+/**
+ * \brief returns base path for given tile
+ * 
+ * \param tile the tile to get base path from
+ * \param path pointer to a char* that will contain the filename
+ * \private \memberof mapcache_cache_disk
+ */
+static void _mapcache_cache_disk_base_tile_key(mapcache_context *ctx, mapcache_tile *tile, char **path) {
+  *path = apr_pstrcat(ctx->pool,
+        ((mapcache_cache_disk*)tile->tileset->cache)->base_directory,"/",
+        tile->tileset->name,"/",
+        tile->grid_link->grid->name,
+        NULL);
+  if(tile->dimensions) {
+    const apr_array_header_t *elts = apr_table_elts(tile->dimensions);
+    int i = elts->nelts;
+    while(i--) {
+      apr_table_entry_t *entry = &(APR_ARRAY_IDX(elts,i,apr_table_entry_t));
+      const char *dimval = mapcache_util_str_sanitize(ctx->pool,entry->val,"/.",'#');
+      *path = apr_pstrcat(ctx->pool,*path,"/",dimval,NULL);
+    }
+  }
+}
+
 static void _mapcache_cache_disk_blank_tile_key(mapcache_context *ctx, mapcache_tile *tile, unsigned char *color, char **path) {
    /* not implemented for template caches, as symlink_blank will never be set */
    *path = apr_psprintf(ctx->pool,"%s/%s/%s/blanks/%02X%02X%02X%02X.%s",
@@ -63,24 +87,11 @@
  * \param r 
  * \private \memberof mapcache_cache_disk
  */
-static void _mapcache_cache_disk_tile_key(mapcache_context *ctx, mapcache_tile *tile, char **path) {
+static void _mapcache_cache_disk_tilecache_tile_key(mapcache_context *ctx, mapcache_tile *tile, char **path) {
    mapcache_cache_disk *dcache = (mapcache_cache_disk*)tile->tileset->cache;
    if(dcache->base_directory) {
       char *start;
-      start = apr_pstrcat(ctx->pool,
-            dcache->base_directory,"/",
-            tile->tileset->name,"/",
-            tile->grid_link->grid->name,
-            NULL);
-      if(tile->dimensions) {
-         const apr_array_header_t *elts = apr_table_elts(tile->dimensions);
-         int i = elts->nelts;
-         while(i--) {
-            apr_table_entry_t *entry = &(APR_ARRAY_IDX(elts,i,apr_table_entry_t));
-            const char *dimval = mapcache_util_str_sanitize(ctx->pool,entry->val,"/.",'#');
-            start = apr_pstrcat(ctx->pool,start,"/",dimval,NULL);
-         }
-      }
+      _mapcache_cache_disk_base_tile_key(ctx, tile, &start);
       *path = apr_psprintf(ctx->pool,"%s/%02d/%03d/%03d/%03d/%03d/%03d/%03d.%s",
             start,
             tile->z,
@@ -143,11 +154,85 @@
    }
 }
 
+static void _mapcache_cache_disk_template_tile_key(mapcache_context *ctx, mapcache_tile *tile, char **path) {
+   mapcache_cache_disk *dcache = (mapcache_cache_disk*)tile->tileset->cache;
+
+   *path = dcache->filename_template;
+   *path = mapcache_util_str_replace(ctx->pool,*path, "{tileset}", tile->tileset->name);
+   *path = mapcache_util_str_replace(ctx->pool,*path, "{grid}", tile->grid_link->grid->name);
+   *path = mapcache_util_str_replace(ctx->pool,*path, "{ext}",
+         tile->tileset->format?tile->tileset->format->extension:"png");
+
+   if(strstr(*path,"{x}"))
+     *path = mapcache_util_str_replace(ctx->pool,*path, "{x}",
+           apr_psprintf(ctx->pool,"%d",tile->x));
+   else
+     *path = mapcache_util_str_replace(ctx->pool,*path, "{inv_x}",
+           apr_psprintf(ctx->pool,"%d",
+              tile->grid_link->grid->levels[tile->z]->maxx - tile->x - 1));
+   if(strstr(*path,"{y}"))
+     *path = mapcache_util_str_replace(ctx->pool,*path, "{y}",
+           apr_psprintf(ctx->pool,"%d",tile->y));
+   else
+     *path = mapcache_util_str_replace(ctx->pool,*path, "{inv_y}",
+           apr_psprintf(ctx->pool,"%d",
+              tile->grid_link->grid->levels[tile->z]->maxy - tile->y - 1));
+   if(strstr(*path,"{z}"))
+     *path = mapcache_util_str_replace(ctx->pool,*path, "{z}",
+           apr_psprintf(ctx->pool,"%d",tile->z));
+   else
+     *path = mapcache_util_str_replace(ctx->pool,*path, "{inv_z}",
+           apr_psprintf(ctx->pool,"%d",
+              tile->grid_link->grid->nlevels - tile->z - 1));
+   if(tile->dimensions) {
+     char *dimstring="";
+     const apr_array_header_t *elts = apr_table_elts(tile->dimensions);
+     int i = elts->nelts;
+     while(i--) {
+       apr_table_entry_t *entry = &(APR_ARRAY_IDX(elts,i,apr_table_entry_t));
+       char *dimval = apr_pstrdup(ctx->pool,entry->val);
+       char *iter = dimval;
+       while(*iter) {
+         /* replace dangerous characters by '#' */
+         if(*iter == '.' || *iter == '/') {
+           *iter = '#';
+         }
+         iter++;
+       }
+       dimstring = apr_pstrcat(ctx->pool,dimstring,"#",entry->key,"#",dimval,NULL);
+     }
+     *path = mapcache_util_str_replace(ctx->pool,*path, "{dim}", dimstring);
+   }
+   
+   if(!*path) {
+      ctx->set_error(ctx,500, "failed to allocate tile key");
+   }
+}
+
+static void _mapcache_cache_disk_arcgis_tile_key(mapcache_context *ctx, mapcache_tile *tile, char **path) {
+   mapcache_cache_disk *dcache = (mapcache_cache_disk*)tile->tileset->cache;
+   if(dcache->base_directory) {
+      char *start;
+      _mapcache_cache_disk_base_tile_key(ctx, tile, &start);
+      *path = apr_psprintf(ctx->pool,"%s/L%02d/R%08x/C%08x.%s" ,
+            start,
+            tile->z,
+            tile->y,
+            tile->x,
+            tile->tileset->format?tile->tileset->format->extension:"png");
+   }
+   
+   if(!*path) {
+      ctx->set_error(ctx,500, "failed to allocate tile key");
+   }
+}
+
+
 static int _mapcache_cache_disk_has_tile(mapcache_context *ctx, mapcache_tile *tile) {
    char *filename;
    apr_finfo_t finfo;
    int rv;
-   _mapcache_cache_disk_tile_key(ctx, tile, &filename);
+   ((mapcache_cache_disk*)tile->tileset->cache)->tile_key(ctx, tile, &filename);
    if(GC_HAS_ERROR(ctx)) {
       return MAPCACHE_FALSE;
    }
@@ -163,7 +248,7 @@
    apr_status_t ret;
    char errmsg[120];
    char *filename;
-   _mapcache_cache_disk_tile_key(ctx, tile, &filename);
+   ((mapcache_cache_disk*)tile->tileset->cache)->tile_key(ctx, tile, &filename);
    GC_CHECK_ERROR(ctx);
 
    ret = apr_file_remove(filename,ctx->pool);
@@ -188,7 +273,7 @@
    apr_size_t size;
    apr_mmap_t *tilemmap;
      
-   _mapcache_cache_disk_tile_key(ctx, tile, &filename);
+   ((mapcache_cache_disk*)tile->tileset->cache)->tile_key(ctx, tile, &filename);
    if(GC_HAS_ERROR(ctx)) {
       return MAPCACHE_FAILURE;
    }
@@ -280,7 +365,7 @@
    }
 #endif
 
-   _mapcache_cache_disk_tile_key(ctx, tile, &filename);
+   ((mapcache_cache_disk*)tile->tileset->cache)->tile_key(ctx, tile, &filename);
    GC_CHECK_ERROR(ctx);
 
    /* find the location of the last '/' in the string */
@@ -467,24 +552,42 @@
 static void _mapcache_cache_disk_configuration_parse_xml(mapcache_context *ctx, ezxml_t node, mapcache_cache *cache, mapcache_cfg *config) {
    ezxml_t cur_node;
    mapcache_cache_disk *dcache = (mapcache_cache_disk*)cache;
+   char *layout = NULL;
+   int template_layout = MAPCACHE_FALSE;
+   
+   layout = (char*)ezxml_attr(node,"layout");
+   if (!layout || !strlen(layout) || !strcmp(layout,"tilecache")) {
+     dcache->tile_key = _mapcache_cache_disk_tilecache_tile_key;
+   } else if(!strcmp(layout,"arcgis")) {
+       dcache->tile_key = _mapcache_cache_disk_arcgis_tile_key;
+   } else if (!strcmp(layout,"template")) {
+       dcache->tile_key = _mapcache_cache_disk_template_tile_key;
+       template_layout = MAPCACHE_TRUE;
+       if ((cur_node = ezxml_child(node,"template")) != NULL) {
+         dcache->filename_template = apr_pstrdup(ctx->pool,cur_node->txt);
+       } else {
+         ctx->set_error(ctx, 400, "no template specified for cache \"%s\"", cache->name);
+         return;
+       }
+   }
+   else {
+     ctx->set_error(ctx, 400, "unknown layout type %s for cache \"%s\"", layout, cache->name);
+     return;
+   }
 
-   if ((cur_node = ezxml_child(node,"base")) != NULL) {
+   if (!template_layout && (cur_node = ezxml_child(node,"base")) != NULL) {
       dcache->base_directory = apr_pstrdup(ctx->pool,cur_node->txt);
-      /* we don't check for symlinking in the case where we are using a "template" cache type */
-      if ((cur_node = ezxml_child(node,"symlink_blank")) != NULL) {
-         if(strcasecmp(cur_node->txt,"false")){
+   }
+
+   if (!template_layout && (cur_node = ezxml_child(node,"symlink_blank")) != NULL) {
+     if(strcasecmp(cur_node->txt,"false")){
 #ifdef HAVE_SYMLINK
-            dcache->symlink_blank = 1;
+       dcache->symlink_blank = 1;
 #else
-            ctx->set_error(ctx,400,"cache %s: host system does not support file symbolic linking",cache->name);
-            return;
+       ctx->set_error(ctx,400,"cache %s: host system does not support file symbolic linking",cache->name);
+       return;
 #endif
-         }
-      }
-   } else {
-      if ((cur_node = ezxml_child(node,"template")) != NULL) {
-         dcache->filename_template = apr_pstrdup(ctx->pool,cur_node->txt);
-      }
+     }
    }
 
    if ((cur_node = ezxml_child(node,"creation_retry")) != NULL) {



More information about the mapserver-commits mailing list