LCOV - code coverage report
Current view: top level - frmts/wms - minidriver_wms.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 79 108 73.1 %
Date: 2024-11-21 22:18:42 Functions: 8 9 88.9 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  WMS Client Driver
       4             :  * Purpose:  Implementation of Dataset and RasterBand classes for WMS
       5             :  *           and other similar services.
       6             :  * Author:   Adam Nowacki, nowak@xpam.de
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 2007, Adam Nowacki
      10             :  * Copyright (c) 2007-2012, Even Rouault <even dot rouault at spatialys.com>
      11             :  *
      12             :  * SPDX-License-Identifier: MIT
      13             :  ****************************************************************************/
      14             : 
      15             : #include "wmsdriver.h"
      16             : #include "minidriver_wms.h"
      17             : 
      18             : #include <algorithm>
      19             : 
      20           4 : WMSMiniDriver_WMS::WMSMiniDriver_WMS() : m_iversion(0)
      21             : {
      22           4 : }
      23             : 
      24           8 : WMSMiniDriver_WMS::~WMSMiniDriver_WMS()
      25             : {
      26           8 : }
      27             : 
      28           8 : static double GetBBoxCoord(const GDALWMSImageRequestInfo &iri, char what)
      29             : {
      30           8 :     switch (what)
      31             :     {
      32           2 :         case 'x':
      33           2 :             return std::min(iri.m_x0, iri.m_x1);
      34           2 :         case 'y':
      35           2 :             return std::min(iri.m_y0, iri.m_y1);
      36           2 :         case 'X':
      37           2 :             return std::max(iri.m_x0, iri.m_x1);
      38           2 :         case 'Y':
      39           2 :             return std::max(iri.m_y0, iri.m_y1);
      40             :     }
      41           0 :     return 0.0;
      42             : }
      43             : 
      44           4 : CPLErr WMSMiniDriver_WMS::Initialize(CPLXMLNode *config,
      45             :                                      CPL_UNUSED char **papszOpenOptions)
      46             : {
      47           4 :     CPLErr ret = CE_None;
      48             : 
      49             :     {
      50           4 :         const char *version = CPLGetXMLValue(config, "Version", "1.1.0");
      51           4 :         if (version[0] != '\0')
      52             :         {
      53           4 :             m_version = version;
      54           4 :             m_iversion = VersionStringToInt(version);
      55           4 :             if (m_iversion == -1)
      56             :             {
      57           0 :                 CPLError(CE_Failure, CPLE_AppDefined,
      58             :                          "GDALWMS, WMS mini-driver: Invalid version.");
      59           0 :                 ret = CE_Failure;
      60             :             }
      61             :         }
      62             :         else
      63             :         {
      64           0 :             CPLError(CE_Failure, CPLE_AppDefined,
      65             :                      "GDALWMS, WMS mini-driver: Version missing.");
      66           0 :             ret = CE_Failure;
      67             :         }
      68             :     }
      69             : 
      70           4 :     if (ret == CE_None)
      71             :     {
      72           4 :         const char *base_url = CPLGetXMLValue(config, "ServerURL", "");
      73           4 :         if (base_url[0] != '\0')
      74             :         {
      75             :             /* Try the old name */
      76           4 :             base_url = CPLGetXMLValue(config, "ServerUrl", "");
      77             :         }
      78           4 :         if (base_url[0] != '\0')
      79             :         {
      80           4 :             m_base_url = base_url;
      81             :         }
      82             :         else
      83             :         {
      84           0 :             CPLError(CE_Failure, CPLE_AppDefined,
      85             :                      "GDALWMS, WMS mini-driver: ServerURL missing.");
      86           0 :             ret = CE_Failure;
      87             :         }
      88             :     }
      89             : 
      90           4 :     if (ret == CE_None)
      91             :     {
      92             :         /* SRS is WMS version 1.1 and earlier, if SRS is not set use default
      93             :            unless CRS is set CRS is WMS version 1.3, if CRS is not set use
      94             :            default unless SRS is set */
      95           4 :         const char *crs = CPLGetXMLValue(config, "CRS", "");
      96           4 :         const char *srs = CPLGetXMLValue(config, "SRS", "");
      97           4 :         if (m_iversion >= VersionStringToInt("1.3"))
      98             :         {
      99             :             /* Version 1.3 and above */
     100           0 :             if ((srs[0] != '\0') && (crs[0] == '\0'))
     101             :             {
     102           0 :                 CPLError(CE_Failure, CPLE_AppDefined,
     103             :                          "GDALWMS, WMS mini-driver: WMS version 1.3 and above "
     104             :                          "expects CRS however SRS was set instead.");
     105           0 :                 ret = CE_Failure;
     106             :             }
     107           0 :             else if (crs[0] != '\0')
     108             :             {
     109           0 :                 m_crs = crs;
     110             :             }
     111             :             else
     112             :             {
     113           0 :                 m_crs = "EPSG:4326";
     114             :             }
     115             :         }
     116             :         else
     117             :         {
     118             :             /* Version 1.1.1 and below */
     119           4 :             if ((srs[0] == '\0') && (crs[0] != '\0'))
     120             :             {
     121           0 :                 CPLError(CE_Failure, CPLE_AppDefined,
     122             :                          "GDALWMS, WMS mini-driver: WMS version 1.1.1 and "
     123             :                          "below expects SRS however CRS was set instead.");
     124           0 :                 ret = CE_Failure;
     125             :             }
     126           4 :             else if (srs[0] != '\0')
     127             :             {
     128           4 :                 m_srs = srs;
     129             :             }
     130             :             else
     131             :             {
     132           0 :                 m_srs = "EPSG:4326";
     133             :             }
     134             :         }
     135             :     }
     136             : 
     137           4 :     if (ret == CE_None)
     138             :     {
     139           4 :         if (!m_srs.empty())
     140             :         {
     141           4 :             m_oSRS = ProjToSRS(m_srs);
     142             :         }
     143           0 :         else if (!m_crs.empty())
     144             :         {
     145           0 :             m_oSRS = ProjToSRS(m_crs);
     146             :         }
     147             :     }
     148             : 
     149           4 :     if (ret == CE_None)
     150             :     {
     151           4 :         m_image_format = CPLGetXMLValue(config, "ImageFormat", "image/jpeg");
     152             :         m_info_format =
     153           4 :             CPLGetConfigOption("WMS_INFO_FORMAT", "application/vnd.ogc.gml");
     154           4 :         m_layers = CPLGetXMLValue(config, "Layers", "");
     155           4 :         m_styles = CPLGetXMLValue(config, "Styles", "");
     156           4 :         m_transparent = CPLGetXMLValue(config, "Transparent", "");
     157             :         // the transparent flag needs to be "TRUE" or "FALSE" in upper case
     158             :         // according to the WMS spec so force upper case
     159           9 :         for (int i = 0; i < (int)m_transparent.size(); i++)
     160             :         {
     161           5 :             m_transparent[i] =
     162           5 :                 (char)toupper(static_cast<unsigned char>(m_transparent[i]));
     163             :         }
     164             :     }
     165             : 
     166           4 :     if (ret == CE_None)
     167             :     {
     168           4 :         const char *bbox_order = CPLGetXMLValue(config, "BBoxOrder", "xyXY");
     169           4 :         if (bbox_order[0] != '\0')
     170             :         {
     171             :             int i;
     172          20 :             for (i = 0; i < 4; ++i)
     173             :             {
     174          16 :                 if ((bbox_order[i] != 'x') && (bbox_order[i] != 'y') &&
     175           8 :                     (bbox_order[i] != 'X') && (bbox_order[i] != 'Y'))
     176           0 :                     break;
     177             :             }
     178           4 :             if (i == 4)
     179             :             {
     180           4 :                 m_bbox_order = bbox_order;
     181             :             }
     182             :             else
     183             :             {
     184           0 :                 CPLError(CE_Failure, CPLE_AppDefined,
     185             :                          "GDALWMS, WMS mini-driver: Incorrect BBoxOrder.");
     186           0 :                 ret = CE_Failure;
     187             :             }
     188             :         }
     189             :         else
     190             :         {
     191           0 :             CPLError(CE_Failure, CPLE_AppDefined,
     192             :                      "GDALWMS, WMS mini-driver: BBoxOrder missing.");
     193           0 :             ret = CE_Failure;
     194             :         }
     195             :     }
     196             : 
     197           4 :     return ret;
     198             : }
     199             : 
     200           4 : void WMSMiniDriver_WMS::GetCapabilities(WMSMiniDriverCapabilities *caps)
     201             : {
     202           4 :     caps->m_has_getinfo = 1;
     203           4 : }
     204             : 
     205           2 : void WMSMiniDriver_WMS::BuildURL(CPLString &url,
     206             :                                  const GDALWMSImageRequestInfo &iri,
     207             :                                  const char *pszRequest)
     208             : {
     209             :     // http://onearth.jpl.nasa.gov/wms.cgi?request=GetMap&width=1000&height=500&layers=modis,global_mosaic&styles=&srs=EPSG:4326&format=image/jpeg&bbox=-180.000000,-90.000000,180.000000,090.000000
     210           2 :     url = m_base_url;
     211             : 
     212           2 :     URLPrepare(url);
     213           2 :     url += "request=";
     214           2 :     url += pszRequest;
     215             : 
     216           2 :     if (url.ifind("service=") == std::string::npos)
     217           1 :         url += "&service=WMS";
     218             : 
     219           4 :     url += CPLOPrintf(
     220             :         "&version=%s&layers=%s&styles=%s&format=%s&width=%d&height=%d&bbox=%."
     221             :         "8f,%.8f,%.8f,%.8f",
     222             :         m_version.c_str(), m_layers.c_str(), m_styles.c_str(),
     223           2 :         m_image_format.c_str(), iri.m_sx, iri.m_sy,
     224           2 :         GetBBoxCoord(iri, m_bbox_order[0]), GetBBoxCoord(iri, m_bbox_order[1]),
     225           4 :         GetBBoxCoord(iri, m_bbox_order[2]), GetBBoxCoord(iri, m_bbox_order[3]));
     226             : 
     227           2 :     if (!m_srs.empty())
     228           2 :         url += CPLOPrintf("&srs=%s", m_srs.c_str());
     229           2 :     if (!m_crs.empty())
     230           0 :         url += CPLOPrintf("&crs=%s", m_crs.c_str());
     231           2 :     if (!m_transparent.empty())
     232           1 :         url += CPLOPrintf("&transparent=%s", m_transparent.c_str());
     233           2 : }
     234             : 
     235           2 : CPLErr WMSMiniDriver_WMS::TiledImageRequest(
     236             :     WMSHTTPRequest &request, const GDALWMSImageRequestInfo &iri,
     237             :     CPL_UNUSED const GDALWMSTiledImageRequestInfo &tiri)
     238             : {
     239           2 :     CPLString &url = request.URL;
     240           2 :     BuildURL(url, iri, "GetMap");
     241           2 :     return CE_None;
     242             : }
     243             : 
     244           0 : void WMSMiniDriver_WMS::GetTiledImageInfo(
     245             :     CPLString &url, const GDALWMSImageRequestInfo &iri,
     246             :     CPL_UNUSED const GDALWMSTiledImageRequestInfo &tiri, int nXInBlock,
     247             :     int nYInBlock)
     248             : {
     249           0 :     BuildURL(url, iri, "GetFeatureInfo");
     250           0 :     url += CPLOPrintf("&query_layers=%s&x=%d&y=%d&info_format=%s",
     251             :                       m_layers.c_str(), nXInBlock, nYInBlock,
     252           0 :                       m_info_format.c_str());
     253           0 : }

Generated by: LCOV version 1.14