[mapserver-commits] r7291 - trunk/mapserver

svn at osgeo.org svn at osgeo.org
Mon Jan 21 17:02:14 EST 2008


Author: warmerdam
Date: 2008-01-21 17:02:14 -0500 (Mon, 21 Jan 2008)
New Revision: 7291

Modified:
   trunk/mapserver/mapwcs.c
   trunk/mapserver/mapwcs.h
Log:
added imageCRS and GridOrigin support

Modified: trunk/mapserver/mapwcs.c
===================================================================
--- trunk/mapserver/mapwcs.c	2008-01-21 21:56:57 UTC (rev 7290)
+++ trunk/mapserver/mapwcs.c	2008-01-21 22:02:14 UTC (rev 7291)
@@ -29,6 +29,7 @@
 #include "mapserver.h"
 #include "maperror.h"
 #include "mapthread.h"
+#include <assert.h>
 
 MS_CVSID("$Id$")
 
@@ -351,6 +352,10 @@
            
          params->crs = strdup(tokens[4]);
          msFreeCharArray(tokens, n);
+         /* normalize imageCRS urns to simply "imageCRS" */
+         if( strncasecmp(params->crs,"urn:ogc:def:crs:",16) == 0 
+             && strncasecmp(params->crs+strlen(params->crs)-8,"imageCRS",8)==0)
+             strcpy( params->crs, "imageCRS" );
        } else if(strcasecmp(request->ParamNames[i], "GridOffsets") == 0) {
          tokens = msStringSplit(request->ParamValues[i], ',', &n);
          if(tokens==NULL || n < 2) {
@@ -361,12 +366,21 @@
          params->resx = atof(tokens[0]);
          params->resy = fabs(atof(tokens[1]));
          msFreeCharArray(tokens, n);
+       } else if(strcasecmp(request->ParamNames[i], "GridOrigin") == 0) {
+         tokens = msStringSplit(request->ParamValues[i], ',', &n);
+         if(tokens==NULL || n < 2) {
+           msSetError(MS_WMSERR, "Wrong number of arguments for GridOrigin", 
+                      "msWCSParseRequest()");
+           return msWCSException(map, params->version, "InvalidParameterValue", "GridOffsets");
+         }
+         params->originx = atof(tokens[0]);
+         params->originy = atof(tokens[1]);
+         msFreeCharArray(tokens, n);
        }
 	   
        /* and so on... */
     }
   }
-
   /* we are not dealing with an XML encoded request at this point */
   return MS_SUCCESS;
 }
@@ -1075,7 +1089,78 @@
   return MS_SUCCESS;
 }    
 
+/************************************************************************/
+/*                   msWCSGetCoverage_ImageCRSSetup()                   */
+/*                                                                      */
+/*      The request was in imageCRS - update the map projection to      */
+/*      map the native projection of the layer, and reset the           */
+/*      bounding box to match the projected bounds corresponding to     */
+/*      the imageCRS request.                                           */
+/************************************************************************/
 
