Skip to content

Commit 4dfd2c6

Browse files
authored
Merge pull request #224 from jbo-ads/ztop
Add support to Z-top, a multi-SQLite, multi-pyramid cache structure
2 parents 2bb6bb7 + 44b5983 commit 4dfd2c6

File tree

2 files changed

+175
-15
lines changed

2 files changed

+175
-15
lines changed

contrib/mapcache_detail/mapcache_detail.c

Lines changed: 110 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ char * str_replace_all(apr_pool_t *pool, const char *string,
398398
char * dbfilename(apr_pool_t * pool, char * template,
399399
mapcache_tileset * tileset, mapcache_grid * grid,
400400
apr_array_header_t * dimensions, apr_hash_t * fmt, int z,
401-
int dbx, int dby, int xcount, int ycount)
401+
int dbx, int dby, int xcount, int ycount, int top)
402402
{
403403
int tilx = dbx * xcount;
404404
int tily = dby * ycount;
@@ -469,6 +469,26 @@ char * dbfilename(apr_pool_t * pool, char * template,
469469
apr_psprintf(pool, curfmt, dby));
470470
}
471471

472+
// Z top
473+
if (top > 0) {
474+
char * curfmt;
475+
curfmt = apr_hash_get(fmt, "top", APR_HASH_KEY_STRING);
476+
path = str_replace_all(pool, path, "{top}",
477+
apr_psprintf(pool, curfmt, top));
478+
curfmt = apr_hash_get(fmt, "top_x", APR_HASH_KEY_STRING);
479+
path = str_replace_all(pool, path, "{top_x}",
480+
apr_psprintf(pool, curfmt, dbx));
481+
curfmt = apr_hash_get(fmt, "inv_top_x", APR_HASH_KEY_STRING);
482+
path = str_replace_all(pool, path, "{inv_top_x}",
483+
apr_psprintf(pool, curfmt, dbx));
484+
curfmt = apr_hash_get(fmt, "top_y", APR_HASH_KEY_STRING);
485+
path = str_replace_all(pool, path, "{top_y}",
486+
apr_psprintf(pool, curfmt, dby));
487+
curfmt = apr_hash_get(fmt, "inv_top_y", APR_HASH_KEY_STRING);
488+
path = str_replace_all(pool, path, "{inv_top_y}",
489+
apr_psprintf(pool, curfmt, dby));
490+
}
491+
472492
return path;
473493
}
474494

@@ -659,7 +679,7 @@ int main(int argc, char * argv[])
659679
int minzoom, maxzoom;
660680
char * dbfile;
661681
apr_hash_t * formats;
662-
int xcount, ycount;
682+
int xcount, ycount, top;
663683
} *cache;
664684
apr_array_header_t * caches = NULL;
665685
int i, ix, iy, iz;
@@ -1067,6 +1087,11 @@ int main(int argc, char * argv[])
10671087
apr_hash_set(c->formats, "div_y", APR_HASH_KEY_STRING, "(not set)");
10681088
apr_hash_set(c->formats, "inv_div_x", APR_HASH_KEY_STRING, "(not set)");
10691089
apr_hash_set(c->formats, "inv_div_y", APR_HASH_KEY_STRING, "(not set)");
1090+
apr_hash_set(c->formats, "top", APR_HASH_KEY_STRING, "(not set)");
1091+
apr_hash_set(c->formats, "top_x", APR_HASH_KEY_STRING, "(not set)");
1092+
apr_hash_set(c->formats, "top_y", APR_HASH_KEY_STRING, "(not set)");
1093+
apr_hash_set(c->formats, "inv_top_x", APR_HASH_KEY_STRING, "(not set)");
1094+
apr_hash_set(c->formats, "inv_top_y", APR_HASH_KEY_STRING, "(not set)");
10701095
for (hi = apr_hash_first(ctx.pool, c->formats)
10711096
; hi
10721097
; hi = apr_hash_next(hi))
@@ -1089,6 +1114,13 @@ int main(int argc, char * argv[])
10891114
text = NULL;
10901115
if (node) text = node->txt;
10911116
if (text) c->ycount = (int)strtol(text, NULL, 10);
1117+
1118+
// Read top
1119+
c->top = -1;
1120+
node = ezxml_child(c->node, "top");
1121+
text = NULL;
1122+
if (node) text = node->txt;
1123+
if (text) c->top = (int)strtol(text, NULL, 10);
10921124
}
10931125

