LCOV - code coverage report
Current view: directory - frmts/ogdi - ogdidataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 291 13 4.5 %
Date: 2012-04-28 Functions: 26 2 7.7 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogdidataset.cpp 20588 2010-09-12 16:29:21Z rouault $
       3                 :  *
       4                 :  * Name:     ogdidataset.cpp
       5                 :  * Project:  OGDI Bridge
       6                 :  * Purpose:  Main driver for OGDI.
       7                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       8                 :  *
       9                 :  ******************************************************************************
      10                 :  * Copyright (c) 1998, Frank Warmerdam
      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 <math.h>
      32                 : #include "ecs.h"
      33                 : #include "gdal_priv.h"
      34                 : #include "cpl_string.h"
      35                 : #include "ogr_spatialref.h"
      36                 : 
      37                 : CPL_CVSID("$Id: ogdidataset.cpp 20588 2010-09-12 16:29:21Z rouault $");
      38                 : 
      39                 : CPL_C_START
      40                 : void  GDALRegister_OGDI(void);
      41                 : CPL_C_END
      42                 : 
      43                 : /************************************************************************/
      44                 : /* ==================================================================== */
      45                 : /*        OGDIDataset       */
      46                 : /* ==================================================================== */
      47                 : /************************************************************************/
      48                 : 
      49                 : class OGDIRasterBand;
      50                 : 
      51                 : class CPL_DLL OGDIDataset : public GDALDataset
      52                 : {
      53                 :     friend class OGDIRasterBand;
      54                 :     
      55                 :     int   nClientID;
      56                 : 
      57                 :     ecs_Region  sGlobalBounds;
      58                 :     ecs_Region  sCurrentBounds;
      59                 :     int         nCurrentBand;
      60                 :     int         nCurrentIndex;
      61                 : 
      62                 :     char  *pszProjection;
      63                 : 
      64                 :     static CPLErr CollectLayers(int, char***,char***);
      65                 :     static CPLErr OverrideGlobalInfo(OGDIDataset*,const char *);
      66                 : 
      67                 :     void        AddSubDataset( const char *pszType, const char *pszLayer );
      68                 :     char  **papszSubDatasets;
      69                 : 
      70                 :   public:
      71                 :         OGDIDataset();
      72                 :         ~OGDIDataset();
      73                 :                 
      74                 :     static GDALDataset *Open( GDALOpenInfo * );
      75                 : 
      76                 :     int   GetClientID() { return nClientID; }
      77                 : 
      78                 :     virtual const char *GetProjectionRef(void);
      79                 :     virtual CPLErr GetGeoTransform( double * );
      80                 : 
      81                 :     virtual void *GetInternalHandle( const char * );
      82                 : 
      83                 :     virtual char **GetMetadata( const char * pszDomain = "" );
      84                 : };
      85                 : 
      86                 : /************************************************************************/
      87                 : /* ==================================================================== */
      88                 : /*                            OGDIRasterBand                             */
      89                 : /* ==================================================================== */
      90                 : /************************************************************************/
      91                 : 
      92                 : class OGDIRasterBand : public GDALRasterBand
      93                 : {
      94                 :     friend class OGDIDataset;
      95                 : 
      96                 :     int   nOGDIImageType; /* ie. 1 for RGB */
      97                 : 
      98                 :     char  *pszLayerName;
      99                 :     ecs_Family  eFamily;
     100                 : 
     101                 :     int   nComponent; /* varies only for RGB layers */
     102                 : 
     103                 :     GDALColorTable *poCT;
     104                 : 
     105                 :     virtual CPLErr IRasterIO( GDALRWFlag, int, int, int, int,
     106                 :                               void *, int, int, GDALDataType,
     107                 :                               int, int );
     108                 : 
     109                 :     CPLErr         EstablishAccess( int nXOff, int nYOff, 
     110                 :                                     int nXSize, int nYSize,
     111                 :                                     int nBufXSize, int nBufYSize );
     112                 : 
     113                 :   public:
     114                 : 
     115                 :                    OGDIRasterBand( OGDIDataset *, int, const char *,
     116                 :                                    ecs_Family, int );
     117                 :                    ~OGDIRasterBand();
     118                 : 
     119                 :     virtual CPLErr IReadBlock( int, int, void * );
     120                 :     virtual int    HasArbitraryOverviews();
     121                 :     virtual GDALColorInterp GetColorInterpretation();
     122                 :     virtual GDALColorTable *GetColorTable();
     123                 : 
     124                 :     virtual CPLErr AdviseRead( int nXOff, int nYOff, int nXSize, int nYSize,
     125                 :                                int nBufXSize, int nBufYSize, 
     126                 :                                GDALDataType eDT, char **papszOptions );
     127                 : 
     128                 : };
     129                 : 
     130                 : /************************************************************************/
     131                 : /*                           OGDIRasterBand()                            */
     132                 : /************************************************************************/
     133                 : 
     134               0 : OGDIRasterBand::OGDIRasterBand( OGDIDataset *poDS, int nBand, 
     135                 :                                 const char * pszName, ecs_Family eFamily,
     136               0 :                                 int nComponent )
     137                 : 
     138                 : {
     139                 :     ecs_Result  *psResult;
     140                 :     
     141               0 :     this->poDS = poDS;
     142               0 :     this->nBand = nBand;
     143               0 :     this->eFamily = eFamily;
     144               0 :     this->pszLayerName = CPLStrdup(pszName);
     145               0 :     this->nComponent = nComponent;
     146               0 :     poCT = NULL;
     147                 : 
     148                 : /* -------------------------------------------------------------------- */
     149                 : /*      Make this layer current.                                        */
     150                 : /* -------------------------------------------------------------------- */
     151                 :     EstablishAccess( 0, 0, 
     152                 :                      poDS->GetRasterXSize(), poDS->GetRasterYSize(), 
     153               0 :                      poDS->GetRasterXSize(), poDS->GetRasterYSize() );
     154                 : 
     155                 : /* -------------------------------------------------------------------- */
     156                 : /*      Get the raster info.                                            */
     157                 : /* -------------------------------------------------------------------- */
     158               0 :     psResult = cln_GetRasterInfo( poDS->nClientID );
     159               0 :     if( ECSERROR(psResult) )
     160                 :     {
     161                 :         CPLError( CE_Failure, CPLE_AppDefined,
     162               0 :                   "%s", psResult->message );
     163                 :     }
     164                 : 
     165                 : /* -------------------------------------------------------------------- */
     166                 : /*      Establish if we have meaningful colortable information.         */
     167                 : /* -------------------------------------------------------------------- */
     168               0 :     if( eFamily == Matrix )
     169                 :     {
     170                 :         int     i;
     171                 : 
     172               0 :         poCT = new GDALColorTable();
     173                 :         
     174               0 :         for( i = 0; i < (int) ECSRASTERINFO(psResult).cat.cat_len; i++ ) {
     175                 :             GDALColorEntry   sEntry;
     176                 : 
     177               0 :             sEntry.c1 = ECSRASTERINFO(psResult).cat.cat_val[i].r;
     178               0 :             sEntry.c2 = ECSRASTERINFO(psResult).cat.cat_val[i].g;
     179               0 :             sEntry.c3 = ECSRASTERINFO(psResult).cat.cat_val[i].b;
     180               0 :             sEntry.c4 = 255;
     181                 : 
     182               0 :             poCT->SetColorEntry( ECSRASTERINFO(psResult).cat.cat_val[i].no_cat, 
     183               0 :                                  &sEntry );
     184                 :         }
     185                 :     }
     186                 :     
     187                 : /* -------------------------------------------------------------------- */
     188                 : /*      Get the GDAL data type.  Eventually we might use the            */
     189                 : /*      category info to establish what to do here.                     */
     190                 : /* -------------------------------------------------------------------- */
     191               0 :     if( eFamily == Matrix )
     192               0 :         eDataType = GDT_Byte;
     193               0 :     else if( ECSRASTERINFO(psResult).width == 1 )
     194               0 :         eDataType = GDT_Byte;
     195               0 :     else if( ECSRASTERINFO(psResult).width == 2 )
     196               0 :         eDataType = GDT_Byte;
     197               0 :     else if( ECSRASTERINFO(psResult).width == 3 )
     198               0 :         eDataType = GDT_UInt16;
     199               0 :     else if( ECSRASTERINFO(psResult).width == 4 )
     200               0 :         eDataType = GDT_Int16;
     201               0 :     else if( ECSRASTERINFO(psResult).width == 5 )
     202               0 :         eDataType = GDT_Int32;
     203                 :     else
     204               0 :         eDataType = GDT_UInt32;
     205                 : 
     206               0 :     nOGDIImageType = ECSRASTERINFO(psResult).width;
     207                 :     
     208                 : /* -------------------------------------------------------------------- */
     209                 : /*  Currently only works for strips         */
     210                 : /* -------------------------------------------------------------------- */
     211               0 :     nBlockXSize = poDS->GetRasterXSize();
     212               0 :     nBlockYSize = 1;
     213               0 : }
     214                 : 
     215                 : /************************************************************************/
     216                 : /*                          ~OGDIRasterBand()                           */
     217                 : /************************************************************************/
     218                 : 
     219               0 : OGDIRasterBand::~OGDIRasterBand()
     220                 : 
     221                 : {
     222               0 :     FlushCache();
     223               0 :     CPLFree( pszLayerName );
     224               0 : }
     225                 : 
     226                 : /************************************************************************/
     227                 : /*                             IReadBlock()                             */
     228                 : /************************************************************************/
     229                 : 
     230               0 : CPLErr OGDIRasterBand::IReadBlock( int, int nBlockYOff, void * pImage )
     231                 : 
     232                 : {
     233                 :     return IRasterIO( GF_Read, 0, nBlockYOff, nBlockXSize, 1, 
     234                 :                       pImage, nBlockXSize, 1, eDataType, 
     235               0 :                       GDALGetDataTypeSize(eDataType)/8, 0 );
     236                 : }
     237                 : 
     238                 : /************************************************************************/
     239                 : /*                             IRasterIO()                              */
     240                 : /************************************************************************/
     241                 : 
     242               0 : CPLErr OGDIRasterBand::IRasterIO( GDALRWFlag eRWFlag,
     243                 :                                   int nXOff, int nYOff, int nXSize, int nYSize,
     244                 :                                   void * pData, int nBufXSize, int nBufYSize,
     245                 :                                   GDALDataType eBufType,
     246                 :                                   int nPixelSpace, int nLineSpace )
     247                 : 
     248                 : {
     249               0 :     OGDIDataset *poODS = (OGDIDataset *) poDS;
     250                 :     CPLErr    eErr;
     251                 : #ifdef notdef
     252                 :     CPLDebug( "OGDIRasterBand", 
     253                 :               "RasterIO(%d,%d,%d,%d -> %dx%d)", 
     254                 :               nXOff, nYOff, nXSize, nYSize, nBufXSize, nBufYSize );
     255                 : #endif
     256                 : 
     257                 : /* -------------------------------------------------------------------- */
     258                 : /*      Establish access at the desired resolution.                     */
     259                 : /* -------------------------------------------------------------------- */
     260                 :     eErr = EstablishAccess( nXOff, nYOff, nXSize, nYSize, 
     261               0 :                             nBufXSize, nBufYSize );
     262               0 :     if( eErr != CE_None )
     263               0 :         return eErr;
     264                 : 
     265                 : /* -------------------------------------------------------------------- */
     266                 : /*      Read back one scanline at a time, till request is satisfied.    */
     267                 : /* -------------------------------------------------------------------- */
     268                 :     int      iScanline;
     269                 : 
     270               0 :     for( iScanline = 0; iScanline < nBufYSize; iScanline++ )
     271                 :     {
     272                 :         ecs_Result  *psResult;
     273                 :         void    *pLineData;
     274               0 :         pLineData = ((unsigned char *) pData) + iScanline * nLineSpace;
     275                 : 
     276               0 :         poODS->nCurrentIndex++;
     277               0 :         psResult = cln_GetNextObject( poODS->nClientID );
     278                 : 
     279               0 :         if( ECSERROR(psResult) )
     280                 :         {
     281                 :             CPLError( CE_Failure, CPLE_AppDefined,
     282               0 :                       "%s", psResult->message );
     283               0 :             return( CE_Failure );
     284                 :         }
     285                 : 
     286               0 :         if( eFamily == Matrix )
     287                 :         {
     288                 :             GDALCopyWords( ECSRASTER(psResult), GDT_UInt32, 4, 
     289                 :                            pLineData, eBufType, nPixelSpace,
     290               0 :                            nBufXSize );
     291                 :         }
     292               0 :         else if( nOGDIImageType == 1 )
     293                 :         {
     294                 :             GDALCopyWords( ((GByte *) ECSRASTER(psResult)) + nComponent, 
     295                 :                            GDT_Byte, 4,
     296               0 :                            pLineData, eBufType, nPixelSpace, nBufXSize );
     297                 : 
     298               0 :             if( nComponent == 3 )
     299                 :             {
     300                 :                 int i;
     301                 : 
     302               0 :                 for( i = 0; i < nBufXSize; i++ )
     303                 :                 {
     304               0 :                     if( ((GByte *) pLineData)[i] != 0 )
     305               0 :                         ((GByte *) pLineData)[i] = 255;
     306                 :                     else
     307               0 :                         ((GByte *) pLineData)[i] = 0;
     308                 :                     
     309                 :                 }
     310                 :             }
     311                 :         }
     312               0 :         else if( nOGDIImageType == 2 )
     313                 :         {
     314                 :             GDALCopyWords( ECSRASTER(psResult), GDT_Byte, 1,
     315                 :                            pLineData, eBufType, nPixelSpace,
     316               0 :                            nBufXSize );
     317                 :         }
     318               0 :         else if( nOGDIImageType == 3 )
     319                 :         {
     320                 :             GDALCopyWords( ECSRASTER(psResult), GDT_UInt16, 2,
     321                 :                            pLineData, eBufType, nPixelSpace,
     322               0 :                            nBufXSize );
     323                 :         }
     324               0 :         else if( nOGDIImageType == 4 )
     325                 :         {
     326                 :             GDALCopyWords( ECSRASTER(psResult), GDT_Int16, 2,
     327                 :                            pLineData, eBufType, nPixelSpace,
     328               0 :                            nBufXSize );
     329                 :         }
     330               0 :         else if( nOGDIImageType == 5 )
     331                 :         {
     332                 :             GDALCopyWords( ECSRASTER(psResult), GDT_Int32, 4,
     333                 :                            pLineData, eBufType, nPixelSpace,
     334               0 :                            nBufXSize );
     335                 :         }
     336                 :     }
     337                 : 
     338               0 :     return CE_None;
     339                 : }
     340                 : 
     341                 : /************************************************************************/
     342                 : /*                       HasArbitraryOverviews()                        */
     343                 : /************************************************************************/
     344                 : 
     345               0 : int OGDIRasterBand::HasArbitraryOverviews()
     346                 : 
     347                 : {
     348               0 :     return TRUE;
     349                 : }
     350                 : 
     351                 : /************************************************************************/
     352                 : /*                          EstablishAccess()                           */
     353                 : /************************************************************************/
     354                 : 
     355               0 : CPLErr OGDIRasterBand::EstablishAccess( int nXOff, int nYOff, 
     356                 :                                         int nWinXSize, int nWinYSize, 
     357                 :                                         int nBufXSize, int nBufYSize )
     358                 : 
     359                 : {
     360                 :     ecs_Result   *psResult;
     361               0 :     OGDIDataset  *poODS = (OGDIDataset *) poDS;
     362                 : 
     363                 : /* -------------------------------------------------------------------- */
     364                 : /*      Is this already the current band?  If not, make it so now.      */
     365                 : /* -------------------------------------------------------------------- */
     366               0 :     if( poODS->nCurrentBand != nBand )
     367                 :     {
     368                 :         ecs_LayerSelection sSelection;
     369                 :         
     370               0 :         sSelection.Select = pszLayerName;
     371               0 :         sSelection.F = eFamily;
     372                 :         
     373                 :         CPLDebug( "OGDIRasterBand", "<EstablishAccess: SelectLayer(%s)>",
     374               0 :                   pszLayerName );
     375               0 :         psResult = cln_SelectLayer( poODS->nClientID, &sSelection );
     376               0 :         if( ECSERROR(psResult) )
     377                 :         {
     378                 :             CPLError( CE_Failure, CPLE_AppDefined,
     379               0 :                       "%s", psResult->message );
     380               0 :             return CE_Failure;
     381                 :         }
     382                 : 
     383               0 :         poODS->nCurrentBand = nBand;
     384               0 :         poODS->nCurrentIndex = -1;
     385                 :     }
     386                 :         
     387                 : /* -------------------------------------------------------------------- */
     388                 : /*      What region would represent this resolution and window?         */
     389                 : /* -------------------------------------------------------------------- */
     390                 :     ecs_Region   sWin;
     391               0 :     double       dfNSTolerance = 0.0000001;
     392                 : 
     393                 :     sWin.west = nXOff * poODS->sGlobalBounds.ew_res
     394               0 :         + poODS->sGlobalBounds.west;
     395                 :     sWin.east = (nXOff+nWinXSize) * poODS->sGlobalBounds.ew_res
     396               0 :         + poODS->sGlobalBounds.west;
     397               0 :     sWin.ew_res = poODS->sGlobalBounds.ew_res*(nWinXSize/(double)nBufXSize);
     398                 : 
     399                 :     sWin.north = poODS->sGlobalBounds.north 
     400               0 :         - nYOff*poODS->sGlobalBounds.ns_res;
     401               0 :     if( nBufYSize == 1 && nWinYSize == 1 )
     402                 :     {
     403                 :         sWin.ns_res = sWin.ew_res 
     404               0 :             * (poODS->sGlobalBounds.ns_res / poODS->sGlobalBounds.ew_res);
     405                 :         nWinYSize = (int) ((sWin.north - poODS->sGlobalBounds.south + sWin.ns_res*0.9)
     406               0 :                                 / sWin.ns_res);
     407                 : 
     408               0 :         sWin.south = sWin.north - nWinYSize * sWin.ns_res;
     409               0 :         dfNSTolerance = MAX(poODS->sCurrentBounds.ns_res,sWin.ns_res);
     410                 :     }
     411               0 :     else if( nBufYSize == 1 )
     412                 :     {
     413                 :         sWin.ns_res = poODS->sGlobalBounds.ns_res
     414               0 :             *(nWinYSize/(double)nBufYSize);
     415                 :         nWinYSize = (int) ((sWin.north - poODS->sGlobalBounds.south + sWin.ns_res*0.9)
     416               0 :                                 / sWin.ns_res);
     417                 : 
     418               0 :         sWin.south = sWin.north - nWinYSize * sWin.ns_res;
     419               0 :         dfNSTolerance = MAX(poODS->sCurrentBounds.ns_res,sWin.ns_res);
     420                 :     }
     421                 :     else
     422                 :     {
     423                 :         sWin.ns_res = poODS->sGlobalBounds.ns_res
     424               0 :             *(nWinYSize/(double)nBufYSize);
     425               0 :         sWin.south = sWin.north - nWinYSize * sWin.ns_res;
     426               0 :         dfNSTolerance = sWin.ns_res * 0.001;
     427                 :     }
     428                 : 
     429               0 :     if( poODS->nCurrentIndex != 0
     430                 :         || ABS(sWin.west - poODS->sCurrentBounds.west) > 0.0001 
     431                 :         || ABS(sWin.east - poODS->sCurrentBounds.east) > 0.0001 
     432                 :         || ABS(sWin.north - (poODS->sCurrentBounds.north - poODS->nCurrentIndex * poODS->sCurrentBounds.ns_res)) > dfNSTolerance 
     433                 :         || ABS(sWin.ew_res/poODS->sCurrentBounds.ew_res - 1.0) > 0.0001
     434                 :         || ABS(sWin.ns_res - poODS->sCurrentBounds.ns_res) > dfNSTolerance )
     435                 :     {
     436                 :         CPLDebug( "OGDIRasterBand", 
     437                 :                   "<EstablishAccess: Set Region(%d,%d,%d,%d,%d,%d>",
     438               0 :                   nXOff, nYOff, nWinXSize, nWinYSize, nBufXSize, nBufYSize );
     439                 : 
     440               0 :         psResult = cln_SelectRegion( poODS->nClientID, &sWin );
     441               0 :         if( ECSERROR(psResult) )
     442                 :         {
     443                 :             CPLError( CE_Failure, CPLE_AppDefined,
     444               0 :                       "%s", psResult->message );
     445               0 :             return CE_Failure;
     446                 :         }
     447                 :         
     448               0 :         poODS->sCurrentBounds = sWin;
     449               0 :         poODS->nCurrentIndex = 0;
     450                 :     }
     451                 : 
     452               0 :     return CE_None;
     453                 : }
     454                 : 
     455                 : /************************************************************************/
     456                 : /*                       GetColorInterpretation()                       */
     457                 : /************************************************************************/
     458                 : 
     459               0 : GDALColorInterp OGDIRasterBand::GetColorInterpretation()
     460                 : 
     461                 : {
     462               0 :     if( poCT != NULL )
     463               0 :         return GCI_PaletteIndex;
     464               0 :     else if( nOGDIImageType == 1 && eFamily == Image && nComponent == 0 )
     465               0 :         return GCI_RedBand;
     466               0 :     else if( nOGDIImageType == 1 && eFamily == Image && nComponent == 1 )
     467               0 :         return GCI_GreenBand;
     468               0 :     else if( nOGDIImageType == 1 && eFamily == Image && nComponent == 2 )
     469               0 :         return GCI_BlueBand;
     470               0 :     else if( nOGDIImageType == 1 && eFamily == Image && nComponent == 3 )
     471               0 :         return GCI_AlphaBand;
     472                 :     else
     473               0 :         return GCI_Undefined;
     474                 : }
     475                 : 
     476                 : /************************************************************************/
     477                 : /*                           GetColorTable()                            */
     478                 : /************************************************************************/
     479                 : 
     480               0 : GDALColorTable *OGDIRasterBand::GetColorTable()
     481                 : 
     482                 : {
     483               0 :     return poCT;
     484                 : }
     485                 : 
     486                 : /************************************************************************/
     487                 : /*                             AdviseRead()                             */
     488                 : /*                                                                      */
     489                 : /*      Allow the application to give us a hint in advance how they     */
     490                 : /*      want the data.                                                  */
     491                 : /************************************************************************/
     492                 : 
     493               0 : CPLErr OGDIRasterBand::AdviseRead( int nXOff, int nYOff, 
     494                 :                                    int nXSize, int nYSize,
     495                 :                                    int nBufXSize, int nBufYSize, 
     496                 :                                    GDALDataType eDT, char **papszOptions )
     497                 : 
     498                 : {
     499                 :     return EstablishAccess( nXOff, nYOff, nXSize, nYSize, 
     500               0 :                             nBufXSize, nBufYSize );
     501                 : }
     502                 :     
     503                 : /************************************************************************/
     504                 : /* ==================================================================== */
     505                 : /*                            OGDIDataset                               */
     506                 : /* ==================================================================== */
     507                 : /************************************************************************/
     508                 : 
     509                 : 
     510                 : /************************************************************************/
     511                 : /*                            OGDIDataset()                            */
     512                 : /************************************************************************/
     513                 : 
     514               0 : OGDIDataset::OGDIDataset()
     515                 : 
     516                 : {
     517               0 :     nClientID = -1;
     518               0 :     nCurrentBand = -1;
     519               0 :     nCurrentIndex = -1;
     520               0 :     papszSubDatasets = NULL;
     521               0 : }
     522                 : 
     523                 : /************************************************************************/
     524                 : /*                           ~OGDIDataset()                            */
     525                 : /************************************************************************/
     526                 : 
     527               0 : OGDIDataset::~OGDIDataset()
     528                 : 
     529                 : {
     530               0 :     cln_DestroyClient( nClientID );
     531               0 :     CSLDestroy( papszSubDatasets );
     532               0 :     CPLFree( pszProjection );
     533               0 : }
     534                 : 
     535                 : /************************************************************************/
     536                 : /*                            GetMetadata()                             */
     537                 : /************************************************************************/
     538                 : 
     539               0 : char **OGDIDataset::GetMetadata( const char *pszDomain )
     540                 : 
     541                 : {
     542               0 :     if( pszDomain != NULL && EQUAL(pszDomain,"SUBDATASETS") )
     543               0 :         return papszSubDatasets;
     544                 :     else
     545               0 :         return GDALDataset::GetMetadata( pszDomain );
     546                 : }
     547                 : 
     548                 : /************************************************************************/
     549                 : /*                                Open()                                */
     550                 : /************************************************************************/
     551                 : 
     552           26664 : GDALDataset *OGDIDataset::Open( GDALOpenInfo * poOpenInfo )
     553                 : 
     554                 : {
     555                 :     ecs_Result  *psResult;
     556                 :     int   nClientID;
     557           26664 :     char        **papszImages=NULL, **papszMatrices=NULL;
     558                 :     
     559           26664 :     if( !EQUALN(poOpenInfo->pszFilename,"gltp:",5) )
     560           26664 :         return( NULL );
     561                 :     
     562                 : /* -------------------------------------------------------------------- */
     563                 : /*      Confirm the requested access is supported.                      */
     564                 : /* -------------------------------------------------------------------- */
     565               0 :     if( poOpenInfo->eAccess == GA_Update )
     566                 :     {
     567                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     568                 :                   "The OGDI driver does not support update access to existing"
     569               0 :                   " datasets.\n" );
     570               0 :         return NULL;
     571                 :     }
     572                 :     
     573                 : /* -------------------------------------------------------------------- */
     574                 : /*      Has the user hardcoded a layer and family in the URL?           */
     575                 : /*      Honour quoted strings for the layer name, since some layers     */
     576                 : /*      (ie. RPF/CADRG) have embedded colons.                           */
     577                 : /* -------------------------------------------------------------------- */
     578               0 :     int       nC1=-1, nC2=-1, i, bInQuotes = FALSE;
     579               0 :     char      *pszURL = CPLStrdup(poOpenInfo->pszFilename);
     580                 : 
     581               0 :     for( i = strlen(pszURL)-1; i > 0; i-- )
     582                 :     {
     583               0 :         if( pszURL[i] == '/' )
     584               0 :             break;
     585                 : 
     586               0 :         if( pszURL[i] == '"' && pszURL[i-1] != '\\' )
     587               0 :             bInQuotes = !bInQuotes;
     588                 :             
     589               0 :         else if( pszURL[i] == ':' && !bInQuotes )
     590                 :         {
     591               0 :             if( nC1 == -1 )
     592                 :             {
     593               0 :                 nC1 = i;
     594               0 :                 pszURL[nC1] = '\0';
     595                 :             }
     596               0 :             else if( nC2 == -1 )
     597                 :             {
     598               0 :                 nC2 = i;
     599               0 :                 pszURL[nC2] = '\0';
     600                 :             }
     601                 :         }
     602                 :     } 
     603                 : 
     604                 : /* -------------------------------------------------------------------- */
     605                 : /*      If we got a "family", and it is a vector family then return     */
     606                 : /*      quietly.                                                        */
     607                 : /* -------------------------------------------------------------------- */
     608               0 :     if( nC2 != -1 
     609                 :         && !EQUAL(pszURL+nC1+1,"Matrix") 
     610                 :         && !EQUAL(pszURL+nC1+1,"Image") )
     611                 :     {
     612               0 :         CPLFree( pszURL );
     613               0 :         return NULL;
     614                 :     }
     615                 : 
     616                 : /* -------------------------------------------------------------------- */
     617                 : /*      Open the client interface.                                      */
     618                 : /* -------------------------------------------------------------------- */
     619               0 :     psResult = cln_CreateClient( &nClientID, pszURL );
     620                 : 
     621               0 :     if( ECSERROR(psResult) )
     622                 :     {
     623                 :         CPLError( CE_Failure, CPLE_AppDefined,
     624               0 :                   "%s", psResult->message );
     625               0 :         CPLFree(pszURL);
     626               0 :         return NULL;
     627                 :     }
     628                 : 
     629                 : /* -------------------------------------------------------------------- */
     630                 : /*      collect the list of images and matrices available.              */
     631                 : /* -------------------------------------------------------------------- */
     632               0 :     if( nC2 == -1 )
     633                 :     {
     634               0 :         CollectLayers( nClientID, &papszImages, &papszMatrices );
     635                 :     }
     636                 :     else
     637                 :     {
     638               0 :         char  *pszLayerName = CPLStrdup( pszURL+nC2+1 );
     639                 :         
     640               0 :         if( pszLayerName[0] == '"' )
     641                 :         {
     642               0 :             int   nOut = 0;
     643                 : 
     644               0 :             for( i = 1; pszLayerName[i] != '\0'; i++ )
     645                 :             {
     646               0 :                 if( pszLayerName[i+1] == '"' && pszLayerName[i] == '\\' )
     647               0 :                     pszLayerName[nOut++] = pszLayerName[++i];
     648               0 :                 else if( pszLayerName[i] != '"' )
     649               0 :                     pszLayerName[nOut++] = pszLayerName[i];
     650                 :                 else 
     651               0 :                     break;
     652                 :             }
     653               0 :             pszLayerName[nOut] = '\0';
     654                 :         }
     655                 : 
     656               0 :         if( EQUAL(pszURL+nC1+1,"Image") )
     657               0 :             papszImages = CSLAddString( papszImages, pszLayerName );
     658                 :         else
     659               0 :             papszMatrices = CSLAddString( papszMatrices, pszLayerName );
     660                 : 
     661               0 :         CPLFree( pszLayerName );
     662                 :     }
     663                 : 
     664               0 :     CPLFree( pszURL );
     665                 : 
     666                 : /* -------------------------------------------------------------------- */
     667                 : /*      If this is a 3.1 server (ie, it support                         */
     668                 : /*      cln_GetLayerCapabilities()) and it has no raster layers then    */
     669                 : /*      we can assume it must be a vector datastore.  End without an    */
     670                 : /*      error in case the application wants to try this through         */
     671                 : /*      OGR.                                                            */
     672                 : /* -------------------------------------------------------------------- */
     673               0 :     psResult = cln_GetVersion(nClientID);
     674                 :     
     675               0 :     if( (ECSERROR(psResult) || atof(ECSTEXT(psResult)) >= 3.1)
     676                 :         && CSLCount(papszMatrices) == 0 
     677                 :         && CSLCount(papszImages) == 0 )
     678                 :     {
     679                 :         CPLDebug( "OGDIDataset",
     680                 :                   "While this is an OGDI datastore, it does not appear to\n"
     681                 :                   "have any identifiable raster layers.  Perhaps it is a\n"
     682               0 :                   "vector datastore?" );
     683               0 :         cln_DestroyClient( nClientID );
     684               0 :         return NULL;
     685                 :     }
     686                 :     
     687                 : /* -------------------------------------------------------------------- */
     688                 : /*      Create a corresponding GDALDataset.                             */
     689                 : /* -------------------------------------------------------------------- */
     690                 :     OGDIDataset   *poDS;
     691                 : 
     692               0 :     poDS = new OGDIDataset();
     693                 : 
     694               0 :     poDS->nClientID = nClientID;
     695               0 :     poDS->SetDescription( poOpenInfo->pszFilename );
     696                 : 
     697                 : /* -------------------------------------------------------------------- */
     698                 : /*      Capture some information from the file that is of interest.     */
     699                 : /* -------------------------------------------------------------------- */
     700               0 :     psResult = cln_GetGlobalBound( nClientID );
     701               0 :     if( ECSERROR(psResult) )
     702                 :     {
     703                 :         CPLError( CE_Failure, CPLE_AppDefined,
     704               0 :                   "%s", psResult->message );
     705               0 :         return NULL;
     706                 :     }
     707                 : 
     708               0 :     poDS->sGlobalBounds = ECSREGION(psResult);
     709                 : 
     710               0 :     psResult = cln_GetServerProjection(nClientID);
     711               0 :     if( ECSERROR(psResult) )
     712                 :     {
     713                 :         CPLError( CE_Failure, CPLE_AppDefined,
     714               0 :                   "%s", psResult->message );
     715               0 :         return NULL;
     716                 :     }
     717                 : 
     718               0 :     OGRSpatialReference  oSRS;
     719                 : 
     720               0 :     if( oSRS.importFromProj4( ECSTEXT(psResult) ) == OGRERR_NONE )
     721                 :     {
     722               0 :         poDS->pszProjection = NULL;
     723               0 :         oSRS.exportToWkt( &(poDS->pszProjection) );
     724                 :     }
     725                 :     else
     726                 :     {
     727                 :         CPLError( CE_Warning, CPLE_NotSupported,
     728                 :                   "untranslatable PROJ.4 projection: %s\n", 
     729               0 :                   ECSTEXT(psResult) );
     730               0 :         poDS->pszProjection = CPLStrdup("");
     731                 :     }
     732                 : 
     733                 : /* -------------------------------------------------------------------- */
     734                 : /*      Select the global region.                                       */
     735                 : /* -------------------------------------------------------------------- */
     736               0 :     psResult = cln_SelectRegion( nClientID, &(poDS->sGlobalBounds) );
     737               0 :     if( ECSERROR(psResult) )
     738                 :     {
     739                 :         CPLError( CE_Failure, CPLE_AppDefined,
     740               0 :                   "%s", psResult->message );
     741               0 :         return NULL;
     742                 :     }
     743                 : 
     744               0 :     poDS->sCurrentBounds = poDS->sGlobalBounds;
     745                 : 
     746                 : /* -------------------------------------------------------------------- */
     747                 : /*      If we have only one layer try to find the corresponding         */
     748                 : /*      capabilities, and override the global bounds and resolution     */
     749                 : /*      based on it.                                                    */
     750                 : /* -------------------------------------------------------------------- */
     751               0 :     if( CSLCount(papszMatrices) + CSLCount(papszImages) == 1 )
     752                 :     {
     753               0 :         if( CSLCount(papszMatrices) == 1 )
     754               0 :             OverrideGlobalInfo( poDS, papszMatrices[0] );
     755                 :         else
     756               0 :             OverrideGlobalInfo( poDS, papszImages[0] );
     757                 :     }
     758                 : 
     759                 : /* -------------------------------------------------------------------- */
     760                 : /*      Otherwise setup a subdataset list.                              */
     761                 : /* -------------------------------------------------------------------- */
     762                 :     else
     763                 :     {
     764                 :         int i;
     765                 : 
     766               0 :         for( i = 0; papszMatrices != NULL && papszMatrices[i] != NULL; i++ )
     767               0 :             poDS->AddSubDataset( "Matrix", papszMatrices[i] );
     768                 : 
     769               0 :         for( i = 0; papszImages != NULL && papszImages[i] != NULL; i++ )
     770               0 :             poDS->AddSubDataset( "Image", papszImages[i] );
     771                 :     }
     772                 :     
     773                 : /* -------------------------------------------------------------------- */
     774                 : /*      Establish raster info.                                          */
     775                 : /* -------------------------------------------------------------------- */
     776                 :     poDS->nRasterXSize = (int) 
     777                 :         (((poDS->sGlobalBounds.east - poDS->sGlobalBounds.west)
     778               0 :           / poDS->sGlobalBounds.ew_res) + 0.5);
     779                 :     
     780                 :     poDS->nRasterYSize = (int) 
     781                 :         (((poDS->sGlobalBounds.north - poDS->sGlobalBounds.south)
     782               0 :           / poDS->sGlobalBounds.ns_res) + 0.5);
     783                 : 
     784                 : /* -------------------------------------------------------------------- */
     785                 : /*      Create band information objects.                                */
     786                 : /* -------------------------------------------------------------------- */
     787               0 :     for( i=0; papszMatrices != NULL && papszMatrices[i] != NULL; i++)
     788                 :     {
     789               0 :         if( CSLFindString( papszImages, papszMatrices[i] ) == -1 )
     790                 :             poDS->SetBand( poDS->GetRasterCount()+1, 
     791                 :                            new OGDIRasterBand( poDS, poDS->GetRasterCount()+1, 
     792               0 :                                                papszMatrices[i], Matrix, 0 ) );
     793                 :     }
     794                 : 
     795               0 :     for( i=0; papszImages != NULL && papszImages[i] != NULL; i++)
     796                 :     {
     797                 :         OGDIRasterBand  *poBand;
     798                 : 
     799                 :         poBand = new OGDIRasterBand( poDS, poDS->GetRasterCount()+1, 
     800               0 :                                      papszImages[i], Image, 0 );
     801                 : 
     802               0 :         poDS->SetBand( poDS->GetRasterCount()+1, poBand );
     803                 : 
     804                 :         /* special case for RGBt Layers */
     805               0 :         if( poBand->nOGDIImageType == 1 )
     806                 :         {
     807                 :             poDS->SetBand( poDS->GetRasterCount()+1, 
     808                 :                            new OGDIRasterBand( poDS, poDS->GetRasterCount()+1, 
     809               0 :                                                papszImages[i], Image, 1 ));
     810                 :             poDS->SetBand( poDS->GetRasterCount()+1, 
     811                 :                            new OGDIRasterBand( poDS, poDS->GetRasterCount()+1, 
     812               0 :                                                papszImages[i], Image, 2 ));
     813                 :             poDS->SetBand( poDS->GetRasterCount()+1, 
     814                 :                            new OGDIRasterBand( poDS, poDS->GetRasterCount()+1, 
     815               0 :                                                papszImages[i], Image, 3 ));
     816                 :         }
     817                 :     }
     818                 : 
     819               0 :     CSLDestroy( papszMatrices );
     820               0 :     CSLDestroy( papszImages );
     821                 : 
     822               0 :     return( poDS );
     823                 : }
     824                 : 
     825                 : /************************************************************************/
     826                 : /*                           AddSubDataset()                            */
     827                 : /************************************************************************/
     828                 : 
     829               0 : void OGDIDataset::AddSubDataset( const char *pszType, const char *pszLayer )
     830                 : 
     831                 : {
     832                 :     char  szName[80];
     833               0 :     int   nCount = CSLCount( papszSubDatasets ) / 2;
     834                 : 
     835               0 :     sprintf( szName, "SUBDATASET_%d_NAME", nCount+1 );
     836                 :     papszSubDatasets = 
     837                 :         CSLSetNameValue( papszSubDatasets, szName, 
     838               0 :               CPLSPrintf( "%s:\"%s\":%s", GetDescription(), pszLayer, pszType ) );
     839                 : 
     840               0 :     sprintf( szName, "SUBDATASET_%d_DESC", nCount+1 );
     841                 :     papszSubDatasets = 
     842                 :         CSLSetNameValue( papszSubDatasets, szName, 
     843               0 :               CPLSPrintf( "%s as %s", pszLayer, pszType ) );
     844               0 : }
     845                 : 
     846                 : /************************************************************************/
     847                 : /*                           CollectLayers()                            */
     848                 : /************************************************************************/
     849                 : 
     850               0 : CPLErr OGDIDataset::CollectLayers( int nClientID, 
     851                 :                                    char ***ppapszImages, 
     852                 :                                    char ***ppapszMatrices )
     853                 : 
     854                 : {
     855                 :     const ecs_LayerCapabilities *psLayer;
     856                 :     int   iLayer;
     857                 : 
     858               0 :     for( iLayer = 0; 
     859                 :          (psLayer = cln_GetLayerCapabilities(nClientID,iLayer)) != NULL;
     860                 :          iLayer++ )
     861                 :     {
     862               0 :         if( psLayer->families[Image] )
     863                 :         {
     864               0 :             *ppapszImages = CSLAddString( *ppapszImages, psLayer->name );
     865                 :         }
     866               0 :         if( psLayer->families[Matrix] )
     867                 :         {
     868               0 :             *ppapszMatrices = CSLAddString( *ppapszMatrices, psLayer->name );
     869                 :         }
     870                 :     }
     871                 : 
     872               0 :     return CE_None;
     873                 : }
     874                 : 
     875                 : /************************************************************************/
     876                 : /*                         OverrideGlobalInfo()                         */
     877                 : /*                                                                      */
     878                 : /*      Override the global bounds and resolution based on a layers     */
     879                 : /*      capabilities, if possible.                                      */
     880                 : /************************************************************************/
     881                 : 
     882               0 : CPLErr OGDIDataset::OverrideGlobalInfo( OGDIDataset *poDS,
     883                 :                                         const char *pszLayer )
     884                 : 
     885                 : {
     886                 :     const ecs_LayerCapabilities *psLayer;
     887                 :     int   iLayer;
     888                 : 
     889               0 :     for( iLayer = 0; 
     890                 :          (psLayer = cln_GetLayerCapabilities(poDS->nClientID,iLayer)) != NULL;
     891                 :          iLayer++ )
     892                 :     {
     893               0 :         if( EQUAL(psLayer->name, pszLayer) )
     894                 :         {
     895               0 :             poDS->sGlobalBounds.north = psLayer->srs_north;
     896               0 :             poDS->sGlobalBounds.south = psLayer->srs_south;
     897               0 :             poDS->sGlobalBounds.east = psLayer->srs_east;
     898               0 :             poDS->sGlobalBounds.west = psLayer->srs_west;
     899               0 :             poDS->sGlobalBounds.ew_res = psLayer->srs_ewres;
     900               0 :             poDS->sGlobalBounds.ns_res = psLayer->srs_nsres;
     901                 :         }
     902                 :     }
     903                 : 
     904               0 :     return CE_None;
     905                 : }
     906                 : 
     907                 : /************************************************************************/
     908                 : /*                          GetProjectionRef()                          */
     909                 : /************************************************************************/
     910                 : 
     911               0 : const char *OGDIDataset::GetProjectionRef()
     912                 : 
     913                 : {
     914               0 :     return( pszProjection );
     915                 : }
     916                 : 
     917                 : /************************************************************************/
     918                 : /*                          GetGeoTransform()                           */
     919                 : /************************************************************************/
     920                 : 
     921               0 : CPLErr OGDIDataset::GetGeoTransform( double * padfTransform )
     922                 : 
     923                 : {
     924               0 :     padfTransform[0] = sGlobalBounds.west;
     925               0 :     padfTransform[1] = sGlobalBounds.ew_res;
     926               0 :     padfTransform[2] = 0.0;
     927                 : 
     928               0 :     padfTransform[3] = sGlobalBounds.north;
     929               0 :     padfTransform[4] = 0.0;
     930               0 :     padfTransform[5] = -sGlobalBounds.ns_res;
     931                 : 
     932               0 :     return( CE_None );
     933                 : }
     934                 : 
     935                 : /************************************************************************/
     936                 : /*                         GetInternalHandle()                          */
     937                 : /************************************************************************/
     938                 : 
     939               0 : void *OGDIDataset::GetInternalHandle( const char * pszRequest )
     940                 : 
     941                 : {
     942               0 :     if( EQUAL(pszRequest,"ClientID") )
     943               0 :         return (void *) nClientID;
     944                 :     else
     945               0 :         return NULL;
     946                 : }
     947                 : 
     948                 : /************************************************************************/
     949                 : /*                          GDALRegister_OGDI()                        */
     950                 : /************************************************************************/
     951                 : 
     952            1135 : void GDALRegister_OGDI()
     953                 : 
     954                 : {
     955                 :     GDALDriver  *poDriver;
     956                 : 
     957            1135 :     if (! GDAL_CHECK_VERSION("GDAL/OGDI driver"))
     958               0 :         return;
     959                 :     
     960            1135 :     if( GDALGetDriverByName( "OGDI" ) == NULL )
     961                 :     {
     962            1093 :         poDriver = new GDALDriver();
     963                 :         
     964            1093 :         poDriver->SetDescription( "OGDI" );
     965                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     966            1093 :                                    "OGDI Bridge" );
     967                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
     968            1093 :                                    "frmt_ogdi.html" );
     969                 : 
     970            1093 :         poDriver->pfnOpen = OGDIDataset::Open;
     971                 : 
     972            1093 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     973                 :     }
     974                 : }
     975                 : 

Generated by: LCOV version 1.7