Skip to content
Permalink
Browse files

return blank tile (when outside visible extent) in configured format

  • Loading branch information
tomhel committed May 26, 2016
1 parent 4b93fec commit 074471ec8e266fa4686ab854be38a9f3c659fb28
Showing with 41 additions and 72 deletions.
  1. +3 −10 include/mapcache.h
  2. +2 −31 lib/cache.c
  3. +31 −15 lib/configuration_xml.c
  4. +5 −16 lib/ruleset.c
@@ -1076,13 +1076,13 @@ struct mapcache_rule {
*/
int zoom_level;
/**
* hidden tile color
* color of tiles when outside visible extent, ARGB
*/
unsigned int hidden_color;
/**
* readonly
* tile to return when outside visible extent
*/
int readonly;
mapcache_buffer *hidden_tile;
/**
* visible extents, array of mapcache_extent
*/
@@ -1355,13 +1355,6 @@ mapcache_rule* mapcache_ruleset_rule_get(apr_array_header_t *rules, int idx);
*/
int mapcache_ruleset_is_visible_tile(mapcache_rule* rule, mapcache_tile *tile);

/**
* \brief check if tile is readonly
* @param rule
* @param tile
*/
int mapcache_ruleset_is_readonly_tile(mapcache_rule* rule, mapcache_tile *tile);


/* in grid.c */
mapcache_grid* mapcache_grid_create(apr_pool_t *pool);
@@ -35,15 +35,9 @@ int mapcache_cache_tile_get(mapcache_context *ctx, mapcache_cache *cache, mapcac
ctx->log(ctx,MAPCACHE_DEBUG,"calling tile_get on cache (%s): (tileset=%s, grid=%s, z=%d, x=%d, y=%d",cache->name,tile->tileset->name,tile->grid_link->grid->name,tile->z,tile->x, tile->y);
#endif

/* if tile is outside visible extent, create a blank tile and return */
/* if tile is outside visible limits, return a blank tile */
if (mapcache_ruleset_is_visible_tile(rule, tile) == MAPCACHE_FALSE) {
int tile_sx, tile_sy;
tile_sx = tile->grid_link->grid->tile_sx;
tile_sy = tile->grid_link->grid->tile_sy;
tile->encoded_data = tile->tileset->format->create_empty_image(ctx, tile->tileset->format, tile_sx, tile_sy, rule->hidden_color);
if(GC_HAS_ERROR(ctx)) {
return MAPCACHE_FAILURE;
}
tile->encoded_data = rule->hidden_tile;
return MAPCACHE_SUCCESS;
}

@@ -68,16 +62,9 @@ int mapcache_cache_tile_get(mapcache_context *ctx, mapcache_cache *cache, mapcac

void mapcache_cache_tile_delete(mapcache_context *ctx, mapcache_cache *cache, mapcache_tile *tile) {
int i;
mapcache_rule *rule = mapcache_ruleset_rule_get(tile->grid_link->rules, tile->z);
#ifdef DEBUG
ctx->log(ctx,MAPCACHE_DEBUG,"calling tile_delete on cache (%s): (tileset=%s, grid=%s, z=%d, x=%d, y=%d",cache->name,tile->tileset->name,tile->grid_link->grid->name,tile->z,tile->x, tile->y);
#endif

/* if tile has a readonly rule, return */
if (mapcache_ruleset_is_readonly_tile(rule, tile) == MAPCACHE_TRUE) {
return;
}

if(tile->tileset->read_only)
return;
for(i=0;i<=cache->retry_count;i++) {
@@ -132,16 +119,9 @@ int mapcache_cache_tile_exists(mapcache_context *ctx, mapcache_cache *cache, map

void mapcache_cache_tile_set(mapcache_context *ctx, mapcache_cache *cache, mapcache_tile *tile) {
int i;
mapcache_rule *rule = mapcache_ruleset_rule_get(tile->grid_link->rules, tile->z);
#ifdef DEBUG
ctx->log(ctx,MAPCACHE_DEBUG,"calling tile_set on cache (%s): (tileset=%s, grid=%s, z=%d, x=%d, y=%d",cache->name,tile->tileset->name,tile->grid_link->grid->name,tile->z,tile->x, tile->y);
#endif

/* if tile has a readonly rule, return */
if (mapcache_ruleset_is_readonly_tile(rule, tile) == MAPCACHE_TRUE) {
return;
}

if(tile->tileset->read_only)
return;
for(i=0;i<=cache->retry_count;i++) {
@@ -168,15 +148,6 @@ void mapcache_cache_tile_multi_set(mapcache_context *ctx, mapcache_cache *cache,
ctx->log(ctx,MAPCACHE_DEBUG,"calling tile_multi_set on cache (%s): (tileset=%s, grid=%s, first tile: z=%d, x=%d, y=%d",cache->name,tiles[0].tileset->name,tiles[0].grid_link->grid->name,
tiles[0].z,tiles[0].x, tiles[0].y);
#endif

/* if any tile has a readonly rule, return */
for(i = 0; i < ntiles; i++) {
mapcache_rule *rule = mapcache_ruleset_rule_get((tiles+i)->grid_link->rules, (tiles+i)->z);
if (mapcache_ruleset_is_readonly_tile(rule, tiles+i) == MAPCACHE_TRUE) {
return;
}
}

if((&tiles[0])->tileset->read_only)
return;
if(cache->_tile_multi_set) {
@@ -182,13 +182,8 @@ void parseRuleset(mapcache_context *ctx, ezxml_t node, mapcache_cfg *config)
int *zoom, nzoom, j;
char* zoom_attr = (char*)ezxml_attr(cur_node, "zoom_level");
ezxml_t visibility = ezxml_child(cur_node, "visibility");
ezxml_t readonly = ezxml_child(cur_node, "readonly");
mapcache_rule *rule = mapcache_ruleset_rule_create(ctx->pool);

if(readonly) {
rule->readonly = 1;
}

/* parse zoom_level attribute */
if(zoom_attr && *zoom_attr) {
char *value = apr_pstrdup(ctx->pool, zoom_attr);
@@ -211,6 +206,11 @@ void parseRuleset(mapcache_context *ctx, ezxml_t node, mapcache_cfg *config)
if (hidden_color && *hidden_color) {
/* parse color, base 16 */
rule->hidden_color = (unsigned int)strtol(hidden_color, NULL, 16);

if (strlen(hidden_color) <= 6) {
/* if color is set, but no alpha value. Assume no transparency. */
rule->hidden_color += 0xff000000;
}
}

/* parse extents, <extent> */
@@ -725,6 +725,16 @@ void parseTileset(mapcache_context *ctx, ezxml_t node, mapcache_cfg *config)
havewgs84bbox = 1;
}

if ((cur_node = ezxml_child(node,"format")) != NULL) {
mapcache_image_format *format = mapcache_configuration_get_image_format(config,cur_node->txt);
if(!format) {
ctx->set_error(ctx, 400, "tileset \"%s\" references format \"%s\","
" but it is not configured",name,cur_node->txt);
return;
}
tileset->format = format;
}

for(cur_node = ezxml_child(node,"grid"); cur_node; cur_node = cur_node->next) {
mapcache_grid *grid;
mapcache_grid_link *gridlink;
@@ -805,7 +815,9 @@ void parseTileset(mapcache_context *ctx, ezxml_t node, mapcache_cfg *config)

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

// setup zoom level rules if configured
if(ruleset) {
// prepare one rule per zoom level. if rule is missing it will be NULL
for(i = 0; i < grid->nlevels; i++) {
mapcache_rule *rule = mapcache_ruleset_rule_find(ruleset->rules, i);

@@ -814,6 +826,19 @@ void parseTileset(mapcache_context *ctx, ezxml_t node, mapcache_cfg *config)

if(rule->visible_extents) {
int j;

// create empty tile in configured format to return when outside visible extent
if(tileset->format) {
rule_clone->hidden_tile = tileset->format->create_empty_image(ctx, tileset->format, grid->tile_sx, grid->tile_sy, rule->hidden_color);
} else {
rule_clone->hidden_tile = config->default_image_format->create_empty_image(ctx, config->default_image_format, grid->tile_sx, grid->tile_sy, rule->hidden_color);
}

if(GC_HAS_ERROR(ctx)) {
return;
}

// compute limits for extents
for(j = 0; j < rule->visible_extents->nelts; j++) {
mapcache_extent *visible_extent = APR_ARRAY_IDX(rule->visible_extents, j, mapcache_extent*);
mapcache_extent_i *visible_limit = apr_pcalloc(ctx->pool, sizeof(mapcache_extent_i));
@@ -823,6 +848,7 @@ void parseTileset(mapcache_context *ctx, ezxml_t node, mapcache_cfg *config)
}
APR_ARRAY_PUSH(gridlink->rules, mapcache_rule*) = rule_clone;
} else {
// no rule for zoom level
APR_ARRAY_PUSH(gridlink->rules, mapcache_rule*) = NULL;
}
}
@@ -1023,16 +1049,6 @@ void parseTileset(mapcache_context *ctx, ezxml_t node, mapcache_cfg *config)
}
}

if ((cur_node = ezxml_child(node,"format")) != NULL) {
mapcache_image_format *format = mapcache_configuration_get_image_format(config,cur_node->txt);
if(!format) {
ctx->set_error(ctx, 400, "tileset \"%s\" references format \"%s\","
" but it is not configured",name,cur_node->txt);
return;
}
tileset->format = format;
}

mapcache_tileset_configuration_check(ctx,tileset);
GC_CHECK_ERROR(ctx);
mapcache_configuration_add_tileset(config,tileset,name);
@@ -48,8 +48,8 @@ mapcache_rule* mapcache_ruleset_rule_create(apr_pool_t *pool)
rule->zoom_level = -1;
rule->visible_extents = apr_array_make(pool,0,sizeof(mapcache_extent*));
rule->visible_limits = apr_array_make(pool,0,sizeof(mapcache_extent_i*));
rule->hidden_color = 0xffffff; //default = white
rule->readonly = 0;
rule->hidden_color = 0x00ffffff; // default is white with full transparency
rule->hidden_tile = NULL;
return rule;
}

@@ -62,7 +62,7 @@ mapcache_rule* mapcache_ruleset_rule_clone(apr_pool_t *pool, mapcache_rule *rule

clone->zoom_level = rule->zoom_level;
clone->hidden_color = rule->hidden_color;
clone->readonly = rule->readonly;
clone->hidden_tile = rule->hidden_tile; //no need to copy, just point to same buffer/tile.

if(rule->visible_extents) {
int i;
@@ -108,7 +108,7 @@ mapcache_rule* mapcache_ruleset_rule_find(apr_array_header_t *rules, int zoom_le
}

/*
* get rule at index, or NULL if none exist
* get rule at index, or NULL if index is out of bounds.
*/
mapcache_rule* mapcache_ruleset_rule_get(apr_array_header_t *rules, int idx)
{
@@ -123,7 +123,7 @@ mapcache_rule* mapcache_ruleset_rule_get(apr_array_header_t *rules, int idx)
}

/*
* check if tile is within visible extents
* check if tile is within visible limits
*/
int mapcache_ruleset_is_visible_tile(mapcache_rule* rule, mapcache_tile *tile) {
int i;
@@ -143,14 +143,3 @@ int mapcache_ruleset_is_visible_tile(mapcache_rule* rule, mapcache_tile *tile) {

return MAPCACHE_FALSE;
}

/*
* check if tile is readonly
*/
int mapcache_ruleset_is_readonly_tile(mapcache_rule* rule, mapcache_tile *tile) {
if(rule && rule->readonly) {
return MAPCACHE_TRUE;
}

return MAPCACHE_FALSE;
}

0 comments on commit 074471e

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