[mapserver-commits] r7256 - trunk/mapserver

svn at osgeo.org svn at osgeo.org
Fri Jan 11 23:54:04 EST 2008


Author: warmerdam
Date: 2008-01-11 23:54:04 -0500 (Fri, 11 Jan 2008)
New Revision: 7256

Modified:
   trunk/mapserver/mapwcs.c
   trunk/mapserver/mapwcs.h
   trunk/mapserver/mapwcs11.c
Log:
implement WCS 1.1 RangeSubset support

Modified: trunk/mapserver/mapwcs.c
===================================================================
--- trunk/mapserver/mapwcs.c	2008-01-10 15:32:46 UTC (rev 7255)
+++ trunk/mapserver/mapwcs.c	2008-01-12 04:54:04 UTC (rev 7256)
@@ -197,7 +197,7 @@
 /*                      msWCSGetRequestParameter()                      */
 /************************************************************************/
 
-static const char *msWCSGetRequestParameter(cgiRequestObj *request, char *name) {
+const char *msWCSGetRequestParameter(cgiRequestObj *request, char *name) {
   int i;
 
   if(!request || !name) /* nothing to do */
@@ -359,7 +359,7 @@
            return msWCSException(map, params->version, "InvalidParameterValue", "GridOffsets");
          }
          params->resx = atof(tokens[0]);
-         params->resy = atof(tokens[1]);
+         params->resy = fabs(atof(tokens[1]));
          msFreeCharArray(tokens, n);
        }
 	   
@@ -1017,6 +1017,66 @@
 }
 
 /************************************************************************/
+/*                       msWCSGetCoverageBands10()                      */
+/************************************************************************/
+
+static int msWCSGetCoverageBands10( mapObj *map, cgiRequestObj *request, 
+                                    wcsParamsObj *params, layerObj *lp,
+                                    char **p_bandlist )
+
+{
+  const char *value;
+  int i;
+
+  /* Are there any non-spatio/temporal ranges to do subsetting on (e.g. bands) */
+  value = msOWSLookupMetadata(&(lp->metadata), "COM", "rangeset_axes"); /* this will get all the compound range sets */
+  if(value) { 
+    char **tokens;
+    int numtokens;
+    char tag[100];
+    const char *rangeitem;
+
+    tokens = msStringSplit(value, ',', &numtokens);
+    for(i=0; i<numtokens; i++) {
+      if((value = msWCSGetRequestParameter(request, tokens[i])) == NULL) continue; /* next rangeset parameter */
+       
+      if(msWCSValidateRangeSetParam(&(lp->metadata), tokens[i], "COM", value) != MS_SUCCESS) {
+        msSetError( MS_WCSERR, "Error specifying \"%s\" parameter value(s).", "msWCSGetCoverage()", tokens[i]);
+        return msWCSException(map, params->version, NULL, NULL);
+      }
+       
+      /* xxxxx_rangeitem tells us how to subset */
+      snprintf(tag, 100, "%s_rangeitem", tokens[i]);
+      if((rangeitem = msOWSLookupMetadata(&(lp->metadata), "COM", tag)) == NULL) {
+        msSetError( MS_WCSERR, "Missing required metadata element \"%s\", unable to process %s=%s.", "msWCSGetCoverage()", tag, tokens[i], value);
+        return msWCSException(map, params->version, NULL, NULL);
+      }
+         
+      if(strcasecmp(rangeitem, "_bands") == 0) { /* special case, subset bands */
+        *p_bandlist = msWCSConvertRangeSetToString(value);
+           
+        if(!*p_bandlist) {
+          msSetError( MS_WCSERR, "Error specifying \"%s\" paramter value(s).", "msWCSGetCoverage()", tokens[i]);
+          return msWCSException(map, params->version, NULL, NULL);
+        }          
+      } else if(strcasecmp(rangeitem, "_pixels") == 0) { /* special case, subset pixels */
+        msSetError( MS_WCSERR, "Arbitrary range sets based on pixel values are not yet supported.", "msWCSGetCoverage()" );
+        return msWCSException(map, params->version, NULL, NULL);
+      } else {
+        msSetError( MS_WCSERR, "Arbitrary range sets based on tile (i.e. image) attributes are not yet supported.", "msWCSGetCoverage()" );
+        return msWCSException(map, params->version, NULL, NULL);
+      }
+    }
+       
+    /* clean-up */
+    msFreeCharArray(tokens, numtokens);
+  }
+
+  return MS_SUCCESS;
+}    
+
+
+/************************************************************************/
 /*                          msWCSGetCoverage()                          */
 /************************************************************************/
 
