static void _mapcache_cache_bdb_set(mapcache_context *ctx, mapcache_tile *tile) { DBT key,data; int ret; mapcache_cache_bdb *cache = (mapcache_cache_bdb*)tile->tileset->cache; char *skey = mapcache_util_get_tile_key(ctx,tile,cache->key_template,NULL,NULL); struct bdb_env *benv = _bdb_get_conn(ctx,tile,0); GC_CHECK_ERROR(ctx); apr_time_t now = apr_time_now(); memset(&key, 0, sizeof(DBT)); memset(&data, 0, sizeof(DBT)); if(!tile->encoded_data) { tile->encoded_data = tile->tileset->format->write(ctx, tile->raw_image, tile->tileset->format); GC_CHECK_ERROR(ctx); } mapcache_buffer_append(tile->encoded_data,sizeof(apr_time_t),&now); key.data = skey; key.size = strlen(skey)+1; data.data = tile->encoded_data->buf; data.size = tile->encoded_data->size; ret = benv->db->put(benv->db,NULL,&key,&data,0); tile->encoded_data->size -= sizeof(apr_time_t); if(ret != 0) { ctx->set_error(ctx,500,"dbd backend failed on tile_set: %s", db_strerror(ret)); } else { ret = benv->db->sync(benv->db,0); if(ret) ctx->set_error(ctx,500,"bdb backend sync failure on tile_set: %s",db_strerror(ret)); } _bdb_release_conn(ctx,tile,benv); }
static void _mapcache_cache_mbtiles_multi_set(mapcache_context *ctx, mapcache_tile *tiles, int ntiles) { struct sqlite_conn *conn = NULL; int i; /* decode/encode image data before going into the sqlite write lock */ for (i = 0; i < ntiles; i++) { mapcache_tile *tile = &tiles[i]; if(!tile->raw_image) { tile->raw_image = mapcache_imageio_decode(ctx, tile->encoded_data); GC_CHECK_ERROR(ctx); } /* only encode to image format if tile is not blank */ if (mapcache_image_blank_color(tile->raw_image) != MAPCACHE_TRUE && !tile->encoded_data) { tile->encoded_data = tile->tileset->format->write(ctx, tile->raw_image, tile->tileset->format); GC_CHECK_ERROR(ctx); } } conn = _sqlite_get_conn(ctx, &tiles[0], 0); GC_CHECK_ERROR(ctx); sqlite3_exec(conn->handle, "BEGIN TRANSACTION", 0, 0, 0); for (i = 0; i < ntiles; i++) { mapcache_tile *tile = &tiles[i]; _single_mbtile_set(ctx,tile,conn); if(GC_HAS_ERROR(ctx)) break; } if (GC_HAS_ERROR(ctx)) { sqlite3_exec(conn->handle, "ROLLBACK TRANSACTION", 0, 0, 0); } else { sqlite3_exec(conn->handle, "END TRANSACTION", 0, 0, 0); } _sqlite_release_conn(ctx, &tiles[0], conn); }
/** * \brief push tile data to memcached * * writes the content of mapcache_tile::data to the configured memcached instance(s) * \returns MAPCACHE_FAILURE if there is no data to write, or if the tile isn't locked * \returns MAPCACHE_SUCCESS if the tile has been successfully written * \private \memberof mapcache_cache_memcache * \sa mapcache_cache::tile_set() */ static void _mapcache_cache_memcache_set(mapcache_context *ctx, mapcache_tile *tile) { char *key; int rv; /* set expiration to one day if not configured */ int expires = 86400; if(tile->tileset->auto_expire) expires = tile->tileset->auto_expire; mapcache_cache_memcache *cache = (mapcache_cache_memcache*)tile->tileset->cache; key = mapcache_util_get_tile_key(ctx, tile,NULL," \r\n\t\f\e\a\b","#"); GC_CHECK_ERROR(ctx); if(!tile->encoded_data) { tile->encoded_data = tile->tileset->format->write(ctx, tile->raw_image, tile->tileset->format); GC_CHECK_ERROR(ctx); } /* concatenate the current time to the end of the memcache data so we can extract it out * when we re-get the tile */ char *data = calloc(1,tile->encoded_data->size+sizeof(apr_time_t)); apr_time_t now = apr_time_now(); apr_pool_cleanup_register(ctx->pool, data, (void*)free, apr_pool_cleanup_null); memcpy(data,tile->encoded_data->buf,tile->encoded_data->size); memcpy(&(data[tile->encoded_data->size]),&now,sizeof(apr_time_t)); rv = apr_memcache_set(cache->memcache,key,data,tile->encoded_data->size+sizeof(apr_time_t),expires,0); if(rv != APR_SUCCESS) { ctx->set_error(ctx,500,"failed to store tile %d %d %d to memcache cache %s", tile->x,tile->y,tile->z,cache->cache.name); return; } }
static void _mapcache_cache_riak_delete(mapcache_context *ctx, mapcache_cache *pcache, mapcache_tile *tile) { int error; RIACK_STRING key; struct RIACK_CLIENT *client; struct RIACK_DEL_PROPERTIES properties; mapcache_pooled_connection *pc; mapcache_cache_riak *cache = (mapcache_cache_riak*)pcache; memset(&properties, 0, sizeof(struct RIACK_DEL_PROPERTIES)); key.value = mapcache_util_get_tile_key(ctx, tile, NULL, " \r\n\t\f\e\a\b", "#"); GC_CHECK_ERROR(ctx); key.len = strlen(key.value); pc = _riak_get_connection(ctx, cache, tile); GC_CHECK_ERROR(ctx); client = pc->connection; properties.rw_use = 1; properties.rw = (4294967295 - 3); // Special value meaning "ALL" error = riack_delete(client, cache->bucket, key, &properties); mapcache_connection_pool_release_connection(ctx,pc); if (error != RIACK_SUCCESS) { ctx->set_error(ctx, 500, "riak: failed to delete key %s: %d", key, error); } }
/** * \brief push tile data to memcached * * writes the content of mapcache_tile::data to the configured memcached instance(s) * \returns MAPCACHE_FAILURE if there is no data to write, or if the tile isn't locked * \returns MAPCACHE_SUCCESS if the tile has been successfully written * \private \memberof mapcache_cache_memcache * \sa mapcache_cache::tile_set() */ static void _mapcache_cache_memcache_set(mapcache_context *ctx, mapcache_cache *pcache, mapcache_tile *tile) { char *key; int rv; /* set no expiration if not configured */ int expires =0; mapcache_buffer *encoded_data = NULL; mapcache_cache_memcache *cache = (mapcache_cache_memcache*)pcache; mapcache_pooled_connection *pc; struct mapcache_memcache_pooled_connection *mpc; pc = _mapcache_memcache_get_conn(ctx,cache,tile); GC_CHECK_ERROR(ctx); mpc = pc->connection; key = mapcache_util_get_tile_key(ctx, tile,NULL," \r\n\t\f\e\a\b","#"); if(GC_HAS_ERROR(ctx)) goto cleanup; if(tile->tileset->auto_expire) expires = tile->tileset->auto_expire; if(cache->detect_blank) { if(!tile->raw_image) { tile->raw_image = mapcache_imageio_decode(ctx, tile->encoded_data); GC_CHECK_ERROR(ctx); } if(mapcache_image_blank_color(tile->raw_image) != MAPCACHE_FALSE) { encoded_data = mapcache_buffer_create(5,ctx->pool); ((char*)encoded_data->buf)[0] = '#'; memcpy(((char*)encoded_data->buf)+1,tile->raw_image->data,4); encoded_data->size = 5; } } if(!encoded_data) { if(!tile->encoded_data) { tile->encoded_data = tile->tileset->format->write(ctx, tile->raw_image, tile->tileset->format); if(GC_HAS_ERROR(ctx)) goto cleanup; } encoded_data = tile->encoded_data; } /* concatenate the current time to the end of the memcache data so we can extract it out * when we re-get the tile */ char *data = calloc(1,encoded_data->size+sizeof(apr_time_t)); apr_time_t now = apr_time_now(); apr_pool_cleanup_register(ctx->pool, data, (void*)free, apr_pool_cleanup_null); memcpy(data,encoded_data->buf,encoded_data->size); memcpy(&(data[encoded_data->size]),&now,sizeof(apr_time_t)); rv = apr_memcache_set(mpc->memcache,key,data,encoded_data->size+sizeof(apr_time_t),expires,0); if(rv != APR_SUCCESS) { ctx->set_error(ctx,500,"failed to store tile %d %d %d to memcache cache %s", tile->x,tile->y,tile->z,cache->cache.name); goto cleanup; } cleanup: _mapcache_memcache_release_conn(ctx,pc); }
void parseSource(mapcache_context *ctx, ezxml_t node, mapcache_cfg *config) { ezxml_t cur_node; char *name = NULL, *type = NULL; mapcache_source *source; name = (char*)ezxml_attr(node,"name"); type = (char*)ezxml_attr(node,"type"); if(!name || !strlen(name)) { ctx->set_error(ctx, 400, "mandatory attribute \"name\" not found in <source>"); return; } else { name = apr_pstrdup(ctx->pool, name); /* check we don't already have a source defined with this name */ if(mapcache_configuration_get_source(config, name)) { ctx->set_error(ctx, 400, "duplicate source with name \"%s\"",name); return; } } if(!type || !strlen(type)) { ctx->set_error(ctx, 400, "mandatory attribute \"type\" not found in <source>"); return; } source = NULL; if(!strcmp(type,"wms")) { source = mapcache_source_wms_create(ctx); } else if(!strcmp(type,"mapserver")) { source = mapcache_source_mapserver_create(ctx); } else if(!strcmp(type,"gdal")) { source = mapcache_source_gdal_create(ctx); } else if(!strcmp(type,"dummy")) { source = mapcache_source_dummy_create(ctx); } else { ctx->set_error(ctx, 400, "unknown source type %s for source \"%s\"", type, name); return; } if(source == NULL) { ctx->set_error(ctx, 400, "failed to parse source \"%s\"", name); return; } source->name = name; if ((cur_node = ezxml_child(node,"metadata")) != NULL) { parseMetadata(ctx, cur_node, source->metadata); GC_CHECK_ERROR(ctx); } source->configuration_parse_xml(ctx,node,source); GC_CHECK_ERROR(ctx); source->configuration_check(ctx,config,source); GC_CHECK_ERROR(ctx); mapcache_configuration_add_source(config,source,name); }
void _mapcache_source_wms_query(mapcache_context *ctx, mapcache_feature_info *fi) { mapcache_map *map = (mapcache_map*)fi; mapcache_source_wms *wms = (mapcache_source_wms*)map->tileset->source; apr_table_t *params = apr_table_clone(ctx->pool,wms->wms_default_params); apr_table_overlap(params,wms->getmap_params,0); apr_table_setn(params,"BBOX",apr_psprintf(ctx->pool,"%f,%f,%f,%f", map->extent.minx,map->extent.miny,map->extent.maxx,map->extent.maxy)); apr_table_setn(params,"REQUEST","GetFeatureInfo"); apr_table_setn(params,"WIDTH",apr_psprintf(ctx->pool,"%d",map->width)); apr_table_setn(params,"HEIGHT",apr_psprintf(ctx->pool,"%d",map->height)); apr_table_setn(params,"SRS",map->grid_link->grid->srs); apr_table_setn(params,"X",apr_psprintf(ctx->pool,"%d",fi->i)); apr_table_setn(params,"Y",apr_psprintf(ctx->pool,"%d",fi->j)); apr_table_setn(params,"INFO_FORMAT",fi->format); apr_table_overlap(params,wms->getfeatureinfo_params,0); if(map->dimensions && !apr_is_empty_table(map->dimensions)) { const apr_array_header_t *elts = apr_table_elts(map->dimensions); int i; for(i=0; i<elts->nelts; i++) { apr_table_entry_t entry = APR_ARRAY_IDX(elts,i,apr_table_entry_t); apr_table_setn(params,entry.key,entry.val); } } fi->data = mapcache_buffer_create(30000,ctx->pool); mapcache_http_do_request_with_params(ctx,wms->http,params,fi->data,NULL,NULL); GC_CHECK_ERROR(ctx); }
void parseDimensions(mapcache_context *ctx, ezxml_t node, mapcache_tileset *tileset) { ezxml_t dimension_node; apr_array_header_t *dimensions = apr_array_make(ctx->pool,1,sizeof(mapcache_dimension*)); for(dimension_node = ezxml_child(node,"dimension"); dimension_node; dimension_node = dimension_node->next) { char *name = (char*)ezxml_attr(dimension_node,"name"); char *type = (char*)ezxml_attr(dimension_node,"type"); char *unit = (char*)ezxml_attr(dimension_node,"unit"); char *default_value = (char*)ezxml_attr(dimension_node,"default"); mapcache_dimension *dimension = NULL; if(!name || !strlen(name)) { ctx->set_error(ctx, 400, "mandatory attribute \"name\" not found in <dimension>"); return; } if(type && *type) { if(!strcmp(type,"values")) { dimension = mapcache_dimension_values_create(ctx->pool); } else if(!strcmp(type,"regex")) { dimension = mapcache_dimension_regex_create(ctx->pool); } else if(!strcmp(type,"intervals")) { dimension = mapcache_dimension_intervals_create(ctx->pool); } else if(!strcmp(type,"time")) { ctx->set_error(ctx,501,"time dimension type not implemented yet"); return; dimension = mapcache_dimension_time_create(ctx->pool); } else { ctx->set_error(ctx,400,"unknown dimension type \"%s\"",type); return; } } else { ctx->set_error(ctx,400, "mandatory attribute \"type\" not found in <dimensions>"); return; } dimension->name = apr_pstrdup(ctx->pool,name); if(unit && *unit) { dimension->unit = apr_pstrdup(ctx->pool,unit); } if(default_value && *default_value) { dimension->default_value = apr_pstrdup(ctx->pool,default_value); } else { ctx->set_error(ctx,400,"dimension \"%s\" has no \"default\" attribute",dimension->name); return; } dimension->configuration_parse_xml(ctx,dimension,dimension_node); GC_CHECK_ERROR(ctx); APR_ARRAY_PUSH(dimensions,mapcache_dimension*) = dimension; } if(apr_is_empty_array(dimensions)) { ctx->set_error(ctx, 400, "<dimensions> for tileset \"%s\" has no dimensions defined (expecting <dimension> children)",tileset->name); return; } tileset->dimensions = dimensions; }
//------------------------------------------------------------------------------ void _mapcache_source_tms_render_map_elevation(mapcache_context *ctx, mapcache_map *map) { mapcache_source_tms *tms; int elevationblock; int zoom, x, y; char* url; double dx, dy; tms = (mapcache_source_tms*)map->tileset->source; elevationblock = map->grid_link->grid->elevationblock; _GetTileCoords(map, &zoom, &x, &y, tms->flipy); url = apr_psprintf(ctx->pool,"%s/1.0.0/%s/%i/%i/%i.%s", tms->url,tms->layer,zoom,x,y,tms->format); tms->http->url = apr_pstrdup(ctx->pool,url); map->encoded_data = mapcache_buffer_create(30000,ctx->pool); mapcache_http_do_request(ctx, tms->http, map->encoded_data, NULL, NULL); GC_CHECK_ERROR(ctx); if(!mapcache_imageio_is_valid_format(ctx,map->encoded_data)) { char *returned_data = apr_pstrndup(ctx->pool,(char*)map->encoded_data->buf,map->encoded_data->size); ctx->set_error(ctx, 502, "tms request for tileset %s returned an unsupported format:\n%s", map->tileset->name, returned_data); return; } map->raw_image = mapcache_imageio_decode(ctx, map->encoded_data); map->raw_image->is_elevation = MC_ELEVATION_YES; GC_CHECK_ERROR(ctx); //map->raw_image->stride = 4 * elevationblock; dx = fabs(map->grid_link->grid->extent.maxx-map->grid_link->grid->extent.minx); dy = fabs(map->grid_link->grid->extent.maxx-map->grid_link->grid->extent.minx); map->raw_image->x0 = map->extent.minx / dx * 2.0; map->raw_image->y0 = map->extent.miny / dy * 2.0; map->raw_image->x1 = map->extent.maxx / dx * 2.0; map->raw_image->y1 = map->extent.maxy / dy * 2.0; if (map->raw_image->w != elevationblock || map->raw_image->h != elevationblock) { ctx->set_error(ctx,500,"Error: size of heightmap from source is not configured propery!"); } }
static void _mapcache_cache_tc_delete(mapcache_context *ctx, mapcache_tile *tile) { struct tc_conn conn; mapcache_cache_tc *cache = (mapcache_cache_tc*)tile->tileset->cache; char *skey = mapcache_util_get_tile_key(ctx,tile,cache->key_template,NULL,NULL); conn = _tc_get_conn(ctx,tile,0); GC_CHECK_ERROR(ctx); tcbdbout2(conn.bdb, skey); _tc_release_conn(ctx,tile,conn); }
void mapcache_locker_fallback_parse_xml(mapcache_context *ctx, mapcache_locker *self, ezxml_t doc) { mapcache_locker_fallback *lm = (mapcache_locker_fallback*)self; ezxml_t node; lm->lockers = apr_array_make(ctx->pool,2,sizeof(mapcache_locker*)); for(node = ezxml_child(doc,"locker"); node; node = node->next) { mapcache_locker *child_locker; mapcache_config_parse_locker(ctx,node,&child_locker); GC_CHECK_ERROR(ctx); APR_ARRAY_PUSH(lm->lockers,mapcache_locker*) = child_locker; } }
static void _mapcache_cache_tc_set(mapcache_context *ctx, mapcache_tile *tile) { struct tc_conn conn; mapcache_cache_tc *cache = (mapcache_cache_tc*)tile->tileset->cache; char *skey = mapcache_util_get_tile_key(ctx,tile,cache->key_template,NULL,NULL); apr_time_t now = apr_time_now(); conn = _tc_get_conn(ctx,tile,0); GC_CHECK_ERROR(ctx); if(!tile->encoded_data) { tile->encoded_data = tile->tileset->format->write(ctx, tile->raw_image, tile->tileset->format); GC_CHECK_ERROR(ctx); } mapcache_buffer_append(tile->encoded_data,sizeof(apr_time_t),&now); if(!tcbdbput(conn.bdb, skey, strlen(skey), tile->encoded_data->buf, tile->encoded_data->size)) { int ecode = tcbdbecode(conn.bdb); ctx->set_error(ctx,500, "tokyocabinet put error: %s\n",tcbdberrmsg(ecode)); } _tc_release_conn(ctx,tile,conn); }
void mapcache_configuration_post_config(mapcache_context *ctx, mapcache_cfg *config) { apr_hash_index_t *cachei = apr_hash_first(ctx->pool,config->caches); while(cachei) { mapcache_cache *cache; const void *key; apr_ssize_t keylen; apr_hash_this(cachei,&key,&keylen,(void**)&cache); cache->configuration_post_config(ctx,cache,config); GC_CHECK_ERROR(ctx); cachei = apr_hash_next(cachei); } }
static void _mapcache_cache_disk_delete(mapcache_context *ctx, mapcache_tile *tile) { apr_status_t ret; char errmsg[120]; char *filename; ((mapcache_cache_disk*)tile->tileset->cache)->tile_key(ctx, tile, &filename); GC_CHECK_ERROR(ctx); ret = apr_file_remove(filename,ctx->pool); if(ret != APR_SUCCESS && !APR_STATUS_IS_ENOENT(ret)) { ctx->set_error(ctx, 500, "failed to remove file %s: %s",filename, apr_strerror(ret,errmsg,120)); } }
void mapcache_image_create_empty(mapcache_context *ctx, mapcache_cfg *cfg) { unsigned int color=0; /* create a transparent image for PNG, and a white one for jpeg */ if(cfg->default_image_format->mime_type && !strstr(cfg->default_image_format->mime_type,"png")) { color = 0xffffffff; } cfg->empty_image = cfg->default_image_format->create_empty_image(ctx, cfg->default_image_format, 256,256, color); GC_CHECK_ERROR(ctx); }
static void _mapcache_cache_memcache_delete(mapcache_context *ctx, mapcache_tile *tile) { char *key; int rv; char errmsg[120]; mapcache_cache_memcache *cache = (mapcache_cache_memcache*)tile->tileset->cache; key = mapcache_util_get_tile_key(ctx, tile,NULL," \r\n\t\f\e\a\b","#"); GC_CHECK_ERROR(ctx); rv = apr_memcache_delete(cache->memcache,key,0); if(rv != APR_SUCCESS && rv!= APR_NOTFOUND) { int code = 500; ctx->set_error(ctx,code,"memcache: failed to delete key %s: %s", key, apr_strerror(rv,errmsg,120)); } }
static void _mapcache_cache_sqlite_set(mapcache_context *ctx, mapcache_tile *tile) { struct sqlite_conn *conn = _sqlite_get_conn(ctx, tile, 0); GC_CHECK_ERROR(ctx); sqlite3_exec(conn->handle, "BEGIN TRANSACTION", 0, 0, 0); _single_sqlitetile_set(ctx,tile,conn); if (GC_HAS_ERROR(ctx)) { sqlite3_exec(conn->handle, "ROLLBACK TRANSACTION", 0, 0, 0); } else { sqlite3_exec(conn->handle, "END TRANSACTION", 0, 0, 0); } _sqlite_release_conn(ctx, tile, conn); }
void mapcache_configuration_parse(mapcache_context *ctx, const char *filename, mapcache_cfg *config, int cgi) { apr_dir_t *lockdir; apr_status_t rv; char errmsg[120]; char *url; mapcache_configuration_parse_xml(ctx,filename,config); GC_CHECK_ERROR(ctx); if(!config->lockdir || !strlen(config->lockdir)) { config->lockdir = apr_pstrdup(ctx->pool, "/tmp"); } rv = apr_dir_open(&lockdir,config->lockdir,ctx->pool); if(rv != APR_SUCCESS) { ctx->set_error(ctx,500, "failed to open lock directory %s: %s" ,config->lockdir,apr_strerror(rv,errmsg,120)); return; } /* only remove lockfiles if we're not in cgi mode */ if(!cgi) { apr_finfo_t finfo; while ((apr_dir_read(&finfo, APR_FINFO_DIRENT|APR_FINFO_TYPE|APR_FINFO_NAME, lockdir)) == APR_SUCCESS) { if(finfo.filetype == APR_REG) { if(!strncmp(finfo.name, MAPCACHE_LOCKFILE_PREFIX, strlen(MAPCACHE_LOCKFILE_PREFIX))) { ctx->log(ctx,MAPCACHE_WARN,"found old lockfile %s/%s, deleting it",config->lockdir, finfo.name); rv = apr_file_remove(apr_psprintf(ctx->pool,"%s/%s",config->lockdir, finfo.name),ctx->pool); if(rv != APR_SUCCESS) { ctx->set_error(ctx,500, "failed to remove lockfile %s: %s",finfo.name,apr_strerror(rv,errmsg,120)); return; } } } } } apr_dir_close(lockdir); /* if we were suppplied with an onlineresource, make sure it ends with a / */ if(NULL != (url = (char*)apr_table_get(config->metadata,"url"))) { char *urlend = url + strlen(url)-1; if(*urlend != '/') { url = apr_pstrcat(ctx->pool,url,"/",NULL); apr_table_setn(config->metadata,"url",url); } } }
static void _bind_mbtiles_params(mapcache_context *ctx, void *vstmt, mapcache_tile *tile) { sqlite3_stmt *stmt = vstmt; int paramidx; paramidx = sqlite3_bind_parameter_index(stmt, ":x"); if (paramidx) sqlite3_bind_int(stmt, paramidx, tile->x); /* tile->y */ paramidx = sqlite3_bind_parameter_index(stmt, ":y"); if (paramidx) sqlite3_bind_int(stmt, paramidx, tile->y); /* tile->y */ paramidx = sqlite3_bind_parameter_index(stmt, ":z"); if (paramidx) sqlite3_bind_int(stmt, paramidx, tile->z); /* mbtiles foreign key */ paramidx = sqlite3_bind_parameter_index(stmt, ":key"); if (paramidx) { char *key = apr_psprintf(ctx->pool,"%d-%d-%d",tile->x,tile->y,tile->z); sqlite3_bind_text(stmt, paramidx, key, -1, SQLITE_STATIC); } paramidx = sqlite3_bind_parameter_index(stmt, ":color"); if (paramidx) { char *key; assert(tile->raw_image); key = apr_psprintf(ctx->pool,"#%02x%02x%02x%02x", tile->raw_image->data[0], tile->raw_image->data[1], tile->raw_image->data[2], tile->raw_image->data[3]); sqlite3_bind_text(stmt, paramidx, key, -1, SQLITE_STATIC); } /* tile blob data */ paramidx = sqlite3_bind_parameter_index(stmt, ":data"); if (paramidx) { if (!tile->encoded_data) { tile->encoded_data = tile->tileset->format->write(ctx, tile->raw_image, tile->tileset->format); GC_CHECK_ERROR(ctx); } if (tile->encoded_data && tile->encoded_data->size) { sqlite3_bind_blob(stmt, paramidx, tile->encoded_data->buf, tile->encoded_data->size, SQLITE_STATIC); } else { sqlite3_bind_text(stmt, paramidx, "", -1, SQLITE_STATIC); } } }
static void _mapcache_cache_sqlite_delete(mapcache_context *ctx, mapcache_tile *tile) { mapcache_cache_sqlite *cache = (mapcache_cache_sqlite*)tile->tileset->cache; sqlite3* handle = _get_conn(ctx,tile,0); sqlite3_stmt *stmt; int ret; GC_CHECK_ERROR(ctx); sqlite3_prepare(handle,cache->delete_stmt.sql,-1,&stmt,NULL); _bind_sqlite_params(ctx,stmt,tile); ret = sqlite3_step(stmt); if(ret != SQLITE_DONE && ret != SQLITE_ROW) { ctx->set_error(ctx,500,"sqlite backend failed on delete: %s",sqlite3_errmsg(handle)); } sqlite3_finalize(stmt); sqlite3_close(handle); }
/** * \private \memberof mapcache_source_wms * \sa mapcache_source::render_map() */ void _mapcache_source_wms_render_map(mapcache_context *ctx, mapcache_map *map) { mapcache_source_wms *wms = (mapcache_source_wms*)map->tileset->source; mapcache_http *http; apr_table_t *params = apr_table_clone(ctx->pool,wms->wms_default_params); apr_table_setn(params,"BBOX",apr_psprintf(ctx->pool,"%f,%f,%f,%f", map->extent.minx,map->extent.miny,map->extent.maxx,map->extent.maxy)); apr_table_setn(params,"WIDTH",apr_psprintf(ctx->pool,"%d",map->width)); apr_table_setn(params,"HEIGHT",apr_psprintf(ctx->pool,"%d",map->height)); apr_table_setn(params,"FORMAT","image/png"); apr_table_setn(params,"SRS",map->grid_link->grid->srs); apr_table_overlap(params,wms->getmap_params,APR_OVERLAP_TABLES_SET); if(map->dimensions && !apr_is_empty_table(map->dimensions)) { const apr_array_header_t *elts = apr_table_elts(map->dimensions); int i; for(i=0; i<elts->nelts; i++) { apr_table_entry_t entry = APR_ARRAY_IDX(elts,i,apr_table_entry_t); /* set both DIM_key=val and key=val KVP params */ apr_table_setn(params,entry.key,entry.val); if(strcasecmp(entry.key,"TIME") && strcasecmp(entry.key,"ELEVATION")) { char *dim_name = apr_pstrcat(ctx->pool,"DIM_",entry.key,NULL); apr_table_setn(params,dim_name,entry.val); } } } /* if the source has no LAYERS parameter defined, then use the tileset name * as the LAYERS to request. When using mirror-mode, the source has no layers * defined, it is added based on the incoming request */ if(!apr_table_get(params,"layers")) { apr_table_set(params,"LAYERS",map->tileset->name); } map->encoded_data = mapcache_buffer_create(30000,ctx->pool); http = mapcache_http_clone(ctx, wms->http); http->url = mapcache_http_build_url(ctx,http->url,params); mapcache_http_do_request(ctx,http,map->encoded_data,NULL,NULL); GC_CHECK_ERROR(ctx); if(!mapcache_imageio_is_valid_format(ctx,map->encoded_data)) { char *returned_data = apr_pstrndup(ctx->pool,(char*)map->encoded_data->buf,map->encoded_data->size); ctx->set_error(ctx, 502, "wms request for tileset %s returned an unsupported format:\n%s", map->tileset->name, returned_data); } }
/** * \brief apply appropriate tile properties to the sqlite statement */ static void _bind_sqlite_params(mapcache_context *ctx, sqlite3_stmt *stmt, mapcache_tile *tile) { int paramidx; /* tile->x */ paramidx = sqlite3_bind_parameter_index(stmt, ":x"); if(paramidx) sqlite3_bind_int(stmt, paramidx, tile->x); /* tile->y */ paramidx = sqlite3_bind_parameter_index(stmt, ":y"); if(paramidx) sqlite3_bind_int(stmt, paramidx, tile->y); /* tile->y */ paramidx = sqlite3_bind_parameter_index(stmt, ":z"); if(paramidx) sqlite3_bind_int(stmt, paramidx, tile->z); /* eventual dimensions */ paramidx = sqlite3_bind_parameter_index(stmt, ":dim"); if(paramidx) { if(tile->dimensions) { const char *dim = _get_tile_dimkey(ctx,tile); sqlite3_bind_text(stmt,paramidx,dim,-1,SQLITE_STATIC); } else { sqlite3_bind_text(stmt,paramidx,"",-1,SQLITE_STATIC); } } /* grid */ paramidx = sqlite3_bind_parameter_index(stmt, ":grid"); if(paramidx) sqlite3_bind_text(stmt,paramidx,tile->grid_link->grid->name,-1,SQLITE_STATIC); /* tileset */ paramidx = sqlite3_bind_parameter_index(stmt, ":tileset"); if(paramidx) sqlite3_bind_text(stmt,paramidx,tile->tileset->name,-1,SQLITE_STATIC); /* tile blob data */ paramidx = sqlite3_bind_parameter_index(stmt, ":data"); if(paramidx) { if(!tile->encoded_data) { tile->encoded_data = tile->tileset->format->write(ctx, tile->raw_image, tile->tileset->format); GC_CHECK_ERROR(ctx); } if(tile->encoded_data && tile->encoded_data->size) { sqlite3_bind_blob(stmt,paramidx,tile->encoded_data->buf, tile->encoded_data->size,SQLITE_STATIC); } else { sqlite3_bind_text(stmt,paramidx,"",-1,SQLITE_STATIC); } } }
void mapcache_configuration_parse(mapcache_context *ctx, const char *filename, mapcache_cfg *config, int cgi) { char *url; mapcache_configuration_parse_xml(ctx,filename,config); GC_CHECK_ERROR(ctx); /* if we were suppplied with an onlineresource, make sure it ends with a / */ if(NULL != (url = (char*)apr_table_get(config->metadata,"url"))) { char *urlend = url + strlen(url)-1; if(*urlend != '/') { url = apr_pstrcat(ctx->pool,url,"/",NULL); apr_table_setn(config->metadata,"url",url); } } }
static void _mapcache_cache_sqlite_multi_set(mapcache_context *ctx, mapcache_tile *tiles, int ntiles) { struct sqlite_conn *conn = _sqlite_get_conn(ctx, &tiles[0], 0); int i; GC_CHECK_ERROR(ctx); sqlite3_exec(conn->handle, "BEGIN TRANSACTION", 0, 0, 0); for (i = 0; i < ntiles; i++) { mapcache_tile *tile = &tiles[i]; _single_sqlitetile_set(ctx,tile,conn); if(GC_HAS_ERROR(ctx)) break; } if (GC_HAS_ERROR(ctx)) { sqlite3_exec(conn->handle, "ROLLBACK TRANSACTION", 0, 0, 0); } else { sqlite3_exec(conn->handle, "END TRANSACTION", 0, 0, 0); } _sqlite_release_conn(ctx, &tiles[0], conn); }
static void _mapcache_cache_mbtiles_set(mapcache_context *ctx, mapcache_tile *tile) { struct sqlite_conn *conn = _sqlite_get_conn(ctx, tile, 0); GC_CHECK_ERROR(ctx); if(!tile->raw_image) { tile->raw_image = mapcache_imageio_decode(ctx, tile->encoded_data); if(GC_HAS_ERROR(ctx)) { _sqlite_release_conn(ctx, tile, conn); return; } } sqlite3_exec(conn->handle, "BEGIN TRANSACTION", 0, 0, 0); _single_mbtile_set(ctx,tile,conn); if (GC_HAS_ERROR(ctx)) { sqlite3_exec(conn->handle, "ROLLBACK TRANSACTION", 0, 0, 0); } else { sqlite3_exec(conn->handle, "END TRANSACTION", 0, 0, 0); } _sqlite_release_conn(ctx, tile, conn); }
static void _mapcache_cache_bdb_delete(mapcache_context *ctx, mapcache_tile *tile) { DBT key; int ret; mapcache_cache_bdb *cache = (mapcache_cache_bdb*)tile->tileset->cache; char *skey = mapcache_util_get_tile_key(ctx,tile,cache->key_template,NULL,NULL); struct bdb_env *benv = _bdb_get_conn(ctx,tile,0); GC_CHECK_ERROR(ctx); memset(&key, 0, sizeof(DBT)); key.data = skey; key.size = strlen(skey)+1; ret = benv->db->del(benv->db, NULL, &key, 0); if(ret && ret != DB_NOTFOUND) { ctx->set_error(ctx,500,"bdb backend failure on tile_delete: %s",db_strerror(ret)); } else { ret = benv->db->sync(benv->db,0); if(ret) ctx->set_error(ctx,500,"bdb backend sync failure on tile_delete: %s",db_strerror(ret)); } _bdb_release_conn(ctx,tile,benv); }
static void _mapcache_cache_sqlite_set(mapcache_context *ctx, mapcache_tile *tile) { mapcache_cache_sqlite *cache = (mapcache_cache_sqlite*)tile->tileset->cache; sqlite3* handle = _get_conn(ctx,tile,0); sqlite3_stmt *stmt; int ret; GC_CHECK_ERROR(ctx); sqlite3_prepare(handle,cache->set_stmt.sql,-1,&stmt,NULL); _bind_sqlite_params(ctx,stmt,tile); do { ret = sqlite3_step(stmt); if(ret != SQLITE_DONE && ret != SQLITE_ROW && ret != SQLITE_BUSY && ret != SQLITE_LOCKED) { ctx->set_error(ctx,500,"sqlite backend failed on set: %s (%d)",sqlite3_errmsg(handle),ret); break; } if(ret == SQLITE_BUSY) { sqlite3_reset(stmt); } } while (ret == SQLITE_BUSY || ret == SQLITE_LOCKED); sqlite3_finalize(stmt); sqlite3_close(handle); }
//------------------------------------------------------------------------------ void _mapcache_source_tms_render_map_image(mapcache_context *ctx, mapcache_map *map) { int zoom, x, y; mapcache_source_tms *tms; char* url; tms = (mapcache_source_tms*)map->tileset->source; _GetTileCoords(map, &zoom, &x, &y, tms->flipy); url = apr_psprintf(ctx->pool,"%s/1.0.0/%s/%i/%i/%i.%s", tms->url,tms->layer,zoom,x,y,tms->format); tms->http->url = apr_pstrdup(ctx->pool,url); map->encoded_data = mapcache_buffer_create(30000,ctx->pool); mapcache_http_do_request(ctx, tms->http, map->encoded_data, NULL, NULL); GC_CHECK_ERROR(ctx); if(!mapcache_imageio_is_valid_format(ctx,map->encoded_data)) { char *returned_data = apr_pstrndup(ctx->pool,(char*)map->encoded_data->buf,map->encoded_data->size); ctx->set_error(ctx, 502, "tms request for tileset %s returned an unsupported format:\n%s", map->tileset->name, returned_data); } }
static void _mapcache_cache_memcache_delete(mapcache_context *ctx, mapcache_cache *pcache, mapcache_tile *tile) { char *key; int rv; char errmsg[120]; mapcache_cache_memcache *cache = (mapcache_cache_memcache*)pcache; mapcache_pooled_connection *pc; struct mapcache_memcache_pooled_connection *mpc; pc = _mapcache_memcache_get_conn(ctx,cache,tile); GC_CHECK_ERROR(ctx); mpc = pc->connection; key = mapcache_util_get_tile_key(ctx, tile,NULL," \r\n\t\f\e\a\b","#"); if(GC_HAS_ERROR(ctx)) goto cleanup; rv = apr_memcache_delete(mpc->memcache,key,0); if(rv != APR_SUCCESS && rv!= APR_NOTFOUND) { ctx->set_error(ctx,500,"memcache: failed to delete key %s: %s", key, apr_strerror(rv,errmsg,120)); goto cleanup; } cleanup: _mapcache_memcache_release_conn(ctx,pc); }
static void _mapcache_cache_couchbase_delete(mapcache_context *ctx, mapcache_tile *tile) { char *key; libcouchbase_t *instance; libcouchbase_error_t error; key = mapcache_util_get_tile_key(ctx, tile,NULL," \r\n\t\f\e\a\b","#"); GC_CHECK_ERROR(ctx); instance = _couchbase_get_connection(ctx, tile); error = libcouchbase_remove(*instance, 0, key, strlen(key), 0); if (error != LIBCOUCHBASE_SUCCESS) { ctx->set_error(ctx, 500, "couchbase: failed to delete key %s: %s", key, libcouchbase_strerror(*instance, error)); } libcouchbase_wait(*instance); error = libcouchbase_get_last_error(*instance); if (error != LIBCOUCHBASE_SUCCESS) { ctx->set_error(ctx, 500, "couchbase: failed to delete key %s: %s", key, libcouchbase_strerror(*instance, error)); } _couchbase_release_connection(tile, instance); }