LTP GCOV extension - code coverage report
Current view: directory - frmts/wms - dataset.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 245
Code covered: 64.5 % Executed lines: 158

       1                 : /******************************************************************************
       2                 :  * $Id: dataset.cpp 19089 2010-03-15 13:20:41Z nowakpl $
       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                 : #include "stdinc.h"
      32                 : 
      33               5 : GDALWMSDataset::GDALWMSDataset() {
      34               5 :     m_mini_driver = 0;
      35               5 :     m_cache = 0;
      36               5 :     m_hint.m_valid = false;
      37               5 :     m_data_type = GDT_Byte;
      38               5 :     m_clamp_requests = true;
      39               5 : }
      40                 : 
      41               5 : GDALWMSDataset::~GDALWMSDataset() {
      42               5 :     if (m_mini_driver) delete m_mini_driver;
      43               5 :     if (m_cache) delete m_cache;
      44               5 : }
      45               5 : CPLErr GDALWMSDataset::Initialize(CPLXMLNode *config) {
      46               5 :     CPLErr ret = CE_None;
      47                 : 
      48               5 :     const char *pszUserAgent = CPLGetXMLValue(config, "UserAgent", "");
      49               5 :     if (pszUserAgent[0] != '\0')
      50               0 :         m_osUserAgent = pszUserAgent;
      51                 : 
      52               5 :     if (ret == CE_None) {
      53               5 :         const char *max_conn = CPLGetXMLValue(config, "MaxConnections", "");
      54               5 :         if (max_conn[0] != '\0') {
      55               0 :             m_http_max_conn = atoi(max_conn);
      56                 :         } else {
      57               5 :             m_http_max_conn = 2;
      58                 :         }
      59                 :     }
      60               5 :     if (ret == CE_None) {
      61               5 :         const char *timeout = CPLGetXMLValue(config, "Timeout", "");
      62               5 :         if (timeout[0] != '\0') {
      63               0 :             m_http_timeout = atoi(timeout);
      64                 :         } else {
      65               5 :             m_http_timeout = 300;
      66                 :         }
      67                 :     }
      68               5 :     if (ret == CE_None) {
      69               5 :         const char *offline_mode = CPLGetXMLValue(config, "OfflineMode", "");
      70               5 :         if (offline_mode[0] != '\0') {
      71               0 :             const int offline_mode_bool = StrToBool(offline_mode);
      72               0 :             if (offline_mode_bool == -1) {
      73               0 :                 CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of OfflineMode, true / false expected.");
      74               0 :                 ret = CE_Failure;
      75                 :             } else {
      76               0 :                 m_offline_mode = offline_mode_bool;
      77                 :             }
      78                 :         } else {
      79               5 :             m_offline_mode = 0;
      80                 :         }
      81                 :     }
      82               5 :     if (ret == CE_None) {
      83               5 :         const char *advise_read = CPLGetXMLValue(config, "AdviseRead", "");
      84               5 :         if (advise_read[0] != '\0') {
      85               0 :             const int advise_read_bool = StrToBool(advise_read);
      86               0 :             if (advise_read_bool == -1) {
      87               0 :                 CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of AdviseRead, true / false expected.");
      88               0 :                 ret = CE_Failure;
      89                 :             } else {
      90               0 :                 m_use_advise_read = advise_read_bool;
      91                 :             }
      92                 :         } else {
      93               5 :             m_use_advise_read = 0;
      94                 :         }
      95                 :     }
      96               5 :     if (ret == CE_None) {
      97               5 :         const char *verify_advise_read = CPLGetXMLValue(config, "VerifyAdviseRead", "");
      98               5 :         if (m_use_advise_read) {
      99               0 :             if (verify_advise_read[0] != '\0') {
     100               0 :                 const int verify_advise_read_bool = StrToBool(verify_advise_read);
     101               0 :                 if (verify_advise_read_bool == -1) {
     102               0 :                     CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of VerifyAdviseRead, true / false expected.");
     103               0 :                     ret = CE_Failure;
     104                 :                 } else {
     105               0 :                     m_verify_advise_read = verify_advise_read_bool;
     106                 :                 }
     107                 :             } else {
     108               0 :                 m_verify_advise_read = 1;
     109                 :             }
     110                 :         }
     111                 :     }
     112               5 :     if (ret == CE_None) {
     113               5 :         const char *block_size_x = CPLGetXMLValue(config, "BlockSizeX", "1024");
     114               5 :         const char *block_size_y = CPLGetXMLValue(config, "BlockSizeY", "1024");
     115               5 :         m_block_size_x = atoi(block_size_x);
     116               5 :         m_block_size_y = atoi(block_size_y);
     117               5 :         if (m_block_size_x <= 0 || m_block_size_y <= 0)
     118                 :         {
     119                 :             CPLError( CE_Failure, CPLE_AppDefined,
     120               0 :                       "GDALWMS: Invalid value in BlockSizeX or BlockSizeY" );
     121               0 :             ret = CE_Failure;
     122                 :         }
     123                 :     }
     124               5 :     if (ret == CE_None)
     125                 :     {
     126               5 :         const char *data_type = CPLGetXMLValue(config, "DataType", "Byte");
     127               5 :         m_data_type = GDALGetDataTypeByName( data_type );
     128               5 :         if ( m_data_type == GDT_Unknown || m_data_type >= GDT_TypeCount )
     129                 :         {
     130                 :             CPLError( CE_Failure, CPLE_AppDefined,
     131               0 :                       "GDALWMS: Invalid value in DataType. Data type \"%s\" is not supported.", data_type );
     132               0 :             ret = CE_Failure;
     133                 :         }
     134                 :     }
     135               5 :     if (ret == CE_None) {
     136               5 :       const int clamp_requests_bool = StrToBool(CPLGetXMLValue(config, "ClampRequests", "true"));
     137               5 :       if (clamp_requests_bool == -1) {
     138               0 :       CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of ClampRequests, true / false expected.");
     139               0 :       ret = CE_Failure;
     140                 :   } else {
     141               5 :       m_clamp_requests = clamp_requests_bool;
     142                 :   }
     143                 :     }
     144               5 :     if (ret == CE_None) {
     145               5 :         CPLXMLNode *data_window_node = CPLGetXMLNode(config, "DataWindow");
     146               5 :         if (data_window_node == NULL) {
     147               0 :             CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: DataWindow missing.");
     148               0 :             ret = CE_Failure;
     149                 :         } else {
     150               5 :             const char *overview_count = CPLGetXMLValue(config, "OverviewCount", "");
     151               5 :             const char *ulx = CPLGetXMLValue(data_window_node, "UpperLeftX", "-180.0");
     152               5 :             const char *uly = CPLGetXMLValue(data_window_node, "UpperLeftY", "90.0");
     153               5 :             const char *lrx = CPLGetXMLValue(data_window_node, "LowerRightX", "180.0");
     154               5 :             const char *lry = CPLGetXMLValue(data_window_node, "LowerRightY", "-90.0");
     155               5 :             const char *sx = CPLGetXMLValue(data_window_node, "SizeX", "");
     156               5 :             const char *sy = CPLGetXMLValue(data_window_node, "SizeY", "");
     157               5 :             const char *tx = CPLGetXMLValue(data_window_node, "TileX", "0");
     158               5 :             const char *ty = CPLGetXMLValue(data_window_node, "TileY", "0");
     159               5 :             const char *tlevel = CPLGetXMLValue(data_window_node, "TileLevel", "");
     160               5 :             const char *str_tile_count_x = CPLGetXMLValue(data_window_node, "TileCountX", "1");
     161               5 :             const char *str_tile_count_y = CPLGetXMLValue(data_window_node, "TileCountY", "1");
     162               5 :             const char *y_origin = CPLGetXMLValue(data_window_node, "YOrigin", "default");
     163                 : 
     164               5 :             if (ret == CE_None) {
     165              10 :                 if ((ulx[0] != '\0') && (uly[0] != '\0') && (lrx[0] != '\0') && (lry[0] != '\0')) {
     166               5 :                     m_data_window.m_x0 = atof(ulx);
     167               5 :                     m_data_window.m_y0 = atof(uly);
     168               5 :                     m_data_window.m_x1 = atof(lrx);
     169               5 :                     m_data_window.m_y1 = atof(lry);
     170                 :                 } else {
     171               0 :                     CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Mandatory elements of DataWindow missing: UpperLeftX, UpperLeftY, LowerRightX, LowerRightY.");
     172               0 :                     ret = CE_Failure;
     173                 :                 }
     174                 :             }
     175               5 :             if (ret == CE_None) {
     176               5 :                 if (tlevel[0] != '\0') {
     177               3 :                     m_data_window.m_tlevel = atoi(tlevel);
     178                 :                 } else {
     179               2 :                     m_data_window.m_tlevel = 0;
     180                 :                 }
     181                 :             }
     182               5 :             if (ret == CE_None) {
     183               8 :                 if ((sx[0] != '\0') && (sy[0] != '\0')) {
     184               3 :                     m_data_window.m_sx = atoi(sx);
     185               3 :                     m_data_window.m_sy = atoi(sy);
     186               4 :                 } else if ((tlevel[0] != '\0') && (str_tile_count_x[0] != '\0') && (str_tile_count_y[0] != '\0')) {
     187               2 :                     int tile_count_x = atoi(str_tile_count_x);
     188               2 :                     int tile_count_y = atoi(str_tile_count_y);
     189               2 :                     m_data_window.m_sx = tile_count_x * m_block_size_x * (1 << m_data_window.m_tlevel);
     190               2 :                     m_data_window.m_sy = tile_count_y * m_block_size_y * (1 << m_data_window.m_tlevel);
     191                 :                 } else {
     192               0 :                     CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Mandatory elements of DataWindow missing: SizeX, SizeY.");
     193               0 :                     ret = CE_Failure;
     194                 :                 }
     195                 :             }
     196               5 :             if (ret == CE_None) {
     197              10 :                 if ((tx[0] != '\0') && (ty[0] != '\0')) {
     198               5 :                     m_data_window.m_tx = atoi(tx);
     199               5 :                     m_data_window.m_ty = atoi(ty);
     200                 :                 } else {
     201               0 :                     CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Mandatory elements of DataWindow missing: TileX, TileY.");
     202               0 :                     ret = CE_Failure;
     203                 :                 }
     204                 :             }
     205               5 :             if (ret == CE_None) {
     206               5 :                 if (overview_count[0] != '\0') {
     207               1 :                     m_overview_count = atoi(overview_count);
     208               4 :                 } else if (tlevel[0] != '\0') {
     209               2 :                     m_overview_count = m_data_window.m_tlevel;
     210                 :                 } else {
     211               2 :                     const int min_overview_size = MAX(32, MIN(m_block_size_x, m_block_size_y));
     212                 :                     double a = log(static_cast<double>(MIN(m_data_window.m_sx, m_data_window.m_sy))) / log(2.0) 
     213               2 :                                 - log(static_cast<double>(min_overview_size)) / log(2.0);
     214               2 :                     m_overview_count = MAX(0, MIN(static_cast<int>(ceil(a)), 32));
     215                 :                 }
     216                 :             }
     217               5 :             if (ret == CE_None) {
     218               5 :                 CPLString y_origin_str = y_origin;
     219               5 :                 if (y_origin_str == "top") {
     220               0 :                     m_data_window.m_y_origin = GDALWMSDataWindow::TOP;
     221               5 :                 } else if (y_origin_str == "bottom") {
     222               0 :                     m_data_window.m_y_origin = GDALWMSDataWindow::BOTTOM;
     223               5 :                 } else if (y_origin_str == "default") {
     224               5 :                     m_data_window.m_y_origin = GDALWMSDataWindow::DEFAULT;
     225                 :                 } else {
     226                 :                     CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: DataWindow YOrigin must be set to " 
     227               0 :                                 "one of 'default', 'top', or 'bottom', not '%s'.", y_origin_str.c_str());
     228               0 :                     ret = CE_Failure;
     229               5 :                 }
     230                 :             }
     231                 :         }
     232                 :     }
     233               5 :     if (ret == CE_None) {
     234               5 :         const char *proj = CPLGetXMLValue(config, "Projection", "");
     235               5 :         if (proj[0] != '\0') {
     236               5 :             m_projection = ProjToWKT(proj);
     237               5 :             if (m_projection.size() == 0) {
     238               0 :                 CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Bad projection specified.");
     239               0 :                 ret = CE_Failure;
     240                 :             }
     241                 :         }
     242                 :     }
     243                 :     
     244               5 :     const char *bands_count = CPLGetXMLValue(config, "BandsCount", "3");
     245               5 :     int nBandCount = atoi(bands_count);
     246                 :     
     247               5 :     if (ret == CE_None) {
     248               5 :         CPLXMLNode *cache_node = CPLGetXMLNode(config, "Cache");
     249               5 :         if (cache_node != NULL) {
     250               1 :             m_cache = new GDALWMSCache();
     251               1 :             if (m_cache->Initialize(cache_node) != CE_None) {
     252               0 :                 delete m_cache;
     253               0 :                 m_cache = NULL;
     254               0 :                 CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Failed to initialize cache.");
     255               0 :                 ret = CE_Failure;
     256                 :             }
     257                 :         }
     258                 :     }
     259               5 :     if (ret == CE_None) {
     260               5 :         CPLXMLNode *service_node = CPLGetXMLNode(config, "Service");
     261               5 :         if (service_node != NULL) {
     262               5 :             const char *service_name = CPLGetXMLValue(service_node, "name", "");
     263               5 :             if (service_name[0] != '\0') {
     264               5 :                 GDALWMSMiniDriverManager *const mdm = GetGDALWMSMiniDriverManager();
     265               5 :                 GDALWMSMiniDriverFactory *const mdf = mdm->Find(CPLString(service_name));
     266               5 :                 if (mdf != NULL) {
     267               5 :                     m_mini_driver = mdf->New();
     268               5 :                     m_mini_driver->m_parent_dataset = this;
     269               5 :                     if (m_mini_driver->Initialize(service_node) == CE_None) {
     270               5 :                         m_mini_driver_caps.m_capabilities_version = -1;
     271               5 :                         m_mini_driver->GetCapabilities(&m_mini_driver_caps);
     272               5 :                         if (m_mini_driver_caps.m_capabilities_version == -1) {
     273               0 :                             CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Internal error, mini-driver capabilities version not set.");
     274               0 :                             ret = CE_Failure;
     275                 :                         }
     276                 :                     } else {
     277               0 :                         delete m_mini_driver;
     278               0 :                         m_mini_driver = NULL;
     279                 : 
     280               0 :                         CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Failed to initialize minidriver.");
     281               0 :                         ret = CE_Failure;
     282                 :                     }
     283                 :                 } else {
     284               0 :                     CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: No mini-driver registered for '%s'.", service_name);
     285               0 :                     ret = CE_Failure;
     286                 :                 }
     287                 :             } else {
     288               0 :                 CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: No Service specified.");
     289               0 :                 ret = CE_Failure;
     290                 :             }
     291                 :         } else {
     292               0 :             CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: No Service specified.");
     293               0 :             ret = CE_Failure;
     294                 :         }
     295                 :     }
     296               5 :     if (ret == CE_None) {
     297               5 :         nRasterXSize = m_data_window.m_sx;
     298               5 :         nRasterYSize = m_data_window.m_sy;
     299                 : 
     300               5 :         if (!GDALCheckDatasetDimensions(nRasterXSize, nRasterYSize) ||
     301                 :             !GDALCheckBandCount(nBandCount, TRUE))
     302                 :         {
     303               0 :             return CE_Failure;
     304                 :         }
     305                 : 
     306                 :         GDALColorInterp default_color_interp[4][4] = {
     307                 :             { GCI_GrayIndex, GCI_Undefined, GCI_Undefined, GCI_Undefined },
     308                 :             { GCI_GrayIndex, GCI_AlphaBand, GCI_Undefined, GCI_Undefined },
     309                 :             { GCI_RedBand, GCI_GreenBand, GCI_BlueBand, GCI_Undefined },
     310                 :             { GCI_RedBand, GCI_GreenBand, GCI_BlueBand, GCI_AlphaBand }
     311               5 :         };
     312              20 :         for (int i = 0; i < nBandCount; ++i) {
     313              15 :             GDALColorInterp color_interp = (nBandCount <= 4 && i <= 3 ? default_color_interp[nBandCount - 1][i] : GCI_Undefined);
     314              15 :             GDALWMSRasterBand *band = new GDALWMSRasterBand(this, i, 1.0);
     315              15 :             band->m_color_interp = color_interp;
     316              15 :             SetBand(i + 1, band);
     317              15 :             double scale = 0.5;
     318             222 :             for (int j = 0; j < m_overview_count; ++j) {
     319             207 :                 band->AddOverview(scale);
     320             207 :                 band->m_color_interp = color_interp;
     321             207 :                 scale *= 0.5;
     322                 :             }
     323                 :         }
     324                 :     }
     325                 : 
     326               5 :     if (ret == CE_None) {
     327                 :         /* If we dont have projection already set ask mini-driver. */
     328               5 :         if (!m_projection.size()) {
     329               0 :             const char *proj = m_mini_driver->GetProjectionInWKT();
     330               0 :             if (proj != NULL) {
     331               0 :                 m_projection = proj;
     332                 :             }
     333                 :         }
     334                 :     }
     335                 : 
     336               5 :     return ret;
     337                 : }
     338                 : 
     339               0 : 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) {
     340                 :     CPLErr ret;
     341                 : 
     342               0 :     if (rw != GF_Read) return CE_Failure;
     343               0 :     if (buffer == NULL) return CE_Failure;
     344               0 :     if ((sx == 0) || (sy == 0) || (bsx == 0) || (bsy == 0) || (band_count == 0)) return CE_None;
     345                 : 
     346               0 :     m_hint.m_x0 = x0;
     347               0 :     m_hint.m_y0 = y0;
     348               0 :     m_hint.m_sx = sx;
     349               0 :     m_hint.m_sy = sy;
     350               0 :     m_hint.m_overview = -1;
     351               0 :     m_hint.m_valid = true;
     352                 :     //  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);
     353               0 :     ret = GDALDataset::IRasterIO(rw, x0, y0, sx, sy, buffer, bsx, bsy, bdt, band_count, band_map, pixel_space, line_space, band_space);
     354               0 :     m_hint.m_valid = false;
     355                 : 
     356               0 :     return ret;
     357                 : }
     358                 : 
     359               1 : const char *GDALWMSDataset::GetProjectionRef() {
     360               1 :     return m_projection.c_str();
     361                 : }
     362                 : 
     363               0 : CPLErr GDALWMSDataset::SetProjection(const char *proj) {
     364               0 :     return CE_Failure;
     365                 : }
     366                 : 
     367               1 : CPLErr GDALWMSDataset::GetGeoTransform(double *gt) {
     368               1 :     gt[0] = m_data_window.m_x0;
     369               1 :     gt[1] = (m_data_window.m_x1 - m_data_window.m_x0) / static_cast<double>(m_data_window.m_sx);
     370               1 :     gt[2] = 0.0;
     371               1 :     gt[3] = m_data_window.m_y0;
     372               1 :     gt[4] = 0.0;
     373               1 :     gt[5] = (m_data_window.m_y1 - m_data_window.m_y0) / static_cast<double>(m_data_window.m_sy);
     374               1 :     return CE_None;
     375                 : }
     376                 : 
     377               0 : CPLErr GDALWMSDataset::SetGeoTransform(double *gt) {
     378               0 :     return CE_Failure;
     379                 : }
     380                 : 
     381               4 : const GDALWMSDataWindow *GDALWMSDataset::WMSGetDataWindow() const {
     382               4 :     return &m_data_window;
     383                 : }
     384                 : 
     385               0 : int GDALWMSDataset::WMSGetBlockSizeX() const {
     386               0 :     return m_block_size_x;
     387                 : }
     388                 : 
     389               0 : int GDALWMSDataset::WMSGetBlockSizeY() const {
     390               0 :     return m_block_size_y;
     391                 : }
     392                 : 
     393               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) {
     394                 : //    printf("AdviseRead(%d, %d, %d, %d)\n", x0, y0, sx, sy);
     395               0 :     if (m_offline_mode || !m_use_advise_read) return CE_None;
     396               0 :     if (m_cache == NULL) return CE_Failure;
     397                 : 
     398               0 :     GDALRasterBand *band = GetRasterBand(1);
     399               0 :     if (band == NULL) return CE_Failure;
     400               0 :     return band->AdviseRead(x0, y0, sx, sy, bsx, bsy, bdt, options);
     401                 : }

Generated by: LTP GCOV extension version 1.5