コード例 #1
0
ファイル: cache_bdb.c プロジェクト: ophidian/mapcache
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);
}
コード例 #2
0
ファイル: cache_sqlite.c プロジェクト: MiniHero/mapcache
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);
}
コード例 #3
0
ファイル: cache_memcache.c プロジェクト: havatv/mapcache
/**
 * \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;
   }
}
コード例 #4
0
ファイル: cache_riak.c プロジェクト: tbonfort/mapcache
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);
    }
}
コード例 #5
0
ファイル: cache_memcache.c プロジェクト: jmckenna/mapcache
/**
 * \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);
}
コード例 #6
0
ファイル: configuration_xml.c プロジェクト: EOX-A/mapcache
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);
}
コード例 #7
0
ファイル: source_wms.c プロジェクト: MiniHero/mapcache
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);

}
コード例 #8
0
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;
}
コード例 #9
0
ファイル: source_tms.c プロジェクト: OpenWebGlobe/mapcache
//------------------------------------------------------------------------------
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!");
    }

}
コード例 #10
0
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);
}
コード例 #11
0
ファイル: lock.c プロジェクト: jmckenna/mapcache
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;
  }
}
コード例 #12
0
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);
}
コード例 #13
0
ファイル: configuration.c プロジェクト: havatv/mapcache
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);
   }
} 
コード例 #14
0
ファイル: cache_disk.c プロジェクト: havatv/mapcache
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));
   }
}
コード例 #15
0
ファイル: imageio.c プロジェクト: mapserver/mapcache
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);
}
コード例 #16
0
ファイル: cache_memcache.c プロジェクト: havatv/mapcache
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));
   }
}
コード例 #17
0
ファイル: cache_sqlite.c プロジェクト: MiniHero/mapcache
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);
}
コード例 #18
0
ファイル: configuration.c プロジェクト: havatv/mapcache
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);
      }
   }
}
コード例 #19
0
ファイル: cache_sqlite.c プロジェクト: MiniHero/mapcache
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);
    }
  }

}
コード例 #20
0
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);
}
コード例 #21
0
ファイル: source_wms.c プロジェクト: umeier/mapcache
/**
 * \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);
  }
}
コード例 #22
0
/**
 * \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);
      }
   }
}
コード例 #23
0
ファイル: configuration.c プロジェクト: mapserver/mapcache
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);
    }
  }
}
コード例 #24
0
ファイル: cache_sqlite.c プロジェクト: MiniHero/mapcache
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);
}
コード例 #25
0
ファイル: cache_sqlite.c プロジェクト: MiniHero/mapcache
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);
}
コード例 #26
0
ファイル: cache_bdb.c プロジェクト: ophidian/mapcache
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);
}
コード例 #27
0
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);
}
コード例 #28
0
ファイル: source_tms.c プロジェクト: OpenWebGlobe/mapcache
//------------------------------------------------------------------------------
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);
    }
}
コード例 #29
0
ファイル: cache_memcache.c プロジェクト: jmckenna/mapcache
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);
}
コード例 #30
0
ファイル: cache_couchbase.c プロジェクト: umeier/mapcache
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);
}