@@ -1150,50 +1210,13 @@
     msLoadExpressionString(&tlp->filter, params->time);
   }
            
-  /* Are there any non-spatio/temporal ranges to do subsetting on (e.g. bands) */
-  value = msOWSLookupMetadata(&(lp->metadata), "COM", "rangeset_axes"); /* this will get all the compound range sets */
-  if(value) { 
-    char **tokens;
-    int numtokens;
-    char tag[100];
-    const char *rangeitem;
+  if( strncasecmp(params->version,"1.0",3) == 0 )
+      status = msWCSGetCoverageBands10( map, request, params, lp, &bandlist );
+  else
+      status = msWCSGetCoverageBands11( map, request, params, lp, &bandlist );
+  if( status != MS_SUCCESS )
+      return status;
 
-    tokens = msStringSplit(value, ',', &numtokens);
-    for(i=0; i<numtokens; i++) {
-      if((value = msWCSGetRequestParameter(request, tokens[i])) == NULL) continue; /* next rangeset parameter */
-       
-      if(msWCSValidateRangeSetParam(&(lp->metadata), tokens[i], "COM", value) != MS_SUCCESS) {
-        msSetError( MS_WCSERR, "Error specifying \"%s\" parameter value(s).", "msWCSGetCoverage()", tokens[i]);
-        return msWCSException(map, params->version, NULL, NULL);
-      }
-       
-      /* xxxxx_rangeitem tells us how to subset */
-      snprintf(tag, 100, "%s_rangeitem", tokens[i]);
-      if((rangeitem = msOWSLookupMetadata(&(lp->metadata), "COM", tag)) == NULL) {
-        msSetError( MS_WCSERR, "Missing required metadata element \"%s\", unable to process %s=%s.", "msWCSGetCoverage()", tag, tokens[i], value);
-        return msWCSException(map, params->version, NULL, NULL);
-      }
-         
-      if(strcasecmp(rangeitem, "_bands") == 0) { /* special case, subset bands */
-        bandlist = msWCSConvertRangeSetToString(value);
-           
-        if(!bandlist) {
-          msSetError( MS_WCSERR, "Error specifying \"%s\" paramter value(s).", "msWCSGetCoverage()", tokens[i]);
-          return msWCSException(map, params->version, NULL, NULL);
-        }          
-      } else if(strcasecmp(rangeitem, "_pixels") == 0) { /* special case, subset pixels */
-        msSetError( MS_WCSERR, "Arbitrary range sets based on pixel values are not yet supported.", "msWCSGetCoverage()" );
-        return msWCSException(map, params->version, NULL, NULL);
-      } else {
-        msSetError( MS_WCSERR, "Arbitrary range sets based on tile (i.e. image) attributes are not yet supported.", "msWCSGetCoverage()" );
-        return msWCSException(map, params->version, NULL, NULL);
-      }
-    }
-       
-    /* clean-up */
-    msFreeCharArray(tokens, numtokens);
-  }
-    
   /* did we get BBOX values? if not use the exent stored in the coverageMetadataObj */
   if( fabs((params->bbox.maxx - params->bbox.minx)) < 0.000000000001  
       || fabs(params->bbox.maxy - params->bbox.miny) < 0.000000000001 ) {
@@ -1362,6 +1385,9 @@
     return msWCSException(map, params->version, NULL, NULL);
   }
 