+static int msWCSGetCoverage_ImageCRSSetup(
+    mapObj *map, cgiRequestObj *request, wcsParamsObj *params,
+    coverageMetadataObj *cm, layerObj *layer )
+
+{
+/* -------------------------------------------------------------------- */
+/*      Load map with the layer (coverage) coordinate system.  We       */
+/*      really need a set projectionObj from projectionObj function!    */
+/* -------------------------------------------------------------------- */
+    char *layer_proj = msGetProjectionString( &(layer->projection) );
+
+    if (msLoadProjectionString(&(map->projection), layer_proj) != 0)
+        return msWCSException( map, params->version, NULL, NULL);
+
+    free( layer_proj );
+    layer_proj = NULL;
+
+/* -------------------------------------------------------------------- */
+/*      Reset bounding box.                                             */
+/* -------------------------------------------------------------------- */
+    if( params->bbox.maxx != params->bbox.minx )
+    {
+        rectObj orig_bbox = params->bbox;
+        
+        params->bbox.minx = 
+            cm->geotransform[0]
+            + orig_bbox.minx * cm->geotransform[1]
+            + orig_bbox.miny * cm->geotransform[2];
+        params->bbox.maxy = 
+            cm->geotransform[3]
+            + orig_bbox.minx * cm->geotransform[4]
+            + orig_bbox.miny * cm->geotransform[5];
+        params->bbox.maxx = 
+            cm->geotransform[0]
+            + (orig_bbox.maxx+1) * cm->geotransform[1]
+            + (orig_bbox.maxy+1) * cm->geotransform[2];
+        params->bbox.miny = 
+            cm->geotransform[3]
+            + (orig_bbox.maxx+1) * cm->geotransform[4]
+            + (orig_bbox.maxy+1) * cm->geotransform[5];
+
+      /* WCS 1.1 boundbox is center of pixel oriented. */
+      if( strncasecmp(params->version,"1.1",3) == 0 )
+      {
+          params->bbox.minx += cm->geotransform[1]/2 + cm->geotransform[2]/2;
+          params->bbox.maxx -= cm->geotransform[1]/2 + cm->geotransform[2]/2;
+          params->bbox.maxy += cm->geotransform[4]/2 + cm->geotransform[5]/2;
+          params->bbox.miny -= cm->geotransform[4]/2 + cm->geotransform[5]/2;
+      }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Reset resolution.                                               */
+/* -------------------------------------------------------------------- */
+    if( params->resx != 0.0 )
+    {
+        params->resx = cm->geotransform[1] * params->resx;
+        params->resy = fabs(cm->geotransform[5] * params->resy);
+    }
+
+    return MS_SUCCESS;
+}
+
 /************************************************************************/
 /*                          msWCSGetCoverage()                          */
 /************************************************************************/
@@ -1125,6 +1210,9 @@
           msAxisNormalizePoints( &proj, 1, 
                                  &(params->resx), 
                                  &(params->resy) );
+          msAxisNormalizePoints( &proj, 1, 
+                                 &(params->originx), 
+                                 &(params->originy) );
       }
       msFreeProjection( &proj );
   }
@@ -1165,6 +1253,11 @@
         || strncasecmp(crs_to_use,"urn:ogc:def:crs:",16) == 0 ) {
       if (msLoadProjectionString(&(map->projection), (char *) crs_to_use) != 0)
         return msWCSException( map, params->version, NULL, NULL);
+    } else if( strcasecmp(crs_to_use,"imageCRS") == 0 ) {
+        /* use layer native CRS, and rework bounding box accordingly */
+        if( msWCSGetCoverage_ImageCRSSetup( map, request, params, &cm, lp )
+            != MS_SUCCESS )
+            return MS_FAILURE;
     } else {  /* should we support WMS style AUTO: projections? (not for now) */
       msSetError(MS_WCSERR, "Unsupported SRS namespace (only EPSG currently supported).", "msWCSGetCoverage()");
       return msWCSException(map, params->version, "InvalidParameterValue", "srs");
@@ -1252,57 +1345,67 @@
       {
           params->bbox.minx += cm.geotransform[1]/2 + cm.geotransform[2]/2;
           params->bbox.maxx -= cm.geotransform[1]/2 + cm.geotransform[2]/2;
-          params->bbox.miny += cm.geotransform[4]/2 + cm.geotransform[5]/2;
-          params->bbox.maxy -= cm.geotransform[4]/2 + cm.geotransform[5]/2;
+          params->bbox.maxy += cm.geotransform[4]/2 + cm.geotransform[5]/2;
+          params->bbox.miny -= cm.geotransform[4]/2 + cm.geotransform[5]/2;
       }
   }
