[mapserver-commits] r12307 - in trunk/mapserver/mapcache: . include
src
svn at osgeo.org
svn at osgeo.org
Fri Aug 26 07:15:38 EDT 2011
Author: tbonfort
Date: 2011-08-26 04:15:38 -0700 (Fri, 26 Aug 2011)
New Revision: 12307
Modified:
trunk/mapserver/mapcache/Makefile.inc.in
trunk/mapserver/mapcache/configure.in
trunk/mapserver/mapcache/geocache.xml
trunk/mapserver/mapcache/include/geocache.h
trunk/mapserver/mapcache/src/grid.c
trunk/mapserver/mapcache/src/mod_geocache.c
trunk/mapserver/mapcache/src/service_demo.c
trunk/mapserver/mapcache/src/service_wms.c
trunk/mapserver/mapcache/src/tileset.c
trunk/mapserver/mapcache/src/util.c
Log:
allow building with apr-0.9
thomas.bonfort | 2011-02-10 12:19:51 +0100 (Thu, 10 Feb 2011)
Modified: trunk/mapserver/mapcache/Makefile.inc.in
===================================================================
--- trunk/mapserver/mapcache/Makefile.inc.in 2011-08-26 11:15:29 UTC (rev 12306)
+++ trunk/mapserver/mapcache/Makefile.inc.in 2011-08-26 11:15:38 UTC (rev 12307)
@@ -38,10 +38,14 @@
GDAL_LIB=@GDAL_LIB@
GDAL_ENABLED=@GDAL_ENABLED@
-INCLUDES=-I../include $(CURL_CFLAGS) $(PNG_INC) $(JPEG_INC) $(GDAL_INC) $(GDAL_ENABLED) $(APR_INC) $(APU_INC) $(MEMCACHE_ENABLED) $(PCRE_CFLAGS) $(PCRE_ENABLED)
-LIBS=$(CURL_LIBS) $(PNG_LIB) $(JPEG_LIB) $(GDAL_LIB) $(APR_LIBS) $(APU_LIBS) $(PCRE_LIBS)
+CAIRO_INC=@CAIRO_INC@
+CAIRO_LIB=@CAIRO_LIB@
+CAIRO_ENABLED=@CAIRO_ENABLED@
+INCLUDES=-I../include $(CAIRO_ENABLED) $(CAIRO_INC) $(CURL_CFLAGS) $(PNG_INC) $(JPEG_INC) $(GDAL_INC) $(GDAL_ENABLED) $(APR_INC) $(APU_INC) $(MEMCACHE_ENABLED) $(PCRE_CFLAGS) $(PCRE_ENABLED)
+LIBS=$(CURL_LIBS) $(CAIRO_LIB) $(PNG_LIB) $(JPEG_LIB) $(GDAL_LIB) $(APR_LIBS) $(APU_LIBS) $(PCRE_LIBS)
+
OBJS=$(shell find . -regex '^.*\.c$$' -print | grep -v geocache_seed.c | grep -v mod_geocache.c | grep -v fastcgi_geocache.c |sed "s/^\(.*\)\.c$$/\1.o/")
LOBJS=$(shell find . -regex '^.*\.c$$' -print | grep -v geocache_seed.c | grep -v mod_geocache.c | grep -v fastcgi_geocache.c | sed "s/^\(.*\)\.c$$/\1.lo/")
Modified: trunk/mapserver/mapcache/configure.in
===================================================================
--- trunk/mapserver/mapcache/configure.in 2011-08-26 11:15:29 UTC (rev 12306)
+++ trunk/mapserver/mapcache/configure.in 2011-08-26 11:15:38 UTC (rev 12307)
@@ -109,6 +109,78 @@
AC_SUBST(CURL_LIBS,`$CURLCONFIG --libs`)
])
+AC_DEFUN([PKGCONFIG_CHECK],[
+ AC_SUBST(PKGCONFIG)
+ AC_ARG_WITH(pkg-config,
+ AC_HELP_STRING([--with-pkg-config[=PATH]],[path to pkg-config)]),
+ ,
+ [with_pkg_config=yes])
+ if test "$with_pkg_config" = "no"; then
+ AC_MSG_CHECKING(for pkg-config usability)
+ AC_MSG_RESULT(disabled by request)
+ else
+ if test "$with_pkg_config" = "yes" ; then
+ AC_PATH_PROG(PKGCONFIG, pkg-config)
+ else
+ AC_MSG_CHECKING(for pkg-config usability in $with_pkg_config)
+ if test -x "$with_pkg_config"; then
+ PKGCONFIG=$with_pkg_config
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_ERROR($with_pkg_config not found or not executable)
+ fi
+ fi
+ if test -z "$PKGCONFIG"; then
+ AC_MSG_ERROR(pkg-config utility not found. use --with-pkg-config to specify its location.)
+ fi
+ fi
+ AC_SUBST(PKGCONFIG)
+])
+
+AC_DEFUN([CAIRO_CHECK],[
+ AC_ARG_WITH(cairo,
+ AC_HELP_STRING([--with-cairo[[=ARG]]],[Include Cairo Support (ARG=yes/no/path to cairo.pc)]),
+ ,
+ [with_cairo=yes])
+
+ if test "$with_cairo" = "no" -o "$with_cairo" = "" ; then
+ AC_MSG_RESULT(no)
+ CAIRO_CONFIG="no"
+ else
+ if test -z "$PKGCONFIG"; then
+ AC_MSG_ERROR([cairo support requested, but pkg-config not found/configured])
+ fi
+ if test "$with_cairo" = "yes" ; then
+ AC_MSG_CHECKING(for cairo pkg-config entry)
+ `$PKGCONFIG --silence-errors -- cairo >> /dev/null`
+ if test $? -eq 0 ; then
+ AC_MSG_RESULT(found)
+ CAIRO_CONFIG="cairo cairo-png"
+ else
+ AC_MSG_ERROR([cairo support requested, but not found.Try installing the cairo development headers])
+ fi
+ else
+ CAIRO_CONFIG=$with_cairo_config
+ fi
+ fi
+
+ if test "$CAIRO_CONFIG" = "no" ; then
+ AC_MSG_WARN([cairo support has been disabled or could not be configured.
+ full WMS support cannot be enabled on the resulting build])
+ CAIRO_ENABLED=
+ CAIRO_INC=
+ CAIRO_LIB=
+ else
+ CAIRO_ENABLED="-DUSE_CAIRO"
+ CAIRO_LIB=`$PKGCONFIG --libs $CAIRO_CONFIG`
+ CAIRO_INC=`$PKGCONFIG --cflags $CAIRO_CONFIG`
+ fi
+ AC_SUBST(CAIRO_ENABLED,$CAIRO_ENABLED)
+ AC_SUBST(CAIRO_INC,$CAIRO_INC)
+ AC_SUBST(CAIRO_LIB,$CAIRO_LIB)
+])
+
+
AC_DEFUN([APU_CHECK],[
AC_SUBST(APUCONFIG)
AC_SUBST(MEMCACHE_ENABLED)
@@ -512,7 +584,8 @@
APR_CHECK
APU_CHECK
-
+PKGCONFIG_CHECK
+CAIRO_CHECK
PNG_CHECK
JPEG_CHECK
Modified: trunk/mapserver/mapcache/geocache.xml
===================================================================
--- trunk/mapserver/mapcache/geocache.xml 2011-08-26 11:15:29 UTC (rev 12306)
+++ trunk/mapserver/mapcache/geocache.xml 2011-08-26 11:15:38 UTC (rev 12307)
@@ -333,7 +333,7 @@
NOTE: when adding a <grid> element, you *MUST* make sure that the source you have selected is able to
return images in the grid's srs.
-->
- <grid>WGS84</grid>
+ <grid restricted_extent="-10 40 10 50">WGS84</grid>
<grid>google</grid>
<!-- metadata
Modified: trunk/mapserver/mapcache/include/geocache.h
===================================================================
--- trunk/mapserver/mapcache/include/geocache.h 2011-08-26 11:15:29 UTC (rev 12306)
+++ trunk/mapserver/mapcache/include/geocache.h 2011-08-26 11:15:38 UTC (rev 12307)
@@ -82,6 +82,7 @@
typedef struct geocache_request_get_capabilities_kml geocache_request_get_capabilities_kml;
typedef struct geocache_request_get_tile geocache_request_get_tile;
+typedef struct geocache_request_get_map geocache_request_get_map;
typedef struct geocache_service geocache_service;
typedef struct geocache_service_wms geocache_service_wms;
typedef struct geocache_service_wmts geocache_service_wmts;
@@ -130,7 +131,14 @@
* \memberof geocache_context
*/
char* (*get_error_message)(geocache_context * ctx);
+
+ /**
+ * \brief get human readable message for the error
+ * \memberof geocache_context
+ */
+ char* (*clear_errors)(geocache_context * ctx);
+
/**
* \brief log a message
* \memberof geocache_context
@@ -367,6 +375,10 @@
* before being returned to the client
*/
int ntiles;
+
+ /* only used for getmap requests */
+ int width, height;
+ double *extent;
};
struct geocache_request_get_capabilities {
@@ -606,6 +618,10 @@
*/
void geocache_image_merge(geocache_context *ctx, geocache_image *base, geocache_image *overlay);
+void geocache_image_copy_resampled(geocache_context *ctx, geocache_image *src, geocache_image *dst,
+ int srcX, int srcY, int srcW, int srcH,
+ int dstX, int dstY, int dstW, int dstH);
+
/**
* \brief split the given metatile into tiles
* \param mt the metatile to split
@@ -874,10 +890,29 @@
* handle to the configuration this tileset belongs to
*/
geocache_cfg *config;
-
+
+ /**
+ * should we service wms requests not aligned to a grid
+ */
+ int full_wms;
+
apr_table_t *metadata;
};
+void geocache_tileset_get_map_tiles(geocache_context *ctx, geocache_tileset *tileset,
+ geocache_grid_link *grid_link,
+ double *bbox, int width, int height,
+ int *ntiles,
+ geocache_tile ***tiles);
+
+#ifdef USE_CAIRO
+geocache_image* geocache_tileset_assemble_map_tiles(geocache_context *ctx, geocache_tileset *tileset,
+ geocache_grid_link *grid_link,
+ double *bbox, int width, int height,
+ int ntiles,
+ geocache_tile **tiles);
+#endif
+
/**
* \brief compute a tile's x,y and z value given a BBOX.
* @param tile
@@ -885,7 +920,7 @@
* @param r
* @return
*/
-void geocache_tileset_tile_lookup(geocache_context *ctx, geocache_tile *tile, double *bbox);
+int geocache_tileset_tile_lookup(geocache_context *ctx, geocache_tile *tile, double *bbox);
/**
* \brief verify the created tile respects configured constraints
@@ -907,7 +942,7 @@
*/
void geocache_tileset_get_level(geocache_context *ctx, geocache_tileset *tileset, double *resolution, int *level);
-
+void geocache_grid_get_closest_level(geocache_context *ctx, geocache_grid *grid, double resolution, int *level);
void geocache_tileset_tile_get(geocache_context *ctx, geocache_tile *tile);
/**
@@ -978,8 +1013,8 @@
*/
void geocache_grid_get_xy(geocache_context *ctx, geocache_grid *grid, double dx, double dy, int z, int *x, int *y);
-double geocache_grid_get_resolution(geocache_grid *grid, double *bbox);
-void geocache_grid_get_level(geocache_context *ctx, geocache_grid *grid, double *resolution, int *level);
+double geocache_grid_get_resolution(double *bbox, int sx, int sy);
+int geocache_grid_get_level(geocache_context *ctx, geocache_grid *grid, double *resolution, int *level);
void geocache_grid_compute_limits(const geocache_grid *grid, const double *extent, int **limits);
/* in util.c */
Modified: trunk/mapserver/mapcache/src/grid.c
===================================================================
--- trunk/mapserver/mapcache/src/grid.c 2011-08-26 11:15:29 UTC (rev 12306)
+++ trunk/mapserver/mapcache/src/grid.c 2011-08-26 11:15:38 UTC (rev 12307)
@@ -67,25 +67,38 @@
}
}
-double geocache_grid_get_resolution(geocache_grid *grid, double *bbox) {
- double rx = (bbox[2] - bbox[0]) / (double)grid->tile_sx;
- double ry = (bbox[3] - bbox[1]) / (double)grid->tile_sy;
+double geocache_grid_get_resolution(double *bbox, int sx, int sy) {
+ double rx = (bbox[2] - bbox[0]) / (double)sx;
+ double ry = (bbox[3] - bbox[1]) / (double)sy;
return GEOCACHE_MAX(rx,ry);
}
-void geocache_grid_get_level(geocache_context *ctx, geocache_grid *grid, double *resolution, int *level) {
+int geocache_grid_get_level(geocache_context *ctx, geocache_grid *grid, double *resolution, int *level) {
double max_diff = *resolution / (double)GEOCACHE_MAX(grid->tile_sx, grid->tile_sy);
int i;
for(i=0; i<grid->nlevels; i++) {
if(fabs(grid->levels[i]->resolution - *resolution) < max_diff) {
*resolution = grid->levels[i]->resolution;
*level = i;
- return;
+ return GEOCACHE_SUCCESS;
}
}
- ctx->set_error(ctx, 400, "grid %s: failed lookup for resolution %f", grid->name, *resolution);
+ return GEOCACHE_FAILURE;
}
+void geocache_grid_get_closest_level(geocache_context *ctx, geocache_grid *grid, double resolution, int *level) {
+ double dst = fabs(grid->levels[0]->resolution - resolution);
+ *level = 0;
+ int i;
+ for(i=1; i<grid->nlevels; i++) {
+ double curdst = fabs(grid->levels[i]->resolution - resolution);
+ if( curdst < dst) {
+ dst = curdst;
+ *level = i;
+ }
+ }
+}
+
void geocache_grid_get_xy(geocache_context *ctx, geocache_grid *grid, double dx, double dy,
int z, int *x, int *y) {
#ifdef DEBUG
Modified: trunk/mapserver/mapcache/src/mod_geocache.c
===================================================================
--- trunk/mapserver/mapcache/src/mod_geocache.c 2011-08-26 11:15:29 UTC (rev 12306)
+++ trunk/mapserver/mapcache/src/mod_geocache.c 2011-08-26 11:15:38 UTC (rev 12307)
@@ -257,35 +257,72 @@
}
request->service->create_capabilities_response(global_ctx,req_caps,url,original->path_info,config);
return geocache_write_capabilities(apache_ctx,req_caps);
- } else if( request->type != GEOCACHE_REQUEST_GET_TILE) {
- return report_error(apache_ctx);
- }
- req_tile = (geocache_request_get_tile*)request;
+ } else if( request->type == GEOCACHE_REQUEST_GET_TILE) {
+ req_tile = (geocache_request_get_tile*)request;
- if( !req_tile->ntiles) {
- return report_error(apache_ctx);
- }
+ if( !req_tile->ntiles) {
+ return report_error(apache_ctx);
+ }
- for(i=0;i<req_tile->ntiles;i++) {
- geocache_tile *tile = req_tile->tiles[i];
- geocache_tileset_tile_get(global_ctx, tile);
- if(GC_HAS_ERROR(global_ctx)) {
+ for(i=0;i<req_tile->ntiles;i++) {
+ geocache_tile *tile = req_tile->tiles[i];
+ geocache_tileset_tile_get(global_ctx, tile);
+ if(GC_HAS_ERROR(global_ctx)) {
+ return report_error(apache_ctx);
+ }
+ }
+ if(req_tile->ntiles == 1) {
+ tile = req_tile->tiles[0];
+ } else {
+ /* TODO: individual check on tiles if merging is allowed */
+ tile = (geocache_tile*)geocache_image_merge_tiles(global_ctx,config->merge_format,req_tile->tiles,req_tile->ntiles);
+ if(!tile || GC_HAS_ERROR(global_ctx)) {
+ return report_error(apache_ctx);
+ }
+ tile->tileset = req_tile->tiles[0]->tileset;
+ }
+ ret = geocache_write_tile(apache_ctx,tile);
+ return ret;
+ } else if(request->type == GEOCACHE_REQUEST_GET_MAP) {
+#ifdef USE_CAIRO
+ req_tile = (geocache_request_get_tile*)request;
+ if(req_tile->ntiles==1) {
+ geocache_tile *tile = req_tile->tiles[0];
+ geocache_tile **maptiles;
+ int nmaptiles;
+ geocache_tileset_get_map_tiles(global_ctx,tile->tileset,tile->grid_link,
+ req_tile->extent, req_tile->width, req_tile->height,
+ &nmaptiles,
+ &maptiles);
+ for(i=0;i<nmaptiles;i++) {
+ geocache_tile *tile = maptiles[i];
+ geocache_tileset_tile_get(global_ctx, tile);
+ if(GC_HAS_ERROR(global_ctx)) {
+ return report_error(apache_ctx);
+ }
+ }
+ geocache_image *getmapim = geocache_tileset_assemble_map_tiles(global_ctx,tile->tileset,tile->grid_link,
+ req_tile->extent, req_tile->width, req_tile->height,
+ nmaptiles,
+ maptiles);
+
+ geocache_tile *getmaptile = geocache_tileset_tile_create(global_ctx->pool,tile->tileset, tile->grid_link);
+ getmaptile->data = tile->tileset->format->write(global_ctx,getmapim,tile->tileset->format);
+ ret = geocache_write_tile(apache_ctx,getmaptile);
+ return ret;
+
+ } else{
+ global_ctx->set_error(global_ctx,501,"get map not implemented for merged layers");
return report_error(apache_ctx);
}
- }
- if(req_tile->ntiles == 1) {
- tile = req_tile->tiles[0];
+#else
+ global_ctx->set_error(global_ctx,501,"wms getmap handling not configured in this build");
+ return report_error(apache_ctx);
+#endif
} else {
- /* TODO: individual check on tiles if merging is allowed */
- tile = (geocache_tile*)geocache_image_merge_tiles(global_ctx,config->merge_format,req_tile->tiles,req_tile->ntiles);
- if(!tile || GC_HAS_ERROR(global_ctx)) {
- return report_error(apache_ctx);
- }
- tile->tileset = req_tile->tiles[0]->tileset;
+ return report_error(apache_ctx);
}
- ret = geocache_write_tile(apache_ctx,tile);
- return ret;
}
static int mod_geocache_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) {
Modified: trunk/mapserver/mapcache/src/service_demo.c
===================================================================
--- trunk/mapserver/mapcache/src/service_demo.c 2011-08-26 11:15:29 UTC (rev 12306)
+++ trunk/mapserver/mapcache/src/service_demo.c 2011-08-26 11:15:38 UTC (rev 12307)
@@ -47,6 +47,17 @@
" }\n"
" );\n";
+static char *demo_layer_singletile =
+ " var %s_%s_slayer = new OpenLayers.Layer.WMS( \"%s-%s (singleTile)\",\n"
+ " \"%s\",{layers: '%s'},\n"
+ " { gutter:0,ratio:1,isBaseLayer:true,transitionEffect:'resize',\n"
+ " resolutions:[%s],\n"
+ " singleTile:true,\n"
+ " maxExtent: new OpenLayers.Bounds(%f,%f,%f,%f),\n"
+ " projection: new OpenLayers.Projection(\"%s\")\n"
+ " }\n"
+ " );\n";
+
/**
* \brief parse a demo request
* \private \memberof geocache_service_demo
@@ -96,6 +107,23 @@
grid->extent[3],
grid->srs);
caps = apr_psprintf(ctx->pool,"%s%s",caps,ol_layer);
+
+#ifdef USE_CAIRO
+ layers = apr_psprintf(ctx->pool,"%s,%s_%s_slayer",layers,tileset->name,grid->name);
+ ol_layer = apr_psprintf(ctx->pool,demo_layer_singletile,
+ tileset->name,
+ grid->name,
+ tileset->name,
+ grid->name,
+ apr_pstrcat(ctx->pool,onlineresource,"/wms?",NULL),
+ tileset->name,resolutions,
+ grid->extent[0],
+ grid->extent[1],
+ grid->extent[2],
+ grid->extent[3],
+ grid->srs);
+ caps = apr_psprintf(ctx->pool,"%s%s",caps,ol_layer);
+#endif
}
tileindex_index = apr_hash_next(tileindex_index);
}
Modified: trunk/mapserver/mapcache/src/service_wms.c
===================================================================
--- trunk/mapserver/mapcache/src/service_wms.c 2011-08-26 11:15:29 UTC (rev 12306)
+++ trunk/mapserver/mapcache/src/service_wms.c 2011-08-26 11:15:38 UTC (rev 12307)
@@ -186,6 +186,13 @@
grid->extent[3],
grid->srs);
srss = apr_pstrcat(ctx->pool,srss,bbox,NULL);
+ if(!strcasecmp(grid->srs,"epsg:4326")) {
+ char *wgs84bbox = apr_psprintf(ctx->pool,"<LatLonBoundingBox minx=\"%f\" miny=\"%f\" maxx=\"%f\" maxy=\"%f\"/>",
+ grid->extent[0], grid->extent[1],
+ grid->extent[2], grid->extent[3]);
+ srss = apr_pstrcat(ctx->pool,srss,wgs84bbox,NULL);
+
+ }
}
char *layercaps = apr_psprintf(ctx->pool,wms_layer,
tileset->name,
@@ -295,13 +302,13 @@
char *last, *key, *layers;
int count=1;
char *sep=",";
- geocache_request_get_tile *req = (geocache_request_get_tile*)apr_pcalloc(
+ geocache_request_get_tile *tile_req = (geocache_request_get_tile*)apr_pcalloc(
ctx->pool,sizeof(geocache_request_get_tile));
+ tile_req->ntiles = 0;
+ tile_req->tiles = (geocache_tile**)apr_pcalloc(ctx->pool,count * sizeof(geocache_tile*));
+ tile_req->request.type = GEOCACHE_REQUEST_UNKNOWN;
layers = apr_pstrdup(ctx->pool,str);
- req->request.type = GEOCACHE_REQUEST_GET_TILE;
for(key=layers;*key;key++) if(*key == ',') count++;
- req->ntiles = 0;
- req->tiles = (geocache_tile**)apr_pcalloc(ctx->pool,count * sizeof(geocache_tile*));
for (key = apr_strtok(layers, sep, &last); key != NULL;
key = apr_strtok(NULL, sep, &last)) {
geocache_tile *tile;
@@ -315,31 +322,47 @@
for(i=0;i<tileset->grid_links->nelts;i++){
geocache_grid_link *sgrid = APR_ARRAY_IDX(tileset->grid_links,i,geocache_grid_link*);
if(strcasecmp(sgrid->grid->srs,srs)) continue;
- if(sgrid->grid->tile_sx != width) continue;
- if(sgrid->grid->tile_sy != height) continue;
grid_link = sgrid;
break;
}
if(!grid_link) {
ctx->set_error(ctx, 400,
- "received unsuitable wms request: no suitable <grid> found");
+ "received unsuitable wms request: no <grid> with suitable srs found for layer %s",tileset->name);
return;
}
+
+ tile = geocache_tileset_tile_create(ctx->pool, tileset, grid_link);
- tile = geocache_tileset_tile_create(ctx->pool, tileset, grid_link);
- if(!tile) {
- ctx->set_error(ctx, 500, "failed to allocate tile");
+ if(grid_link->grid->tile_sx == width && grid_link->grid->tile_sy == height) {
+ if(!tile) {
+ ctx->set_error(ctx, 500, "failed to allocate tile");
+ return;
+ }
+ if(geocache_tileset_tile_lookup(ctx, tile, bbox) == GEOCACHE_SUCCESS) {
+ geocache_tileset_tile_validate(ctx,tile);
+ GC_CHECK_ERROR(ctx);
+ if(tile_req->request.type == GEOCACHE_REQUEST_UNKNOWN) {
+ tile_req->request.type = GEOCACHE_REQUEST_GET_TILE;
+ }
+ }
+ }
+ if(tile_req->request.type == GEOCACHE_REQUEST_UNKNOWN) {
+#ifdef USE_CAIRO
+ /*we have a request for a tile not aligned on the grid*/
+ tile_req->request.type = GEOCACHE_REQUEST_GET_MAP;
+ tile_req->width = width;
+ tile_req->height = height;
+ tile_req->extent = bbox;
+#else
+ ctx->set_error(ctx,404, "received unaligned wms request: no suitable <grid> found, and full wms support not enabled on this build");
return;
+#endif
}
- geocache_tileset_tile_lookup(ctx, tile, bbox);
- GC_CHECK_ERROR(ctx);
- geocache_tileset_tile_validate(ctx,tile);
- GC_CHECK_ERROR(ctx);
-
/*look for dimensions*/
+ apr_table_t *dimtable = NULL;
if(tileset->dimensions) {
int i;
- tile->dimensions = apr_table_make(ctx->pool,tileset->dimensions->nelts);
+ dimtable = apr_table_make(ctx->pool,tileset->dimensions->nelts);
for(i=0;i<tileset->dimensions->nelts;i++) {
geocache_dimension *dimension = APR_ARRAY_IDX(tileset->dimensions,i,geocache_dimension*);
const char *value;
@@ -348,20 +371,20 @@
int ok = dimension->validate(ctx,dimension,&tmpval);
GC_CHECK_ERROR(ctx);
if(ok == GEOCACHE_SUCCESS)
- apr_table_setn(tile->dimensions,dimension->name,tmpval);
+ apr_table_setn(dimtable,dimension->name,tmpval);
else {
ctx->set_error(ctx,400,"dimension \"%s\" value \"%s\" fails to validate",
dimension->name, value);
return;
}
} else {
- apr_table_setn(tile->dimensions,dimension->name,dimension->default_value);
+ apr_table_setn(dimtable,dimension->name,dimension->default_value);
}
}
}
- req->tiles[req->ntiles++] = tile;
+ tile_req->tiles[tile_req->ntiles++] = tile;
+ *request = (geocache_request*)tile_req;
}
- *request = (geocache_request*)req;
}
}
Modified: trunk/mapserver/mapcache/src/tileset.c
===================================================================
--- trunk/mapserver/mapcache/src/tileset.c 2011-08-26 11:15:29 UTC (rev 12306)
+++ trunk/mapserver/mapcache/src/tileset.c 2011-08-26 11:15:38 UTC (rev 12307)
@@ -42,10 +42,11 @@
* will return GEOCACHE_TILESET_WRONG_RESOLUTION or GEOCACHE_TILESET_WRONG_EXTENT
* if the bbox does not correspond to the tileset's configuration
*/
-static void _geocache_tileset_tile_get_cell(geocache_context *ctx, geocache_tile *tile, double *bbox) {
- double res = geocache_grid_get_resolution(tile->grid_link->grid,bbox);
- geocache_grid_get_level(ctx, tile->grid_link->grid, &res, &(tile->z));
- GC_CHECK_ERROR(ctx);
+static int _geocache_tileset_tile_get_cell(geocache_context *ctx, geocache_tile *tile, double *bbox) {
+ double res = geocache_grid_get_resolution(bbox,tile->grid_link->grid->tile_sx,
+ tile->grid_link->grid->tile_sy);
+ if(GEOCACHE_SUCCESS != geocache_grid_get_level(ctx, tile->grid_link->grid, &res, &(tile->z)))
+ return GEOCACHE_FAILURE;
/* TODO: strict mode
if exact and self.extent_type == "strict" and not self.contains((minx, miny), res):
raise TileCacheException("Lower left corner (%f, %f) is outside layer bounds %s. \nTo remove this condition, set extent_type=loose in your configuration."
@@ -57,11 +58,101 @@
if((fabs(bbox[0] - (tile->x * res * tile->grid_link->grid->tile_sx) - tile->grid_link->grid->extent[0] ) / res > 1) ||
(fabs(bbox[1] - (tile->y * res * tile->grid_link->grid->tile_sy) - tile->grid_link->grid->extent[1] ) / res > 1)) {
- ctx->set_error(ctx, 404, "grid %s: supplied bbox not aligned on configured grid",tile->grid_link->grid->name);
+ return GEOCACHE_FAILURE;
}
+ return GEOCACHE_SUCCESS;
}
+void geocache_tileset_get_map_tiles(geocache_context *ctx, geocache_tileset *tileset,
+ geocache_grid_link *grid_link,
+ double *bbox, int width, int height,
+ int *ntiles,
+ geocache_tile ***tiles) {
+ double resolution;
+ int level;
+ resolution = geocache_grid_get_resolution(bbox, width, height);
+ geocache_grid_get_closest_level(ctx,grid_link->grid,resolution,&level);
+ int mx,my,Mx,My;
+ int x,y;
+ geocache_grid_get_xy(ctx,grid_link->grid,bbox[0],bbox[1],level,&mx,&my);
+ geocache_grid_get_xy(ctx,grid_link->grid,bbox[2],bbox[3],level,&Mx,&My);
+ *ntiles = (Mx-mx+1)*(My-my+1);
+ if(*ntiles<=0) {
+ ctx->set_error(ctx,500,"BUG: negative number of tiles");
+ return;
+ }
+ int i=0;
+ *tiles = (geocache_tile**)apr_pcalloc(ctx->pool, *ntiles*sizeof(geocache_tile*));
+ for(x=mx;x<=Mx;x++) {
+ for(y=my;y<=My;y++) {
+ geocache_tile *tile = geocache_tileset_tile_create(ctx->pool,tileset, grid_link);
+ tile->x = x;
+ tile->y = y;
+ tile->z = level;
+ geocache_tileset_tile_validate(ctx,tile);
+ if(GC_HAS_ERROR(ctx)) {
+ //clear the error message
+ ctx->clear_errors(ctx);
+ } else {
+ (*tiles)[i++]=tile;
+ }
+ }
+ }
+ *ntiles = i;
+}
+#ifdef USE_CAIRO
+
+#include <cairo/cairo.h>
+#include <math.h>
+
+geocache_image* geocache_tileset_assemble_map_tiles(geocache_context *ctx, geocache_tileset *tileset,
+ geocache_grid_link *grid_link,
+ double *bbox, int width, int height,
+ int ntiles,
+ geocache_tile **tiles) {
+ double resolution = geocache_grid_get_resolution(bbox, width, height);
+ double tilebbox[4];
+ geocache_image *image = geocache_image_create(ctx);
+ image->w = width;
+ image->h = height;
+ image->stride = width*4;
+ image->data = apr_pcalloc(ctx->pool,width*height*4*sizeof(unsigned char));
+ cairo_surface_t* dstsurface= cairo_image_surface_create_for_data(image->data, CAIRO_FORMAT_ARGB32,
+ width, height,image->stride);
+ cairo_t *cr = cr = cairo_create (dstsurface);
+
+ int i;
+ for(i=0;i<ntiles;i++) {
+ geocache_tile *tile = tiles[i];
+ double tileresolution = tile->grid_link->grid->levels[tile->z]->resolution;
+ geocache_tileset_tile_bbox(tile,tilebbox);
+ geocache_image *im = geocache_imageio_decode(ctx,tile->data);
+ cairo_surface_t* srcsurface= cairo_image_surface_create_for_data(im->data, CAIRO_FORMAT_ARGB32,
+ im->w, im->h,im->stride);
+ /*compute the pixel position of top left corner*/
+ double dstminx = floor((tilebbox[0]-bbox[0])/resolution);
+ double dstminy = floor((bbox[3]-tilebbox[3])/resolution);
+ double f = tileresolution/resolution;
+ double dstwidth = ceil(im->w*f);
+ f = dstwidth/(double)im->w;
+ cairo_save(cr);
+ //cairo_clip(cr);
+ cairo_translate (cr, dstminx,dstminy);
+ cairo_scale (cr, f, f);
+ cairo_set_source_surface (cr, srcsurface, 0, 0);
+ cairo_paint (cr);
+ cairo_restore(cr);
+
+
+
+
+ }
+ return image;
+}
+
+#endif
+
/*
* compute the metatile that should be rendered for the given tile
*/
@@ -177,8 +268,8 @@
}
-void geocache_tileset_tile_lookup(geocache_context *ctx, geocache_tile *tile, double *bbox) {
- _geocache_tileset_tile_get_cell(ctx, tile,bbox);
+int geocache_tileset_tile_lookup(geocache_context *ctx, geocache_tile *tile, double *bbox) {
+ return _geocache_tileset_tile_get_cell(ctx, tile,bbox);
}
/**
Modified: trunk/mapserver/mapcache/src/util.c
===================================================================
--- trunk/mapserver/mapcache/src/util.c 2011-08-26 11:15:29 UTC (rev 12306)
+++ trunk/mapserver/mapcache/src/util.c 2011-08-26 11:15:38 UTC (rev 12307)
@@ -115,13 +115,19 @@
va_end(args);
}
+void _geocache_context_clear_error_default(geocache_context *ctx) {
+ ctx->_errcode = 0;
+ ctx->_errmsg = NULL;
+}
+
void geocache_context_init(geocache_context *ctx) {
ctx->_errcode = 0;
ctx->_errmsg = NULL;
ctx->get_error = _geocache_context_get_error_default;
ctx->get_error_message = _geocache_context_get_error_msg_default;
ctx->set_error = _geocache_context_set_error_default;
+ ctx->clear_errors = _geocache_context_clear_error_default;
}
/* vim: ai ts=3 sts=3 et sw=3
More information about the mapserver-commits
mailing list