Skip to content

Commit c2fae80

Browse files
authored
Merge pull request #166 from sdlime/vector-tiles
Merging the raw tile pull request to master - this allows for caching non-image tiles (e.g. mvt) with MapCache.
2 parents 2576f2d + d59dce0 commit c2fae80

File tree

11 files changed

+131
-37
lines changed

11 files changed

+131
-37
lines changed

include/mapcache.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ typedef struct mapcache_image_format_mixed mapcache_image_format_mixed;
7878
typedef struct mapcache_image_format_png mapcache_image_format_png;
7979
typedef struct mapcache_image_format_png_q mapcache_image_format_png_q;
8080
typedef struct mapcache_image_format_jpeg mapcache_image_format_jpeg;
81+
typedef struct mapcache_image_format_raw mapcache_image_format_raw;
8182
typedef struct mapcache_cfg mapcache_cfg;
8283
typedef struct mapcache_tileset mapcache_tileset;
8384
typedef struct mapcache_cache mapcache_cache;
@@ -663,7 +664,7 @@ MS_DLL_EXPORT int mapcache_config_services_enabled(mapcache_context *ctx, mapcac
663664
/** @{ */
664665

665666
typedef enum {
666-
GC_UNKNOWN, GC_PNG, GC_JPEG
667+
GC_UNKNOWN, GC_PNG, GC_JPEG, GC_RAW
667668
} mapcache_image_format_type;
668669

669670
typedef enum {
@@ -1434,10 +1435,16 @@ struct mapcache_image_format_mixed {
14341435

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

1437-
14381438
mapcache_image_format* mapcache_imageio_create_mixed_format(apr_pool_t *pool,
14391439
char *name, mapcache_image_format *transparent, mapcache_image_format *opaque, unsigned int alpha_cutoff);
14401440

1441+
struct mapcache_image_format_raw {
1442+
mapcache_image_format format;
1443+
};
1444+
1445+
mapcache_image_format* mapcache_imageio_create_raw_format(apr_pool_t *pool, char *name, char *extension, char *mime_type);
1446+
int mapcache_imageio_is_raw_tileset(mapcache_tileset *tileset);
1447+
14411448
/**\class mapcache_image_format_png_q
14421449
* \brief Quantized PNG format
14431450
* \extends mapcache_image_format_png

lib/cache_disk.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -532,14 +532,13 @@ static void _mapcache_cache_disk_set(mapcache_context *ctx, mapcache_cache *pcac
532532
ctx->set_error(ctx, 500, "failed to remove file %s: %s",filename, apr_strerror(ret,errmsg,120));
533533
}
534534

535-
536535
#ifdef HAVE_SYMLINK
537536
if(cache->symlink_blank) {
538-
if(!tile->raw_image) {
537+
if(tile->tileset->format->type != GC_RAW && !tile->raw_image) {
539538
tile->raw_image = mapcache_imageio_decode(ctx, tile->encoded_data);
540539
GC_CHECK_ERROR(ctx);
541540
}
542-
if(mapcache_image_blank_color(tile->raw_image) != MAPCACHE_FALSE) {
541+
if(tile->tileset->format->type != GC_RAW && mapcache_image_blank_color(tile->raw_image) != MAPCACHE_FALSE) {
543542
char *blankname;
544543
int retry_count_create_symlink = 0;
545544
char *blankname_rel = NULL;
@@ -620,7 +619,7 @@ static void _mapcache_cache_disk_set(mapcache_context *ctx, mapcache_cache *pcac
620619
return;
621620
}
622621
}
623-
#endif /*HAVE_SYMLINK*/
622+
#endif /* HAVE_SYMLINK */
624623

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

lib/configuration_xml.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,12 @@ void parseFormat(mapcache_context *ctx, ezxml_t node, mapcache_cfg *config)
520520
alpha_cutoff = atoi(cur_node->txt);
521521
}
522522
format = mapcache_imageio_create_mixed_format(ctx->pool,name,transparent, opaque, alpha_cutoff);
523+
} else if(!strcasecmp(type,"RAW")) {
524+
char *extension=NULL;
525+
char *mime_type=NULL;
526+
if ((cur_node = ezxml_child(node,"extension")) != NULL) extension = apr_pstrdup(ctx->pool, cur_node->txt);
527+
if ((cur_node = ezxml_child(node,"mime_type")) != NULL) mime_type = apr_pstrdup(ctx->pool, cur_node->txt);
528+
format = mapcache_imageio_create_raw_format(ctx->pool,name,extension,mime_type);
523529
} else {
524530
ctx->set_error(ctx, 400, "unknown format type %s for format \"%s\"", type, name);
525531
return;
@@ -529,7 +535,6 @@ void parseFormat(mapcache_context *ctx, ezxml_t node, mapcache_cfg *config)
529535
return;
530536
}
531537

532-
533538
mapcache_configuration_add_image_format(config,format,name);
534539
return;
535540
}
@@ -628,6 +633,7 @@ void parseTileset(mapcache_context *ctx, ezxml_t node, mapcache_cfg *config)
628633
ezxml_t cur_node;
629634
char* value;
630635
int havewgs84bbox=0;
636+
631637
if(config->mode == MAPCACHE_MODE_NORMAL) {
632638
name = (char*)ezxml_attr(node,"name");
633639
} else {
@@ -741,7 +747,6 @@ void parseTileset(mapcache_context *ctx, ezxml_t node, mapcache_cfg *config)
741747
APR_ARRAY_PUSH(gridlink->intermediate_grids,mapcache_grid_link*) = intermediate_gridlink;
742748
}
743749

