LCOV - code coverage report
Current view: top level - frmts/wms - wmsdrivercore.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 87 94 92.6 %
Date: 2024-11-21 22:18:42 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       53670 : int WMSDriverIdentify(GDALOpenInfo *poOpenInfo)
      22             : 
      23             : {
      24       53670 :     const char *pszFilename = poOpenInfo->pszFilename;
      25       53670 :     const char *pabyHeader = (const char *)poOpenInfo->pabyHeader;
      26       53670 :     if (poOpenInfo->nHeaderBytes == 0 &&
      27       48923 :         STARTS_WITH_CI(pszFilename, "<GDAL_WMS>"))
      28             :     {
      29         666 :         return TRUE;
      30             :     }
      31       53004 :     else if (poOpenInfo->nHeaderBytes >= 10 &&
      32        4570 :              STARTS_WITH_CI(pabyHeader, "<GDAL_WMS>"))
      33             :     {
      34          25 :         return TRUE;
      35             :     }
      36      101234 :     else if (poOpenInfo->nHeaderBytes == 0 &&
      37       48256 :              (STARTS_WITH_CI(pszFilename, "WMS:") ||
      38      101231 :               CPLString(pszFilename).ifind("SERVICE=WMS") != std::string::npos))
      39             :     {
      40           2 :         return TRUE;
      41             :     }
      42      154172 :     else if (poOpenInfo->nHeaderBytes == 0 &&
      43       52980 :              poOpenInfo->IsSingleAllowedDriver("WMS") &&
      44          21 :              (STARTS_WITH(poOpenInfo->pszFilename, "http://") ||
      45          19 :               STARTS_WITH(poOpenInfo->pszFilename, "https://")))
      46             :     {
      47           2 :         return true;
      48             :     }
      49       52966 :     else if (poOpenInfo->nHeaderBytes != 0 &&
      50        4722 :              (strstr(pabyHeader, "<WMT_MS_Capabilities") != nullptr ||
      51        4722 :               strstr(pabyHeader, "<WMS_Capabilities") != nullptr ||
      52        4722 :               strstr(pabyHeader, "<!DOCTYPE WMT_MS_Capabilities") != nullptr))
      53             :     {
      54           0 :         return TRUE;
      55             :     }
      56       52966 :     else if (poOpenInfo->nHeaderBytes != 0 &&
      57        4722 :              strstr(pabyHeader, "<WMS_Tile_Service") != nullptr)
      58             :     {
      59           4 :         return TRUE;
      60             :     }
      61       52962 :     else if (poOpenInfo->nHeaderBytes != 0 &&
      62        4718 :              strstr(pabyHeader, "<TileMap version=\"1.0.0\"") != nullptr)
      63             :     {
      64           0 :         return TRUE;
      65             :     }
      66       52962 :     else if (poOpenInfo->nHeaderBytes != 0 &&
      67        4718 :              strstr(pabyHeader, "<Services") != nullptr &&
      68           0 :              strstr(pabyHeader, "<TileMapService version=\"1.0") != nullptr)
      69             :     {
      70           0 :         return TRUE;
      71             :     }
      72       52962 :     else if (poOpenInfo->nHeaderBytes != 0 &&
      73        4718 :              strstr(pabyHeader, "<TileMapService version=\"1.0.0\"") != nullptr)
      74             :     {
      75           0 :         return TRUE;
      76             :     }
      77       52962 :     else if (poOpenInfo->nHeaderBytes == 0 &&
      78       48233 :              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       52960 :     else if (poOpenInfo->nHeaderBytes == 0 &&
      87       48245 :              STARTS_WITH_CI(pszFilename, "AGS:"))
      88             :     {
      89           0 :         return TRUE;
      90             :     }
      91       52960 :     else if (poOpenInfo->nHeaderBytes == 0 &&
      92       48234 :              STARTS_WITH_CI(pszFilename, "IIP:"))
      93             :     {
      94           2 :         return TRUE;
      95             :     }
      96             :     else
      97       52958 :         return FALSE;
      98             : }
      99             : 
     100             : /************************************************************************/
     101             : /*                    OGRWMSDriverGetSubdatasetInfo()                   */
     102             : /************************************************************************/
     103             : 
     104             : struct WMSDriverSubdatasetInfo : public GDALSubdatasetInfo
     105             : {
     106             :   public:
     107           8 :     explicit WMSDriverSubdatasetInfo(const std::string &fileName)
     108           8 :         : GDALSubdatasetInfo(fileName)
     109             :     {
     110           8 :     }
     111             : 
     112             :     // GDALSubdatasetInfo interface
     113             :   private:
     114           8 :     void parseFileName() override
     115             :     {
     116           8 :         if (!STARTS_WITH_CI(m_fileName.c_str(), "WMS:"))
     117             :         {
     118           0 :             return;
     119             :         }
     120             : 
     121          16 :         const CPLString osLayers = CPLURLGetValue(m_fileName.c_str(), "LAYERS");
     122             : 
     123           8 :         if (!osLayers.empty())
     124             :         {
     125           6 :             m_subdatasetComponent = "LAYERS=" + osLayers;
     126           6 :             m_driverPrefixComponent = "WMS";
     127             : 
     128           6 :             m_pathComponent = m_fileName;
     129           6 :             m_pathComponent.erase(m_pathComponent.find(m_subdatasetComponent),
     130           6 :                                   m_subdatasetComponent.length());
     131           6 :             m_pathComponent.erase(0, 4);
     132           6 :             const std::size_t nDoubleAndPos = m_pathComponent.find("&&");
     133           6 :             if (nDoubleAndPos != std::string::npos)
     134             :             {
     135           2 :                 m_pathComponent.erase(nDoubleAndPos, 1);
     136             :             }
     137             :             // Reconstruct URL with LAYERS at the end or ModifyPathComponent will fail
     138          12 :             m_fileName = m_driverPrefixComponent + ":" + m_pathComponent + "&" +
     139          12 :                          m_subdatasetComponent;
     140             :         }
     141             :     }
     142             : };
     143             : 
     144        2615 : static GDALSubdatasetInfo *WMSDriverGetSubdatasetInfo(const char *pszFileName)
     145             : {
     146        2615 :     if (STARTS_WITH(pszFileName, "WMS:"))
     147             :     {
     148             :         std::unique_ptr<GDALSubdatasetInfo> info =
     149           8 :             std::make_unique<WMSDriverSubdatasetInfo>(pszFileName);
     150          22 :         if (!info->GetSubdatasetComponent().empty() &&
     151          14 :             !info->GetPathComponent().empty())
     152             :         {
     153           6 :             return info.release();
     154             :         }
     155             :     }
     156        2609 :     return nullptr;
     157             : }
     158             : 
     159             : /************************************************************************/
     160             : /*                      WMSDriverSetCommonMetadata()                    */
     161             : /************************************************************************/
     162             : 
     163        1302 : void WMSDriverSetCommonMetadata(GDALDriver *poDriver)
     164             : {
     165        1302 :     poDriver->SetDescription(DRIVER_NAME);
     166        1302 :     poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
     167        1302 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "OGC Web Map Service");
     168        1302 :     poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/wms.html");
     169        1302 :     poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
     170        1302 :     poDriver->SetMetadataItem(GDAL_DMD_SUBDATASETS, "YES");
     171             : 
     172        1302 :     poDriver->pfnIdentify = WMSDriverIdentify;
     173        1302 :     poDriver->pfnGetSubdatasetInfoFunc = WMSDriverGetSubdatasetInfo;
     174        1302 :     poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES");
     175        1302 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATECOPY, "YES");
     176        1302 : }
     177             : 
     178             : /************************************************************************/
     179             : /*                     DeclareDeferredWMSPlugin()                       */
     180             : /************************************************************************/
     181             : 
     182             : #ifdef PLUGIN_FILENAME
     183        1595 : void DeclareDeferredWMSPlugin()
     184             : {
     185        1595 :     if (GDALGetDriverByName(DRIVER_NAME) != nullptr)
     186             :     {
     187         302 :         return;
     188             :     }
     189        1293 :     auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME);
     190             : #ifdef PLUGIN_INSTALLATION_MESSAGE
     191             :     poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE,
     192             :                               PLUGIN_INSTALLATION_MESSAGE);
     193             : #endif
     194        1293 :     WMSDriverSetCommonMetadata(poDriver);
     195        1293 :     GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver);
     196             : }
     197             : #endif

Generated by: LCOV version 1.14