Пример #1
0
xmlNodePtr msWFSDumpLayer11(mapObj *map, layerObj *lp, xmlNsPtr psNsOws,
                            int nWFSVersion, const char* validate_language)
{
  rectObj ext;

  xmlNodePtr psRootNode, psNode;
  const char *value    = NULL;
  char *valueToFree;
  char **tokens;
  int n=0,i=0;

  psRootNode = xmlNewNode(NULL, BAD_CAST "FeatureType");

  /* add namespace to layer name */
  value = msOWSLookupMetadata(&(map->web.metadata), "FO", "namespace_prefix");

  /* FIXME? Should probably be applied to WFS 1.1 as well, but the addition */
  /* of the prefix can be disruptive for clients */
  if( value == NULL && nWFSVersion >= OWS_2_0_0 )
      value = MS_DEFAULT_NAMESPACE_PREFIX;

  if(value) {
    n = strlen(value)+strlen(lp->name)+1+1;
    valueToFree = (char *) msSmallMalloc(sizeof(char*)*n);
    snprintf(valueToFree, n, "%s%s%s", (value ? value : ""), (value ? ":" : ""), lp->name);

    psNode = xmlNewChild(psRootNode, NULL, BAD_CAST "Name", BAD_CAST valueToFree);
    msFree(valueToFree);
  } else {
    psNode = xmlNewChild(psRootNode, NULL, BAD_CAST "Name", BAD_CAST lp->name);
  }

  if (lp->name && strlen(lp->name) > 0 &&
      (msIsXMLTagValid(lp->name) == MS_FALSE || isdigit(lp->name[0])))
  {
    char szTmp[512];
    snprintf(szTmp, sizeof(szTmp),
             "WARNING: The layer name '%s' might contain spaces or "
             "invalid characters or may start with a number. This could lead to potential problems",
             lp->name);
    xmlAddSibling(psNode, xmlNewComment(BAD_CAST szTmp));
  }

  value = msOWSLookupMetadataWithLanguage(&(lp->metadata), "FO", "title", validate_language);
  if (!value)
    value =(const char*)lp->name;

  psNode = xmlNewChild(psRootNode, NULL, BAD_CAST "Title", BAD_CAST value);


  value = msOWSLookupMetadataWithLanguage(&(lp->metadata), "FO", "abstract", validate_language);
  if (value)
    psNode = xmlNewChild(psRootNode, NULL, BAD_CAST "Abstract", BAD_CAST value);



  value = msOWSLookupMetadataWithLanguage(&(lp->metadata), "FO", "keywordlist", validate_language);

  if(value)
    msLibXml2GenerateList(
        xmlNewChild(psRootNode, psNsOws, BAD_CAST "Keywords", NULL),
        NULL, "Keyword", value, ',' );

  /*support DefaultSRS and OtherSRS*/
  valueToFree = msOWSGetProjURN(&(map->projection),&(map->web.metadata),"FO",MS_FALSE);
  if (!valueToFree)
    valueToFree = msOWSGetProjURN(&(lp->projection), &(lp->metadata), "FO", MS_FALSE);

  if (valueToFree) {
    tokens = msStringSplit(valueToFree, ' ', &n);
    if (tokens && n > 0) {
      if( nWFSVersion == OWS_1_1_0 )
        psNode = xmlNewChild(psRootNode, NULL, BAD_CAST "DefaultSRS", BAD_CAST tokens[0]);
      else
        psNode = xmlNewChild(psRootNode, NULL, BAD_CAST "DefaultCRS", BAD_CAST tokens[0]);
      for (i=1; i<n; i++)
      {
        if( nWFSVersion == OWS_1_1_0 )
          psNode = xmlNewChild(psRootNode, NULL, BAD_CAST "OtherSRS", BAD_CAST tokens[i]);
        else
          psNode = xmlNewChild(psRootNode, NULL, BAD_CAST "OtherCRS", BAD_CAST tokens[i]);
      }

      msFreeCharArray(tokens, n);
    }
  } else
    xmlAddSibling(psNode,
                  xmlNewComment(BAD_CAST "WARNING: Mandatory mapfile parameter: (at least one of) MAP.PROJECTION, LAYER.PROJECTION or wfs/ows_srs metadata was missing in this context."));

  free(valueToFree);
  valueToFree = NULL;

  /*TODO: adevertize only gml3?*/
  psNode = xmlNewNode(NULL, BAD_CAST "OutputFormats");
  xmlAddChild(psRootNode, psNode);

  {
    char *formats_list = msWFSGetOutputFormatList( map, lp, nWFSVersion );
    int iformat, n;
    char **tokens;

    n = 0;
    tokens = msStringSplit(formats_list, ',', &n);

    for( iformat = 0; iformat < n; iformat++ )
      xmlNewChild(psNode, NULL, BAD_CAST "Format",
                  BAD_CAST tokens[iformat] );
    msFree( formats_list );
    msFreeCharArray( tokens, n );
  }

  /*bbox*/
  if (msOWSGetLayerExtent(map, lp, "FO", &ext) == MS_SUCCESS) {
    /*convert to latlong*/
    if (lp->projection.numargs > 0)
      msOWSProjectToWGS84(&lp->projection, &ext);
    else
      msOWSProjectToWGS84(&map->projection, &ext);

    xmlAddChild(psRootNode,
                msOWSCommonWGS84BoundingBox( psNsOws, 2,
                    ext.minx, ext.miny,
                    ext.maxx, ext.maxy));
  } else {
    xmlNewChild(psRootNode, psNsOws, BAD_CAST "WGS84BoundingBox", NULL);
    xmlAddSibling(psNode,
                  xmlNewComment(BAD_CAST "WARNING: Optional WGS84BoundingBox could not be established for this layer.  Consider setting the EXTENT in the LAYER object, or wfs_extent metadata. Also check that your data exists in the DATA statement"));
  }

  value = msOWSLookupMetadata(&(lp->metadata), "FO", "metadataurl_href");

  if (value) {
    if( nWFSVersion >= OWS_2_0_0 )
    {
        psNode = xmlNewChild(psRootNode, NULL, BAD_CAST "MetadataURL", NULL);
        xmlNewProp(psNode, BAD_CAST "xlink:href", BAD_CAST value);

        value = msOWSLookupMetadata(&(lp->metadata), "FO", "metadataurl_about");
        if( value != NULL )
            xmlNewProp(psNode, BAD_CAST "about", BAD_CAST value);
    }
    else
    {
        psNode = xmlNewChild(psRootNode, NULL, BAD_CAST "MetadataURL", BAD_CAST value);

        value = msOWSLookupMetadata(&(lp->metadata), "FO", "metadataurl_format");

        if (!value)
            value = msStrdup("text/html"); /* default */

        xmlNewProp(psNode, BAD_CAST "format", BAD_CAST value);

        value = msOWSLookupMetadata(&(lp->metadata), "FO", "metadataurl_type");

        if (!value)
            value = msStrdup("FGDC"); /* default */

        xmlNewProp(psNode, BAD_CAST "type", BAD_CAST value);
    }
  }

  return psRootNode;
}
Пример #2
0
static xmlNodePtr msWFSDumpLayer11(mapObj *map, layerObj *lp, xmlNsPtr psNsOws)
{
    rectObj ext;
   
    xmlNodePtr psRootNode, psNode;
    const char *value    = NULL;
    const char *encoding = NULL;
    char *encoded=NULL;
    char *valueToFree;
    char **tokens;
    int n=0,i=0;      

    encoding = msOWSLookupMetadata(&(map->web.metadata), "FO", "encoding");
    if (!encoding)
      encoding = "ISO-8859-1";

    psRootNode = xmlNewNode(NULL, BAD_CAST "FeatureType");

    /*if there is an encoding using it on some of the items*/
    psNode = msOWSCommonxmlNewChildEncoded(psRootNode, NULL, "Name", lp->name, encoding);


    if (lp->name && strlen(lp->name) > 0 &&
        (msIsXMLTagValid(lp->name) == MS_FALSE || isdigit(lp->name[0])))
      xmlAddSibling(psNode,
                    xmlNewComment(BAD_CAST "WARNING: The layer name '%s' might contain spaces or "
                                  "invalid characters or may start with a number. This could lead to potential problems"));
   
    value = msOWSLookupMetadata(&(lp->metadata), "FO", "title");
    if (!value)
      value =(const char*)lp->name;

    psNode = msOWSCommonxmlNewChildEncoded(psRootNode, NULL, "Title", value, encoding);

 
    value = msOWSLookupMetadata(&(lp->metadata), "FO", "abstract");
    if (value)
      psNode = msOWSCommonxmlNewChildEncoded(psRootNode, NULL, "Abstract", value, encoding);



    value = msOWSLookupMetadata(&(lp->metadata), "FO", "keywordlist");

    if (value)
    {
	if (encoding)
	  encoded = msGetEncodedString(value, encoding);
        else
          encoded = msGetEncodedString(value, "ISO-8859-1");

        msLibXml2GenerateList(
            xmlNewChild(psRootNode, psNsOws, BAD_CAST "Keywords", NULL),
            NULL, "Keyword", encoded, ',' );
	msFree(encoded);
    }
      /*support DefaultSRS and OtherSRS*/
    valueToFree = msOWSGetProjURN(&(map->projection),&(map->web.metadata),"FO",MS_FALSE);
    if (!valueToFree)
      valueToFree = msOWSGetProjURN(&(lp->projection), &(lp->metadata), "FO", MS_FALSE);

    if (valueToFree)
    {
        tokens = msStringSplit(valueToFree, ' ', &n);
        if (tokens && n > 0)
        {
            psNode = xmlNewChild(psRootNode, NULL, BAD_CAST "DefaultSRS", BAD_CAST tokens[0]);
            for (i=1; i<n; i++)
              psNode = xmlNewChild(psRootNode, NULL, BAD_CAST "OtherSRS", BAD_CAST tokens[i]);

            msFreeCharArray(tokens, n);
        }
    }
    else
      xmlAddSibling(psNode,
                    xmlNewComment(BAD_CAST "WARNING: Mandatory mapfile parameter: (at least one of) MAP.PROJECTION, LAYER.PROJECTION or wfs/ows_srs metadata was missing in this context."));

    free(valueToFree);
    valueToFree = NULL;

    /*TODO: adevertize only gml3?*/
    psNode = xmlNewNode(NULL, BAD_CAST "OutputFormats");
    xmlAddChild(psRootNode, psNode);

    {
        char *formats_list = msWFSGetOutputFormatList( map, lp, "1.1.0" );
        int iformat, n;
        char **tokens;

        n = 0;
        tokens = msStringSplit(formats_list, ',', &n);

        for( iformat = 0; iformat < n; iformat++ )
            xmlNewChild(psNode, NULL, BAD_CAST "Format", 
                        BAD_CAST tokens[iformat] );
        msFree( formats_list );
        msFreeCharArray( tokens, n );
    }
  
    /*bbox*/
    if (msOWSGetLayerExtent(map, lp, "FO", &ext) == MS_SUCCESS)
    {   
        /*convert to latlong*/
        if (lp->projection.numargs > 0)
        {
            if (!pj_is_latlong(&lp->projection.proj))
              msProjectRect(&lp->projection, NULL, &ext);
        }
        else if (map->projection.numargs > 0 && !pj_is_latlong(&map->projection.proj))
          msProjectRect(&map->projection, NULL, &ext);

        xmlAddChild(psRootNode,
                    msOWSCommonWGS84BoundingBox( psNsOws, 2,
                                                 ext.minx, ext.miny,
                                                 ext.maxx, ext.maxy));
    }
    else
    {
        xmlNewChild(psRootNode, psNsOws, BAD_CAST "WGS84BoundingBox", NULL);
        xmlAddSibling(psNode,
                      xmlNewComment(BAD_CAST "WARNING: Optional WGS84BoundingBox could not be established for this layer.  Consider setting the EXTENT in the LAYER object, or wfs_extent metadata. Also check that your data exists in the DATA statement"));
    }

    value = msOWSLookupMetadata(&(lp->metadata), "FO", "metadataurl_href");

    if (value)
    {
        psNode = xmlNewChild(psRootNode, NULL, BAD_CAST "MetadataURL", BAD_CAST value);

        value = msOWSLookupMetadata(&(lp->metadata), "FO", "metadataurl_format");

        if (!value)
          value = msStrdup("text/html"); /* default */

        xmlNewProp(psNode, BAD_CAST "format", BAD_CAST value);

        value = msOWSLookupMetadata(&(lp->metadata), "FO", "metadataurl_type");

        if (!value)
          value = msStrdup("FGDC"); /* default */

        xmlNewProp(psNode, BAD_CAST "type", BAD_CAST value);
    }

    return psRootNode;
}
Пример #3
0
/**********************************************************************
 *                          msBuildWFSLayerGetURL()
 *
 * Build a WFS GetFeature URL for a Get Request.
 *
 * Returns a reference to a newly allocated string that should be freed
 * by the caller.
 **********************************************************************/
