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

svn at osgeo.org svn at osgeo.org
Fri Aug 26 07:01:41 EDT 2011


Author: tbonfort
Date: 2011-08-26 04:01:41 -0700 (Fri, 26 Aug 2011)
New Revision: 12145

Modified:
   trunk/mapserver/mapcache/geocache.xml
   trunk/mapserver/mapcache/include/geocache.h
   trunk/mapserver/mapcache/src/cache_disk.c
   trunk/mapserver/mapcache/src/image.c
Log:
refactor code to move apache functions out of the main code. this is to 
prepare the code for building around fastcgi.
code is not very tested yet, users should be sticking woth the 0.1 release
thomas.bonfort | 2010-11-02 18:08:18 +0100 (Tue, 02 Nov 2010)

Modified: trunk/mapserver/mapcache/geocache.xml
===================================================================
--- trunk/mapserver/mapcache/geocache.xml	2011-08-26 11:01:36 UTC (rev 12144)
+++ trunk/mapserver/mapcache/geocache.xml	2011-08-26 11:01:41 UTC (rev 12145)
@@ -2,6 +2,7 @@
 <geocache>
     <cache name="disk" type="disk">
         <base>/tmp</base>
+        <symlink_blank/>
     </cache>
     <format name="PNGQ_FAST" type ="PNG">
         <compression>fast</compression>

Modified: trunk/mapserver/mapcache/include/geocache.h
===================================================================
--- trunk/mapserver/mapcache/include/geocache.h	2011-08-26 11:01:36 UTC (rev 12144)
+++ trunk/mapserver/mapcache/include/geocache.h	2011-08-26 11:01:41 UTC (rev 12145)
@@ -214,6 +214,7 @@
 struct geocache_cache_disk {
    geocache_cache cache;
    char *base_directory;
+   int symlink_blank;
 };
 
 /** @} */
@@ -241,7 +242,7 @@
 
 #define GEOCACHE_SERVICES_COUNT 3
 
-typedef enum {GEOCACHE_SERVICE_WMTS=0, GEOCACHE_SERVICE_TMS, GEOCACHE_SERVICE_WMS} geocache_service_type;
+typedef enum {GEOCACHE_SERVICE_WMS=0, GEOCACHE_SERVICE_TMS, GEOCACHE_SERVICE_WMTS} geocache_service_type;
 
 typedef enum {GEOCACHE_UNIT_UNSET = 0, GEOCACHE_UNIT_METERS, GEOCACHE_UNIT_DEGREES, GEOCACHE_UNIT_FEET} geocache_unit;
 
@@ -344,6 +345,13 @@
  */
 int geocache_image_metatile_split(geocache_metatile *mt, request_rec *r);
 
+/**
+ * \brief check if given image is composed of a unique color
+ * \param image the geocache_image to process
+ * \returns GEOCACHE_TRUE if the image contains a single color
+ * \returns GEOCACHE_FALSE if the image has more than one color
+ */
+int geocache_image_blank_color(geocache_image* image);
 /** @} */
 
 

Modified: trunk/mapserver/mapcache/src/cache_disk.c
===================================================================
--- trunk/mapserver/mapcache/src/cache_disk.c	2011-08-26 11:01:36 UTC (rev 12144)
+++ trunk/mapserver/mapcache/src/cache_disk.c	2011-08-26 11:01:41 UTC (rev 12145)
@@ -11,6 +11,19 @@
 #include <apr_file_io.h>
 #include <http_log.h>
 
+
+
+char *_geocache_cache_disk_blank_tile_key(request_rec *r, geocache_tile *tile, unsigned char *color) {
+   char *path = apr_psprintf(r->pool,"%s/%s/blanks/%02X%02X%02X%02X.%s",
+         ((geocache_cache_disk*)tile->tileset->cache)->base_directory,
+         tile->tileset->name,
+         color[0],
+         color[1],
+         color[2],
+         color[3],
+         tile->tileset->format?tile->tileset->format->extension:"png");
+   return path;
+}
 /**
  * \brief return filename for given tile
  * 
@@ -274,6 +287,44 @@
    }
 #endif
    _geocache_cache_disk_tile_key(r, tile, &filename);
+
+   if(((geocache_cache_disk*)tile->tileset->cache)->symlink_blank) {
+      geocache_image *image = geocache_imageio_decode(r, tile->data);
+      if(geocache_image_blank_color(image) != GEOCACHE_FALSE) {
+         char *blankname = _geocache_cache_disk_blank_tile_key(r,tile,image->data);
+         if(apr_file_open(&f, blankname, APR_FOPEN_READ, APR_OS_DEFAULT, r->pool) != APR_SUCCESS) {
+            /* create the blank file */
+            if(APR_SUCCESS != apr_dir_make_recursive(apr_psprintf(r->pool, "%s/%s/blanks",((geocache_cache_disk*)tile->tileset->cache)->base_directory,tile->tileset->name),APR_OS_DEFAULT,r->pool)) {
+               ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "failed to create directory for blank tiles");
+               return GEOCACHE_FAILURE;
+            }
+            if(apr_file_open(&f, blankname,
+                  APR_FOPEN_CREATE|APR_FOPEN_WRITE|APR_FOPEN_BUFFERED|APR_FOPEN_BINARY,
+                  APR_OS_DEFAULT, r->pool) != APR_SUCCESS) {
+               ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "failed to create file %s",blankname);
+               return GEOCACHE_FAILURE; /* we could not create the file */
+            }
+            
+            bytes = (apr_size_t)tile->data->size;
+            apr_file_write(f,(void*)tile->data->buf,&bytes);
+
+            if(bytes != tile->data->size) {
+               ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "failed to write image data to disk, wrote %d of %d bytes",(int)bytes, (int)tile->data->size);
+               return GEOCACHE_FAILURE;
+            }
+            apr_file_close(f);
+            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "created blank tile %s",blankname);
+         }
+         if(apr_file_link(blankname,filename) != GEOCACHE_SUCCESS) {
+            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "failed to link tile %s to %s",filename, blankname);
+            return GEOCACHE_FAILURE; /* we could not create the file */
+         }
+         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "linked blank tile %s to %s",filename,blankname);
+         return GEOCACHE_SUCCESS;
+      }
+   }
+   
+   /* go the normal way: either we haven't configured blank tile detection, or the tile was not blank */
    if(apr_file_open(&f, filename,
          APR_FOPEN_CREATE|APR_FOPEN_WRITE|APR_FOPEN_BUFFERED|APR_FOPEN_BINARY,
          APR_OS_DEFAULT, r->pool) != APR_SUCCESS) {
@@ -305,6 +356,12 @@
          xmlChar* value = xmlNodeGetContent(cur_node);
          dcache->base_directory = (char*)value;
       }