+  if( image == NULL )
+    return msWCSException(map, params->version, NULL, NULL);
+
   /* Actually produce the "grid". */
   status = msDrawRasterLayerLow( map, lp, image );
   if( status != MS_SUCCESS ) {

Modified: trunk/mapserver/mapwcs.h
===================================================================
--- trunk/mapserver/mapwcs.h	2008-01-10 15:32:46 UTC (rev 7255)
+++ trunk/mapserver/mapwcs.h	2008-01-12 04:54:04 UTC (rev 7256)
@@ -78,6 +78,7 @@
 void msWCSSetDefaultBandsRangeSetInfo( wcsParamsObj *params,
                                        coverageMetadataObj *cm,
                                        layerObj *lp );
+const char *msWCSGetRequestParameter(cgiRequestObj *request, char *name);
 
 /* -------------------------------------------------------------------- */
 /*      Some WCS 1.1 specific functions from mapwcs11.c                 */
@@ -86,5 +87,8 @@
                            cgiRequestObj *req);
 int msWCSDescribeCoverage11(mapObj *map, wcsParamsObj *params );
 int msWCSReturnCoverage11( wcsParamsObj *params, mapObj *map, imageObj *image);
+int msWCSGetCoverageBands11( mapObj *map, cgiRequestObj *request, 
+                             wcsParamsObj *params, layerObj *lp,
+                             char **p_bandlist );
 
 #endif /* nef MAPWCS_H */

Modified: trunk/mapserver/mapwcs11.c
===================================================================
--- trunk/mapserver/mapwcs11.c	2008-01-10 15:32:46 UTC (rev 7255)
+++ trunk/mapserver/mapwcs11.c	2008-01-12 04:54:04 UTC (rev 7256)
@@ -638,7 +638,7 @@
         /* ows:Abstract? TODO */
 
         value = msOWSGetEncodeMetadata( &(layer->metadata), "COM", 
-                                        "rangeset_name", "bands" );
+                                        "rangeset_name", "raster" );
         xmlNewChild( psField, NULL, BAD_CAST "Identifier", BAD_CAST value );
         
         /* <NullValue> TODO */
@@ -651,29 +651,31 @@
         xmlNewChild( psInterpMethods, NULL, BAD_CAST "OtherMethod", BAD_CAST "bilinear" );
 
 /* -------------------------------------------------------------------- */
-/*      Do axes properly later...                                       */
+/*      Bands axis.                                                     */
 /* -------------------------------------------------------------------- */
-        psAxis = xmlNewChild( psField, NULL, BAD_CAST "Axis", NULL );
-        xmlNewProp( psAxis, BAD_CAST "identifier", BAD_CAST "Band" );
+        {
+            xmlNodePtr psKeys;
+            int iBand;
 
-        msLibXml2GenerateList( 
-            xmlNewChild(psAxis, NULL, BAD_CAST "AvailableKeys", NULL),
-            NULL, "Key", "1", ',' );
-        
+            value = msOWSGetEncodeMetadata( &(layer->metadata), "COM", 
+                                            "bands_name", "bands" );
+            psAxis = xmlNewChild( psField, NULL, BAD_CAST "Axis", NULL );
+            xmlNewProp( psAxis, BAD_CAST "identifier", BAD_CAST value );
+            
+            psKeys = xmlNewChild( psAxis, NULL, BAD_CAST 
+                                  "AvailableKeys",  NULL );
+            
+            for( iBand = 0; iBand < cm.bandcount; iBand++ )
+            {
+                char szBandName[32];
+
+                sprintf( szBandName, "%d", iBand+1 );
+                xmlNewChild( psKeys, NULL, BAD_CAST "Key", 
+                             BAD_CAST szBandName );
+            }
+        }
     }        
         
-#ifdef notdef
-  /* compound range sets */
-  if((value = msOWSLookupMetadata(&(layer->metadata), "COM", "rangeset_axes")) != NULL) {
-     tokens = msStringSplit(value, ',', &numtokens);
-     if(tokens && numtokens > 0) {
-       for(i=0; i<numtokens; i++)
-         msWCSDescribeCoverage_AxisDescription(layer, tokens[i]);
-       msFreeCharArray(tokens, numtokens);
-     }
-  }
-#endif  
-
 /* -------------------------------------------------------------------- */
 /*      SupportedCRS                                                    */
 /* -------------------------------------------------------------------- */