744-
745750
mapcache_grid_compute_limits(grid,extent,gridlink->grid_limits,tolerance);
746751

747752
sTolerance = (char*)ezxml_attr(cur_node,"minzoom");
@@ -808,8 +813,6 @@ void parseTileset(mapcache_context *ctx, ezxml_t node, mapcache_cfg *config)
808813
}
809814
}
810815

811-
812-
813816
/* compute wgs84 bbox if it wasn't supplied already */
814817
if(!havewgs84bbox && !strcasecmp(grid->srs,"EPSG:4326")) {
815818
tileset->wgs84bbox = *extent;
@@ -893,7 +896,6 @@ void parseTileset(mapcache_context *ctx, ezxml_t node, mapcache_cfg *config)
893896
tileset->metasize_y = values[1];
894897
}
895898

896-
897899
if ((cur_node = ezxml_child(node,"watermark")) != NULL) {
898900
if(!*cur_node->txt) {
899901
ctx->set_error(ctx,400, "watermark config entry empty");

lib/core.c

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ mapcache_http_response *mapcache_http_response_create(apr_pool_t *pool)
7777

7878
void mapcache_prefetch_tiles(mapcache_context *ctx, mapcache_tile **tiles, int ntiles)
7979
{
80-
8180
apr_thread_t **threads;
8281
apr_threadattr_t *thread_attrs;
8382
int nthreads;
@@ -99,7 +98,6 @@ void mapcache_prefetch_tiles(mapcache_context *ctx, mapcache_tile **tiles, int n
9998
return;
10099
}
101100

102-
103101
/* allocate a thread struct for each tile. Not all will be used */
104102
thread_tiles = (_thread_tile*)apr_pcalloc(ctx->pool,ntiles*sizeof(_thread_tile));
105103
#if 1 || !USE_THREADPOOL
@@ -205,7 +203,7 @@ mapcache_http_response *mapcache_core_get_tile(mapcache_context *ctx, mapcache_r
205203
format = NULL;
206204

207205
#ifdef DEBUG
208-
if(req_tile->ntiles ==0) {
206+
if(req_tile->ntiles == 0) {
209207
ctx->set_error(ctx,500,"BUG: get_tile called with 0 tiles");
210208
return NULL;
211209
}
@@ -216,7 +214,6 @@ mapcache_http_response *mapcache_core_get_tile(mapcache_context *ctx, mapcache_r
216214
req_tile->tiles[0]->allow_redirect = 1;
217215
}
218216

219-
220217
mapcache_prefetch_tiles(ctx,req_tile->tiles,req_tile->ntiles);
221218
if(GC_HAS_ERROR(ctx))
222219
return NULL;
@@ -295,7 +292,7 @@ mapcache_http_response *mapcache_core_get_tile(mapcache_context *ctx, mapcache_r
295292
}
296293

297294
if(!response->data) {
298-
/* we need to encode the raw image data*/
295+
/* we need to encode the raw image data */
299296
if(base) {
300297
if(req_tile->image_request.format) {
301298
format = req_tile->image_request.format;
@@ -320,14 +317,28 @@ mapcache_http_response *mapcache_core_get_tile(mapcache_context *ctx, mapcache_r
320317
response->data = mapcache_empty_png_decode(ctx,req_tile->tiles[0]->grid_link->grid->tile_sx, req_tile->tiles[0]->grid_link->grid->tile_sy, empty,&is_empty); /* is_empty is unchanged and left to 1 */
321318
format = mapcache_configuration_get_image_format(ctx->config,"PNG8");
322319
}
320+
} else {
321+
/* set format, not an image type (e.g. GC_RAW) */
322+
if(req_tile->image_request.format) {
323+
format = req_tile->image_request.format;
324+
} else {
325+
format = req_tile->tiles[0]->tileset->format;
326+
if(!format) {
327+
format = ctx->config->default_image_format; /* this one is always defined */
328+
}
329+
}
323330
}
324331

325332
/* compute the content-type */
326-
t = mapcache_imageio_header_sniff(ctx,response->data);
327-
if(t == GC_PNG)
328-
apr_table_set(response->headers,"Content-Type","image/png");
329-
else if(t == GC_JPEG)
330-
apr_table_set(response->headers,"Content-Type","image/jpeg");
333+
if(format && format->type == GC_RAW) {
334+
apr_table_set(response->headers,"Content-Type",format->mime_type);
335+
} else {
336+
t = mapcache_imageio_header_sniff(ctx,response->data);
337+
if(t == GC_PNG)
338+
apr_table_set(response->headers,"Content-Type","image/png");
339+
else if(t == GC_JPEG)
340+
apr_table_set(response->headers,"Content-Type","image/jpeg");
341+
}
331342

332343
/* compute expiry headers */
333344
if(expires) {
@@ -428,14 +439,14 @@ mapcache_http_response *mapcache_core_get_map(mapcache_context *ctx, mapcache_re
428439
mapcache_http_response *response;
429440
mapcache_map *basemap = NULL;
430441
char *timestr;
442+
431443
#ifdef DEBUG
432444
if(req_map->nmaps ==0) {
433445
ctx->set_error(ctx,500,"BUG: get_map called with 0 maps");
434446
return NULL;
435447
}
436448
#endif
437449

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

447-
448458
if(req_map->getmap_strategy == MAPCACHE_GETMAP_ASSEMBLE) {
449459
basemap = mapcache_assemble_maps(ctx, req_map->maps, req_map->nmaps, req_map->resample_mode);
450460
if(GC_HAS_ERROR(ctx)) return NULL;

lib/image.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,12 +280,22 @@ void mapcache_image_copy_resampled_bilinear(mapcache_context *ctx, mapcache_imag
280280

281281
void mapcache_image_metatile_split(mapcache_context *ctx, mapcache_metatile *mt)
282282
{
283+
283284
if(mt->map.tileset->format) {
284285
/* the tileset has a format defined, we will use it to encode the data */
285286
mapcache_image *tileimg;
286287
mapcache_image *metatile;
287288
int i,j;
288289
int sx,sy;
290+
291+
/*
292+
** No metatile support for raw format types...
293+
*/
294+
if(mt->map.tileset->format->type == GC_RAW) {
295+
mt->tiles[0].encoded_data = mt->map.encoded_data;
296+
return;
297+
}
298+
289299
if(mt->map.raw_image) {
290300
metatile = mt->map.raw_image;
291301
} else {

lib/imageio.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,6 @@ mapcache_image_format_type mapcache_imageio_header_sniff(mapcache_context *ctx,
5858
}
5959
}
6060

61-
62-
6361
mapcache_image* mapcache_imageio_decode(mapcache_context *ctx, mapcache_buffer *buffer)
6462
{
6563
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 *
7371
}
7472
}
7573

76-
7774
void mapcache_image_create_empty(mapcache_context *ctx, mapcache_cfg *cfg)
7875
{
7976
unsigned int color=0;

lib/imageio_raw.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/******************************************************************************
2+
* $Id$
3+
*
4+
* Project: MapServer
5+
* Purpose: MapCache tile caching support file: raw (generic) format I/O
6+
* Author: Thomas Bonfort and the MapServer team.
7+
*
8+
******************************************************************************
9+
* Copyright (c) 1996-2011 Regents of the University of Minnesota.
10+
*
11+
* Permission is hereby granted, free of charge, to any person obtaining a
12+
* copy of this software and associated documentation files (the "Software"),
13+
* to deal in the Software without restriction, including without limitation
14+
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
15+
* and/or sell copies of the Software, and to permit persons to whom the
16+
* Software is furnished to do so, subject to the following conditions:
17+
*
18+
* The above copyright notice and this permission notice shall be included in
19+
* all copies of this Software or works derived from this Software.
20+
*
21+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22+
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24+
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27+
* DEALINGS IN THE SOFTWARE.
28+
*****************************************************************************/
29+
30+
#include "mapcache.h"
31+
#include <apr_strings.h>
32+
33+
int mapcache_imageio_is_raw_tileset(mapcache_tileset *tileset)
34+
{
35+
if(!tileset || !tileset->format || tileset->format->type != GC_RAW) return MAPCACHE_FALSE;
36+
return MAPCACHE_TRUE;
37+
}
38+
39+
static mapcache_buffer* _mapcache_imageio_raw_create_empty(mapcache_context *ctx, mapcache_image_format *format,
40+
size_t width, size_t height, unsigned int color)
41+
{
42+
return NULL;
43+
}
44+
45+
mapcache_buffer* _mapcache_imageio_raw_encode(mapcache_context *ctx, mapcache_image *img, mapcache_image_format *format)
46+
{
47+
return NULL;
48+
}
49+
50+
mapcache_image_format* mapcache_imageio_create_raw_format(apr_pool_t *pool, char *name, char *extension, char *mime_type)
51+
{
52+
mapcache_image_format_raw *format = apr_pcalloc(pool, sizeof(mapcache_image_format_raw));
53+
format->format.name = name;
54+
format->format.extension = apr_pstrdup(pool, extension);
55+
format->format.mime_type = apr_pstrdup(pool, mime_type);
56+
format->format.metadata = apr_table_make(pool,3);
57+
format->format.create_empty_image = _mapcache_imageio_raw_create_empty;
58+
format->format.write = _mapcache_imageio_raw_encode;
59+
format->format.type = GC_RAW;
60+
return (mapcache_image_format*)format;
61+
}

lib/service_wms.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,11 @@ void _create_capabilities_wms(mapcache_context *ctx, mapcache_request_get_capabi
264264
int i;
265265
apr_hash_this(tileindex_index,&key,&keylen,(void**)&tileset);
266266

267+
if(mapcache_imageio_is_raw_tileset(tileset)) {
268+
tileindex_index = apr_hash_next(tileindex_index);
269+
continue; /* WMS is not supported for raw layers */
270+
}
271+
267272
layerxml = ezxml_add_child(toplayer,"Layer",0);
268273
ezxml_set_attr(layerxml, "cascaded", "1");
269274
ezxml_set_attr(layerxml, "queryable", (tileset->source && tileset->source->info_formats)?"1":"0");
@@ -611,7 +616,7 @@ void _mapcache_service_wms_parse_request(mapcache_context *ctx, mapcache_service
611616
key = apr_strtok(layers, ",", &last); /* extract first layer */
612617
}
613618
main_tileset = mapcache_configuration_get_tileset(config,key);
614-
if(!main_tileset) {
619+
if(!main_tileset || mapcache_imageio_is_raw_tileset(main_tileset)) {
615620
errcode = 404;
616621
errmsg = apr_psprintf(ctx->pool,"received wms request with invalid layer %s", key);
617622
goto proxies;
@@ -710,7 +715,7 @@ void _mapcache_service_wms_parse_request(mapcache_context *ctx, mapcache_service
710715
* this step is not done for the first tileset as we have already performed it
711716
*/
712717
tileset = mapcache_configuration_get_tileset(config,key);
713-
if (!tileset) {
718+
if (!tileset || mapcache_imageio_is_raw_tileset(tileset)) {
714719
errcode = 404;
715720
errmsg = apr_psprintf(ctx->pool,"received wms request with invalid layer %s", key);
716721
goto proxies;
@@ -810,7 +815,7 @@ void _mapcache_service_wms_parse_request(mapcache_context *ctx, mapcache_service
810815
goto proxies;
811816
} else {
812817
mapcache_tileset *tileset = mapcache_configuration_get_tileset(config,str);
813-
if(!tileset) {
818+
if(!tileset || mapcache_imageio_is_raw_tileset(tileset)) {
814819
errcode = 404;
815820
errmsg = apr_psprintf(ctx->pool,"received wms getfeatureinfo request with invalid layer %s", str);
816821
goto proxies;

lib/source.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@
3030
#include "mapcache.h"
3131
#include <apr_time.h>
3232

33-
34-
3533
void mapcache_source_init(mapcache_context *ctx, mapcache_source *source)
3634
{
3735
mapcache_extent tmp_extent = {-1,-1,-1,-1};
@@ -41,7 +39,6 @@ void mapcache_source_init(mapcache_context *ctx, mapcache_source *source)
4139
source->retry_delay = 0.1;
4240
}
4341

44-
4542
void mapcache_source_render_map(mapcache_context *ctx, mapcache_source *source, mapcache_map *map) {
4643
int i;
4744
#ifdef DEBUG

lib/source_wms.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ void _mapcache_source_wms_render_map(mapcache_context *ctx, mapcache_source *pso
5656
mapcache_source_wms *wms = (mapcache_source_wms*)psource;
5757
mapcache_http *http;
5858
apr_table_t *params = apr_table_clone(ctx->pool,wms->wms_default_params);
59+
5960
apr_table_setn(params,"BBOX",apr_psprintf(ctx->pool,"%f,%f,%f,%f",
6061
map->extent.minx,map->extent.miny,map->extent.maxx,map->extent.maxy));
6162
apr_table_setn(params,"WIDTH",apr_psprintf(ctx->pool,"%d",map->width));
@@ -92,7 +93,7 @@ void _mapcache_source_wms_render_map(mapcache_context *ctx, mapcache_source *pso
9293
mapcache_http_do_request(ctx,http,map->encoded_data,NULL,NULL);
9394
GC_CHECK_ERROR(ctx);
9495

95-
if(!mapcache_imageio_is_valid_format(ctx,map->encoded_data)) {
96+
if(!mapcache_imageio_is_raw_tileset(map->tileset) && !mapcache_imageio_is_valid_format(ctx,map->encoded_data)) {
9697
char *returned_data = apr_pstrndup(ctx->pool,(char*)map->encoded_data->buf,map->encoded_data->size);
9798
ctx->set_error(ctx, 502, "wms request for tileset %s returned an unsupported format:\n%s",
9899
map->tileset->name, returned_data);

0 commit comments

Comments
 (0)