LCOV - code coverage report
Current view: directory - frmts/wms - dataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 372 276 74.2 %
Date: 2012-12-26 Functions: 30 22 73.3 %

       1                 : /******************************************************************************
       2                 :  * $Id: dataset.cpp 24237 2012-04-14 15:06:21Z rouault $
       3                 :  *
       4                 :  * Project:  WMS Client Driver
       5                 :  * Purpose:  Implementation of Dataset and RasterBand classes for WMS
       6                 :  *           and other similar services.
       7                 :  * Author:   Adam Nowacki, nowak@xpam.de
       8                 :  *
       9                 :  ******************************************************************************
      10                 :  * Copyright (c) 2007, Adam Nowacki
      11                 :  *
      12                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      13                 :  * copy of this software and associated documentation files (the "Software"),
      14                 :  * to deal in the Software without restriction, including without limitation
      15                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16                 :  * and/or sell copies of the Software, and to permit persons to whom the
      17                 :  * Software is furnished to do so, subject to the following conditions:
      18                 :  *
      19                 :  * The above copyright notice and this permission notice shall be included
      20                 :  * in all copies or substantial portions of the Software.
      21                 :  *
      22                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      23                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      25                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      27                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      28                 :  * DEALINGS IN THE SOFTWARE.
      29                 :  ****************************************************************************
      30                 :  *
      31                 :  * dataset.cpp:
      32                 :  * Initialization of the GDALWMSdriver, parsing the XML configuration file, 
      33                 :  * instantiation of the minidrivers and accessors used by minidrivers
      34                 :  *
      35                 :  ***************************************************************************/ 
      36                 : 
      37                 : 
      38                 : #include "stdinc.h"
      39                 : 
      40              14 : GDALWMSDataset::GDALWMSDataset() {
      41              14 :     m_mini_driver = 0;
      42              14 :     m_cache = 0;
      43              14 :     m_hint.m_valid = false;
      44              14 :     m_data_type = GDT_Byte;
      45              14 :     m_clamp_requests = true;
      46              14 :     m_unsafeSsl = false;
      47              14 :     m_data_window.m_sx = -1;
      48              14 :     nBands = 0;
      49              14 :     m_default_block_size_x = 1024;
      50              14 :     m_default_block_size_y = 1024;
      51              14 :     m_bNeedsDataWindow = TRUE;
      52              14 :     m_default_tile_count_x = 1;
      53              14 :     m_default_tile_count_y = 1;
      54              14 :     m_default_overview_count = -1;
      55              14 :     m_zeroblock_on_serverexceptions = 0;
      56              14 :     m_poColorTable = NULL;
      57              14 : }
      58                 : 
      59              14 : GDALWMSDataset::~GDALWMSDataset() {
      60              14 :     if (m_mini_driver) delete m_mini_driver;
      61              14 :     if (m_cache) delete m_cache;
      62              14 :     if (m_poColorTable) delete m_poColorTable;
      63              14 : }
      64                 : 
      65              14 : CPLErr GDALWMSDataset::Initialize(CPLXMLNode *config) {
      66              14 :     CPLErr ret = CE_None;
      67                 : 
      68              14 :     char* pszXML = CPLSerializeXMLTree( config );
      69              14 :     if (pszXML)
      70                 :     {
      71              14 :         m_osXML = pszXML;
      72              14 :         CPLFree(pszXML);
      73                 :     }
      74                 : 
      75                 :     // Initialize the minidriver, which can set parameters for the dataset using member functions
      76              14 :     CPLXMLNode *service_node = CPLGetXMLNode(config, "Service");
      77              14 :     if (service_node != NULL)
      78                 :     {
      79              14 :         const CPLString service_name = CPLGetXMLValue(service_node, "name", "");
      80              14 :         if (!service_name.empty())
      81                 :         {
      82              14 :             GDALWMSMiniDriverManager *const mdm = GetGDALWMSMiniDriverManager();
      83              14 :             GDALWMSMiniDriverFactory *const mdf = mdm->Find(service_name);
      84              14 :             if (mdf != NULL)
      85                 :             {
      86              14 :                 m_mini_driver = mdf->New();
      87              14 :                 m_mini_driver->m_parent_dataset = this;
      88              14 :                 if (m_mini_driver->Initialize(service_node) == CE_None)
      89                 :                 {
      90              14 :                     m_mini_driver_caps.m_capabilities_version = -1;
      91              14 :                     m_mini_driver->GetCapabilities(&m_mini_driver_caps);
      92              14 :                     if (m_mini_driver_caps.m_capabilities_version == -1)
      93                 :                     {
      94               0 :                         CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Internal error, mini-driver capabilities version not set.");
      95               0 :                         ret = CE_Failure;
      96                 :                     }
      97                 :                 }
      98                 :                 else
      99                 :                 {
     100               0 :                     delete m_mini_driver;
     101               0 :                     m_mini_driver = NULL;
     102                 : 
     103               0 :                     CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Failed to initialize minidriver.");
     104               0 :                     ret = CE_Failure;
     105                 :                 }
     106                 :             }
     107                 :             else
     108                 :             {
     109                 :                 CPLError(CE_Failure, CPLE_AppDefined,
     110               0 :                                 "GDALWMS: No mini-driver registered for '%s'.", service_name.c_str());
     111               0 :                 ret = CE_Failure;
     112                 :             }
     113                 :         }
     114                 :         else
     115                 :         {
     116               0 :             CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: No Service specified.");
     117               0 :             ret = CE_Failure;
     118              14 :         }
     119                 :     }
     120                 :     else
     121                 :     {
     122               0 :         CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: No Service specified.");
     123               0 :         ret = CE_Failure;
     124                 :     }
     125                 : 
     126                 : 
     127                 :     /*
     128                 :     Parameters that could be set by minidriver already, based on server side information.
     129                 :     If the size is set, minidriver has done this already
     130                 :     A "server" side minidriver needs to set at least:
     131                 :       - Blocksize (x and y)
     132                 :       - Clamp flag (defaults to true)
     133                 :       - DataWindow
     134                 :       - Band Count
     135                 :       - Data Type
     136                 :     It should also initialize and register the bands and overviews.
     137                 :     */
     138                 : 
     139              14 :     if (m_data_window.m_sx<1)
     140                 :     {
     141              11 :         int nOverviews = 0;
     142                 : 
     143              11 :         if (ret == CE_None)
     144                 :         {
     145              11 :             m_block_size_x = atoi(CPLGetXMLValue(config, "BlockSizeX", CPLString().Printf("%d", m_default_block_size_x)));
     146              22 :             m_block_size_y = atoi(CPLGetXMLValue(config, "BlockSizeY", CPLString().Printf("%d", m_default_block_size_y)));
     147              22 :             if (m_block_size_x <= 0 || m_block_size_y <= 0)
     148                 :             {
     149               0 :                 CPLError( CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value in BlockSizeX or BlockSizeY" );
     150               0 :                 ret = CE_Failure;
     151                 :             }
     152                 :         }
     153                 : 
     154              11 :         if (ret == CE_None)
     155                 :         {
     156              11 :             m_clamp_requests = StrToBool(CPLGetXMLValue(config, "ClampRequests", "true"));
     157              11 :             if (m_clamp_requests<0)
     158                 :             {
     159               0 :                 CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of ClampRequests, true/false expected.");
     160               0 :                 ret = CE_Failure;
     161                 :             }
     162                 :         }
     163                 : 
     164              11 :         if (ret == CE_None)
     165                 :         {
     166              11 :             CPLXMLNode *data_window_node = CPLGetXMLNode(config, "DataWindow");
     167              11 :             if (data_window_node == NULL && m_bNeedsDataWindow)
     168                 :             {
     169               0 :                 CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: DataWindow missing.");
     170               0 :                 ret = CE_Failure;
     171                 :             }
     172                 :             else
     173                 :             {
     174              11 :                 CPLString osDefaultX0, osDefaultX1, osDefaultY0, osDefaultY1;
     175              11 :                 CPLString osDefaultTileCountX, osDefaultTileCountY, osDefaultTileLevel;
     176              11 :                 CPLString osDefaultOverviewCount;
     177              11 :                 osDefaultX0.Printf("%.8f", m_default_data_window.m_x0);
     178              11 :                 osDefaultX1.Printf("%.8f", m_default_data_window.m_x1);
     179              11 :                 osDefaultY0.Printf("%.8f", m_default_data_window.m_y0);
     180              11 :                 osDefaultY1.Printf("%.8f", m_default_data_window.m_y1);
     181              11 :                 osDefaultTileCountX.Printf("%d", m_default_tile_count_x);
     182              11 :                 osDefaultTileCountY.Printf("%d", m_default_tile_count_y);
     183              11 :                 if (m_default_data_window.m_tlevel >= 0)
     184               1 :                     osDefaultTileLevel.Printf("%d", m_default_data_window.m_tlevel);
     185              11 :                 if (m_default_overview_count >= 0)
     186               1 :                     osDefaultOverviewCount.Printf("%d", m_default_overview_count);
     187              11 :                 const char *overview_count = CPLGetXMLValue(config, "OverviewCount", osDefaultOverviewCount);
     188              11 :                 const char *ulx = CPLGetXMLValue(data_window_node, "UpperLeftX", osDefaultX0);
     189              11 :                 const char *uly = CPLGetXMLValue(data_window_node, "UpperLeftY", osDefaultY0);
     190              11 :                 const char *lrx = CPLGetXMLValue(data_window_node, "LowerRightX", osDefaultX1);
     191              11 :                 const char *lry = CPLGetXMLValue(data_window_node, "LowerRightY", osDefaultY1);
     192              11 :                 const char *sx = CPLGetXMLValue(data_window_node, "SizeX", "");
     193              11 :                 const char *sy = CPLGetXMLValue(data_window_node, "SizeY", "");
     194              11 :                 const char *tx = CPLGetXMLValue(data_window_node, "TileX", "0");
     195              11 :                 const char *ty = CPLGetXMLValue(data_window_node, "TileY", "0");
     196              11 :                 const char *tlevel = CPLGetXMLValue(data_window_node, "TileLevel", osDefaultTileLevel);
     197              11 :                 const char *str_tile_count_x = CPLGetXMLValue(data_window_node, "TileCountX", osDefaultTileCountX);
     198              11 :                 const char *str_tile_count_y = CPLGetXMLValue(data_window_node, "TileCountY", osDefaultTileCountY);
     199              11 :                 const char *y_origin = CPLGetXMLValue(data_window_node, "YOrigin", "default");
     200                 : 
     201              11 :                 if (ret == CE_None)
     202                 :                 {
     203              22 :                     if ((ulx[0] != '\0') && (uly[0] != '\0') && (lrx[0] != '\0') && (lry[0] != '\0'))
     204                 :                     {
     205              11 :                         m_data_window.m_x0 = atof(ulx);
     206              11 :                         m_data_window.m_y0 = atof(uly);
     207              11 :                         m_data_window.m_x1 = atof(lrx);
     208              11 :                         m_data_window.m_y1 = atof(lry);
     209                 :                     }
     210                 :                     else
     211                 :                     {
     212                 :                         CPLError(CE_Failure, CPLE_AppDefined,
     213               0 :                                  "GDALWMS: Mandatory elements of DataWindow missing: UpperLeftX, UpperLeftY, LowerRightX, LowerRightY.");
     214               0 :                         ret = CE_Failure;
     215                 :                     }
     216                 :                 }
     217                 : 
     218              11 :                 m_data_window.m_tlevel = atoi(tlevel);
     219                 : 
     220              11 :                 if (ret == CE_None)
     221                 :                 {
     222              16 :                     if ((sx[0] != '\0') && (sy[0] != '\0'))
     223                 :                     {
     224               5 :                         m_data_window.m_sx = atoi(sx);
     225               5 :                         m_data_window.m_sy = atoi(sy);
     226                 :                     }
     227              12 :                     else if ((tlevel[0] != '\0') && (str_tile_count_x[0] != '\0') && (str_tile_count_y[0] != '\0'))
     228                 :                     {
     229               6 :                         int tile_count_x = atoi(str_tile_count_x);
     230               6 :                         int tile_count_y = atoi(str_tile_count_y);
     231               6 :                         m_data_window.m_sx = tile_count_x * m_block_size_x * (1 << m_data_window.m_tlevel);
     232               6 :                         m_data_window.m_sy = tile_count_y * m_block_size_y * (1 << m_data_window.m_tlevel);
     233                 :                     }
     234                 :                     else
     235                 :                     {
     236                 :                         CPLError(CE_Failure, CPLE_AppDefined,
     237               0 :                                  "GDALWMS: Mandatory elements of DataWindow missing: SizeX, SizeY.");
     238               0 :                         ret = CE_Failure;
     239                 :                     }
     240                 :                 }
     241              11 :                 if (ret == CE_None)
     242                 :                 {
     243              22 :                     if ((tx[0] != '\0') && (ty[0] != '\0'))
     244                 :                     {
     245              11 :                         m_data_window.m_tx = atoi(tx);
     246              11 :                         m_data_window.m_ty = atoi(ty);
     247                 :                     }
     248                 :                     else
     249                 :                     {
     250                 :                         CPLError(CE_Failure, CPLE_AppDefined,
     251               0 :                                  "GDALWMS: Mandatory elements of DataWindow missing: TileX, TileY.");
     252               0 :                         ret = CE_Failure;
     253                 :                     }
     254                 :                 }
     255                 : 
     256              11 :                 if (ret == CE_None)
     257                 :                 {
     258              11 :                     if (overview_count[0] != '\0')
     259                 :                     {
     260               4 :                         nOverviews = atoi(overview_count);
     261                 :                     }
     262               7 :                     else if (tlevel[0] != '\0')
     263                 :                     {
     264               6 :                         nOverviews = m_data_window.m_tlevel;
     265                 :                     }
     266                 :                     else
     267                 :                     {
     268               1 :                         const int min_overview_size = MAX(32, MIN(m_block_size_x, m_block_size_y));
     269                 :                         double a = log(static_cast<double>(MIN(m_data_window.m_sx, m_data_window.m_sy))) / log(2.0)
     270               1 :                             - log(static_cast<double>(min_overview_size)) / log(2.0);
     271               1 :                         nOverviews = MAX(0, MIN(static_cast<int>(ceil(a)), 32));
     272                 :                     }
     273                 :                 }
     274              11 :                 if (ret == CE_None)
     275                 :                 {
     276              11 :                     CPLString y_origin_str = y_origin;
     277              11 :                     if (y_origin_str == "top") {
     278               2 :                         m_data_window.m_y_origin = GDALWMSDataWindow::TOP;
     279               9 :                     } else if (y_origin_str == "bottom") {
     280               0 :                         m_data_window.m_y_origin = GDALWMSDataWindow::BOTTOM;
     281               9 :                     } else if (y_origin_str == "default") {
     282               9 :                         m_data_window.m_y_origin = GDALWMSDataWindow::DEFAULT;
     283                 :                     } else {
     284                 :                         CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: DataWindow YOrigin must be set to "
     285               0 :                             "one of 'default', 'top', or 'bottom', not '%s'.", y_origin_str.c_str());
     286               0 :                         ret = CE_Failure;
     287              11 :                     }
     288              11 :                 }
     289                 :             }
     290                 :         }
     291                 : 
     292              11 :         if (ret == CE_None)
     293                 :         {
     294              11 :             if (nBands<1)
     295              11 :                 nBands=atoi(CPLGetXMLValue(config,"BandsCount","3"));
     296              11 :             if (nBands<1)
     297                 :             {
     298                 :                 CPLError(CE_Failure, CPLE_AppDefined,
     299               0 :                          "GDALWMS: Bad number of bands.");
     300               0 :                 ret = CE_Failure;
     301                 :             }
     302                 :         }
     303                 : 
     304              11 :         if (ret == CE_None)
     305                 :         {
     306              11 :             const char *data_type = CPLGetXMLValue(config, "DataType", "Byte");
     307              11 :             m_data_type = GDALGetDataTypeByName( data_type );
     308              11 :             if ( m_data_type == GDT_Unknown || m_data_type >= GDT_TypeCount )
     309                 :             {
     310                 :                 CPLError( CE_Failure, CPLE_AppDefined,
     311               0 :                           "GDALWMS: Invalid value in DataType. Data type \"%s\" is not supported.", data_type );
     312               0 :                 ret = CE_Failure;
     313                 :             }
     314                 :         }
     315                 : 
     316                 :         // Initialize the bands and the overviews.  Assumes overviews are powers of two
     317              11 :         if (ret == CE_None)
     318                 :         {
     319              11 :             nRasterXSize = m_data_window.m_sx;
     320              11 :             nRasterYSize = m_data_window.m_sy;
     321                 : 
     322              11 :             if (!GDALCheckDatasetDimensions(nRasterXSize, nRasterYSize) ||
     323                 :                 !GDALCheckBandCount(nBands, TRUE))
     324                 :             {
     325               0 :                 return CE_Failure;
     326                 :             }
     327                 : 
     328                 :             GDALColorInterp default_color_interp[4][4] = {
     329                 :                 { GCI_GrayIndex, GCI_Undefined, GCI_Undefined, GCI_Undefined },
     330                 :                 { GCI_GrayIndex, GCI_AlphaBand, GCI_Undefined, GCI_Undefined },
     331                 :                 { GCI_RedBand, GCI_GreenBand, GCI_BlueBand, GCI_Undefined },
     332                 :                 { GCI_RedBand, GCI_GreenBand, GCI_BlueBand, GCI_AlphaBand }
     333              11 :             };
     334              44 :             for (int i = 0; i < nBands; ++i)
     335                 :             {
     336              33 :                 GDALColorInterp color_interp = (nBands <= 4 && i <= 3 ? default_color_interp[nBands - 1][i] : GCI_Undefined);
     337              33 :                 GDALWMSRasterBand *band = new GDALWMSRasterBand(this, i, 1.0);
     338              33 :                 band->m_color_interp = color_interp;
     339              33 :                 SetBand(i + 1, band);
     340              33 :                 double scale = 0.5;
     341             630 :                 for (int j = 0; j < nOverviews; ++j)
     342                 :                 {
     343             597 :                     band->AddOverview(scale);
     344             597 :                     band->m_color_interp = color_interp;
     345             597 :                     scale *= 0.5;
     346                 :                 }
     347                 :             }
     348                 :         }
     349                 :     }
     350                 : 
     351              14 :     const char *pszUserAgent = CPLGetXMLValue(config, "UserAgent", "");
     352              14 :     if (pszUserAgent[0] != '\0')
     353               0 :         m_osUserAgent = pszUserAgent;
     354                 :     
     355              14 :     const char *pszReferer = CPLGetXMLValue(config, "Referer", "");
     356              14 :     if (pszReferer[0] != '\0')
     357               0 :         m_osReferer = pszReferer;
     358                 :     
     359              14 :     if (ret == CE_None) {
     360              14 :         const char *pszHttpZeroBlockCodes = CPLGetXMLValue(config, "ZeroBlockHttpCodes", "");
     361              14 :         if(pszHttpZeroBlockCodes == '\0') {
     362               0 :             m_http_zeroblock_codes.push_back(204);
     363                 :         } else {
     364              14 :             char **kv = CSLTokenizeString2(pszHttpZeroBlockCodes,",",CSLT_HONOURSTRINGS);
     365              14 :             int nCount = CSLCount(kv);
     366              14 :             for(int i=0; i<nCount; i++) {
     367               0 :                 int code = atoi(kv[i]);
     368               0 :                 if(code <= 0) {
     369                 :                     CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of ZeroBlockHttpCodes \"%s\", comma separated HTTP response codes expected.",
     370               0 :                             kv[i]);
     371               0 :                     ret = CE_Failure;
     372               0 :                     break;
     373                 :                 }
     374               0 :                 m_http_zeroblock_codes.push_back(code);
     375                 :             }
     376              14 :             CSLDestroy(kv);
     377                 :         }
     378                 :     }
     379                 : 
     380              14 :     if (ret == CE_None) {
     381              14 :         const char *pszZeroExceptions = CPLGetXMLValue(config, "ZeroBlockOnServerException", "");
     382              14 :         if(pszZeroExceptions[0] != '\0') {
     383               0 :             m_zeroblock_on_serverexceptions = StrToBool(pszZeroExceptions);
     384               0 :             if (m_zeroblock_on_serverexceptions == -1) {
     385                 :                 CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of ZeroBlockOnServerException \"%s\", true/false expected.",
     386               0 :                      pszZeroExceptions);
     387               0 :                 ret = CE_Failure;
     388                 :             }
     389                 :         }
     390                 :     }
     391                 : 
     392              14 :     if (ret == CE_None) {
     393              14 :         const char *max_conn = CPLGetXMLValue(config, "MaxConnections", "");
     394              14 :         if (max_conn[0] != '\0') {
     395               0 :             m_http_max_conn = atoi(max_conn);
     396                 :         } else {
     397              14 :             m_http_max_conn = 2;
     398                 :         }
     399                 :     }
     400              14 :     if (ret == CE_None) {
     401              14 :         const char *timeout = CPLGetXMLValue(config, "Timeout", "");
     402              14 :         if (timeout[0] != '\0') {
     403               0 :             m_http_timeout = atoi(timeout);
     404                 :         } else {
     405              14 :             m_http_timeout = 300;
     406                 :         }
     407                 :     }
     408              14 :     if (ret == CE_None) {
     409              14 :         const char *offline_mode = CPLGetXMLValue(config, "OfflineMode", "");
     410              14 :         if (offline_mode[0] != '\0') {
     411               0 :             const int offline_mode_bool = StrToBool(offline_mode);
     412               0 :             if (offline_mode_bool == -1) {
     413               0 :                 CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of OfflineMode, true / false expected.");
     414               0 :                 ret = CE_Failure;
     415                 :             } else {
     416               0 :                 m_offline_mode = offline_mode_bool;
     417                 :             }
     418                 :         } else {
     419              14 :             m_offline_mode = 0;
     420                 :         }
     421                 :     }
     422                 : 
     423              14 :     if (ret == CE_None) {
     424              14 :         const char *advise_read = CPLGetXMLValue(config, "AdviseRead", "");
     425              14 :         if (advise_read[0] != '\0') {
     426               0 :             const int advise_read_bool = StrToBool(advise_read);
     427               0 :             if (advise_read_bool == -1) {
     428               0 :                 CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of AdviseRead, true / false expected.");
     429               0 :                 ret = CE_Failure;
     430                 :             } else {
     431               0 :                 m_use_advise_read = advise_read_bool;
     432                 :             }
     433                 :         } else {
     434              14 :             m_use_advise_read = 0;
     435                 :         }
     436                 :     }
     437                 : 
     438              14 :     if (ret == CE_None) {
     439              14 :         const char *verify_advise_read = CPLGetXMLValue(config, "VerifyAdviseRead", "");
     440              14 :         if (m_use_advise_read) {
     441               0 :             if (verify_advise_read[0] != '\0') {
     442               0 :                 const int verify_advise_read_bool = StrToBool(verify_advise_read);
     443               0 :                 if (verify_advise_read_bool == -1) {
     444               0 :                     CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of VerifyAdviseRead, true / false expected.");
     445               0 :                     ret = CE_Failure;
     446                 :                 } else {
     447               0 :                     m_verify_advise_read = verify_advise_read_bool;
     448                 :                 }
     449                 :             } else {
     450               0 :                 m_verify_advise_read = 1;
     451                 :             }
     452                 :         }
     453                 :     }
     454                 : 
     455                 :     // Let the local configuration override the minidriver supplied projection
     456                 : 
     457              14 :     if (ret == CE_None) {
     458              14 :         const char *proj = CPLGetXMLValue(config, "Projection", "");
     459              14 :         if (proj[0] != '\0') {
     460               8 :             m_projection = ProjToWKT(proj);
     461               8 :             if (m_projection.size() == 0) {
     462               0 :                 CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Bad projection specified.");
     463               0 :                 ret = CE_Failure;
     464                 :             }
     465                 :         }
     466                 :     }
     467                 : 
     468                 :     // Same for Min, Max and NoData, defined per band or per dataset
     469                 :     // If they are set as null strings, they clear the server declared values
     470              14 :     if (ret == CE_None) {
     471                 :        // Data values are attributes, they include NoData Min and Max
     472                 :        // TODO: document those options
     473              14 :        if (0!=CPLGetXMLNode(config,"DataValues")) {
     474               0 :            const char *nodata=CPLGetXMLValue(config,"DataValues.NoData",NULL);
     475               0 :            if (nodata!=NULL) WMSSetNoDataValue(nodata);
     476               0 :            const char *min=CPLGetXMLValue(config,"DataValues.min",NULL);
     477               0 :            if (min!=NULL) WMSSetMinValue(min);
     478               0 :            const char *max=CPLGetXMLValue(config,"DataValues.max",NULL);
     479               0 :            if (max!=NULL) WMSSetMaxValue(max);
     480                 :        }
     481                 :     }
     482                 : 
     483              14 :     if (ret == CE_None) {
     484              14 :         CPLXMLNode *cache_node = CPLGetXMLNode(config, "Cache");
     485              14 :         if (cache_node != NULL) {
     486               4 :             m_cache = new GDALWMSCache();
     487               4 :             if (m_cache->Initialize(cache_node) != CE_None) {
     488               0 :                 delete m_cache;
     489               0 :                 m_cache = NULL;
     490               0 :                 CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Failed to initialize cache.");
     491               0 :                 ret = CE_Failure;
     492                 :             }
     493                 :         }
     494                 :     }
     495                 :     
     496              14 :     if (ret == CE_None) {
     497              14 :       const int v = StrToBool(CPLGetXMLValue(config, "UnsafeSSL", "false"));
     498              14 :       if (v == -1) {
     499               0 :       CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of UnsafeSSL: true or false expected.");
     500               0 :       ret = CE_Failure;
     501                 :   } else {
     502              14 :       m_unsafeSsl = v;
     503                 :   }
     504                 :     }
     505                 : 
     506              14 :     if (ret == CE_None) {
     507                 :         /* If we dont have projection already set ask mini-driver. */
     508              14 :         if (!m_projection.size()) {
     509               6 :             const char *proj = m_mini_driver->GetProjectionInWKT();
     510               6 :             if (proj != NULL) {
     511               6 :                 m_projection = proj;
     512                 :             }
     513                 :         }
     514                 :     }
     515                 : 
     516              14 :     return ret;
     517                 : }
     518                 : 
     519               1 : CPLErr GDALWMSDataset::IRasterIO(GDALRWFlag rw, int x0, int y0, int sx, int sy, void *buffer, int bsx, int bsy, GDALDataType bdt, int band_count, int *band_map, int pixel_space, int line_space, int band_space) {
     520                 :     CPLErr ret;
     521                 : 
     522               1 :     if (rw != GF_Read) return CE_Failure;
     523               1 :     if (buffer == NULL) return CE_Failure;
     524               1 :     if ((sx == 0) || (sy == 0) || (bsx == 0) || (bsy == 0) || (band_count == 0)) return CE_None;
     525                 : 
     526               1 :     m_hint.m_x0 = x0;
     527               1 :     m_hint.m_y0 = y0;
     528               1 :     m_hint.m_sx = sx;
     529               1 :     m_hint.m_sy = sy;
     530               1 :     m_hint.m_overview = -1;
     531               1 :     m_hint.m_valid = true;
     532                 :     //  printf("[%p] GDALWMSDataset::IRasterIO(x0: %d, y0: %d, sx: %d, sy: %d, bsx: %d, bsy: %d, band_count: %d, band_map: %p)\n", this, x0, y0, sx, sy, bsx, bsy, band_count, band_map);
     533               1 :     ret = GDALDataset::IRasterIO(rw, x0, y0, sx, sy, buffer, bsx, bsy, bdt, band_count, band_map, pixel_space, line_space, band_space);
     534               1 :     m_hint.m_valid = false;
     535                 : 
     536               1 :     return ret;
     537                 : }
     538                 : 
     539               2 : const char *GDALWMSDataset::GetProjectionRef() {
     540               2 :     return m_projection.c_str();
     541                 : }
     542                 : 
     543               0 : CPLErr GDALWMSDataset::SetProjection(const char *proj) {
     544               0 :     return CE_Failure;
     545                 : }
     546                 : 
     547               7 : CPLErr GDALWMSDataset::GetGeoTransform(double *gt) {
     548               7 :     gt[0] = m_data_window.m_x0;
     549               7 :     gt[1] = (m_data_window.m_x1 - m_data_window.m_x0) / static_cast<double>(m_data_window.m_sx);
     550               7 :     gt[2] = 0.0;
     551               7 :     gt[3] = m_data_window.m_y0;
     552               7 :     gt[4] = 0.0;
     553               7 :     gt[5] = (m_data_window.m_y1 - m_data_window.m_y0) / static_cast<double>(m_data_window.m_sy);
     554               7 :     return CE_None;
     555                 : }
     556                 : 
     557               0 : CPLErr GDALWMSDataset::SetGeoTransform(double *gt) {
     558               0 :     return CE_Failure;
     559                 : }
     560                 : 
     561               6 : const GDALWMSDataWindow *GDALWMSDataset::WMSGetDataWindow() const {
     562               6 :     return &m_data_window;
     563                 : }
     564                 : 
     565               3 : void GDALWMSDataset::WMSSetBlockSize(int x, int y) {
     566               3 :     m_block_size_x=x;
     567               3 :     m_block_size_y=y;
     568               3 : }
     569                 : 
     570               3 : void GDALWMSDataset::WMSSetRasterSize(int x, int y) {
     571               3 :     nRasterXSize=x;
     572               3 :     nRasterYSize=y;
     573               3 : }
     574                 : 
     575               3 : void GDALWMSDataset::WMSSetBandsCount(int count) {
     576               3 :     nBands=count;
     577               3 : }
     578                 : 
     579               3 : void GDALWMSDataset::WMSSetClamp(bool flag=true) {
     580               3 :     m_clamp_requests=flag;
     581               3 : }
     582                 : 
     583               3 : void GDALWMSDataset::WMSSetDataType(GDALDataType type) {
     584               3 :     m_data_type=type;
     585               3 : }
     586                 : 
     587               3 : void GDALWMSDataset::WMSSetDataWindow(GDALWMSDataWindow &window) {
     588               3 :     m_data_window=window;
     589               3 : }
     590                 : 
     591               1 : void GDALWMSDataset::WMSSetDefaultBlockSize(int x, int y) {
     592               1 :     m_default_block_size_x=x;
     593               1 :     m_default_block_size_y=y;
     594               1 : }
     595                 : 
     596               1 : void GDALWMSDataset::WMSSetDefaultDataWindowCoordinates(double x0, double y0, double x1, double y1)
     597                 : {
     598               1 :     m_default_data_window.m_x0 = x0;
     599               1 :     m_default_data_window.m_y0 = y0;
     600               1 :     m_default_data_window.m_x1 = x1;
     601               1 :     m_default_data_window.m_y1 = y1;
     602               1 : }
     603                 : 
     604               0 : void GDALWMSDataset::WMSSetDefaultTileCount(int tilecountx, int tilecounty)
     605                 : {
     606               0 :     m_default_tile_count_x = tilecountx;
     607               0 :     m_default_tile_count_y = tilecounty;
     608               0 : }
     609                 : 
     610               1 : void GDALWMSDataset::WMSSetDefaultTileLevel(int tlevel)
     611                 : {
     612               1 :     m_default_data_window.m_tlevel = tlevel;
     613               1 : }
     614                 : 
     615               1 : void GDALWMSDataset::WMSSetDefaultOverviewCount(int overview_count)
     616                 : {
     617               1 :     m_default_overview_count = overview_count;
     618               1 : }
     619                 : 
     620               1 : void GDALWMSDataset::WMSSetNeedsDataWindow(int flag)
     621                 : {
     622               1 :     m_bNeedsDataWindow = flag;
     623               1 : }
     624                 : 
     625               2 : static void list2vec(std::vector<double> &v,const char *pszList)
     626                 : {
     627               2 :     if ((pszList==NULL)||(pszList[0]==0)) return;
     628                 :     char **papszTokens=CSLTokenizeString2(pszList," \t\n\r",
     629               2 :         CSLT_STRIPLEADSPACES|CSLT_STRIPENDSPACES);
     630               2 :     v.clear();
     631               4 :     for (int i=0;i<CSLCount(papszTokens);i++)
     632               2 :         v.push_back(CPLStrtod(papszTokens[i],NULL));
     633               2 :     CSLDestroy(papszTokens);
     634                 : }
     635                 : 
     636               0 : void GDALWMSDataset::WMSSetNoDataValue(const char * pszNoData)
     637                 : {
     638               0 :     list2vec(vNoData,pszNoData);
     639               0 : }
     640                 : 
     641               1 : void GDALWMSDataset::WMSSetMinValue(const char * pszMin)
     642                 : {
     643               1 :     list2vec(vMin,pszMin);
     644               1 : }
     645                 : 
     646               1 : void GDALWMSDataset::WMSSetMaxValue(const char * pszMax)
     647                 : {
     648               1 :     list2vec(vMax,pszMax);
     649               1 : }
     650                 : 
     651               0 : CPLErr GDALWMSDataset::AdviseRead(int x0, int y0, int sx, int sy, int bsx, int bsy, GDALDataType bdt, int band_count, int *band_map, char **options) {
     652                 : //    printf("AdviseRead(%d, %d, %d, %d)\n", x0, y0, sx, sy);
     653               0 :     if (m_offline_mode || !m_use_advise_read) return CE_None;
     654               0 :     if (m_cache == NULL) return CE_Failure;
     655                 : 
     656               0 :     GDALRasterBand *band = GetRasterBand(1);
     657               0 :     if (band == NULL) return CE_Failure;
     658               0 :     return band->AdviseRead(x0, y0, sx, sy, bsx, bsy, bdt, options);
     659                 : }
     660                 : 
     661               1 : const char *GDALWMSDataset::GetMetadataItem( const char * pszName,
     662                 :                                              const char * pszDomain )
     663                 : {
     664               1 :     if( pszName != NULL && EQUAL(pszName, "XML") &&
     665                 :         pszDomain != NULL && EQUAL(pszDomain, "WMS") )
     666                 :     {
     667               1 :         return (m_osXML.size()) ? m_osXML.c_str() : NULL;
     668                 :     }
     669                 : 
     670               0 :     return GDALPamDataset::GetMetadataItem(pszName, pszDomain);
     671                 : }

Generated by: LCOV version 1.7