[mapserver-commits] r12940 - sandbox/inspire_soc2011/mapserver

svn at osgeo.org svn at osgeo.org
Mon Jan 2 14:15:01 EST 2012


Author: schpidi
Date: 2012-01-02 11:15:01 -0800 (Mon, 02 Jan 2012)
New Revision: 12940

Modified:
   sandbox/inspire_soc2011/mapserver/mapows.c
   sandbox/inspire_soc2011/mapserver/mapwms.c
Log:
Further work on INSIRE view service support:
 * Switch to "." instead of "_" for language metadata key extension
 * Support named group layers via "wms_layer_group"
 * Add isUsedInNestedGroup to msWMSPrintNestedGroups() indicating if the layers is used as group as set through the WMS_LAYER_GROUP metadata
 * Account "wms_layer_group" in GetCapabilities, GetMap, GetLegendGraphic, GetStyles, DescribeFeature, and GetFeatureInfo operations
 * Allow for longer GetLegendGraphic URLs


Modified: sandbox/inspire_soc2011/mapserver/mapows.c
===================================================================
--- sandbox/inspire_soc2011/mapserver/mapows.c	2012-01-02 15:01:01 UTC (rev 12939)
+++ sandbox/inspire_soc2011/mapserver/mapows.c	2012-01-02 19:15:01 UTC (rev 12940)
@@ -646,7 +646,7 @@
     {
        bufferSize = strlen(name)+strlen(validated_language)+2;
        name2 = (char *) msSmallMalloc( bufferSize );
-       snprintf(name2, bufferSize, "%s_%s", name, validated_language);
+       snprintf(name2, bufferSize, "%s.%s", name, validated_language);
        value = msOWSLookupMetadata(metadata, namespaces, name2);
     }
 
@@ -1269,7 +1269,7 @@
     {
         if (action_if_not_found == OWS_WARN)
         {
-            msIO_fprintf(stream, "<!-- WARNING: Mandatory metadata '%s%s%s%s' was missing in this context. -->\n", (namespaces?"..._":""), name, (validated_language?"_":""), (validated_language?validated_language:""));
+            msIO_fprintf(stream, "<!-- WARNING: Mandatory metadata '%s%s%s%s' was missing in this context. -->\n", (namespaces?"..._":""), name, (validated_language?".":""), (validated_language?validated_language:""));
             status = action_if_not_found;
         }
 

Modified: sandbox/inspire_soc2011/mapserver/mapwms.c
===================================================================
--- sandbox/inspire_soc2011/mapserver/mapwms.c	2012-01-02 15:01:01 UTC (rev 12939)
+++ sandbox/inspire_soc2011/mapserver/mapwms.c	2012-01-02 19:15:01 UTC (rev 12940)
@@ -377,7 +377,74 @@
     return MS_SUCCESS;
 }
 