@@ -830,6 +832,107 @@
 #endif /* defined(USE_WCS_SVR) && defined(USE_LIBXML2) */
 
 /************************************************************************/
+/*                      msWCSGetCoverageBands11()                       */
+/*                                                                      */
+/*      We expect input to be of the form:                              */
+/*      RangeSubset=raster[bands[1]].                                   */
+/*                                                                      */
+/*      We really need to support pulling interpolation out of this     */
+/*      as well.  eg.                                                   */
+/*                                                                      */
+/*      RangeSet=raster:bilinear[bands[1,2]]                            */
+/*       or                                                              */
+/*      RangeSet=raster:bilinear                                        */
+/************************************************************************/
+
+int msWCSGetCoverageBands11( mapObj *map, cgiRequestObj *request, 
+                             wcsParamsObj *params, layerObj *lp,
+                             char **p_bandlist )
+
+{
+    char *rangesubset, *field_id;
+    const char *axis_id, *value;
+    int i;
+
+/* -------------------------------------------------------------------- */
+/*      Fetch the RangeSubset from the parameters, skip building a      */
+/*      bands list if not found.                                        */
+/* -------------------------------------------------------------------- */
+    value = msWCSGetRequestParameter(request, "RangeSubset");
+    if( value == NULL )
+        return MS_SUCCESS;
+
+    rangesubset = strdup(value);
+
+/* -------------------------------------------------------------------- */
+/*      What is the <Field identifier=...> (rangeset_name)?             */
+/* -------------------------------------------------------------------- */
+    value = msOWSLookupMetadata( &(lp->metadata), "COM", "rangeset_name" );
+    if( value == NULL )
+        value = "raster";
+    field_id = strdup(value);
+
+/* -------------------------------------------------------------------- */
+/*      What is the <Axis identifier=...> (bands_name)?                 */
+/* -------------------------------------------------------------------- */
+    axis_id = msOWSLookupMetadata( &(lp->metadata), "COM", "bands_name" );
+    if( axis_id == NULL )
+        axis_id = "bands";
+
+/* -------------------------------------------------------------------- */
+/*      Parse out the field identifier from the request and verify.     */
+/* -------------------------------------------------------------------- */
+    if( strlen(rangesubset) <= strlen(field_id)+1 
+        || strncasecmp(rangesubset,field_id,strlen(field_id)) != 0 
+        || rangesubset[strlen(field_id)] != '[' )
+    {
+        msSetError( MS_WCSERR, 
+                    "RangeSubset field name malformed, expected '%s', got RangeSubset=%s",
+                    "msWCSGetCoverageBands11()", 
+                    field_id, rangesubset );
+        return msWCSException(map, params->version, NULL, NULL );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Parse out the axis name, and verify.                            */
+/* -------------------------------------------------------------------- */
+    value = rangesubset + strlen(field_id)+1;
+
+    free( field_id );
+    field_id = NULL;
+    
+    if( strlen(value) <= strlen(axis_id)+1
+        || strncasecmp(value,axis_id,strlen(axis_id)) != 0
+        || value[strlen(axis_id)] != '[' )
+    {
+        msSetError( MS_WCSERR, 
+                    "RangeSubset axis name malformed, expected '%s', got RangeSubset=%s",
+                    "msWCSGetCoverageBands11()", 
+                    axis_id, rangesubset );
+        return msWCSException(map, params->version, NULL, NULL );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Parse the band list.  Basically assuming the band list is       */
+/*      everything from here to a close ';'.                            */
+/* -------------------------------------------------------------------- */
+    value += strlen(axis_id) + 1;
+
+    *p_bandlist = strdup(value);
+
+    for( i = 0; (*p_bandlist)[i] != '\0'; i++ )
+    {
+        if( (*p_bandlist)[i] == '[' )
+        {
+            (*p_bandlist)[i] = '\0';
+            break;
+        }
+    }
+
+    return MS_SUCCESS;
+}    
+
+/************************************************************************/
 /*                       msWCSReturnCoverage11()                        */
 /*                                                                      */
 /*      Return a render image as a coverage to the caller with WCS      */



More information about the mapserver-commits mailing list