[mapserver-commits] r7547 - trunk/mapserver
svn at osgeo.org
svn at osgeo.org
Wed Apr 30 16:26:57 EDT 2008
Author: pramsey
Date: 2008-04-30 16:26:56 -0400 (Wed, 30 Apr 2008)
New Revision: 7547
Added:
trunk/mapserver/maptile.c
trunk/mapserver/maptile.h
Modified:
trunk/mapserver/HISTORY.TXT
trunk/mapserver/Makefile.in
trunk/mapserver/mapserv.c
trunk/mapserver/mapserv.h
trunk/mapserver/maptemplate.h
Log:
Tiling API (RFC 43) mode=tile, tilemode=spheremerc, tile=x y zoom (#2581)
Modified: trunk/mapserver/HISTORY.TXT
===================================================================
--- trunk/mapserver/HISTORY.TXT 2008-04-30 14:27:38 UTC (rev 7546)
+++ trunk/mapserver/HISTORY.TXT 2008-04-30 20:26:56 UTC (rev 7547)
@@ -13,6 +13,8 @@
Current Version (5.1-dev, SVN trunk):
-------------------------------------
+- Tiling API (RFC 43) mode=tile, tilemode=spheremerc, tile=x y zoom (#2581)
+
- Remove C++-style comments and most other warnings thrown by -pedantic (#2598)
- Fix PostGIS transaction behavior in fcgi situations (#2497)
Modified: trunk/mapserver/Makefile.in
===================================================================
--- trunk/mapserver/Makefile.in 2008-04-30 14:27:38 UTC (rev 7546)
+++ trunk/mapserver/Makefile.in 2008-04-30 20:26:56 UTC (rev 7547)
@@ -329,8 +329,8 @@
scalebar: $(LIBMAP_STATIC) scalebar.o mapserver.h
$(LD) $(CFLAGS) scalebar.o $(EXE_LDFLAGS) -o scalebar
-mapserv: mapserv.h $(LIBMAP_STATIC) mapserv.o cgiutil.o mapserver.h
- $(LD) $(CFLAGS) mapserv.o cgiutil.o $(EXE_LDFLAGS) -o mapserv
+mapserv: mapserv.h maptile.h $(LIBMAP_STATIC) mapserv.o cgiutil.o maptile.o mapserver.h
+ $(LD) $(CFLAGS) mapserv.o cgiutil.o maptile.o $(EXE_LDFLAGS) -o mapserv
shpindex: $(LIBMAP_STATIC) shpindex.o mapserver.h
$(LD) $(CFLAGS) shpindex.o $(EXE_LDFLAGS) -o shpindex
Modified: trunk/mapserver/mapserv.c
===================================================================
--- trunk/mapserver/mapserv.c 2008-04-30 14:27:38 UTC (rev 7546)
+++ trunk/mapserver/mapserv.c 2008-04-30 20:26:56 UTC (rev 7547)
@@ -843,6 +843,40 @@
continue;
}
+ /* --------------------------------------------------------------------
+ * The following code is used to support mode=tile
+ * -------------------------------------------------------------------- */
+
+ if(strcasecmp(msObj->request->ParamNames[i], "tilemode") == 0) {
+ /* currently, only valid tilemode is "spheremerc" */
+ if( strcasecmp(msObj->request->ParamValues[i], "spheremerc") != 0) {
+ msSetError(MS_WEBERR, "Invalid tilemode. Use one of: spheremerc", "loadForm()");
+ writeError();
+ }
+ msObj->TileMode = SPHEREMERC;
+ continue;
+ }
+
+ if(strcasecmp(msObj->request->ParamNames[i],"tile") == 0) {
+
+ int num_coords = 0;
+ char **coords = NULL;
+ int l = 0;
+
+ msObj->CoordSource = FROMTILE;
+ coords = msStringSplit(msObj->request->ParamValues[i], ' ', &(num_coords));
+ if( num_coords != 3 ) {
+ msSetError(MS_WEBERR, "Invalid number of tile coordinates (should be three).", "loadForm()");
+ writeError();
+ }
+
+ msObj->TileCoords = (long *) malloc(sizeof(long) * 3);
+ for(l = 0; l < num_coords; l++) {
+ *(msObj->TileCoords + l) = strtol(coords[l], NULL, 10);
+ }
+ continue;
+ }
+
/* -------------------------------------------------------------------- */
/* The following code is used to support the rosa applet (for */
/* more information on Rosa, please consult : */
@@ -1258,6 +1292,16 @@
if(msObj->CoordSource == FROMREFPNT) /* force browse mode if the reference coords are set */
msObj->Mode = BROWSE;
+ /*
+ ** Tile mode:
+ ** Set the projection up and test the parameters for legality.
+ */
+ if(msObj->Mode == TILE) {
+ if( msTileSetup(msObj) != MS_SUCCESS ) {
+ writeError();
+ }
+ }
+
if(msObj->Mode == BROWSE) {
if(!msObj->Map->web.template) {
@@ -1297,10 +1341,19 @@
}
}
- } else if(msObj->Mode == MAP || msObj->Mode == SCALEBAR || msObj->Mode == REFERENCE) { /* "image" only modes */
+ } else if(msObj->Mode == MAP || msObj->Mode == SCALEBAR || msObj->Mode == REFERENCE || msObj->Mode == TILE) { /* "image" only modes */
+
setExtent(msObj);
checkWebScale(msObj);
+ /*
+ ** We set tile extents here instead of setExtent so that all the
+ ** non-CGI utilities don't require maptile.o in their build.
+ */
+ if( msObj->Mode == TILE ) {
+ msTileSetExtent(msObj);
+ }
+
switch(msObj->Mode) {
case MAP:
if(QueryFile) {
@@ -1317,12 +1370,25 @@
case SCALEBAR:
img = msDrawScalebar(msObj->Map);
break;
+ case TILE:
+ /* TODO: we may need an msDrawTile for doing "draw large then clip" tricks */
+ img = msDrawMap(msObj->Map, MS_FALSE);
+ break;
}
if(!img) writeError();
+ /*
+ ** Set the Cache control headers if the option is set.
+ */
+ if( msLookupHashTable(&(msObj->Map->web.metadata), "http_max_age") ) {
+ msIO_printf("Cache-Control: max-age=%s%c", msLookupHashTable(&(msObj->Map->web.metadata), "http_max_age"), 10);
+ }
+
msIO_printf("Content-type: %s%c%c",MS_IMAGE_MIME_TYPE(msObj->Map->outputformat), 10,10);
- if( msObj->Mode == MAP )
+
+
+ if( msObj->Mode == MAP || msObj->Mode == TILE )
status = msSaveImage(msObj->Map,img, NULL);
else
status = msSaveImage(NULL,img, NULL);
@@ -1699,7 +1765,7 @@
if(QueryLayer) free(QueryLayer);
if(SelectLayer) free(SelectLayer);
if(QueryFile) free(QueryFile);
-
+
msFreeMapServObj(msObj);
#ifdef USE_FASTCGI
Modified: trunk/mapserver/mapserv.h
===================================================================
--- trunk/mapserver/mapserv.h 2008-04-30 14:27:38 UTC (rev 7546)
+++ trunk/mapserver/mapserv.h 2008-04-30 20:26:56 UTC (rev 7547)
@@ -38,6 +38,7 @@
#include <time.h>
#include "maptemplate.h"
+#include "maptile.h"
#include "cgiutil.h"
/*
@@ -56,13 +57,13 @@
/*
** Enumerated types, keep the query modes in sequence and at the end of the enumeration (mode enumeration is in maptemplate.h).
*/
-int numModes = 27;
-static char *modeStrings[27] = {"BROWSE","ZOOMIN","ZOOMOUT","MAP","LEGEND","LEGENDICON","REFERENCE","SCALEBAR","COORDINATE",
+int numModes = 28;
+static char *modeStrings[28] = {"BROWSE","ZOOMIN","ZOOMOUT","MAP","LEGEND","LEGENDICON","REFERENCE","SCALEBAR","COORDINATE",
"QUERY","QUERYMAP","NQUERY","NQUERYMAP",
"ITEMQUERY","ITEMQUERYMAP","ITEMNQUERY","ITEMNQUERYMAP",
"FEATUREQUERY","FEATUREQUERYMAP","FEATURENQUERY","FEATURENQUERYMAP",
"ITEMFEATUREQUERY","ITEMFEATUREQUERYMAP","ITEMFEATURENQUERY","ITEMFEATURENQUERYMAP",
- "INDEXQUERY","INDEXQUERYMAP"};
+ "INDEXQUERY","INDEXQUERYMAP","TILE"};
/*
** Global variables
Modified: trunk/mapserver/maptemplate.h
===================================================================
--- trunk/mapserver/maptemplate.h 2008-04-30 14:27:38 UTC (rev 7546)
+++ trunk/mapserver/maptemplate.h 2008-04-30 20:26:56 UTC (rev 7547)
@@ -38,15 +38,16 @@
#define MAXZOOM 25
#define MINZOOM -25
-enum coordSources {NONE, FROMIMGPNT, FROMIMGBOX, FROMIMGSHAPE, FROMREFPNT, FROMUSERPNT, FROMUSERBOX, FROMUSERSHAPE, FROMBUF, FROMSCALE};
+enum coordSources {NONE, FROMIMGPNT, FROMIMGBOX, FROMIMGSHAPE, FROMREFPNT, FROMUSERPNT, FROMUSERBOX, FROMUSERSHAPE, FROMBUF, FROMSCALE, FROMTILE};
enum modes {BROWSE, ZOOMIN, ZOOMOUT, MAP, LEGEND, LEGENDICON, REFERENCE, SCALEBAR, COORDINATE,
QUERY, QUERYMAP, NQUERY, NQUERYMAP,
ITEMQUERY, ITEMQUERYMAP, ITEMNQUERY, ITEMNQUERYMAP,
FEATUREQUERY, FEATUREQUERYMAP, FEATURENQUERY, FEATURENQUERYMAP,
- ITEMFEATUREQUERY, ITEMFEATUREQUERYMAP,ITEMFEATURENQUERY,ITEMFEATURENQUERYMAP,
- INDEXQUERY,INDEXQUERYMAP};
+ ITEMFEATUREQUERY, ITEMFEATUREQUERYMAP, ITEMFEATURENQUERY, ITEMFEATURENQUERYMAP,
+ INDEXQUERY, INDEXQUERYMAP, TILE};
+
/*! \srtuct mapservObj
* \brief Global structur used by template and mapserv
*
@@ -93,6 +94,11 @@
/* can be BROWSE, QUERY, etc. */
int Mode;
+ /* can be SPHEREMERC */
+ int TileMode;
+ /* three integral coordinates, X, Y, Zoom */
+ long *TileCoords;
+
/* big enough for time + pid */
char Id[IDSIZE];
Added: trunk/mapserver/maptile.c
===================================================================
--- trunk/mapserver/maptile.c (rev 0)
+++ trunk/mapserver/maptile.c 2008-04-30 20:26:56 UTC (rev 7547)
@@ -0,0 +1,213 @@
+/******************************************************************************
+ * $Id$
+ *
+ * Project: MapServer
+ * Purpose: MapServer Tile Access API
+ * Author: Paul Ramsey <pramsey at cleverelephant.ca>
+ *
+ ******************************************************************************
+ * Copyright (c) 2008, Paul Ramsey
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies of this Software or works derived from this Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#include "maptile.h"
+#include "mapproject.h"
+
+/************************************************************************
+ * msTileSetup *
+ * *
+ * Called from mapserv.c, this is where the fun begins *
+ * Set up projections and test the parameters for legality. *
+ ************************************************************************/
+int msTileSetup(mapservObj* msObj) {
+#ifdef USE_TILE_API
+
+ char *outProjStr = NULL;
+
+ /*
+ ** Ensure all the LAYERs have a projection.
+ **/
+ if( msTileSetProjections(msObj->Map) != 0 ) {
+ return(MS_FAILURE);
+ }
+
+ /*
+ ** Set the projection string for this mode.
+ **/
+ if( msObj->TileMode == SPHEREMERC ) {
+ outProjStr = SPHEREMERC_PROJ4;
+ } else {
+ return(MS_FAILURE); /* Huh? No mode? */
+ }
+ if( msLoadProjectionString(&(msObj->Map->projection), outProjStr) != 0 ) {
+ msSetError(MS_CGIERR, "Unable to load projection string.", "msTileSetExtent()");
+ return(MS_FAILURE);
+ }
+
+ /*
+ ** Set up the output extents for this tilemode and tile coordinates
+ **/
+ if( msObj->TileMode == SPHEREMERC ) {
+
+ int x = msObj->TileCoords[0];
+ int y = msObj->TileCoords[1];
+ int zoom = msObj->TileCoords[2];
+ double zoomfactor = pow(2.0, (double)zoom);
+
+ /*
+ ** Check the input request for sanity.
+ **/
+ if( x >= zoomfactor || y >= zoomfactor ) {
+ msSetError(MS_CGIERR, "Tile coordinates are too large for supplied zoom.", "msTileSetExtent()");
+ return(MS_FAILURE);
+ }
+ if( x < 0 || y < 0 ) {
+ msSetError(MS_CGIERR, "Tile coordinates should not be less than zero.", "msTileSetExtent()");
+ return(MS_FAILURE);
+ }
+
+ /*
+ ** Set the output tile size.
+ **/
+ msObj->ImgCols = SPHEREMERC_IMAGE_SIZE;
+ msObj->ImgRows = SPHEREMERC_IMAGE_SIZE;
+ msObj->Map->width = SPHEREMERC_IMAGE_SIZE;
+ msObj->Map->height = SPHEREMERC_IMAGE_SIZE;
+
+ }
+ else {
+ return(MS_FAILURE); /* Huh? Should have a mode. */
+ }
+
+ return MS_SUCCESS;
+#else
+ msSetError(MS_CGIERR, "Tile API is not available.", "msTileSetExtent()");
+ return(MS_FAILURE);
+#endif
+}
+
+/************************************************************************
+ * msTileSetExtent *
+ * *
+ * Called from setExtent() in maptemplate.c. *
+ ************************************************************************/
+int msTileSetExtent(mapservObj* msObj) {
+#ifdef USE_TILE_API
+
+ mapObj *map = msObj->Map;
+
+ if( msObj->TileMode == SPHEREMERC ) {
+
+ int x = msObj->TileCoords[0];
+ int y = msObj->TileCoords[1];
+ int zoom = msObj->TileCoords[2];
+ double zoomfactor = pow(2.0, (double)zoom);
+
+ /*
+ * Calculate the ground extents of the tile request.
+ */
+// printf("X: %i Y: %i Z: %i\n",x,y,zoom);
+ double tilesize = SPHEREMERC_GROUND_SIZE / zoomfactor;
+ double xmin = (x * tilesize) - (SPHEREMERC_GROUND_SIZE / 2.0);
+ double xmax = ((x + 1) * tilesize) - (SPHEREMERC_GROUND_SIZE / 2.0);
+ double ymin = (SPHEREMERC_GROUND_SIZE / 2.0) - ((y + 1) * tilesize);
+ double ymax = (SPHEREMERC_GROUND_SIZE / 2.0) - (y * tilesize);
+
+ map->extent.minx = xmin;
+ map->extent.maxx = xmax;
+ map->extent.miny = ymin;
+ map->extent.maxy = ymax;
+
+ /*
+ * Set the output tile size.
+ */
+ msObj->ImgCols = SPHEREMERC_IMAGE_SIZE;
+ msObj->ImgRows = SPHEREMERC_IMAGE_SIZE;
+ map->width = SPHEREMERC_IMAGE_SIZE;
+ map->height = SPHEREMERC_IMAGE_SIZE;
+
+ /*
+ * Adjust the extents inwards by 1/2 pixel so they are from
+ * center-of-pixel to center-of-pixel, instead of edge-to-edge.
+ * This is the way mapserver does it.
+ */
+ double dx, dy;
+ dx = (map->extent.maxx - map->extent.minx) / map->width;
+ map->extent.minx += dx*0.5;
+ map->extent.maxx -= dx*0.5;
+ dy = (map->extent.maxy - map->extent.miny) / map->height;
+ map->extent.miny += dy*0.5;
+ map->extent.maxy -= dy*0.5;
+
+ }
+ else {
+ return(MS_FAILURE); /* Huh? Should have a mode. */
+ }
+
+ return MS_SUCCESS;
+#else
+ msSetError(MS_CGIERR, "Tile API is not available.", "msTileSetExtent()");
+ return(MS_FAILURE);
+#endif
+}
+
+/************************************************************************
+ * msTileSetProjections *
+ * *
+ * Ensure that all the layers in the map file have a projection *
+ * by copying the map-level projection to all layers than have no *
+ * projection. *
+ ************************************************************************/
+
+int msTileSetProjections(mapObj* map) {
+
+ char *mapProjStr = NULL;
+
+ if (map->projection.numargs <= 0) {
+ msSetError(MS_WMSERR, "Cannot set new SRS on a map that doesn't "
+ "have any projection set. Please make sure your mapfile "
+ "has a PROJECTION defined at the top level.",
+ "msTileSetExtent()");
+ return(MS_FAILURE);
+ }
+ int i;
+ for(i=0; i<map->numlayers; i++) {
+ /* This layer is turned on and needs a projection? */
+ if (GET_LAYER(map, i)->projection.numargs <= 0 &&
+ GET_LAYER(map, i)->status != MS_OFF &&
+ GET_LAYER(map, i)->transform == MS_TRUE) {
+
+ /* Fetch main map projection string only now that we need it */
+ if (mapProjStr == NULL)
+ mapProjStr = msGetProjectionString(&(map->projection));
+
+ /* Set the projection to the map file projection */
+ if (msLoadProjectionString(&(GET_LAYER(map, i)->projection), mapProjStr) != 0) {
+ msSetError(MS_CGIERR, "Unable to set projection on layer.", "msTileSetExtent()");
+ return(MS_FAILURE);
+ }
+ GET_LAYER(map, i)->project = MS_TRUE;
+ }
+ }
+ msFree(mapProjStr);
+ return(MS_SUCCESS);
+}
+
+
Added: trunk/mapserver/maptile.h
===================================================================
--- trunk/mapserver/maptile.h (rev 0)
+++ trunk/mapserver/maptile.h 2008-04-30 20:26:56 UTC (rev 7547)
@@ -0,0 +1,46 @@
+/******************************************************************************
+ * $Id$
+ *
+ * Project: MapServer
+ * Purpose: MapServer Tile Access API
+ * Author: Paul Ramsey <pramsey at cleverelephant.ca>
+ *
+ ******************************************************************************
+ * Copyright (c) 2008, Paul Ramsey
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies of this Software or works derived from this Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#include "mapserver.h"
+#include "maptemplate.h"
+
+/* TODO: add this to build environment */
+#define USE_TILE_API 1
+
+#define SPHEREMERC_PROJ4 "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +units=m +k=1.0 +nadgrids=@null"
+#define SPHEREMERC_GROUND_SIZE (20037508.34*2)
+#define SPHEREMERC_IMAGE_SIZE 256
+
+enum tileModes {SPHEREMERC};
+
+MS_DLL_EXPORT int msTileSetup(mapservObj *msObj);
+MS_DLL_EXPORT int msTileSetExtent(mapservObj *msObj);
+MS_DLL_EXPORT int msTileSetProjections(mapObj *map);
+
+
More information about the mapserver-commits
mailing list