LCOV - code coverage report
Current view: top level - frmts/wms - minidriver_arcgis_server.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 58 103 56.3 %
Date: 2024-11-21 22:18:42 Functions: 7 9 77.8 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  Arc GIS Server Client Driver
       4             :  * Purpose:  Implementation of Dataset and RasterBand classes for WMS
       5             :  *           and other similar services.
       6             :  * Author:   Alexander Lisovenko
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 2014-2020, NextGIS <info@nextgis.com>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #include "wmsdriver.h"
      15             : #include "minidriver_arcgis_server.h"
      16             : 
      17             : #include <algorithm>
      18             : 
      19           2 : WMSMiniDriver_AGS::WMSMiniDriver_AGS()
      20             : {
      21           2 : }
      22             : 
      23           4 : WMSMiniDriver_AGS::~WMSMiniDriver_AGS()
      24             : {
      25           4 : }
      26             : 
      27           8 : static double GetBBoxCoord(const GDALWMSImageRequestInfo &iri, char what)
      28             : {
      29           8 :     switch (what)
      30             :     {
      31           2 :         case 'x':
      32           2 :             return std::min(iri.m_x0, iri.m_x1);
      33           2 :         case 'y':
      34           2 :             return std::min(iri.m_y0, iri.m_y1);
      35           2 :         case 'X':
      36           2 :             return std::max(iri.m_x0, iri.m_x1);
      37           2 :         case 'Y':
      38           2 :             return std::max(iri.m_y0, iri.m_y1);
      39             :     }
      40           0 :     return 0.0;
      41             : }
      42             : 
      43           0 : char **WMSMiniDriver_AGS::GetMetadataDomainList(void)
      44             : {
      45           0 :     return CSLAddString(nullptr, "LocationInfo");
      46             : }
      47             : 
      48           2 : CPLErr WMSMiniDriver_AGS::Initialize(CPLXMLNode *config,
      49             :                                      CPL_UNUSED char **papszOpenOptions)
      50             : {
      51             :     // Bounding box, if specified, has to be xyXY.
      52           2 :     m_bbox_order = CPLGetXMLValue(config, "BBoxOrder", "xyXY");
      53           2 :     if (m_bbox_order.size() < 4 || m_bbox_order.find("xyXY") != 0)
      54             :     {
      55           0 :         CPLError(CE_Failure, CPLE_AppDefined,
      56             :                  "GDALWMS: ArcGIS BBoxOrder value has to be xyXY");
      57           0 :         return CE_Failure;
      58             :     }
      59             : 
      60             :     m_base_url = CPLGetXMLValue(config, "ServerURL",
      61           2 :                                 CPLGetXMLValue(config, "ServerUrl", ""));
      62           2 :     if (m_base_url.empty())
      63             :     {
      64           0 :         CPLError(CE_Failure, CPLE_AppDefined,
      65             :                  "GDALWMS: ArcGIS Server mini-driver: ServerURL missing.");
      66           0 :         return CE_Failure;
      67             :     }
      68             : 
      69           2 :     m_image_format = CPLGetXMLValue(config, "ImageFormat", "png");
      70           2 :     m_time_range = CPLGetXMLValue(config, "TimeRange", "");
      71             :     m_transparent =
      72           2 :         CPLString(CPLGetXMLValue(config, "Transparent", "")).tolower();
      73           2 :     m_layers = CPLGetXMLValue(config, "Layers", "");
      74             : 
      75           2 :     const char *irs = CPLGetXMLValue(config, "SRS", "102100");
      76             : 
      77           2 :     if (irs != nullptr)
      78             :     {
      79           2 :         if (STARTS_WITH_CI(
      80             :                 irs, "EPSG:"))  // If we have EPSG code just convert it to WKT.
      81             :         {
      82           2 :             m_oSRS = ProjToSRS(irs);
      83           2 :             m_irs = irs + 5;
      84             :         }
      85             :         else  // If we have AGS code - try if it's EPSG.
      86             :         {
      87           0 :             m_irs = irs;
      88           0 :             m_oSRS = ProjToSRS("EPSG:" + m_irs);
      89             :         }
      90             :         // TODO: If we have AGS JSON.
      91             :     }
      92             :     m_identification_tolerance =
      93           2 :         CPLGetXMLValue(config, "IdentificationTolerance", "2");
      94             : 
      95           2 :     return CE_None;
      96             : }
      97             : 
      98           2 : void WMSMiniDriver_AGS::GetCapabilities(WMSMiniDriverCapabilities *caps)
      99             : {
     100           2 :     caps->m_has_getinfo = 1;
     101           2 : }
     102             : 
     103           2 : CPLErr WMSMiniDriver_AGS::TiledImageRequest(
     104             :     WMSHTTPRequest &request, const GDALWMSImageRequestInfo &iri,
     105             :     CPL_UNUSED const GDALWMSTiledImageRequestInfo &tiri)
     106             : {
     107           2 :     CPLString &url = request.URL;
     108           2 :     url = m_base_url;
     109             : 
     110             :     // Assume map service if exportImage is not explicitly requested.
     111           3 :     if ((url.ifind("/export?") == std::string::npos) &&
     112           1 :         (url.ifind("/exportImage?") == std::string::npos))
     113             :     {
     114           1 :         url += "/export?";
     115             :     }
     116             : 
     117           2 :     URLPrepare(url);
     118           2 :     url += "f=image";
     119           2 :     char *pszEscapedValue = CPLEscapeString(m_layers, -1, CPLES_URL);
     120           2 :     url += CPLOPrintf("&bbox=%.8f%%2C%.8f%%2C%.8f%%2C%.8f",
     121           2 :                       GetBBoxCoord(iri, m_bbox_order[0]),
     122           2 :                       GetBBoxCoord(iri, m_bbox_order[1]),
     123           2 :                       GetBBoxCoord(iri, m_bbox_order[2]),
     124           6 :                       GetBBoxCoord(iri, m_bbox_order[3])) +
     125           8 :            CPLOPrintf("&size=%d%%2C%d", iri.m_sx, iri.m_sy) +
     126           8 :            CPLOPrintf("&imageSR=%s", m_irs.c_str()) +
     127           8 :            CPLOPrintf("&bboxSR=%s", m_irs.c_str()) +
     128           8 :            CPLOPrintf("&format=%s", m_image_format.c_str()) +
     129           6 :            CPLOPrintf("&layers=%s", pszEscapedValue);
     130           2 :     CPLFree(pszEscapedValue);
     131             : 
     132           2 :     if (!m_transparent.empty())
     133             :     {
     134           0 :         url += "&transparent=" + m_transparent;
     135             :     }
     136             :     else
     137             :     {
     138           2 :         url += "&transparent=false";
     139             :     }
     140             : 
     141           2 :     if (!m_time_range.empty())
     142             :     {
     143           0 :         pszEscapedValue = CPLEscapeString(m_time_range, -1, CPLES_URL);
     144           0 :         url += CPLOPrintf("&time=%s", pszEscapedValue);
     145           0 :         CPLFree(pszEscapedValue);
     146             :     }
     147             :     else
     148             :     {
     149           2 :         url += "&time=";
     150             :     }
     151             : 
     152           2 :     return CE_None;
     153             : }
     154             : 
     155           0 : void WMSMiniDriver_AGS::GetTiledImageInfo(
     156             :     CPLString &url, const GDALWMSImageRequestInfo &iri,
     157             :     CPL_UNUSED const GDALWMSTiledImageRequestInfo &tiri, int nXInBlock,
     158             :     int nYInBlock)
     159             : {
     160           0 :     url = m_base_url;
     161             : 
     162           0 :     if (m_base_url.ifind("/identify?") == std::string::npos)
     163             :     {
     164           0 :         url += "/identify?";
     165             :     }
     166             : 
     167           0 :     URLPrepare(url);
     168             :     // Constant part.
     169             :     url += "f=json&geometryType=esriGeometryPoint&returnGeometry=false"
     170           0 :            "&layerdefs=&time=&layerTimeOptions=&maxAllowableOffset=";
     171             : 
     172           0 :     double fX = GetBBoxCoord(iri, 'x') +
     173           0 :                 nXInBlock * (GetBBoxCoord(iri, 'X') - GetBBoxCoord(iri, 'x')) /
     174           0 :                     iri.m_sx;
     175           0 :     double fY = GetBBoxCoord(iri, 'y') +
     176           0 :                 (iri.m_sy - nYInBlock) *
     177           0 :                     (GetBBoxCoord(iri, 'Y') - GetBBoxCoord(iri, 'y')) /
     178           0 :                     iri.m_sy;
     179             : 
     180           0 :     url += "&geometry=" + std::to_string(fX) + "%2C" + std::to_string(fY) +
     181           0 :            "&sr=" + m_irs;
     182             : 
     183           0 :     CPLString layers("visible");
     184           0 :     if (m_layers.find("show") != std::string::npos)
     185             :     {
     186           0 :         layers = m_layers;
     187           0 :         layers.replace(layers.find("show"), 4, "all");
     188             :     }
     189             : 
     190           0 :     if (m_layers.find("hide") != std::string::npos ||
     191           0 :         m_layers.find("include") != std::string::npos ||
     192           0 :         m_layers.find("exclude") != std::string::npos)
     193             :     {
     194           0 :         layers = "top";
     195             :     }
     196             : 
     197           0 :     url += "&layers=" + layers;
     198           0 :     url += "&tolerance=" + m_identification_tolerance;
     199           0 :     url += CPLOPrintf("&mapExtent=%.8f%%2C%.8f%%2C%.8f%%2C%.8f",
     200           0 :                       GetBBoxCoord(iri, m_bbox_order[0]),
     201           0 :                       GetBBoxCoord(iri, m_bbox_order[1]),
     202           0 :                       GetBBoxCoord(iri, m_bbox_order[2]),
     203           0 :                       GetBBoxCoord(iri, m_bbox_order[3])) +
     204           0 :            CPLOPrintf("&imageDisplay=%d%%2C%d%%2C96", iri.m_sx, iri.m_sy);
     205           0 : }

Generated by: LCOV version 1.14