static char *msBuildWFSLayerGetURL(mapObj *map, layerObj *lp, rectObj *bbox,
                                   wfsParamsObj *psParams)
{
  char *pszURL = NULL, *pszOnlineResource=NULL;
  const char *pszTmp;
  char *pszVersion, *pszService, *pszTypename = NULL;
  int bVersionInConnection = 0, bServiceInConnection = 0;
  int bTypenameInConnection = 0;
  size_t bufferSize = 0;

  if (lp->connectiontype != MS_WFS || lp->connection == NULL) {
    msSetError(MS_WFSCONNERR, "Call supported only for CONNECTIONTYPE WFS",
               "msBuildWFSLayerGetURL()");
    return NULL;
  }

  /* -------------------------------------------------------------------- */
  /*      Find out request version. Look first for the wfs_version        */
  /*      metedata. If not available try to find out if the CONNECTION    */
  /*      string contains the version. This last test is done for         */
  /*      backward compatiblity but is depericated.                       */
  /* -------------------------------------------------------------------- */
  pszVersion = psParams->pszVersion;
  if (!pszVersion) {
    if ((pszTmp = strstr(lp->connection, "VERSION=")) == NULL &&
        (pszTmp = strstr(lp->connection, "version=")) == NULL ) {
      msSetError(MS_WFSCONNERR, "Metadata wfs_version must be set in the layer", "msBuildWFSLayerGetURL()");
      return NULL;
    }
    pszVersion = strchr(pszTmp, '=')+1;
    bVersionInConnection = 1;
  }


  if (strncmp(pszVersion, "0.0.14", 6) != 0 &&
      strncmp(pszVersion, "1.0.0", 5) != 0 &&
      strncmp(pszVersion, "1.1", 3) != 0) {
    msSetError(MS_WFSCONNERR, "MapServer supports only WFS 1.0.0 or 0.0.14 (please verify the version metadata wfs_version).", "msBuildWFSLayerGetURL()");
    return NULL;
  }

  /* -------------------------------------------------------------------- */
  /*      Find out the service. It is always set to WFS in function       */
  /*      msBuildRequestParms  (check Bug 1302 for details).              */
  /* -------------------------------------------------------------------- */
  pszService = psParams->pszService;


  /* -------------------------------------------------------------------- */
  /*      Find out the typename. Look first for the wfs_tyename           */
  /*      metadata. If not available try to find out if the CONNECTION    */
  /*      string contains it. This last test is done for                  */
  /*      backward compatiblity but is depericated.                       */
  /* -------------------------------------------------------------------- */
  pszTypename = psParams->pszTypeName;
  if (!pszTypename) {
    if ((pszTmp = strstr(lp->connection, "TYPENAME=")) == NULL &&
        (pszTmp = strstr(lp->connection, "typename=")) == NULL ) {
      msSetError(MS_WFSCONNERR, "Metadata wfs_typename must be set in the layer", "msBuildWFSLayerGetURL()");
      return NULL;
    }
    bTypenameInConnection = 1;
  }


  /* --------------------------------------------------------------------
   * Build the request URL.
   * At this point we set only the following parameters for GetFeature:
   *   REQUEST
   *   BBOX
   *   VERSION
   *   SERVICE
   *   TYPENAME
   *   FILTER
   *   MAXFEATURES
   *
   * For backward compatiblity the user could also have in the connection
   * string the following parameters (but it is depricated):
   *   VERSION
   *   SERVICE
   *   TYPENAME
   * -------------------------------------------------------------------- */
  /* Make sure we have a big enough buffer for the URL */
  bufferSize = strlen(lp->connection)+1024;
  pszURL = (char *)malloc(bufferSize);
  MS_CHECK_ALLOC(pszURL, bufferSize, NULL);

  /* __TODO__ We have to urlencode each value... especially the BBOX values */
  /* because if they end up in exponent format (123e+06) the + will be seen */
  /* as a space by the remote server. */

  /* -------------------------------------------------------------------- */
  /*      build the URL,                                                  */
  /* -------------------------------------------------------------------- */
  /* make sure connection ends with "&" or "?" */
  pszOnlineResource = msOWSTerminateOnlineResource(lp->connection);
  snprintf(pszURL, bufferSize, "%s", pszOnlineResource);
  msFree(pszOnlineResource);

  /* REQUEST */
  snprintf(pszURL + strlen(pszURL), bufferSize-strlen(pszURL),  "&REQUEST=GetFeature");

  /* VERSION */
  if (!bVersionInConnection)
    snprintf(pszURL + strlen(pszURL), bufferSize-strlen(pszURL),  "&VERSION=%s", pszVersion);

  /* SERVICE */
  if (!bServiceInConnection)
    snprintf(pszURL + strlen(pszURL), bufferSize-strlen(pszURL),  "&SERVICE=%s", pszService);

  /* TYPENAME */
  if (!bTypenameInConnection)
    snprintf(pszURL + strlen(pszURL), bufferSize-strlen(pszURL),  "&TYPENAME=%s", pszTypename);

  /* -------------------------------------------------------------------- */
  /*      If the filter parameter is given in the wfs_filter metadata,    */
  /*      we use it and do not send the BBOX paramter as they are         */
  /*      mutually exclusive.                                             */
  /* -------------------------------------------------------------------- */
  if (psParams->pszFilter) {
    char *encoded_filter = msEncodeUrl(psParams->pszFilter);
    snprintf(pszURL + strlen(pszURL), bufferSize-strlen(pszURL), "&FILTER=%s",encoded_filter);
    free(encoded_filter);
  } else {
	  /*
	   * take care about the axis order for WFS 1.1
	   */
	  char *projUrn;
	  char *projEpsg;
	  projUrn = msOWSGetProjURN(&(lp->projection), &(lp->metadata), "FO", 1);
	  msOWSGetEPSGProj(&(lp->projection), &(lp->metadata), "FO", 1, &projEpsg);

	  /*
	   * WFS 1.1 supports including the SRS in the BBOX parameter, should
	   * respect axis order in the BBOX and has a separate SRSNAME parameter for
	   * the desired result SRS.
	   * WFS 1.0 is always easting, northing, doesn't include the SRS as part of
	   * the BBOX parameter and has no SRSNAME parameter: if we don't have a
	   * URN then fallback to WFS 1.0 style */
	  if ((strncmp(pszVersion, "1.1", 3) == 0) && projUrn) {
		 if (projEpsg && (strncmp(projEpsg, "EPSG:", 5) == 0) &&
				 msIsAxisInverted(atoi(projEpsg + 5))) {
			 snprintf(pszURL + strlen(pszURL), bufferSize - strlen(pszURL),
					 "&BBOX=%.15g,%.15g,%.15g,%.15g,%s&SRSNAME=%s",
					 bbox->miny, bbox->minx, bbox->maxy, bbox->maxx,
					 projUrn, projUrn);
		 } else {
			 snprintf(pszURL + strlen(pszURL), bufferSize - strlen(pszURL),
					 "&BBOX=%.15g,%.15g,%.15g,%.15g,%s&SRSNAME=%s",
					 bbox->minx, bbox->miny, bbox->maxy, bbox->maxy,
					 projUrn, projUrn);
		 }
	  } else {
		  snprintf(pszURL + strlen(pszURL), bufferSize - strlen(pszURL),
				  "&BBOX=%.15g,%.15g,%.15g,%.15g",
				  bbox->minx, bbox->miny, bbox->maxx, bbox->maxy);
	  }

	  msFree(projUrn);
	  msFree(projEpsg);
  }

  if (psParams->nMaxFeatures > 0)
    snprintf(pszURL + strlen(pszURL), bufferSize-strlen(pszURL),
             "&MAXFEATURES=%d", psParams->nMaxFeatures);

  return pszURL;

}