static void* APR_THREAD_FUNC seed_thread(apr_thread_t *thread, void *data) #endif { mapcache_tile *tile; mapcache_context seed_ctx = ctx; seed_ctx.log = seed_log; apr_pool_create(&seed_ctx.pool,ctx.pool); tile = mapcache_tileset_tile_create(ctx.pool, tileset, grid_link); tile->dimensions = dimensions; while(1) { struct seed_cmd cmd; apr_status_t ret; apr_pool_clear(seed_ctx.pool); ret = pop_queue(&cmd); if(ret != APR_SUCCESS || cmd.command == MAPCACHE_CMD_STOP) break; tile->x = cmd.x; tile->y = cmd.y; tile->z = cmd.z; if(cmd.command == MAPCACHE_CMD_SEED) { /* aquire a lock on the metatile ?*/ mapcache_metatile *mt = mapcache_tileset_metatile_get(&seed_ctx, tile); int isLocked = mapcache_lock_or_wait_for_resource(&seed_ctx, mapcache_tileset_metatile_resource_key(&seed_ctx,mt)); if(isLocked == MAPCACHE_TRUE) { /* this will query the source to create the tiles, and save them to the cache */ mapcache_tileset_render_metatile(&seed_ctx, mt); mapcache_unlock_resource(&seed_ctx, mapcache_tileset_metatile_resource_key(&seed_ctx,mt)); } } else if (cmd.command == MAPCACHE_CMD_TRANSFER) { int i; mapcache_metatile *mt = mapcache_tileset_metatile_get(&seed_ctx, tile); for (i = 0; i < mt->ntiles; i++) { mapcache_tile *subtile = &mt->tiles[i]; mapcache_tileset_tile_get(&seed_ctx, subtile); subtile->tileset = tileset_transfer; tileset_transfer->cache->tile_set(&seed_ctx, subtile); } } else { //CMD_DELETE mapcache_tileset_tile_delete(&seed_ctx,tile,MAPCACHE_TRUE); } if(seed_ctx.get_error(&seed_ctx)) { error_detected++; ctx.log(&ctx,MAPCACHE_INFO,seed_ctx.get_error_message(&seed_ctx)); } } #ifdef USE_FORK return 0; #else apr_thread_exit(thread,MAPCACHE_SUCCESS); return NULL; #endif }
void _create_capabilities_kml(mapcache_context *ctx, mapcache_request_get_capabilities *req, char *url, char *path_info, mapcache_cfg *cfg) { mapcache_request_get_capabilities_kml *request = (mapcache_request_get_capabilities_kml*)req; char *caps; const char *onlineresource = apr_table_get(cfg->metadata,"url"); int i, j; if(!onlineresource) { onlineresource = url; } request->request.mime_type = apr_pstrdup(ctx->pool,"application/vnd.google-earth.kml+xml"); assert(request->tile || (request->grid && request->tileset)); /* if we have no specific tile, create a kml document referencing all the tiles of the first level in the grid*/ if(!request->tile) { mapcache_extent extent = request->grid->restricted_extent?*(request->grid->restricted_extent):request->grid->grid->extent; caps = apr_psprintf(ctx->pool, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" "<kml xmlns=\"http://earth.google.com/kml/2.1\">\n" " <Document>\n" " <Region>\n" " <Lod>\n" " <minLodPixels>128</minLodPixels><maxLodPixels>512</maxLodPixels>\n" " </Lod>\n" " <LatLonAltBox>\n" " <north>%f</north><south>%f</south>\n" " <east>%f</east><west>%f</west>\n" " </LatLonAltBox>\n" " </Region>\n", extent.maxy,extent.miny,extent.maxx,extent.minx); for(i=request->grid->grid_limits[0].minx; i<request->grid->grid_limits[0].maxx; i++) { for(j=request->grid->grid_limits[0].miny; j<request->grid->grid_limits[0].maxy; j++) { mapcache_tile *t = mapcache_tileset_tile_create(ctx->pool, request->tileset, request->grid); mapcache_extent bb; t->x = i; t->y = j; t->z = 0; mapcache_grid_get_extent(ctx, t->grid_link->grid, t->x, t->y, t->z, &bb); caps = apr_psprintf(ctx->pool, "%s" " <NetworkLink>\n" " <name>%d%d%d</name>\n" " <Region>\n" " <Lod>\n" " <minLodPixels>128</minLodPixels><maxLodPixels>-1</maxLodPixels>\n" " </Lod>\n" " <LatLonAltBox>\n" " <north>%f</north><south>%f</south>\n" " <east>%f</east><west>%f</west>\n" " </LatLonAltBox>\n" " </Region>\n" " <Link>\n" " <href>%s/kml/%s@%s/%d/%d/%d.kml</href>\n" " <viewRefreshMode>onRegion</viewRefreshMode>\n" " </Link>\n" " </NetworkLink>\n", caps, t->x, t->y, t->z, bb.maxy, bb.miny, bb.maxx, bb.minx, onlineresource, request->tileset->name, request->grid->grid->name, t->z, t->x, t->y); } } caps = apr_pstrcat(ctx->pool, caps, " </Document>\n</kml>\n", NULL); } else { mapcache_extent bbox; mapcache_grid_get_extent(ctx, request->tile->grid_link->grid, request->tile->x, request->tile->y, request->tile->z, &bbox); caps = apr_psprintf(ctx->pool, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" "<kml xmlns=\"http://earth.google.com/kml/2.1\">\n" " <Document>\n" " <Region>\n" " <Lod>\n" " <minLodPixels>128</minLodPixels><maxLodPixels>%d</maxLodPixels>\n" " </Lod>\n" " <LatLonAltBox>\n" " <north>%f</north><south>%f</south>\n" " <east>%f</east><west>%f</west>\n" " </LatLonAltBox>\n" " </Region>\n" " <GroundOverlay>\n" " <drawOrder>0</drawOrder>\n" " <Icon>\n" " <href>%s/tms/1.0.0/%s@%s/%d/%d/%d.%s</href>\n" " </Icon>\n" " <LatLonBox>\n" " <north>%f</north><south>%f</south>\n" " <east>%f</east><west>%f</west>\n" " </LatLonBox>\n" " </GroundOverlay>\n", (request->tile->z == request->tile->grid_link->grid->nlevels - 1) ? -1 : 512, bbox.maxy, bbox.miny, bbox.maxx, bbox.miny, onlineresource, request->tile->tileset->name, request->tile->grid_link->grid->name, request->tile->z, request->tile->x, request->tile->y, (request->tile->tileset->format) ? request->tile->tileset->format->extension : "png", bbox.maxy, bbox.miny, bbox.maxx, bbox.minx); if (request->tile->z < request->tile->grid_link->grid->nlevels - 1) { for (i = 0; i <= 1; i++) { for (j = 0; j <= 1; j++) { /* compute the addresses of the child tiles */ mapcache_tile *t = mapcache_tileset_tile_create(ctx->pool, request->tile->tileset, request->tile->grid_link); mapcache_extent bb; t->x = (request->tile->x << 1) + i; t->y = (request->tile->y << 1) + j; t->z = request->tile->z + 1; mapcache_grid_get_extent(ctx, t->grid_link->grid, t->x, t->y, t->z, &bb); caps = apr_psprintf(ctx->pool, "%s" " <NetworkLink>\n" " <name>%d%d%d</name>\n" " <Region>\n" " <Lod>\n" " <minLodPixels>128</minLodPixels><maxLodPixels>-1</maxLodPixels>\n" " </Lod>\n" " <LatLonAltBox>\n" " <north>%f</north><south>%f</south>\n" " <east>%f</east><west>%f</west>\n" " </LatLonAltBox>\n" " </Region>\n" " <Link>\n" " <href>%s/kml/%s@%s/%d/%d/%d.kml</href>\n" " <viewRefreshMode>onRegion</viewRefreshMode>\n" " </Link>\n" " </NetworkLink>\n", caps, t->x, t->y, t->z, bb.maxy, bb.miny, bb.maxx, bb.minx, onlineresource, request->tile->tileset->name, request->tile->grid_link->grid->name, t->z, t->x, t->y); } } } caps = apr_pstrcat(ctx->pool, caps, " </Document>\n</kml>\n", NULL); } request->request.capabilities = caps; }
void cmd_thread() { int n; mapcache_tile *tile; int z = minzoom; int x = grid_link->grid_limits[z][0]; int y = grid_link->grid_limits[z][1]; mapcache_context cmd_ctx = ctx; apr_pool_create(&cmd_ctx.pool,ctx.pool); tile = mapcache_tileset_tile_create(ctx.pool, tileset, grid_link); tile->dimensions = dimensions; if(seed_mode == MAPCACHE_SEED_DEPTH_FIRST) { do { tile->x = x; tile->y = y; tile->z = z; cmd_recurse(&cmd_ctx,tile); x += tileset->metasize_x; if( x >= grid_link->grid_limits[z][2] ) { y += tileset->metasize_y; if( y < grid_link->grid_limits[z][3]) { x = grid_link->grid_limits[z][0]; } } } while ( x < grid_link->grid_limits[z][2] && y < grid_link->grid_limits[z][3] ); } else { while(1) { int action; apr_pool_clear(cmd_ctx.pool); if(sig_int_received || error_detected) { //stop if we were asked to stop by hitting ctrl-c //remove all items from the queue struct seed_cmd entry; while (trypop_queue(&entry)!=APR_EAGAIN) {queuedtilestot--;} break; } tile->x = x; tile->y = y; tile->z = z; action = examine_tile(&cmd_ctx, tile); if(action == MAPCACHE_CMD_SEED || action == MAPCACHE_CMD_TRANSFER) { //current x,y,z needs seeding, add it to the queue struct seed_cmd cmd; cmd.x = x; cmd.y = y; cmd.z = z; cmd.command = action; push_queue(cmd); queuedtilestot++; progresslog(x,y,z); } //compute next x,y,z x += tileset->metasize_x; if(x >= grid_link->grid_limits[z][2]) { //x is too big, increment y y += tileset->metasize_y; if(y >= grid_link->grid_limits[z][3]) { //y is too big, increment z z += 1; if(z > maxzoom) break; //we've finished seeding y = grid_link->grid_limits[z][1]; //set y to the smallest value for current z } x = grid_link->grid_limits[z][0]; //set x to smallest value for current z } } } //instruct rendering threads to stop working for(n=0;n<nthreads;n++) { struct seed_cmd cmd; cmd.command = MAPCACHE_CMD_STOP; push_queue(cmd); } if(error_detected && ctx.get_error_message(&ctx)) { printf("%s\n",ctx.get_error_message(&ctx)); } }
void _create_capabilities_kml(mapcache_context *ctx, mapcache_request_get_capabilities *req, char *url, char *path_info, mapcache_cfg *cfg) { mapcache_request_get_capabilities_kml *request = (mapcache_request_get_capabilities_kml*)req; char *caps; const char *onlineresource = apr_table_get(cfg->metadata,"url"); double bbox[4]; if(!onlineresource) { onlineresource = url; } request->request.mime_type = apr_pstrdup(ctx->pool,"application/vnd.google-earth.kml+xml"); mapcache_grid_get_extent(ctx,request->tile->grid_link->grid, request->tile->x, request->tile->y, request->tile->z, bbox); caps = apr_psprintf(ctx->pool,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" "<kml xmlns=\"http://earth.google.com/kml/2.1\">\n" " <Document>\n" " <Region>\n" " <Lod>\n" " <minLodPixels>128</minLodPixels><maxLodPixels>%d</maxLodPixels>\n" " </Lod>\n" " <LatLonAltBox>\n" " <north>%f</north><south>%f</south>\n" " <east>%f</east><west>%f</west>\n" " </LatLonAltBox>\n" " </Region>\n" " <GroundOverlay>\n" " <drawOrder>0</drawOrder>\n" " <Icon>\n" " <href>%s/tms/1.0.0/%s@%s/%d/%d/%d.%s</href>\n" " </Icon>\n" " <LatLonBox>\n" " <north>%f</north><south>%f</south>\n" " <east>%f</east><west>%f</west>\n" " </LatLonBox>\n" " </GroundOverlay>\n", (request->tile->z == request->tile->grid_link->grid->nlevels-1)?-1:512, bbox[3],bbox[1],bbox[2],bbox[0], onlineresource,request->tile->tileset->name,request->tile->grid_link->grid->name, request->tile->z, request->tile->x,request->tile->y, (request->tile->tileset->format)?request->tile->tileset->format->extension:"png", bbox[3],bbox[1],bbox[2],bbox[0]); if(request->tile->z < request->tile->grid_link->grid->nlevels-1) { int i,j; for(i=0;i<=1;i++) { for(j=0;j<=1;j++) { mapcache_tile *t = mapcache_tileset_tile_create(ctx->pool,request->tile->tileset, request->tile->grid_link); double bb[4]; t->x = (request->tile->x << 1) +i; t->y = (request->tile->y << 1) +j; t->z = request->tile->z + 1; mapcache_grid_get_extent(ctx,t->grid_link->grid, t->x, t->y, t->z, bb); caps = apr_psprintf(ctx->pool,"%s" " <NetworkLink>\n" " <name>%d%d%d</name>\n" " <Region>\n" " <Lod>\n" " <minLodPixels>128</minLodPixels><maxLodPixels>-1</maxLodPixels>\n" " </Lod>\n" " <LatLonAltBox>\n" " <north>%f</north><south>%f</south>\n" " <east>%f</east><west>%f</west>\n" " </LatLonAltBox>\n" " </Region>\n" " <Link>\n" " <href>%s/kml/%s@%s/%d/%d/%d.kml</href>\n" " <viewRefreshMode>onRegion</viewRefreshMode>\n" " </Link>\n" " </NetworkLink>\n", caps,t->x,t->y,t->z, bb[3],bb[1],bb[2],bb[0], onlineresource,request->tile->tileset->name,request->tile->grid_link->grid->name, t->z, t->x,t->y); } } } caps = apr_pstrcat(ctx->pool,caps," </Document>\n</kml>\n",NULL); request->request.capabilities = caps; }