LCOV - code coverage report
Current view: top level - frmts/wms - wmsdrivercore.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 90 97 92.8 %
Date: 2025-05-31 00:00:17 Functions: 8 8 100.0 %

          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) 2009-2014, Even Rouault <even dot rouault at spatialys.com>
      11             :  *
      12             :  * SPDX-License-Identifier: MIT
      13             :  ****************************************************************************/
      14             : 
      15             : #include "wmsdrivercore.h"
      16             : 
      17             : /************************************************************************/
      18             : /*                     WMSDriverIdentify()                              */
      19             : /************************************************************************/
      20             : 
      21       58718 : int WMSDriverIdentify(GDALOpenInfo *poOpenInfo)
      22             : 
      23             : {
      24       58718 :     const char *pszFilename = poOpenInfo->pszFilename;
      25       58718 :     const char *pabyHeader = (const char *)poOpenInfo->pabyHeader;
      26       58718 :     if (poOpenInfo->nHeaderBytes == 0 &&
      27       53993 :         STARTS_WITH_CI(pszFilename, "<GDAL_WMS>"))
      28             :     {
      29         670 :         return TRUE;
      30             :     }
      31       58048 :     else if (poOpenInfo->nHeaderBytes >= 10 &&
      32        4586 :              STARTS_WITH_CI(pabyHeader, "<GDAL_WMS>"))
      33             :     {
      34          21 :         return TRUE;
      35             :     }
      36      111350 :     else if (poOpenInfo->nHeaderBytes == 0 &&
      37       53323 :              (STARTS_WITH_CI(pszFilename, "WMS:") ||
      38      111348 :               CPLString(pszFilename).ifind("SERVICE=WMS") != std::string::npos))
      39             :     {
      40           2 :         return TRUE;
      41             :     }
      42      169371 :     else if (poOpenInfo->nHeaderBytes == 0 &&
      43       58046 :              poOpenInfo->IsSingleAllowedDriver("WMS") &&
      44          21 :              (STARTS_WITH(poOpenInfo->pszFilename, "http://") ||
      45          19 :               STARTS_WITH(poOpenInfo->pszFilename, "https://")))
      46             :     {
      47           2 :         return true;
      48             :     }
      49       58023 :     else if (poOpenInfo->nHeaderBytes != 0 &&
      50        4704 :              (strstr(pabyHeader, "<WMT_MS_Capabilities") != nullptr ||
      51        4704 :               strstr(pabyHeader, "<WMS_Capabilities") != nullptr ||
      52        4704 :               strstr(pabyHeader, "<!DOCTYPE WMT_MS_Capabilities") != nullptr))
      53             :     {
      54           0 :         return TRUE;
      55             :     }
      56       58023 :     else if (poOpenInfo->nHeaderBytes != 0 &&
      57        4704 :              strstr(pabyHeader, "<WMS_Tile_Service") != nullptr)
      58             :     {
      59           4 :         return TRUE;
      60             :     }
      61       58019 :     else if (poOpenInfo->nHeaderBytes != 0 &&
      62        4700 :              strstr(pabyHeader, "<TileMap version=\"1.0.0\"") != nullptr)
      63             :     {
      64           0 :         return TRUE;
      65             :     }
      66       58019 :     else if (poOpenInfo->nHeaderBytes != 0 &&
      67        4700 :              strstr(pabyHeader, "<Services") != nullptr &&
      68           0 :              strstr(pabyHeader, "<TileMapService version=\"1.0") != nullptr)
      69             :     {
      70           0 :         return TRUE;
      71             :     }
      72       58019 :     else if (poOpenInfo->nHeaderBytes != 0 &&
      73        4700 :              strstr(pabyHeader, "<TileMapService version=\"1.0.0\"") != nullptr)
      74             :     {
      75           0 :         return TRUE;
      76             :     }
      77       58019 :     else if (poOpenInfo->nHeaderBytes == 0 &&
      78       53319 :              STARTS_WITH_CI(pszFilename, "http") &&
      79          20 :              (strstr(pszFilename, "/MapServer?f=json") != nullptr ||
      80          18 :               strstr(pszFilename, "/MapServer/?f=json") != nullptr ||
      81          18 :               strstr(pszFilename, "/ImageServer?f=json") != nullptr ||
      82          18 :               strstr(pszFilename, "/ImageServer/?f=json") != nullptr))
      83             :     {
      84           2 :         return TRUE;
      85             :     }
      86       58017 :     else if (poOpenInfo->nHeaderBytes == 0 &&
      87       53317 :              STARTS_WITH_CI(pszFilename, "AGS:"))
      88             :     {
      89           0 :         return TRUE;
      90             :     }
      91       58017 :     else if (poOpenInfo->nHeaderBytes == 0 &&
      92       53317 :              STARTS_WITH_CI(pszFilename, "IIP:"))
      93             :     {
      94           2 :         return TRUE;
      95             :     }
      96       58015 :     else if (poOpenInfo->nHeaderBytes == 0 &&
      97       53315 :              STARTS_WITH_CI(pszFilename, "IIIF:"))
      98             :     {
      99           8 :         return TRUE;
     100             :     }
     101             :     else
     102       58007 :         return FALSE;
     103             : }
     104             : 
     105             : /************************************************************************/
     106             : /*                    OGRWMSDriverGetSubdatasetInfo()                   */
     107             : /************************************************************************/
     108             : 
     109             : struct WMSDriverSubdatasetInfo : public GDALSubdatasetInfo
     110             : {
     111             :   public:
     112           8 :     explicit WMSDriverSubdatasetInfo(const std::string &fileName)
     113           8 :         : GDALSubdatasetInfo(fileName)
     114             :     {
     115           8 :     }
     116             : 
     117             :     // GDALSubdatasetInfo interface
     118             :   private:
     119           8 :     void parseFileName() override
     120             :     {
     121           8 :         if (!STARTS_WITH_CI(m_fileName.c_str(), "WMS:"))
     122             :         {
     123           0 :             return;
     124             :         }
     125             : 
     126          16 :         const CPLString osLayers = CPLURLGetValue(m_fileName.c_str(), "LAYERS");
     127             : 
     128           8 :         if (!osLayers.empty())
     129             :         {
     130           6 :             m_subdatasetComponent = "LAYERS=" + osLayers;
     131           6 :             m_driverPrefixComponent = "WMS";
     132             : 
     133           6 :             m_pathComponent = m_fileName;
     134           6 :             m_pathComponent.erase(m_pathComponent.find(m_subdatasetComponent),
     135           6 :                                   m_subdatasetComponent.length());
     136           6 :             m_pathComponent.erase(0, 4);
     137           6 :             const std::size_t nDoubleAndPos = m_pathComponent.find("&&");
     138           6 :             if (nDoubleAndPos != std::string::npos)
     139             :             {
     140           2 :                 m_pathComponent.erase(nDoubleAndPos, 1);
     141             :             }
     142             :             // Reconstruct URL with LAYERS at the end or ModifyPathComponent will fail
     143          12 :             m_fileName = m_driverPrefixComponent + ":" + m_pathComponent + "&" +
     144          12 :                          m_subdatasetComponent;
     145             :         }
     146             :     }
     147             : };
     148             : 
     149        2690 : static GDALSubdatasetInfo *WMSDriverGetSubdatasetInfo(const char *pszFileName)
     150             : {
     151        2690 :     if (STARTS_WITH(pszFileName, "WMS:"))
     152             :     {
     153             :         std::unique_ptr<GDALSubdatasetInfo> info =
     154           8 :             std::make_unique<WMSDriverSubdatasetInfo>(pszFileName);
     155          22 :         if (!info->GetSubdatasetComponent().empty() &&
     156          14 :             !info->GetPathComponent().empty())
     157             :         {
     158           6 :             return info.release();
     159             :         }
     160             :     }
     161        2684 :     return nullptr;
     162             : }
     163             : 
     164             : /************************************************************************/
     165             : /*                      WMSDriverSetCommonMetadata()                    */
     166             : /************************************************************************/
     167             : 
     168        1617 : void WMSDriverSetCommonMetadata(GDALDriver *poDriver)
     169             : {
     170        1617 :     poDriver->SetDescription(DRIVER_NAME);
     171        1617 :     poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
     172        1617 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "OGC Web Map Service");
     173        1617 :     poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/wms.html");
     174        1617 :     poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
     175        1617 :     poDriver->SetMetadataItem(GDAL_DMD_SUBDATASETS, "YES");
     176             : 
     177        1617 :     poDriver->pfnIdentify = WMSDriverIdentify;
     178        1617 :     poDriver->pfnGetSubdatasetInfoFunc = WMSDriverGetSubdatasetInfo;
     179        1617 :     poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES");
     180        1617 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATECOPY, "YES");
     181        1617 : }
     182             : 
     183             : /************************************************************************/
     184             : /*                     DeclareDeferredWMSPlugin()                       */
     185             : /************************************************************************/
     186             : 
     187             : #ifdef PLUGIN_FILENAME
     188        1889 : void DeclareDeferredWMSPlugin()
     189             : {
     190        1889 :     if (GDALGetDriverByName(DRIVER_NAME) != nullptr)
     191             :     {
     192         282 :         return;
     193             :     }
     194        1607 :     auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME);
     195             : #ifdef PLUGIN_INSTALLATION_MESSAGE
     196             :     poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE,
     197             :                               PLUGIN_INSTALLATION_MESSAGE);
     198             : #endif
     199        1607 :     WMSDriverSetCommonMetadata(poDriver);
     200        1607 :     GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver);
     201             : }
     202             : #endif

Generated by: LCOV version 1.14