+/*
+** msWMSPrepareNestedGroups()
+**
+** purpose: Parse WMS_LAYER_GROUP settings into arrays
+**
+** params:
+** - nestedGroups: This array holds the arrays of groups that have been set 
+**                 through the WMS_LAYER_GROUP metadata
+** - numNestedGroups: This array holds the number of groups set in 
+**                    WMS_LAYER_GROUP for each layer
+** - isUsedInNestedGroup: This array indicates if the layer is used as group 
+**                        as set through the WMS_LAYER_GROUP metadata
+*/
+void msWMSPrepareNestedGroups(mapObj* map, int nVersion, char*** nestedGroups, int* numNestedGroups, int* isUsedInNestedGroup)
+{
+  int i, j, k;
+  const char* groups;
+  char* errorMsg;
 
+  for (i = 0; i < map->numlayers; i++)
+  {
+    nestedGroups[i] = NULL; /* default */
+    numNestedGroups[i] = 0; /* default */
+    isUsedInNestedGroup[i] = 0; /* default */
+    
+    groups = msOWSLookupMetadata(&(GET_LAYER(map, i)->metadata), "MO", "layer_group");
+    if ((groups != NULL) && (strlen(groups) != 0))
+    {
+      if (GET_LAYER(map, i)->group != NULL && strlen(GET_LAYER(map, i)->group) != 0)
+      {
+        errorMsg = "It is not allowed to set both the GROUP and WMS_LAYER_GROUP for a layer";
+        msSetError(MS_WMSERR, errorMsg, "msWMSPrepareNestedGroups()", NULL);
+        msIO_fprintf(stdout, "<!-- ERROR: %s -->\n", errorMsg);
+        /* cannot return exception at this point because we are already writing to stdout */
+      }
+      else
+      {
+        if (groups[0] != '/')
+        {      
+          errorMsg = "The WMS_LAYER_GROUP metadata does not start with a '/'";
+          msSetError(MS_WMSERR, errorMsg, "msWMSPrepareNestedGroups()", NULL);
+          msIO_fprintf(stdout, "<!-- ERROR: %s -->\n", errorMsg);
+          /* cannot return exception at this point because we are already writing to stdout */
+        }
+        else
+        {
+          /* split into subgroups. Start at adres + 1 because the first '/' would cause an extra emtpy group */
+          nestedGroups[i] = msStringSplit(groups + 1, '/', &numNestedGroups[i]); 
+          /* */
+          for (j = 0; j < map->numlayers; j++)
+          {
+            if (isUsedInNestedGroup[j])
+              continue;
+            
+            for (k=0; k<numNestedGroups[i]; k++)
+            {
+              if ( GET_LAYER(map, j)->name && strcasecmp(GET_LAYER(map, j)->name, nestedGroups[i][k]) == 0 )
+              {
+                isUsedInNestedGroup[j] = 1;
+                break;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
 
 /*
 ** Validate that a given dimension is inside the extents defined
@@ -917,6 +984,9 @@
     if (strcasecmp(names[i], "LAYERS") == 0)
     {
       int  j, k, iLayer, *layerOrder;
+      char ***nestedGroups = NULL; 
+      int *numNestedGroups = NULL; 
+      int *isUsedInNestedGroup = NULL; 
       
       layerOrder = (int*)malloc(map->numlayers * sizeof(int));
       MS_CHECK_ALLOC(layerOrder, map->numlayers * sizeof(int), MS_FAILURE)
@@ -963,6 +1033,11 @@
         }
       }
 
+      nestedGroups = (char***)msSmallCalloc(map->numlayers, sizeof(char**));
+      numNestedGroups = (int*)msSmallCalloc(map->numlayers, sizeof(int));
+      isUsedInNestedGroup = (int*)msSmallCalloc(map->numlayers, sizeof(int));
+      msWMSPrepareNestedGroups(map, nVersion, nestedGroups, numNestedGroups, isUsedInNestedGroup);
+
       for (k=0; k<numlayers; k++)
       {
           layerfound = 0;
@@ -972,7 +1047,8 @@
               if ( ((GET_LAYER(map, j)->name &&
                      strcasecmp(GET_LAYER(map, j)->name, layers[k]) == 0) ||
                     (map->name && strcasecmp(map->name, layers[k]) == 0) ||
-                    (GET_LAYER(map, j)->group && strcasecmp(GET_LAYER(map, j)->group, layers[k]) == 0)) &&
+                    (GET_LAYER(map, j)->group && strcasecmp(GET_LAYER(map, j)->group, layers[k]) == 0) ||
+                    ((numNestedGroups[j] >0) && msStringInArray(layers[k], nestedGroups[j], numNestedGroups[j]))) &&
                    ((msIntegerInArray(GET_LAYER(map, j)->index, ows_request->enabled_layers, ows_request->numlayers))) )
               {
                   if (GET_LAYER(map, j)->status != MS_DEFAULT)
@@ -993,6 +1069,18 @@
 
       }
 
+      /* free the stuff used for nested layers */
+      for (k = 0; k < map->numlayers; k++)
+      {
+        if (numNestedGroups[k] > 0)
+        {
+          msFreeCharArray(nestedGroups[k], numNestedGroups[k]);
+        }
+      }
+      free(nestedGroups);
+      free(numNestedGroups);
+      free(isUsedInNestedGroup);
+
       /* set all layers with status off at end of array */
       for (j=0; j<map->numlayers; j++)
       {
@@ -2052,7 +2140,7 @@
 /*
 ** msDumpLayer()
 */
-int msDumpLayer(mapObj *map, layerObj *lp, int nVersion, const char *script_url_encoded, const char *indent, const char *validated_language)
+int msDumpLayer(mapObj *map, layerObj *lp, int nVersion, const char *script_url_encoded, const char *indent, const char *validated_language, int grouplayer)
 {
    rectObj ext;
    const char *value;
@@ -2194,7 +2282,7 @@
        if(lp->projection.numargs > 0)
        {
            if (nVersion >= OWS_1_3_0)
-             msOWSPrintEX_GeographicBoundingBox(stdout, "    ", &(ext),
+             msOWSPrintEX_GeographicBoundingBox(stdout, "        ", &(ext),
                                                 &(lp->projection));
            else
              msOWSPrintLatLonBoundingBox(stdout, "        ", &(ext),
@@ -2206,7 +2294,7 @@
        else
        {
            if (nVersion >= OWS_1_3_0)
-             msOWSPrintEX_GeographicBoundingBox(stdout, "    ", &(ext),
+             msOWSPrintEX_GeographicBoundingBox(stdout, "        ", &(ext),
                                                 &(map->projection));
            else
               msOWSPrintLatLonBoundingBox(stdout, "        ", &(ext),
@@ -2489,7 +2577,7 @@
                            snprintf(width, sizeof(width), "%d", size_x);
                            snprintf(height, sizeof(height), "%d", size_y);
 
-                           bufferSize = strlen(script_url_encoded)+200;
+                           bufferSize = strlen(script_url_encoded)+300;
                            legendurl = (char*)msSmallMalloc(bufferSize);
 
 #ifdef USE_GD_PNG
@@ -2622,56 +2710,14 @@
      msWMSPrintScaleHint("        ", lp->minscaledenom, lp->maxscaledenom, map->resolution);
    else
      msWMSPrintScaleDenominator("        ", lp->minscaledenom, lp->maxscaledenom);
-   msIO_printf("%s    </Layer>\n", indent);
+   
+   if ( grouplayer == MS_FALSE )
+      msIO_printf("%s    </Layer>\n", indent);
 
    return MS_SUCCESS;
 }
 
 /*
- * msWMSPrepareNestedGroups
- */
-void msWMSPrepareNestedGroups(mapObj* map, int nVersion, char*** nestedGroups, int* numNestedGroups)
-{
-  int i;
-  const char* groups;
-  char* errorMsg;
-
-  for (i = 0; i < map->numlayers; i++)
-  {
-    nestedGroups[i] = NULL; /* default */
-    numNestedGroups[i] = 0; /* default */
-    
-    groups = msOWSLookupMetadata(&(GET_LAYER(map, i)->metadata), "MO", "layer_group");
-    if ((groups != NULL) && (strlen(groups) != 0))
-    {
-      if (GET_LAYER(map, i)->group != NULL && strlen(GET_LAYER(map, i)->group) != 0)
-      {
-        errorMsg = "It is not allowed to set both the GROUP and WMS_LAYER_GROUP for a layer";
-        msSetError(MS_WMSERR, errorMsg, "msWMSPrepareNestedGroups()", NULL);
-        msIO_fprintf(stdout, "<!-- ERROR: %s -->\n", errorMsg);
-        /* cannot return exception at this point because we are already writing to stdout */
-      }
-      else
-      {
-        if (groups[0] != '/')
-        {      
-          errorMsg = "The WMS_LAYER_GROUP metadata does not start with a '/'";
-          msSetError(MS_WMSERR, errorMsg, "msWMSPrepareNestedGroups()", NULL);
-          msIO_fprintf(stdout, "<!-- ERROR: %s -->\n", errorMsg);
-          /* cannot return exception at this point because we are already writing to stdout */
-        }
-        else
-        {
-          /* split into subgroups. Start at adres + 1 because the first '/' would cause an extra emtpy group */
-          nestedGroups[i] = msStringSplit(groups + 1, '/', &numNestedGroups[i]); 
-        }
-      }
-    }
-  }
-}
-
-
-/*
  * msWMSIsSubGroup
  */
 int msWMSIsSubGroup(char** currentGroups, int currentLevel, char** otherGroups, int numOtherGroups)
@@ -2700,7 +2746,7 @@
  * "WMS_LAYER_GROUP" metadata set.                                                 *
  *                                                                                 *
  * params:                                                                         *
- * -map: The main map object                                                       *      
+ * -map: The main map object                                                       *
  * -nVersion: OGC WMS version                                                      *
  * -pabLayerProcessed: boolean array indicating which layers have been dealt with. *
  * -index: the index of the current layer.                                         *
@@ -2710,28 +2756,56 @@
  * -numNestedGroups: This array holds the number of nested groups for each layer   *
  ***********************************************************************************/
 void msWMSPrintNestedGroups(mapObj* map, int nVersion, char* pabLayerProcessed, 
-    int index, int level, char*** nestedGroups, int* numNestedGroups, const char *script_url_encoded, const char *validated_language)
+    int index, int level, char*** nestedGroups, int* numNestedGroups, int* isUsedInNestedGroup, const char *script_url_encoded, const char *validated_language)
 {
-   int j;
+   int i, j;
+   char *indent = NULL;
+   indent = msStrdup("");
+   
+   for (i = 0; i < level; i++)
+   {
+      indent = msStringConcatenate(indent, "  ");
+   }
 
    if (numNestedGroups[index] <= level) /* no more subgroups */
    {
-      /* we are at the deepest level of the group branchings, so add layer now. */
-      msDumpLayer(map, GET_LAYER(map, index), nVersion, script_url_encoded, "", validated_language);
-      pabLayerProcessed[index] = 1; /* done */
+      if ((!pabLayerProcessed[index]) && (!isUsedInNestedGroup[index]))
+      {
+         /* we are at the deepest level of the group branchings, so add layer now. */
+         msDumpLayer(map, GET_LAYER(map, index), nVersion, script_url_encoded, indent, validated_language, MS_FALSE);
+         pabLayerProcessed[index] = 1; /* done */
+      }
    }
    else /* not yet there, we have to deal with this group and possible subgroups and layers. */
    {
-      /* Beginning of a new group... enclose the group in a layer block */
-      msIO_printf("    <Layer>\n");
-      msIO_printf("    <Title>%s</Title>\n", nestedGroups[index][level]);      
+      for (j = 0; j < map->numlayers; j++) 
+      {
+         if ( GET_LAYER(map, j)->name && strcasecmp(GET_LAYER(map, j)->name, nestedGroups[index][level]) == 0 ) {
+            break;
+         }
+      }
 
+       /* Beginning of a new group... enclose the group in a layer block */
+      if ( j < map->numlayers ) {
+         if (!pabLayerProcessed[j])
+         {
+            msDumpLayer(map, GET_LAYER(map, j), nVersion, script_url_encoded, indent, validated_language, MS_TRUE);
+            pabLayerProcessed[j] = 1; /* done */
+         }
+      }
+      else
+      {
+         msIO_printf("%s    <Layer>\n", indent);
+         msIO_printf("%s      <Title>%s</Title>\n", indent, nestedGroups[index][level]);      
+      }
+
       /* Look for one group deeper in the current layer */
       if (!pabLayerProcessed[index])
       {
          msWMSPrintNestedGroups(map, nVersion, pabLayerProcessed,
                                 index, level + 1, nestedGroups, 
-                                numNestedGroups, script_url_encoded, validated_language);
+                                numNestedGroups, isUsedInNestedGroup, 
+                                script_url_encoded, validated_language);
       }
 
       /* look for subgroups in other layers. */
@@ -2743,7 +2817,8 @@
             {
                msWMSPrintNestedGroups(map, nVersion, pabLayerProcessed,
                                       j, level + 1, nestedGroups, 
-                                      numNestedGroups, script_url_encoded, validated_language);
+                                      numNestedGroups, isUsedInNestedGroup, 
+                                      script_url_encoded, validated_language);
             }
          }
          else
@@ -2754,9 +2829,10 @@
          }
       }
       /* Close group layer block */
-      msIO_printf("    </Layer>\n");
+      msIO_printf("%s    </Layer>\n", indent);
    }
    
+   msFree(indent);
 } /* msWMSPrintNestedGroups */
 
 /*
@@ -3208,7 +3284,6 @@
   }
   msIO_printf("  </Exception>\n");
 
-
   if (nVersion != OWS_1_3_0) 
     msIO_printf("  <VendorSpecificCapabilities />\n"); /* nothing yet */
 
@@ -3388,7 +3463,7 @@
           char width[10], height[10];
           if (msLegendCalcSize(map, 1, &size_x, &size_y,  NULL, 0) == MS_SUCCESS)
           {
-              bufferSize = strlen(script_url_encoded)+200;
+              bufferSize = strlen(script_url_encoded)+300;
               pszLegendURL = (char*)msSmallMalloc(bufferSize);
               snprintf(width, sizeof(width), "%d", size_x);
               snprintf(height, sizeof(height), "%d", size_y);
@@ -3445,17 +3520,17 @@
        char *pabLayerProcessed = NULL;
        char ***nestedGroups = NULL; 
        int *numNestedGroups = NULL; 
+       int *isUsedInNestedGroup = NULL; 
 
        /* We'll use this array of booleans to track which layer/group have been */
        /* processed already */
        pabLayerProcessed = (char *)msSmallCalloc(map->numlayers, sizeof(char*));
-       /* This array holds the arrays of groups that have been set through the WMS_LAYER_GROUP metadata */
+
        nestedGroups = (char***)msSmallCalloc(map->numlayers, sizeof(char**));
-       /* This array holds the number of groups set in WMS_LAYER_GROUP for each layer */
        numNestedGroups = (int*)msSmallCalloc(map->numlayers, sizeof(int));
+       isUsedInNestedGroup = (int*)msSmallCalloc(map->numlayers, sizeof(int));
+       msWMSPrepareNestedGroups(map, nVersion, nestedGroups, numNestedGroups, isUsedInNestedGroup);
 
-       msWMSPrepareNestedGroups(map, nVersion, nestedGroups, numNestedGroups);
-
        for(i=0; i<map->numlayers; i++)
        {
            layerObj *lp;
@@ -3469,14 +3544,18 @@
            {
               /* Has nested groups.  */
                msWMSPrintNestedGroups(map, nVersion, pabLayerProcessed, i, 0, 
-                                      nestedGroups, numNestedGroups, 
+                                      nestedGroups, numNestedGroups, isUsedInNestedGroup, 
                                       script_url_encoded, validated_language);
            }
            else if (lp->group == NULL || strlen(lp->group) == 0)
            {
-               /* This layer is not part of a group... dump it directly */
-               msDumpLayer(map, lp, nVersion, script_url_encoded, "", validated_language);
-               pabLayerProcessed[i] = 1;
+               /* Don't dump layer if it is used in wms_group_layer. */
+               if (!isUsedInNestedGroup[i])
+               {
+                  /* This layer is not part of a group... dump it directly */
+                  msDumpLayer(map, lp, nVersion, script_url_encoded, "", validated_language, MS_FALSE);
+                  pabLayerProcessed[i] = 1;
+               }
            }
            else
            {
@@ -3565,7 +3644,7 @@
                              group_layers =(int *)msSmallRealloc(group_layers,  sizeof(int)*num_layers);
                              if (msLegendCalcSize(map, 1, &size_x, &size_y,  group_layers , num_layers) == MS_SUCCESS)
                              {
-                                 bufferSize = strlen(script_url_encoded)+200;
+                                 bufferSize = strlen(script_url_encoded)+300;
                                  pszLegendURL = (char*)msSmallMalloc(bufferSize);
                                  snprintf(width, sizeof(width), "%d", size_x);
                                  snprintf(height, sizeof(height), "%d", size_y);
@@ -3623,11 +3702,10 @@
                        strcmp(lp->group, GET_LAYER(map, j)->group) == 0 &&
                        msIntegerInArray(GET_LAYER(map, j)->index, ows_request->enabled_layers, ows_request->numlayers))
                    {
-                       msDumpLayer(map, (GET_LAYER(map, j)), nVersion, script_url_encoded, "  ", validated_language);
+                       msDumpLayer(map, (GET_LAYER(map, j)), nVersion, script_url_encoded, "  ", validated_language, MS_FALSE);
                        pabLayerProcessed[j] = 1;
                    }
                }
-
                /* Close group layer block */
                msIO_printf("    </Layer>\n");
            }
@@ -3645,8 +3723,7 @@
        }
        free(nestedGroups);
        free(numNestedGroups);
-
-
+     free(isUsedInNestedGroup);
     }
 
     msIO_printf("  </Layer>\n");
@@ -3760,29 +3837,13 @@
 ** msWMSGetMap()
 */
 int msWMSGetMap(mapObj *map, int nVersion, char **names, char **values, int numentries,
-                char *wms_exception_format, owsRequestObj *ows_request, const char *requested_language)
+                char *wms_exception_format, owsRequestObj *ows_request)
 {
   imageObj *img;
   int i = 0;
   int sldrequested = MS_FALSE,  sldspatialfilter = MS_FALSE;
   const char *http_max_age;
-  char *validated_language = NULL;
 
-  /* This function owns validated_language, so remember to free it later*/
-  validated_language = msOWSGetInspireLanguage(map, "MO", requested_language);
-
-  if (validated_language != NULL)
-  {
-      for(i=0; i<map->numlayers; i++)
-      {
-         layerObj *layer = GET_LAYER(map, i);
-         if(layer->data) layer->data = msCaseReplaceSubstring(layer->data, "%language%", validated_language);
-         if(layer->connection) layer->connection = msCaseReplaceSubstring(layer->connection, "%language%", validated_language);
-      }
-  }
-
-  msFree(validated_language);
-
   /* __TODO__ msDrawMap() will try to adjust the extent of the map */
   /* to match the width/height image ratio. */
   /* The spec states that this should not happen so that we can deliver */
@@ -4001,9 +4062,17 @@
   int wms_layer =  MS_FALSE;
   const char *wms_connection = NULL;
   int numOWSLayers = 0;
+  char ***nestedGroups = NULL; 
+  int *numNestedGroups = NULL; 
+  int *isUsedInNestedGroup = NULL; 
 
   encoding = msOWSLookupMetadata(&(map->web.metadata), "MO", "encoding");
 
+  nestedGroups = (char***)msSmallCalloc(map->numlayers, sizeof(char**));
+  numNestedGroups = (int*)msSmallCalloc(map->numlayers, sizeof(int));
+  isUsedInNestedGroup = (int*)msSmallCalloc(map->numlayers, sizeof(int));
+  msWMSPrepareNestedGroups(map, nVersion, nestedGroups, numNestedGroups, isUsedInNestedGroup);
+
   for(i=0; map && i<numentries; i++) {
     if(strcasecmp(names[i], "QUERY_LAYERS") == 0) {
       char **layers;
@@ -4021,19 +4090,24 @@
         
       for(j=0; j<map->numlayers; j++) {
         /* Force all layers OFF by default */
-    GET_LAYER(map, j)->status = MS_OFF;
+        GET_LAYER(map, j)->status = MS_OFF;
         for(k=0; k<numlayers; k++) {
          if (((GET_LAYER(map, j)->name && strcasecmp(GET_LAYER(map, j)->name, layers[k]) == 0) ||
               (map->name && strcasecmp(map->name, layers[k]) == 0) ||
-              (GET_LAYER(map, j)->group && strcasecmp(GET_LAYER(map, j)->group, layers[k]) == 0)) &&
+              (GET_LAYER(map, j)->group && strcasecmp(GET_LAYER(map, j)->group, layers[k]) == 0) ||
+              ((numNestedGroups[j] >0) && msStringInArray(layers[k], nestedGroups[j], numNestedGroups[j]))) &&
              (msIntegerInArray(GET_LAYER(map, j)->index, ows_request->enabled_layers, ows_request->numlayers)) )
          {
              if (GET_LAYER(map, j)->connectiontype == MS_WMS) {
                  wms_layer = MS_TRUE;
                  wms_connection = GET_LAYER(map, j)->connection;
              }
-             numlayers_found++;
-             GET_LAYER(map, j)->status = MS_ON;               
+             
+             /* Don't turn on layers that are not queryable but have sublayers. */
+             if ((msIsLayerQueryable(GET_LAYER(map, j))) || isUsedInNestedGroup[j] == 0) {
+               numlayers_found++;
+               GET_LAYER(map, j)->status = MS_ON;
+             }
             }
         }
       }
@@ -4079,6 +4153,18 @@
 
   }
   
+  /* free the stuff used for nested layers */
+  for (i = 0; i < map->numlayers; i++)
+  {
+    if (numNestedGroups[i] > 0)
+    {
+      msFreeCharArray(nestedGroups[i], numNestedGroups[i]);
+    }
+  }
+  free(nestedGroups);
+  free(numNestedGroups);
+  free(isUsedInNestedGroup);
+
   if(numlayers_found == 0) 
   {
       if (query_layer)
@@ -4314,6 +4400,9 @@
   char *version = NULL;
   char *sld_version = NULL;
   const char *encoding;
+  char ***nestedGroups = NULL; 
+  int *numNestedGroups = NULL; 
+  int *isUsedInNestedGroup = NULL; 
 
   encoding = msOWSLookupMetadata(&(map->web.metadata), "MO", "encoding");
 
@@ -4377,6 +4466,11 @@
    if (pszOnlineResMapWCS && strlen(pszOnlineResMapWCS) == 0)
      pszOnlineResMapWCS = NULL;
 
+   nestedGroups = (char***)msSmallCalloc(map->numlayers, sizeof(char**));
+   numNestedGroups = (int*)msSmallCalloc(map->numlayers, sizeof(int));
+   isUsedInNestedGroup = (int*)msSmallCalloc(map->numlayers, sizeof(int));
+   msWMSPrepareNestedGroups(map, nVersion, nestedGroups, numNestedGroups, isUsedInNestedGroup);
+
    for(j=0; j<numlayers; j++)
    {
        for(k=0; k<map->numlayers; k++)
@@ -4385,7 +4479,8 @@
 
         if ((map->name && strcasecmp(map->name, layers[j]) == 0) ||
             (lp->name && strcasecmp(lp->name, layers[j]) == 0) ||
-            (lp->group && strcasecmp(lp->group, layers[j]) == 0))
+            (lp->group && strcasecmp(lp->group, layers[j]) == 0) ||
+            ((numNestedGroups[k] >0) && msStringInArray(layers[j], nestedGroups[k], numNestedGroups[k])))
          {
              /* Look for a WFS onlineresouce at the layer level and then at
               * the map level.
@@ -4499,6 +4594,18 @@
    if (layers)
      msFreeCharArray(layers, numlayers);
 
+   /* free the stuff used for nested layers */
+   for (i = 0; i < map->numlayers; i++)
+   {
+      if (numNestedGroups[i] > 0)
+      {
+         msFreeCharArray(nestedGroups[i], numNestedGroups[i]);
+      }
+   }
+   free(nestedGroups);
+   free(numNestedGroups);
+   free(isUsedInNestedGroup);
+
    return(MS_SUCCESS);
 }
 
@@ -4525,6 +4632,9 @@
     const char *format_list = NULL;
     layerObj *lp;
     int nLayers =0;
+    char ***nestedGroups = NULL; 
+    int *numNestedGroups = NULL; 
+    int *isUsedInNestedGroup = NULL; 
 
     sldenabled = msOWSLookupMetadata(&(map->web.metadata), "MO", "sld_enabled");
 
@@ -4589,13 +4699,21 @@
          msSetError(MS_WMSERR, "SLD_VERSION must be 1.1.0", "GetLegendGraphic()");
          return msWMSException(map, nVersion, "InvalidParameterValue", wms_exception_format);
      }
-     /* check if layer name is valid. we check for layer's and group's name*/
+     
+     nestedGroups = (char***)msSmallCalloc(map->numlayers, sizeof(char**));
+     numNestedGroups = (int*)msSmallCalloc(map->numlayers, sizeof(int));
+     isUsedInNestedGroup = (int*)msSmallCalloc(map->numlayers, sizeof(int));
+     msWMSPrepareNestedGroups(map, nVersion, nestedGroups, numNestedGroups, isUsedInNestedGroup);
+
+     /* check if layer name is valid. we check for layer's and group's name */
+     /* as well as wms_layer_group names */
      for (i=0; i<map->numlayers; i++)
      {
          lp = GET_LAYER(map, i);
          if (  ((map->name && strcasecmp(map->name, pszLayer) == 0) ||
                (lp->name && strcasecmp(lp->name, pszLayer) == 0) ||
-               (lp->group && strcasecmp(lp->group, pszLayer) == 0)) &&
+               (lp->group && strcasecmp(lp->group, pszLayer) == 0) ||
+               ((numNestedGroups[i] >0) && (msStringInArray(pszLayer, nestedGroups[i], numNestedGroups[i]))) ) &&
               (msIntegerInArray(lp->index, ows_request->enabled_layers, ows_request->numlayers)) )
            {
                nLayers++;
@@ -4618,6 +4736,18 @@
            lp->status = MS_OFF;
      }  
 
+     /* free the stuff used for nested layers */
+     for (i = 0; i < map->numlayers; i++)
+     {
+       if (numNestedGroups[i] > 0)
+       {
+         msFreeCharArray(nestedGroups[i], numNestedGroups[i]);
+       }
+     }
+     free(nestedGroups);
+     free(numNestedGroups);
+     free(isUsedInNestedGroup);
+
      if (nLayers == 0)
      {
          msSetError(MS_WMSERR, "Invalid layer given in the LAYER parameter.",
@@ -4799,8 +4929,17 @@
     char  *sld = NULL;
     const char *encoding;
 
+    char ***nestedGroups = NULL; 
+    int *numNestedGroups = NULL; 
+    int *isUsedInNestedGroup = NULL; 
+
     encoding = msOWSLookupMetadata(&(map->web.metadata), "MO", "encoding");
 
+    nestedGroups = (char***)msSmallCalloc(map->numlayers, sizeof(char**));
+    numNestedGroups = (int*)msSmallCalloc(map->numlayers, sizeof(int));
+    isUsedInNestedGroup = (int*)msSmallCalloc(map->numlayers, sizeof(int));
+    msWMSPrepareNestedGroups(map, nVersion, nestedGroups, numNestedGroups, isUsedInNestedGroup);
+
     for(i=0; map && i<numentries; i++)
     {
         /* getMap parameters */
@@ -4824,7 +4963,8 @@
                         (GET_LAYER(map, j)->name &&
                          strcasecmp(GET_LAYER(map, j)->name, layers[k]) == 0) ||
                         (GET_LAYER(map, j)->group &&
-                         strcasecmp(GET_LAYER(map, j)->group, layers[k]) == 0))
+                         strcasecmp(GET_LAYER(map, j)->group, layers[k]) == 0) ||
+                        ((numNestedGroups[j] >0) && msStringInArray(layers[k], nestedGroups[j], numNestedGroups[j])) )
                     {
                         GET_LAYER(map, j)->status = MS_ON;
                         validlayer =1;
@@ -4837,6 +4977,18 @@
 
     }
 
+    /* free the stuff used for nested layers */
+    for (i = 0; i < map->numlayers; i++)
+    {
+      if (numNestedGroups[i] > 0)
+      {
+        msFreeCharArray(nestedGroups[i], numNestedGroups[i]);
+      }
+    }
+    free(nestedGroups);
+    free(numNestedGroups);
+    free(isUsedInNestedGroup);
+
     /* validate all layers given. If an invalid layer is sent, return an exception. */
     if (validlayer == 0)
     {
@@ -4920,6 +5072,7 @@
   const char *version=NULL, *request=NULL, *service=NULL, *format=NULL, *updatesequence=NULL, *language=NULL;
   const char * encoding;
   char *wms_exception_format = NULL;
+  char *validated_language = NULL;
   
   encoding = msOWSLookupMetadata(&(map->web.metadata), "MO", "encoding");
 
@@ -5166,9 +5319,21 @@
       if (status != MS_SUCCESS) return status;
   }
 
+  /* This function owns validated_language, so remember to free it later*/
+  validated_language = msOWSGetInspireLanguage(map, "MO", language);
+  if (validated_language != NULL)
+  {
+      for(i=0; i<map->numlayers; i++)
+      {
+         layerObj *layer = GET_LAYER(map, i);
+         if(layer->data) layer->data = msCaseReplaceSubstring(layer->data, "%language%", validated_language);
+         if(layer->connection) layer->connection = msCaseReplaceSubstring(layer->connection, "%language%", validated_language);
+      }
+  }
+  msFree(validated_language);
 
   if (strcasecmp(request, "map") == 0 || strcasecmp(request, "GetMap") == 0)
-     return msWMSGetMap(map, nVersion, req->ParamNames, req->ParamValues, req->NumParams, wms_exception_format, ows_request, language);
+     return msWMSGetMap(map, nVersion, req->ParamNames, req->ParamValues, req->NumParams, wms_exception_format, ows_request);
   else if (strcasecmp(request, "feature_info") == 0 || strcasecmp(request, "GetFeatureInfo") == 0)
     return msWMSFeatureInfo(map, nVersion, req->ParamNames, req->ParamValues, req->NumParams, wms_exception_format, ows_request);
   else if (strcasecmp(request, "DescribeLayer") == 0)



More information about the mapserver-commits mailing list