10941126

@@ -1237,6 +1269,7 @@ int main(int argc, char * argv[])
12371269
mapcache_extent_i db_region_bbox;
12381270
int dbx_has_inv = FALSE;
12391271
int dby_has_inv = FALSE;
1272+
int file_zoom_level;
12401273

12411274
// Select cache according to zoom level
12421275
for ( cid=0 ; cid < caches->nelts ; cid++ ) {
@@ -1260,16 +1293,45 @@ int main(int argc, char * argv[])
12601293

12611294
// Compute region bounding box expressed in tiles and in DB files for the
12621295
// current zoom level
1263-
mapcache_grid_get_xy(&ctx, grid, region_bbox.minx, region_bbox.miny, iz,
1264-
&(til_region_bbox.minx), &(til_region_bbox.miny));
1265-
mapcache_grid_get_xy(&ctx, grid, region_bbox.maxx, region_bbox.maxy, iz,
1266-
&(til_region_bbox.maxx), &(til_region_bbox.maxy));
1296+
file_zoom_level = iz;
1297+
if (cache->top > 0) file_zoom_level = cache->top;
1298+
mapcache_grid_get_xy(&ctx, grid, region_bbox.minx, region_bbox.miny,
1299+
file_zoom_level, &(til_region_bbox.minx), &(til_region_bbox.miny));
1300+
mapcache_grid_get_xy(&ctx, grid, region_bbox.maxx, region_bbox.maxy,
1301+
file_zoom_level, &(til_region_bbox.maxx), &(til_region_bbox.maxy));
1302+
if (til_region_bbox.minx > til_region_bbox.maxx) {
1303+
int swap = til_region_bbox.maxx;
1304+
til_region_bbox.maxx = til_region_bbox.minx;
1305+
til_region_bbox.minx = swap;
1306+
}
1307+
if (til_region_bbox.miny > til_region_bbox.maxy) {
1308+
int swap = til_region_bbox.maxy;
1309+
til_region_bbox.maxy = til_region_bbox.miny;
1310+
til_region_bbox.miny = swap;
1311+
}
12671312

12681313
dbx_has_inv = strstr(cache->dbfile,"{inv_x}")
1269-
|| strstr(cache->dbfile,"{inv_div_x}");
1314+
|| strstr(cache->dbfile,"{inv_div_x}")
1315+
|| strstr(cache->dbfile,"{inv_top_x}");
12701316
dby_has_inv = strstr(cache->dbfile,"{inv_y}")
1271-
|| strstr(cache->dbfile,"{inv_div_y}");
1272-
if ((cache->xcount > 0) && (cache->ycount > 0)) {
1317+
|| strstr(cache->dbfile,"{inv_div_y}")
1318+
|| strstr(cache->dbfile,"{inv_top_y}");
1319+
if (cache->top > 0) {
1320+
if (dbx_has_inv) {
1321+
db_region_bbox.minx = grid->levels[cache->top]->maxx-1 - til_region_bbox.maxx;
1322+
db_region_bbox.maxx = grid->levels[cache->top]->maxx-1 - til_region_bbox.minx;
1323+
} else {
1324+
db_region_bbox.minx = til_region_bbox.minx;
1325+
db_region_bbox.maxx = til_region_bbox.maxx;
1326+
}
1327+
if (dby_has_inv) {
1328+
db_region_bbox.miny = grid->levels[cache->top]->maxy-1 - til_region_bbox.maxy;
1329+
db_region_bbox.maxy = grid->levels[cache->top]->maxy-1 - til_region_bbox.miny;
1330+
} else {
1331+
db_region_bbox.miny = til_region_bbox.miny;
1332+
db_region_bbox.maxy = til_region_bbox.maxy;
1333+
}
1334+
} else if ((cache->xcount > 0) && (cache->ycount > 0)) {
12731335
if (dbx_has_inv) {
12741336
int inv_minx = grid->levels[iz]->maxx - til_region_bbox.minx;
12751337
int inv_maxx = grid->levels[iz]->maxx - til_region_bbox.maxx;
@@ -1340,7 +1402,7 @@ int main(int argc, char * argv[])
13401402
// Retrieve DB file name and check for its existence (read access)
13411403
file_name = dbfilename(ctx.pool, cache->dbfile, tileset, grid,
13421404
dimensions, cache->formats, iz, ix, iy, cache->xcount,
1343-
cache->ycount);
1405+
cache->ycount, cache->top);
13441406

13451407
// Unless this has already been done on this file,
13461408
// Retrieve file size and count cached tiles regardless the region of
@@ -1379,7 +1441,22 @@ int main(int argc, char * argv[])
13791441
}
13801442

13811443
// Compute file bounding box expressed in tiles
1382-
if ((cache->xcount > 0) && (cache->ycount > 0)) {
1444+
if (cache->top > 0) {
1445+
if (dbx_has_inv) {
1446+
til_file_bbox.minx = grid->levels[cache->top]->maxx-1 - ix;
1447+
til_file_bbox.maxx = til_file_bbox.minx;
1448+
} else {
1449+
til_file_bbox.minx = ix;
1450+
til_file_bbox.maxx = til_file_bbox.minx;
1451+
}
1452+
if (dby_has_inv) {
1453+
til_file_bbox.miny = grid->levels[cache->top]->maxy-1 - iy;
1454+
til_file_bbox.maxy = til_file_bbox.miny;
1455+
} else {
1456+
til_file_bbox.miny = iy;
1457+
til_file_bbox.maxy = til_file_bbox.miny;
1458+
}
1459+
} else if ((cache->xcount > 0) && (cache->ycount > 0)) {
13831460
if (dbx_has_inv) {
13841461
til_file_bbox.maxx = grid->levels[iz]->maxx-1 - ix * cache->xcount;
13851462
til_file_bbox.minx = til_file_bbox.maxx + cache->xcount + 1;
@@ -1412,15 +1489,25 @@ int main(int argc, char * argv[])
14121489
// Compute file bounding box expressed in grid units for the current
14131490
// zoom level
14141491
mapcache_grid_get_tile_extent(&ctx, grid, til_file_bbox.minx,
1415-
til_file_bbox.miny, iz, &temp_bbox);
1492+
til_file_bbox.miny, file_zoom_level, &temp_bbox);
14161493
if (GC_HAS_ERROR(&ctx)) goto failure;
14171494
file_bbox.minx = temp_bbox.minx;
14181495
file_bbox.miny = temp_bbox.miny;
14191496
mapcache_grid_get_tile_extent(&ctx, grid, til_file_bbox.maxx,
1420-
til_file_bbox.maxy, iz, &temp_bbox);
1497+
til_file_bbox.maxy, file_zoom_level, &temp_bbox);
14211498
if (GC_HAS_ERROR(&ctx)) goto failure;
14221499
file_bbox.maxx = temp_bbox.maxx;
14231500
file_bbox.maxy = temp_bbox.maxy;
1501+
if (file_bbox.minx > file_bbox.maxx) {
1502+
int swap = file_bbox.maxx;
1503+
file_bbox.maxx = file_bbox.minx;
1504+
file_bbox.minx = swap;
1505+
}
1506+
if (file_bbox.miny > file_bbox.maxy) {
1507+
int swap = file_bbox.maxy;
1508+
file_bbox.maxy = file_bbox.miny;
1509+
file_bbox.miny = swap;
1510+
}
14241511

14251512
// Compute part of region of interest within file bounding box
14261513
#ifdef USE_CLIPPERS
@@ -1487,6 +1574,16 @@ int main(int argc, char * argv[])
14871574
mapcache_grid_get_xy(&ctx, grid, region_in_file_bbox.maxx-res,
14881575
region_in_file_bbox.maxy-res, iz, &(til_region_in_file_bbox.maxx),
14891576
&(til_region_in_file_bbox.maxy));
1577+
if (til_region_in_file_bbox.minx > til_region_in_file_bbox.maxx) {
1578+
int swap = til_region_in_file_bbox.maxx;
1579+
til_region_in_file_bbox.maxx = til_region_in_file_bbox.minx;
1580+
til_region_in_file_bbox.minx = swap;
1581+
}
1582+
if (til_region_in_file_bbox.miny > til_region_in_file_bbox.maxy) {
1583+
int swap = til_region_in_file_bbox.maxy;
1584+
til_region_in_file_bbox.maxy = til_region_in_file_bbox.miny;
1585+
til_region_in_file_bbox.miny = swap;
1586+
}
14901587
if ((cache->xcount > 0) && (cache->ycount > 0)) {
14911588
if (til_region_in_file_bbox.maxx>(til_file_bbox.minx+cache->xcount-1))
14921589
{

lib/cache_sqlite.c

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,10 @@ struct mapcache_cache_sqlite {
7171
void (*bind_stmt)(mapcache_context *ctx, void *stmt, mapcache_cache_sqlite *cache, mapcache_tile *tile);
7272
int n_prepared_statements;
7373
int detect_blank;
74-
char *x_fmt,*y_fmt,*z_fmt,*inv_x_fmt,*inv_y_fmt,*div_x_fmt,*div_y_fmt,*inv_div_x_fmt,*inv_div_y_fmt;
74+
char *x_fmt,*y_fmt,*z_fmt,*inv_x_fmt,*inv_y_fmt,*div_x_fmt,*div_y_fmt,*inv_div_x_fmt,*inv_div_y_fmt,
75+
*top_fmt,*top_x_fmt,*top_y_fmt,*inv_top_x_fmt,*inv_top_y_fmt;
7576
int count_x, count_y;
77+
int top;
7678
};
7779

7880

@@ -277,6 +279,34 @@ static void _mapcache_cache_sqlite_filename_for_tile(mapcache_context *ctx, mapc
277279
apr_psprintf(ctx->pool,dcache->inv_y_fmt,(tile->grid_link->grid->levels[tile->z]->maxy - tile->y - 1)/dcache->count_y*dcache->count_y));
278280

279281
}
282+
283+
if (dcache->top > 0) {
284+
while(strstr(*path,"{top}"))
285+
*path = mapcache_util_str_replace(ctx->pool,*path, "{top}",
286+
apr_psprintf(ctx->pool,dcache->top_fmt,dcache->top));
287+
while(strstr(*path,"{top_x}"))
288+
*path = mapcache_util_str_replace(ctx->pool,*path, "{top_x}",
289+
apr_psprintf(ctx->pool,dcache->top_x_fmt,
290+
tile->x * tile->grid_link->grid->levels[dcache->top]->maxx
291+
/ tile->grid_link->grid->levels[tile->z]->maxx));
292+
while(strstr(*path,"{top_y}"))
293+
*path = mapcache_util_str_replace(ctx->pool,*path, "{top_y}",
294+
apr_psprintf(ctx->pool,dcache->top_y_fmt,
295+
tile->y * tile->grid_link->grid->levels[dcache->top]->maxy
296+
/ tile->grid_link->grid->levels[tile->z]->maxy));
297+
while(strstr(*path,"{inv_top_x}"))
298+
*path = mapcache_util_str_replace(ctx->pool,*path, "{inv_top_x}",
299+
apr_psprintf(ctx->pool,dcache->inv_top_x_fmt,
300+
tile->grid_link->grid->levels[dcache->top]->maxx - 1
301+
- tile->x * tile->grid_link->grid->levels[dcache->top]->maxx
302+
/ tile->grid_link->grid->levels[tile->z]->maxx));
303+
while(strstr(*path,"{inv_top_y}"))
304+
*path = mapcache_util_str_replace(ctx->pool,*path, "{inv_top_y}",
305+
apr_psprintf(ctx->pool,dcache->inv_top_y_fmt,
306+
tile->grid_link->grid->levels[dcache->top]->maxy - 1
307+
- tile->y * tile->grid_link->grid->levels[dcache->top]->maxy
308+
/ tile->grid_link->grid->levels[tile->z]->maxy));
309+
}
280310
}
281311

282312
if(!*path) {
@@ -876,6 +906,26 @@ static void _mapcache_cache_sqlite_configuration_parse_xml(mapcache_context *ctx
876906
if(fmt && *fmt) {
877907
cache->inv_div_y_fmt = apr_pstrdup(ctx->pool,fmt);
878908
}
909+
fmt = (char*)ezxml_attr(cur_node,"top_fmt");
910+
if(fmt && *fmt) {
911+
cache->top_fmt = apr_pstrdup(ctx->pool,fmt);
912+
}
913+
fmt = (char*)ezxml_attr(cur_node,"top_x_fmt");
914+
if(fmt && *fmt) {
915+
cache->top_x_fmt = apr_pstrdup(ctx->pool,fmt);
916+
}
917+
fmt = (char*)ezxml_attr(cur_node,"top_y_fmt");
918+
if(fmt && *fmt) {
919+
cache->top_y_fmt = apr_pstrdup(ctx->pool,fmt);
920+
}
921+
fmt = (char*)ezxml_attr(cur_node,"inv_top_x_fmt");
922+
if(fmt && *fmt) {
923+
cache->inv_top_x_fmt = apr_pstrdup(ctx->pool,fmt);
924+
}
925+
fmt = (char*)ezxml_attr(cur_node,"inv_top_y_fmt");
926+
if(fmt && *fmt) {
927+
cache->inv_top_y_fmt = apr_pstrdup(ctx->pool,fmt);
928+
}
879929
}
880930

881931
cache->detect_blank = 0;
@@ -939,6 +989,16 @@ static void _mapcache_cache_sqlite_configuration_parse_xml(mapcache_context *ctx
939989
return;
940990
}
941991
}
992+
993+
cur_node = ezxml_child(node,"top");
994+
if(cur_node && cur_node->txt && *cur_node->txt) {
995+
char *endptr;
996+
cache->top = (int)strtol(cur_node->txt,&endptr,10);
997+
if(*endptr != 0) {
998+
ctx->set_error(ctx,400,"failed to parse top value %s for sqlite cache %s", cur_node->txt,cache->cache.name);
999+
return;
1000+
}
1001+
}
9421002
}
9431003

9441004
/**
@@ -1018,8 +1078,11 @@ mapcache_cache* mapcache_cache_sqlite_create(mapcache_context *ctx)
10181078
cache->x_fmt = cache->y_fmt = cache->z_fmt
10191079
= cache->inv_x_fmt = cache->inv_y_fmt
10201080
= cache->div_x_fmt = cache->div_y_fmt
1021-
= cache->inv_div_x_fmt = cache->inv_div_y_fmt = apr_pstrdup(ctx->pool,"%d");
1081+
= cache->inv_div_x_fmt = cache->inv_div_y_fmt
1082+
= cache->top_fmt = cache->top_x_fmt = cache->top_y_fmt
1083+
= cache->inv_top_x_fmt = cache->inv_top_y_fmt = apr_pstrdup(ctx->pool,"%d");
10221084
cache->count_x = cache->count_y = -1;
1085+
cache->top = -1;
10231086
return (mapcache_cache*)cache;
10241087
}
10251088

0 commit comments

Comments
 (0)