+
+  /* WCS 1.1+ GridOrigin is effectively resetting the minx/maxy 
+     BOUNDINGBOX values, so apply that here */
+  if( params->originx != 0.0 || params->originy != 0.0 )
+  {
+      /* should never be 1.0 in this logic. */
+      assert( strncasecmp(params->version,"1.0",3) != 0 );
+      params->bbox.minx = params->originx;
+      params->bbox.maxy = params->originy;
+  }
     
   /* if necessary, project the BBOX */
 
   /* in WCS 1.1 the default is full resolution */
   if( strncasecmp(params->version,"1.1",3) == 0 
-      && params->resx == 0.0 && params->resy == 0.0
-      && params->width == 0 && params->height == 0 ) {
+      && params->resx == 0.0 && params->resy == 0.0 ) {
 
     params->resx = cm.geotransform[1];
     params->resy = fabs(cm.geotransform[5]);
   }
 
   /* compute width/height from BBOX and cellsize.  */
-  if( (params->resx == 0.0 || params->resy == 0.0) && params->width != 0 && params->height != 0 ) {
+  if( (params->resx == 0.0 || params->resy == 0.0) 
+      && params->width != 0 && params->height != 0 ) {
 
-    /* WCS 1.1 boundbox is center of pixel oriented. */
-    if( strncasecmp(params->version,"1.1",3) == 0 )
-    {
-        params->resx = (params->bbox.maxx - params->bbox.minx) 
-            / (params->width-1);
-        params->resy = (params->bbox.maxy - params->bbox.miny) 
-            / (params->height-1);
-    }
-    else
-    {
-        params->resx = (params->bbox.maxx -params->bbox.minx) / params->width;
-        params->resy = (params->bbox.maxy -params->bbox.miny) / params->height;
-    }
+    /* should always be 1.0 in this logic. */
+    assert( strncasecmp(params->version,"1.0",3) == 0 );
+
+    params->resx = (params->bbox.maxx -params->bbox.minx) / params->width;
+    params->resy = (params->bbox.maxy -params->bbox.miny) / params->height;
   }
     
   /* compute cellsize/res from bbox and raster size. */
-  if( (params->width == 0 || params->height == 0) && params->resx != 0 && params->resy != 0 ) {
+  if( (params->width == 0 || params->height == 0) 
+      && params->resx != 0 && params->resy != 0 ) {
 
-    /* WCS 1.1 boundbox is center of pixel oriented. */
-    if( strncasecmp(params->version,"1.1",3) == 0 )
+    /* WCS 1.0 boundbox is edge of pixel oriented. */
+    if( strncasecmp(params->version,"1.0",3) == 0 )
     {
         params->width = (int) ((params->bbox.maxx - params->bbox.minx) 
-                               / params->resx + 1.5);
+                               / params->resx + 0.5);
         params->height = (int) ((params->bbox.maxy - params->bbox.miny) 
-                                / params->resy + 1.5);
+                                / params->resy + 0.5);
     }
     else
     {
         params->width = (int) ((params->bbox.maxx - params->bbox.minx) 
-                               / params->resx + 0.5);
+                               / params->resx + 1.000001);
         params->height = (int) ((params->bbox.maxy - params->bbox.miny) 
-                                / params->resy + 0.5);
+                                / params->resy + 1.000001);
+
+        /* recompute bounding box so we get exactly the origin and
+           resolution requested. */
+        params->bbox.maxx = params->bbox.minx 
+            + (params->width-1) * params->resx;
+        params->bbox.miny = params->bbox.maxy 
+            - (params->height-1) * params->resy;
     }
   }
 

Modified: trunk/mapserver/mapwcs.h
===================================================================
--- trunk/mapserver/mapwcs.h	2008-01-21 21:56:57 UTC (rev 7290)
+++ trunk/mapserver/mapwcs.h	2008-01-21 22:02:14 UTC (rev 7291)
@@ -58,6 +58,7 @@
   rectObj bbox;		    /* subset bounding box (3D), although we'll only use 2D */
   char *time;
   long width, height, depth;	/* image dimensions */
+  double originx, originy;      /* WCS 1.1 GridOrigin */
   double resx, resy, resz;      /* resolution */
   char *interpolation;          /* interpolationMethod */
   char *format;



More information about the mapserver-commits mailing list