+      if(!xmlStrcmp(cur_node->name, BAD_CAST "symlink_blank")) {
+         xmlChar* value = xmlNodeGetContent(cur_node);
+         if(xmlStrcasecmp(value,BAD_CAST "false")) {
+            dcache->symlink_blank = 1;
+         }
+      }
    }
    return NULL;
 }
@@ -314,20 +371,25 @@
  */
 char* _geocache_cache_disk_configuration_check(geocache_cache *cache, apr_pool_t *pool) {
    apr_status_t status;
-   apr_dir_t *dir;
    geocache_cache_disk *dcache = (geocache_cache_disk*)cache;
    /* check all required parameters are configured */
    if(!dcache->base_directory || !strlen(dcache->base_directory)) {
       return apr_psprintf(pool,"disk cache %s has no base directory",dcache->cache.name);
    }
-
-   status = apr_dir_open(&dir, dcache->base_directory, pool);
+   
+   /*create our directory for blank images*/
+   status = apr_dir_make_recursive(dcache->base_directory,APR_OS_DEFAULT,pool);
    if(status != APR_SUCCESS) {
-      return apr_psprintf(pool, "failed to access directory %s for cache %s",
-            dcache->base_directory, dcache->cache.name);
+      return apr_psprintf(pool, "failed to create directory %s for cache %s",dcache->base_directory,dcache->cache.name );
    }
-   /* TODO: more checks on directory readability/writability */
-   apr_dir_close(dir);
+   
+   /*win32 isn't buildable yet, but put this check in now for reminders*/
+#ifdef _WIN32
+   if(dcache->symlink_blank) {
+      return apr_psprintf(pool, "linking blank tiles isn't supported on WIN32 due to platform limitations");
+   }
+#endif
+
    return NULL;
 }
 
@@ -336,6 +398,7 @@
  */
 geocache_cache* geocache_cache_disk_create(apr_pool_t *pool) {
    geocache_cache_disk *cache = apr_pcalloc(pool,sizeof(geocache_cache_disk));
+   cache->symlink_blank = 0;
    cache->cache.type = GEOCACHE_CACHE_DISK;
    cache->cache.tile_get = _geocache_cache_disk_get;
    cache->cache.tile_set = _geocache_cache_disk_set;

Modified: trunk/mapserver/mapcache/src/image.c
===================================================================
--- trunk/mapserver/mapcache/src/image.c	2011-08-26 11:01:36 UTC (rev 12144)
+++ trunk/mapserver/mapcache/src/image.c	2011-08-26 11:01:41 UTC (rev 12145)
@@ -96,6 +96,10 @@
       tileimg.w = mt->tile.tileset->tile_sx;
       tileimg.h = mt->tile.tileset->tile_sy;
       metatile = geocache_imageio_decode(r, mt->tile.data);
+      if(!metatile) {
+         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "failed to load image data from metatile");
+         return GEOCACHE_FAILURE;
+      }
       tileimg.stride = metatile->stride;
       if(!metatile) return GEOCACHE_FAILURE;
       for(i=0;i<mt->tile.tileset->metasize_x;i++) {
@@ -120,3 +124,17 @@
    return GEOCACHE_SUCCESS;
 }
 
+int geocache_image_blank_color(geocache_image* image) {
+   int* pixptr;
+   int r,c;
+   for(r=0;r<image->h;r++) {
+      pixptr = (int*)(image->data + r * image->stride);
+      for(c=0;c<image->w;c++) {
+         if(*(pixptr++) != *((int*)image->data)) {
+            return GEOCACHE_FALSE;
+         }
+      }
+   }
+   return GEOCACHE_TRUE;
+}
+



More information about the mapserver-commits mailing list