[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