Skip to content
Permalink
Browse files

Basic source=wms, cache=disk support for blob format...

  • Loading branch information...
sdlime committed Apr 6, 2017
1 parent 5f44ad3 commit 761022e8ea41bf032780ae659888aba675108299
Showing with 136 additions and 25 deletions.
  1. +8 −2 include/mapcache.h
  2. +9 −3 lib/cache_disk.c
  3. +6 −1 lib/configuration_xml.c
  4. +18 −11 lib/core.c
  5. +12 −0 lib/image.c
  6. +0 −3 lib/imageio.c
  7. +55 −0 lib/imageio_blob.c
  8. +2 −3 lib/source.c
  9. +6 −1 lib/source_wms.c
  10. +20 −1 lib/tileset.c
@@ -78,6 +78,7 @@ typedef struct mapcache_image_format_mixed mapcache_image_format_mixed;
typedef struct mapcache_image_format_png mapcache_image_format_png;
typedef struct mapcache_image_format_png_q mapcache_image_format_png_q;
typedef struct mapcache_image_format_jpeg mapcache_image_format_jpeg;
typedef struct mapcache_image_format_blob mapcache_image_format_blob;
typedef struct mapcache_cfg mapcache_cfg;
typedef struct mapcache_tileset mapcache_tileset;
typedef struct mapcache_cache mapcache_cache;
@@ -662,7 +663,7 @@ MS_DLL_EXPORT int mapcache_config_services_enabled(mapcache_context *ctx, mapcac
/** @{ */

typedef enum {
GC_UNKNOWN, GC_PNG, GC_JPEG
GC_UNKNOWN, GC_PNG, GC_JPEG, GC_BLOB
} mapcache_image_format_type;

typedef enum {
@@ -1400,10 +1401,15 @@ struct mapcache_image_format_mixed {

mapcache_buffer* mapcache_empty_png_decode(mapcache_context *ctx, int width, int height, const unsigned char *hex_color, int *is_empty);


mapcache_image_format* mapcache_imageio_create_mixed_format(apr_pool_t *pool,
char *name, mapcache_image_format *transparent, mapcache_image_format *opaque, unsigned int alpha_cutoff);

struct mapcache_image_format_blob {
mapcache_image_format format;
};

mapcache_image_format* mapcache_imageio_create_blob_format(apr_pool_t *pool, char *name, char *extension, char *mime_type);

/**\class mapcache_image_format_png_q
* \brief Quantized PNG format
* \extends mapcache_image_format_png
@@ -492,6 +492,8 @@ static void _mapcache_cache_disk_set(mapcache_context *ctx, mapcache_cache *pcac
const int creation_retry = cache->creation_retry;
int retry_count_create_file = 0;

ctx->log(ctx, MAPCACHE_DEBUG, "SDL: in mapcache_cache_disk_set(): format=%d...", tile->tileset->format->type);

#ifdef DEBUG
/* all this should be checked at a higher level */
if(!tile->encoded_data && !tile->raw_image) {
@@ -515,14 +517,16 @@ static void _mapcache_cache_disk_set(mapcache_context *ctx, mapcache_cache *pcac
ctx->set_error(ctx, 500, "failed to remove file %s: %s",filename, apr_strerror(ret,errmsg,120));
}

ctx->log(ctx, MAPCACHE_DEBUG, "SDL: filename=%s...", filename);
ctx->log(ctx, MAPCACHE_DEBUG, "SDL: tile size=%d bytes...", tile->encoded_data->size);

#ifdef HAVE_SYMLINK
if(cache->symlink_blank) {
if(!tile->raw_image) {
if(tile->tileset->format->type != GC_BLOB && !tile->raw_image) {
tile->raw_image = mapcache_imageio_decode(ctx, tile->encoded_data);
GC_CHECK_ERROR(ctx);
}
if(mapcache_image_blank_color(tile->raw_image) != MAPCACHE_FALSE) {
if(tile->tileset->format->type != GC_BLOB && mapcache_image_blank_color(tile->raw_image) != MAPCACHE_FALSE) {
char *blankname;
int retry_count_create_symlink = 0;
char *blankname_rel = NULL;
@@ -603,10 +607,12 @@ static void _mapcache_cache_disk_set(mapcache_context *ctx, mapcache_cache *pcac
return;
}
}
#endif /*HAVE_SYMLINK*/
#endif /* HAVE_SYMLINK */

/* go the normal way: either we haven't configured blank tile detection, or the tile was not blank */

ctx->log(ctx, MAPCACHE_DEBUG, "SDL: normal way");

if(!tile->encoded_data) {
tile->encoded_data = tile->tileset->format->write(ctx, tile->raw_image, tile->tileset->format);
GC_CHECK_ERROR(ctx);
@@ -480,6 +480,12 @@ void parseFormat(mapcache_context *ctx, ezxml_t node, mapcache_cfg *config)
alpha_cutoff = atoi(cur_node->txt);
}
format = mapcache_imageio_create_mixed_format(ctx->pool,name,transparent, opaque, alpha_cutoff);
} else if(!strcasecmp(type,"BLOB")) {
char *extension=NULL;
char *mime_type=NULL;
if ((cur_node = ezxml_child(node,"extension")) != NULL) extension = apr_pstrdup(ctx->pool, cur_node->txt);
if ((cur_node = ezxml_child(node,"mime_type")) != NULL) mime_type = apr_pstrdup(ctx->pool, cur_node->txt);
format = mapcache_imageio_create_blob_format(ctx->pool,name,extension,mime_type);
} else {
ctx->set_error(ctx, 400, "unknown format type %s for format \"%s\"", type, name);
return;
@@ -489,7 +495,6 @@ void parseFormat(mapcache_context *ctx, ezxml_t node, mapcache_cfg *config)
return;
}


mapcache_configuration_add_image_format(config,format,name);
return;
}
@@ -77,13 +77,13 @@ mapcache_http_response *mapcache_http_response_create(apr_pool_t *pool)

void mapcache_prefetch_tiles(mapcache_context *ctx, mapcache_tile **tiles, int ntiles)
{

apr_thread_t **threads;
apr_threadattr_t *thread_attrs;
int nthreads;
#if !APR_HAS_THREADS
int i;
for(i=0; i<ntiles; i++) {
ctx->log(ctx, MAPCACHE_DEBUG, "SDL: calling mapcache_tileset_tile_get(1)...");
mapcache_tileset_tile_get(ctx, tiles[i]);
GC_CHECK_ERROR(ctx);
}
@@ -93,13 +93,13 @@ void mapcache_prefetch_tiles(mapcache_context *ctx, mapcache_tile **tiles, int n
if(ntiles==1 || ctx->config->threaded_fetching == 0) {
/* if threads disabled, or only fetching a single tile, don't launch a thread for the operation */
for(i=0; i<ntiles; i++) {
ctx->log(ctx, MAPCACHE_DEBUG, "SDL: calling mapcache_tileset_tile_get(2)...");
mapcache_tileset_tile_get(ctx, tiles[i]);
GC_CHECK_ERROR(ctx);
}
return;
}


/* allocate a thread struct for each tile. Not all will be used */
thread_tiles = (_thread_tile*)apr_pcalloc(ctx->pool,ntiles*sizeof(_thread_tile));
#if 1 || !USE_THREADPOOL
@@ -159,6 +159,7 @@ void mapcache_prefetch_tiles(mapcache_context *ctx, mapcache_tile **tiles, int n
for(i=0; i<ntiles; i++) {
/* fetch the tiles that did not get a thread launched for them */
if(thread_tiles[i].launch) continue;
ctx->log(ctx, MAPCACHE_DEBUG, "SDL: calling mapcache_tileset_tile_get(3)...");
mapcache_tileset_tile_get(ctx, tiles[i]);
GC_CHECK_ERROR(ctx);
}
@@ -205,7 +206,8 @@ mapcache_http_response *mapcache_core_get_tile(mapcache_context *ctx, mapcache_r
format = NULL;

#ifdef DEBUG
if(req_tile->ntiles ==0) {
ctx->log(ctx, MAPCACHE_DEBUG, "SDL: In mapcache_core_get_tile(), ntiles=%d...", req_tile->ntiles);
if(req_tile->ntiles == 0) {
ctx->set_error(ctx,500,"BUG: get_tile called with 0 tiles");
return NULL;
}
@@ -216,7 +218,6 @@ mapcache_http_response *mapcache_core_get_tile(mapcache_context *ctx, mapcache_r
req_tile->tiles[0]->allow_redirect = 1;
}


mapcache_prefetch_tiles(ctx,req_tile->tiles,req_tile->ntiles);
if(GC_HAS_ERROR(ctx))
return NULL;
@@ -272,13 +273,15 @@ mapcache_http_response *mapcache_core_get_tile(mapcache_context *ctx, mapcache_r
/* we have an existing tile, so we know we need to merge the current one into it */
if(!base) {
/* the existing tile has not been decoded yet, but we need the access to the raw pixels*/
ctx->log(ctx, MAPCACHE_DEBUG, "SDL: mapcache_imageio_decode(1)...");
base = mapcache_imageio_decode(ctx, response->data);
if(!base) return NULL;
}
response->data = NULL; /* the encoded data is now obsolete, as we will be merging the current tile */

/* we need to access the current tile's pixel data */
if(!tile->raw_image) {
ctx->log(ctx, MAPCACHE_DEBUG, "SDL: mapcache_imageio_decode(2)...");
tile->raw_image = mapcache_imageio_decode(ctx,tile->encoded_data);
if(!tile->raw_image) return NULL;
}
@@ -323,11 +326,15 @@ mapcache_http_response *mapcache_core_get_tile(mapcache_context *ctx, mapcache_r
}

/* compute the content-type */
t = mapcache_imageio_header_sniff(ctx,response->data);
if(t == GC_PNG)
apr_table_set(response->headers,"Content-Type","image/png");
else if(t == GC_JPEG)
apr_table_set(response->headers,"Content-Type","image/jpeg");
if(format && format->type == GC_BLOB) {
apr_table_set(response->headers,"Content-Type",format->mime_type);
} else {
t = mapcache_imageio_header_sniff(ctx,response->data);
if(t == GC_PNG)
apr_table_set(response->headers,"Content-Type","image/png");
else if(t == GC_JPEG)
apr_table_set(response->headers,"Content-Type","image/jpeg");
}

/* compute expiry headers */
if(expires) {
@@ -428,14 +435,15 @@ mapcache_http_response *mapcache_core_get_map(mapcache_context *ctx, mapcache_re
mapcache_http_response *response;
mapcache_map *basemap = NULL;
char *timestr;

#ifdef DEBUG
ctx->log(ctx, MAPCACHE_DEBUG, "SDL: In mapcache_core_get_map()...");
if(req_map->nmaps ==0) {
ctx->set_error(ctx,500,"BUG: get_map called with 0 maps");
return NULL;
}
#endif


if(req_map->getmap_strategy == MAPCACHE_GETMAP_ERROR) {
ctx->set_error(ctx, 404, "full wms support disabled");
return NULL;
@@ -444,7 +452,6 @@ mapcache_http_response *mapcache_core_get_map(mapcache_context *ctx, mapcache_re
format = NULL;
response = mapcache_http_response_create(ctx->pool);


if(req_map->getmap_strategy == MAPCACHE_GETMAP_ASSEMBLE) {
basemap = mapcache_assemble_maps(ctx, req_map->maps, req_map->nmaps, req_map->resample_mode);
if(GC_HAS_ERROR(ctx)) return NULL;
@@ -280,12 +280,24 @@ void mapcache_image_copy_resampled_bilinear(mapcache_context *ctx, mapcache_imag

void mapcache_image_metatile_split(mapcache_context *ctx, mapcache_metatile *mt)
{
ctx->log(ctx, MAPCACHE_DEBUG, "SDL: in mapcache_image_metatile_split(): format=%d", mt->map.tileset->format->type);

if(mt->map.tileset->format) {
/* the tileset has a format defined, we will use it to encode the data */
mapcache_image *tileimg;
mapcache_image *metatile;
int i,j;
int sx,sy;

/*
** No metatile support for blobs...
*/
if(mt->map.tileset->format->type == GC_BLOB) {
ctx->log(ctx, MAPCACHE_DEBUG, "SDL: got a blob");
mt->tiles[0].encoded_data = mt->map.encoded_data;
return;
}

if(mt->map.raw_image) {
metatile = mt->map.raw_image;
} else {
@@ -58,8 +58,6 @@ mapcache_image_format_type mapcache_imageio_header_sniff(mapcache_context *ctx,
}
}



mapcache_image* mapcache_imageio_decode(mapcache_context *ctx, mapcache_buffer *buffer)
{
mapcache_image_format_type type = mapcache_imageio_header_sniff(ctx,buffer);
@@ -73,7 +71,6 @@ mapcache_image* mapcache_imageio_decode(mapcache_context *ctx, mapcache_buffer *
}
}


void mapcache_image_create_empty(mapcache_context *ctx, mapcache_cfg *cfg)
{
unsigned int color=0;
@@ -0,0 +1,55 @@
/******************************************************************************
* $Id$
*
* Project: MapServer
* Purpose: MapCache tile caching support file: generic binary (BLOB) format I/O
* Author: Thomas Bonfort and the MapServer team.
*
******************************************************************************
* Copyright (c) 1996-2011 Regents of the University of Minnesota.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies of this Software or works derived from this Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/

#include "mapcache.h"
#include <apr_strings.h>

static mapcache_buffer* _mapcache_imageio_blob_create_empty(mapcache_context *ctx, mapcache_image_format *format,
size_t width, size_t height, unsigned int color)
{
return NULL;
}

mapcache_buffer* _mapcache_imageio_blob_encode(mapcache_context *ctx, mapcache_image *img, mapcache_image_format *format)
{
return NULL;
}

mapcache_image_format* mapcache_imageio_create_blob_format(apr_pool_t *pool, char *name, char *extension, char *mime_type)
{
mapcache_image_format_blob *format = apr_pcalloc(pool, sizeof(mapcache_image_format_blob));
format->format.name = name;
format->format.extension = apr_pstrdup(pool, extension);
format->format.mime_type = apr_pstrdup(pool, mime_type);
format->format.metadata = apr_table_make(pool,3);
format->format.create_empty_image = _mapcache_imageio_blob_create_empty;
format->format.write = _mapcache_imageio_blob_encode;
format->format.type = GC_BLOB;
return (mapcache_image_format*)format;
}
@@ -30,8 +30,6 @@
#include "mapcache.h"
#include <apr_time.h>



void mapcache_source_init(mapcache_context *ctx, mapcache_source *source)
{
mapcache_extent tmp_extent = {-1,-1,-1,-1};
@@ -41,7 +39,6 @@ void mapcache_source_init(mapcache_context *ctx, mapcache_source *source)
source->retry_delay = 0.1;
}


void mapcache_source_render_map(mapcache_context *ctx, mapcache_source *source, mapcache_map *map) {
int i;
#ifdef DEBUG
@@ -66,6 +63,8 @@ void mapcache_source_render_map(mapcache_context *ctx, mapcache_source *source,
if(!GC_HAS_ERROR(ctx))
break;
}

ctx->log(ctx, MAPCACHE_DEBUG, "SDL: done mapcache_source_render_map()...");
}
/* vim: ts=2 sts=2 et sw=2
*/
@@ -56,6 +56,9 @@ void _mapcache_source_wms_render_map(mapcache_context *ctx, mapcache_map *map)
mapcache_source_wms *wms = (mapcache_source_wms*)map->tileset->source;
mapcache_http *http;
apr_table_t *params = apr_table_clone(ctx->pool,wms->wms_default_params);

ctx->log(ctx, MAPCACHE_DEBUG, "SDL: finally in _mapcache_source_wms_render_map()...");

apr_table_setn(params,"BBOX",apr_psprintf(ctx->pool,"%f,%f,%f,%f",
map->extent.minx,map->extent.miny,map->extent.maxx,map->extent.maxy));
apr_table_setn(params,"WIDTH",apr_psprintf(ctx->pool,"%d",map->width));
@@ -92,11 +95,13 @@ void _mapcache_source_wms_render_map(mapcache_context *ctx, mapcache_map *map)
mapcache_http_do_request(ctx,http,map->encoded_data,NULL,NULL);
GC_CHECK_ERROR(ctx);

if(!mapcache_imageio_is_valid_format(ctx,map->encoded_data)) {
if(map->tileset->format->type != GC_BLOB && !mapcache_imageio_is_valid_format(ctx,map->encoded_data)) {
char *returned_data = apr_pstrndup(ctx->pool,(char*)map->encoded_data->buf,map->encoded_data->size);
ctx->set_error(ctx, 502, "wms request for tileset %s returned an unsupported format:\n%s",
map->tileset->name, returned_data);
}

ctx->log(ctx, MAPCACHE_DEBUG, "SDL: done _mapcache_source_wms_render_map()...");
}

void _mapcache_source_wms_query(mapcache_context *ctx, mapcache_feature_info *fi)

0 comments on commit 761022e

Please sign in to comment.
You can’t perform that action at this time.