Skip to content
Permalink
Browse files

implement ruleset

  • Loading branch information
tomhel committed May 9, 2016
1 parent c5b4683 commit 19e171baa9c240aa7310131ead7a911baee7502c
Showing with 428 additions and 31 deletions.
  1. +84 −0 include/mapcache.h
  2. +89 −0 lib/cache.c
  3. +6 −0 lib/configuration.c
  4. +122 −1 lib/configuration_xml.c
  5. +34 −30 lib/grid.c
  6. +93 −0 lib/ruleset.c
@@ -103,6 +103,8 @@ typedef struct mapcache_image mapcache_image;
typedef struct mapcache_grid mapcache_grid;
typedef struct mapcache_grid_level mapcache_grid_level;
typedef struct mapcache_grid_link mapcache_grid_link;
typedef struct mapcache_rule mapcache_rule;
typedef struct mapcache_ruleset mapcache_ruleset;
typedef struct mapcache_context mapcache_context;
typedef struct mapcache_dimension mapcache_dimension;
typedef struct mapcache_requested_dimension mapcache_requested_dimension;
@@ -834,6 +836,11 @@ struct mapcache_cfg {
*/
apr_hash_t *grids;

/**
* hashtable containing (pre)defined rulesets
*/
apr_hash_t *rulesets;

/**
* the format to use for some miscelaneaous operations:
* - creating an empty image
@@ -888,6 +895,7 @@ MS_DLL_EXPORT mapcache_cache* mapcache_configuration_get_cache(mapcache_cfg *con
mapcache_grid *mapcache_configuration_get_grid(mapcache_cfg *config, const char *key);
MS_DLL_EXPORT mapcache_tileset* mapcache_configuration_get_tileset(mapcache_cfg *config, const char *key);
mapcache_image_format *mapcache_configuration_get_image_format(mapcache_cfg *config, const char *key);
mapcache_ruleset *mapcache_configuration_get_ruleset(mapcache_cfg *config, const char *key);
void mapcache_configuration_add_image_format(mapcache_cfg *config, mapcache_image_format *format, const char * key);
void mapcache_configuration_add_source(mapcache_cfg *config, mapcache_source *source, const char * key);
void mapcache_configuration_add_grid(mapcache_cfg *config, mapcache_grid *grid, const char * key);
@@ -1040,6 +1048,12 @@ struct mapcache_grid_link {
mapcache_extent_i *grid_limits;
int minz,maxz;

/**
* rules (mapcache_rule) for each zoom level or NULL
* index in array = zoom level
*/
apr_array_header_t *rules;

/**
* tiles above this zoom level will not be stored to the cache, but will be
* dynamically generated (either by reconstructing from lower level tiles, or
@@ -1052,6 +1066,46 @@ struct mapcache_grid_link {
apr_array_header_t *intermediate_grids;
};

/**\class mapcache_rule
* \brief a zoom level rule
*/
struct mapcache_rule {
/**
* rule for zoom level
*/
int zoom_level;
/**
* hidden tile color
*/
unsigned int hidden_color;
/**
* readonly
*/
int readonly;
/**
* visible extent
*/
mapcache_extent *visible_extent;
/**
* visible limits
*/
mapcache_extent_i *visible_limits;
};

/**\class mapcache_ruleset
* \brief a set of rules
*/
struct mapcache_ruleset {
/**
* the name of this ruleset
*/
char *name;
/**
* rules (mapcache_rule)
*/
apr_array_header_t *rules;
};

/**\class mapcache_tileset
* \brief a set of tiles that can be requested by a client, created from a mapcache_source
* stored by a mapcache_cache in a mapcache_format
@@ -1258,6 +1312,35 @@ MS_DLL_EXPORT mapcache_http_response* mapcache_core_proxy_request(mapcache_conte
MS_DLL_EXPORT mapcache_http_response* mapcache_core_respond_to_error(mapcache_context *ctx);


/* in ruleset.c */

/**
* \brief allocate and initialize a new ruleset
* @param pool
*/
mapcache_ruleset* mapcache_ruleset_create(apr_pool_t *pool);

/**
* \brief allocate and initialize a new rule
* @param pool
*/
mapcache_rule* mapcache_rule_create(apr_pool_t *pool);

/**
* \brief clone a rule
* @param pool
* @param rule
*/
mapcache_rule* mapcache_rule_clone(apr_pool_t *pool, mapcache_rule *rule);

/**
* \brief get rule for zoom level, or NULL if none exist
* @param ruleset
* @param zoom_level
*/
mapcache_rule* mapcache_rule_get(mapcache_ruleset *ruleset, int zoom_level);


/* in grid.c */
mapcache_grid* mapcache_grid_create(apr_pool_t *pool);

@@ -1300,6 +1383,7 @@ int mapcache_grid_get_level(mapcache_context *ctx, mapcache_grid *grid, double *
* \param tolerance the number of tiles around the given extent that can be requested without returning an error.
*/
MS_DLL_EXPORT void mapcache_grid_compute_limits(const mapcache_grid *grid, const mapcache_extent *extent, mapcache_extent_i *limits, int tolerance);
void mapcache_grid_compute_limits_at_level(const mapcache_grid *grid, const mapcache_extent *extent, mapcache_extent_i *limits_ptr, int tolerance, int zoom_level);

/* in util.c */
MS_DLL_EXPORT int mapcache_util_extract_int_list(mapcache_context *ctx, const char* args, const char *sep, int **numbers,
@@ -28,11 +28,69 @@
#include "mapcache.h"
#include <apr_time.h>

mapcache_rule* mapcache_cache_get_rule(mapcache_tile *tile) {
/* get rule for tile if available */
apr_array_header_t *rules = tile->grid_link->rules;
mapcache_rule *rule;

if(!rules) {
return NULL;
}

rule = APR_ARRAY_IDX(rules, tile->z, mapcache_rule*);
return rule;
}

int mapcache_cache_is_visible_tile(mapcache_tile *tile, mapcache_rule* rule) {
/* check if tile is within visible extent */
if(!rule) {
return MAPCACHE_TRUE;
}

if(!rule->visible_limits) {
return MAPCACHE_TRUE;
}

if(tile->x < rule->visible_limits->minx || tile->y < rule->visible_limits->miny ||
tile->x > rule->visible_limits->maxx || tile->y > rule->visible_limits->maxy) {
return MAPCACHE_FALSE;
}

return MAPCACHE_TRUE;
}

int mapcache_cache_is_readonly_tile(mapcache_tile *tile, mapcache_rule* rule) {
/* check if tile is tile readonly */
if(!rule) {
return MAPCACHE_FALSE;
}

if(rule->readonly) {
return MAPCACHE_TRUE;
}

return MAPCACHE_FALSE;
}

int mapcache_cache_tile_get(mapcache_context *ctx, mapcache_cache *cache, mapcache_tile *tile) {
int i,rv;
mapcache_rule *rule = mapcache_cache_get_rule(tile);
#ifdef DEBUG
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 (mapcache_cache_is_visible_tile(tile, rule) == 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;
}
return MAPCACHE_SUCCESS;
}

for(i=0;i<=cache->retry_count;i++) {
if(i) {
ctx->log(ctx,MAPCACHE_INFO,"cache (%s) get retry %d of %d. previous try returned error: %s",cache->name,i,cache->retry_count,ctx->get_error_message(ctx));
@@ -54,9 +112,16 @@ 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_cache_get_rule(tile);
#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 is readonly, return */
if (mapcache_cache_is_readonly_tile(tile, rule) == MAPCACHE_TRUE) {
return;
}

if(tile->tileset->read_only)
return;
for(i=0;i<=cache->retry_count;i++) {
@@ -79,9 +144,17 @@ void mapcache_cache_tile_delete(mapcache_context *ctx, mapcache_cache *cache, ma

int mapcache_cache_tile_exists(mapcache_context *ctx, mapcache_cache *cache, mapcache_tile *tile) {
int i,rv;
mapcache_rule *rule = mapcache_cache_get_rule(tile);
#ifdef DEBUG
ctx->log(ctx,MAPCACHE_DEBUG,"calling tile_exists 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 limits return TRUE
a blank tile will be returned on subsequent get call on cache */
if (mapcache_cache_is_visible_tile(tile, rule) == MAPCACHE_FALSE) {
return MAPCACHE_TRUE;
}

for(i=0;i<=cache->retry_count;i++) {
if(i) {
ctx->log(ctx,MAPCACHE_INFO,"cache (%s) exists retry %d of %d. previous try returned error: %s",cache->name,i,cache->retry_count,ctx->get_error_message(ctx));
@@ -103,9 +176,16 @@ 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_cache_get_rule(tile);
#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 is readonly, return */
if (mapcache_cache_is_readonly_tile(tile, rule) == MAPCACHE_TRUE) {
return;
}

if(tile->tileset->read_only)
return;
for(i=0;i<=cache->retry_count;i++) {
@@ -132,6 +212,15 @@ 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 is readonly, return */
for(i = 0; i < ntiles; i++) {
mapcache_rule *rule = mapcache_cache_get_rule(tiles+i);
if (mapcache_cache_is_readonly_tile(tiles+i, rule) == MAPCACHE_TRUE) {
return;
}
}

if((&tiles[0])->tileset->read_only)
return;
if(cache->_tile_multi_set) {
@@ -127,6 +127,7 @@ mapcache_cfg* mapcache_configuration_create(apr_pool_t *pool)
cfg->grids = apr_hash_make(pool);
cfg->image_formats = apr_hash_make(pool);
cfg->metadata = apr_table_make(pool,3);
cfg->rulesets = apr_hash_make(pool);

mapcache_configuration_add_image_format(cfg,
mapcache_imageio_create_png_format(pool,"PNG",MAPCACHE_COMPRESSION_FAST),
@@ -241,6 +242,11 @@ mapcache_grid *mapcache_configuration_get_grid(mapcache_cfg *config, const char
return (mapcache_grid*)apr_hash_get(config->grids, (void*)key, APR_HASH_KEY_STRING);
}

mapcache_ruleset *mapcache_configuration_get_ruleset(mapcache_cfg *config, const char *key)
{
return (mapcache_ruleset*)apr_hash_get(config->rulesets, (void*)key, APR_HASH_KEY_STRING);
}

mapcache_tileset *mapcache_configuration_get_tileset(mapcache_cfg *config, const char *key)
{
if(config->mode == MAPCACHE_MODE_NORMAL) {

0 comments on commit 19e171b

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