LCOV - code coverage report
Current view: top level - frmts/wms - minidriver_arcgis_server.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 59 104 56.7 %
Date: 2024-05-15 17:37:59 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             :  * Permission is hereby granted, free of charge, to any person obtaining a
      12             :  * copy of this software and associated documentation files (the "Software"),
      13             :  * to deal in the Software without restriction, including without limitation
      14             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15             :  * and/or sell copies of the Software, and to permit persons to whom the
      16             :  * Software is furnished to do so, subject to the following conditions:
      17             :  *
      18             :  * The above copyright notice and this permission notice shall be included
      19             :  * in all copies or substantial portions of the Software.
      20             :  *
      21             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27             :  * DEALINGS IN THE SOFTWARE.
      28             :  ****************************************************************************/
      29             : 
      30             : #include "wmsdriver.h"
      31             : #include "minidriver_arcgis_server.h"
      32             : 
      33             : #include <algorithm>
      34             : 
      35           2 : WMSMiniDriver_AGS::WMSMiniDriver_AGS()
      36             : {
      37           2 : }
      38             : 
      39           4 : WMSMiniDriver_AGS::~WMSMiniDriver_AGS()
      40             : {
      41           4 : }
      42             : 
      43           8 : static double GetBBoxCoord(const GDALWMSImageRequestInfo &iri, char what)
      44             : {
      45           8 :     switch (what)
      46             :     {
      47           2 :         case 'x':
      48           2 :             return std::min(iri.m_x0, iri.m_x1);
      49           2 :         case 'y':
      50           2 :             return std::min(iri.m_y0, iri.m_y1);
      51           2 :         case 'X':
      52           2 :             return std::max(iri.m_x0, iri.m_x1);
      53           2 :         case 'Y':
      54           2 :             return std::max(iri.m_y0, iri.m_y1);
      55             :     }
      56           0 :     return 0.0;
      57             : }
      58             : 
      59           0 : char **WMSMiniDriver_AGS::GetMetadataDomainList(void)
      60             : {
      61           0 :     return CSLAddString(nullptr, "LocationInfo");
      62             : }
      63             : 
      64           2 : CPLErr WMSMiniDriver_AGS::Initialize(CPLXMLNode *config,
      65             :                                      CPL_UNUSED char **papszOpenOptions)
      66             : {
      67             :     // Bounding box, if specified, has to be xyXY.
      68           2 :     m_bbox_order = CPLGetXMLValue(config, "BBoxOrder", "xyXY");
      69           2 :     if (m_bbox_order.size() < 4 || m_bbox_order.find("xyXY") != 0)
      70             :     {
      71           0 :         CPLError(CE_Failure, CPLE_AppDefined,
      72             :                  "GDALWMS: ArcGIS BBoxOrder value has to be xyXY");
      73           0 :         return CE_Failure;
      74             :     }
      75             : 
      76             :     m_base_url = CPLGetXMLValue(config, "ServerURL",
      77           2 :                                 CPLGetXMLValue(config, "ServerUrl", ""));
      78           2 :     if (m_base_url.empty())
      79             :     {
      80           0 :         CPLError(CE_Failure, CPLE_AppDefined,
      81             :                  "GDALWMS: ArcGIS Server mini-driver: ServerURL missing.");
      82           0 :         return CE_Failure;
      83             :     }
      84             : 
      85           2 :     m_image_format = CPLGetXMLValue(config, "ImageFormat", "png");
      86           2 :     m_time_range = CPLGetXMLValue(config, "TimeRange", "");
      87           2 :     m_transparent = CPLGetXMLValue(config, "Transparent", "");
      88           2 :     m_transparent.tolower();
      89           2 :     m_layers = CPLGetXMLValue(config, "Layers", "");
      90             : 
      91           2 :     const char *irs = CPLGetXMLValue(config, "SRS", "102100");
      92             : 
      93           2 :     if (irs != nullptr)
      94             :     {
      95           2 :         if (STARTS_WITH_CI(
      96             :                 irs, "EPSG:"))  // If we have EPSG code just convert it to WKT.
      97             :         {
      98           2 :             m_oSRS = ProjToSRS(irs);
      99           2 :             m_irs = irs + 5;
     100             :         }
     101             :         else  // If we have AGS code - try if it's EPSG.
     102             :         {
     103           0 :             m_irs = irs;
     104           0 :             m_oSRS = ProjToSRS("EPSG:" + m_irs);
     105             :         }
     106             :         // TODO: If we have AGS JSON.
     107             :     }
     108             :     m_identification_tolerance =
     109           2 :         CPLGetXMLValue(config, "IdentificationTolerance", "2");
     110             : 
     111           2 :     return CE_None;
     112             : }
     113             : 
     114           2 : void WMSMiniDriver_AGS::GetCapabilities(WMSMiniDriverCapabilities *caps)
     115             : {
     116           2 :     caps->m_has_getinfo = 1;
     117           2 : }
     118             : 
     119           2 : CPLErr WMSMiniDriver_AGS::TiledImageRequest(
     120             :     WMSHTTPRequest &request, const GDALWMSImageRequestInfo &iri,
     121             :     CPL_UNUSED const GDALWMSTiledImageRequestInfo &tiri)
     122             : {
     123           2 :     CPLString &url = request.URL;
     124           2 :     url = m_base_url;
     125             : 
     126             :     // Assume map service if exportImage is not explicitly requested.
     127           3 :     if ((url.ifind("/export?") == std::string::npos) &&
     128           1 :         (url.ifind("/exportImage?") == std::string::npos))
     129             :     {
     130           1 :         url += "/export?";
     131             :     }
     132             : 
     133           2 :     URLPrepare(url);
     134           2 :     url += "f=image";
     135           2 :     char *pszEscapedValue = CPLEscapeString(m_layers, -1, CPLES_URL);
     136           2 :     url += CPLOPrintf("&bbox=%.8f%%2C%.8f%%2C%.8f%%2C%.8f",
     137           2 :                       GetBBoxCoord(iri, m_bbox_order[0]),
     138           2 :                       GetBBoxCoord(iri, m_bbox_order[1]),
     139           2 :                       GetBBoxCoord(iri, m_bbox_order[2]),
     140           6 :                       GetBBoxCoord(iri, m_bbox_order[3])) +
     141           8 :            CPLOPrintf("&size=%d%%2C%d", iri.m_sx, iri.m_sy) +
     142           8 :            CPLOPrintf("&imageSR=%s", m_irs.c_str()) +
     143           8 :            CPLOPrintf("&bboxSR=%s", m_irs.c_str()) +
     144           8 :            CPLOPrintf("&format=%s", m_image_format.c_str()) +
     145           6 :            CPLOPrintf("&layers=%s", pszEscapedValue);
     146           2 :     CPLFree(pszEscapedValue);
     147             : 
     148           2 :     if (!m_transparent.empty())
     149             :     {
     150           0 :         url += "&transparent=" + m_transparent;
     151             :     }
     152             :     else
     153             :     {
     154           2 :         url += "&transparent=false";
     155             :     }
     156             : 
     157           2 :     if (!m_time_range.empty())
     158             :     {
     159           0 :         pszEscapedValue = CPLEscapeString(m_time_range, -1, CPLES_URL);
     160           0 :         url += CPLOPrintf("&time=%s", pszEscapedValue);
     161           0 :         CPLFree(pszEscapedValue);
     162             :     }
     163             :     else
     164             :     {
     165           2 :         url += "&time=";
     166             :     }
     167             : 
     168           2 :     return CE_None;
     169             : }
     170             : 
     171           0 : void WMSMiniDriver_AGS::GetTiledImageInfo(
     172             :     CPLString &url, const GDALWMSImageRequestInfo &iri,
     173             :     CPL_UNUSED const GDALWMSTiledImageRequestInfo &tiri, int nXInBlock,
     174             :     int nYInBlock)
     175             : {
     176           0 :     url = m_base_url;
     177             : 
     178           0 :     if (m_base_url.ifind("/identify?") == std::string::npos)
     179             :     {
     180           0 :         url += "/identify?";
     181             :     }
     182             : 
     183           0 :     URLPrepare(url);
     184             :     // Constant part.
     185             :     url += "f=json&geometryType=esriGeometryPoint&returnGeometry=false"
     186           0 :            "&layerdefs=&time=&layerTimeOptions=&maxAllowableOffset=";
     187             : 
     188           0 :     double fX = GetBBoxCoord(iri, 'x') +
     189           0 :                 nXInBlock * (GetBBoxCoord(iri, 'X') - GetBBoxCoord(iri, 'x')) /
     190           0 :                     iri.m_sx;
     191           0 :     double fY = GetBBoxCoord(iri, 'y') +
     192           0 :                 (iri.m_sy - nYInBlock) *
     193           0 :                     (GetBBoxCoord(iri, 'Y') - GetBBoxCoord(iri, 'y')) /
     194           0 :                     iri.m_sy;
     195             : 
     196           0 :     url += "&geometry=" + std::to_string(fX) + "%2C" + std::to_string(fY) +
     197           0 :            "&sr=" + m_irs;
     198             : 
     199           0 :     CPLString layers("visible");
     200           0 :     if (m_layers.find("show") != std::string::npos)
     201             :     {
     202           0 :         layers = m_layers;
     203           0 :         layers.replace(layers.find("show"), 4, "all");
     204             :     }
     205             : 
     206           0 :     if (m_layers.find("hide") != std::string::npos ||
     207           0 :         m_layers.find("include") != std::string::npos ||
     208           0 :         m_layers.find("exclude") != std::string::npos)
     209             :     {
     210           0 :         layers = "top";
     211             :     }
     212             : 
     213           0 :     url += "&layers=" + layers;
     214           0 :     url += "&tolerance=" + m_identification_tolerance;
     215           0 :     url += CPLOPrintf("&mapExtent=%.8f%%2C%.8f%%2C%.8f%%2C%.8f",
     216           0 :                       GetBBoxCoord(iri, m_bbox_order[0]),
     217           0 :                       GetBBoxCoord(iri, m_bbox_order[1]),
     218           0 :                       GetBBoxCoord(iri, m_bbox_order[2]),
     219           0 :                       GetBBoxCoord(iri, m_bbox_order[3])) +
     220           0 :            CPLOPrintf("&imageDisplay=%d%%2C%d%%2C96", iri.m_sx, iri.m_sy);
     221           0 : }

Generated by: LCOV version 1.14