LTP GCOV extension - code coverage report
Current view: directory - frmts/xyz - xyzdataset.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 383
Code covered: 82.0 % Executed lines: 314

       1                 : /******************************************************************************
       2                 :  * $Id: xyzdataset.cpp 20000 2010-07-10 18:19:34Z rouault $
       3                 :  *
       4                 :  * Project:  XYZ driver
       5                 :  * Purpose:  GDALDataset driver for XYZ dataset.
       6                 :  * Author:   Even Rouault, <even dot rouault at mines dash paris dot org>
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2010, Even Rouault
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "cpl_vsi_virtual.h"
      31                 : #include "cpl_string.h"
      32                 : #include "gdal_pam.h"
      33                 : 
      34                 : CPL_CVSID("$Id: xyzdataset.cpp 20000 2010-07-10 18:19:34Z rouault $");
      35                 : 
      36                 : CPL_C_START
      37                 : void    GDALRegister_XYZ(void);
      38                 : CPL_C_END
      39                 : 
      40                 : /************************************************************************/
      41                 : /* ==================================================================== */
      42                 : /*                              XYZDataset                              */
      43                 : /* ==================================================================== */
      44                 : /************************************************************************/
      45                 : 
      46                 : class XYZRasterBand;
      47                 : 
      48                 : class XYZDataset : public GDALPamDataset
      49                 : {
      50                 :     friend class XYZRasterBand;
      51                 :     
      52                 :     FILE       *fp;
      53                 :     int         bHasHeaderLine;
      54                 :     int         nXIndex;
      55                 :     int         nYIndex;
      56                 :     int         nZIndex;
      57                 :     int         nMinTokens;
      58                 :     int         nLineNum;     /* any line */
      59                 :     int         nDataLineNum; /* line with values (header line and empty lines ignored) */
      60                 :     double      adfGeoTransform[6];
      61                 :     
      62                 :     static int          IdentifyEx( GDALOpenInfo *, int& );
      63                 : 
      64                 :   public:
      65                 :                  XYZDataset();
      66                 :     virtual     ~XYZDataset();
      67                 :     
      68                 :     virtual CPLErr GetGeoTransform( double * );
      69                 :     
      70                 :     static GDALDataset *Open( GDALOpenInfo * );
      71                 :     static int          Identify( GDALOpenInfo * );
      72                 :     static GDALDataset *CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, 
      73                 :                                     int bStrict, char ** papszOptions, 
      74                 :                                     GDALProgressFunc pfnProgress, void * pProgressData );
      75                 : };
      76                 : 
      77                 : /************************************************************************/
      78                 : /* ==================================================================== */
      79                 : /*                            XYZRasterBand                             */
      80                 : /* ==================================================================== */
      81                 : /************************************************************************/
      82                 : 
      83                 : class XYZRasterBand : public GDALPamRasterBand
      84              18 : {
      85                 :     friend class XYZDataset;
      86                 : 
      87                 :   public:
      88                 : 
      89                 :                 XYZRasterBand( XYZDataset *, int, GDALDataType );
      90                 : 
      91                 :     virtual CPLErr IReadBlock( int, int, void * );
      92                 : };
      93                 : 
      94                 : 
      95                 : /************************************************************************/
      96                 : /*                           XYZRasterBand()                            */
      97                 : /************************************************************************/
      98                 : 
      99              18 : XYZRasterBand::XYZRasterBand( XYZDataset *poDS, int nBand, GDALDataType eDT )
     100                 : 
     101                 : {
     102              18 :     this->poDS = poDS;
     103              18 :     this->nBand = nBand;
     104                 : 
     105              18 :     eDataType = eDT;
     106                 : 
     107              18 :     nBlockXSize = poDS->GetRasterXSize();
     108              18 :     nBlockYSize = 1;
     109              18 : }
     110                 : 
     111                 : /************************************************************************/
     112                 : /*                             IReadBlock()                             */
     113                 : /************************************************************************/
     114                 : 
     115                 : CPLErr XYZRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     116             445 :                                   void * pImage )
     117                 : 
     118                 : {
     119             445 :     XYZDataset *poGDS = (XYZDataset *) poDS;
     120                 : 
     121             445 :     int nLineInFile = nBlockYOff * nBlockXSize;
     122             445 :     if (poGDS->nDataLineNum > nLineInFile)
     123                 :     {
     124               7 :         poGDS->nDataLineNum = 0;
     125               7 :         VSIFSeekL(poGDS->fp, 0, SEEK_SET);
     126               7 :         if (poGDS->bHasHeaderLine)
     127                 :         {
     128               5 :             const char* pszLine = CPLReadLine2L(poGDS->fp, 100, 0);
     129               5 :             if (pszLine == NULL)
     130                 :             {
     131               0 :                 memset(pImage, 0, nBlockXSize * (GDALGetDataTypeSize(eDataType) / 8));
     132               0 :                 return CE_Failure;
     133                 :             }
     134               5 :             poGDS->nLineNum ++;
     135                 :         }
     136                 :     }
     137                 : 
     138             902 :     while(poGDS->nDataLineNum < nLineInFile)
     139                 :     {
     140              12 :         const char* pszLine = CPLReadLine2L(poGDS->fp, 100, 0);
     141              12 :         if (pszLine == NULL)
     142                 :         {
     143               0 :             memset(pImage, 0, nBlockXSize * (GDALGetDataTypeSize(eDataType) / 8));
     144               0 :             return CE_Failure;
     145                 :         }
     146              12 :         poGDS->nLineNum ++;
     147                 : 
     148              12 :         const char* pszPtr = pszLine;
     149                 :         char ch;
     150              12 :         int nCol = 0;
     151              12 :         int bLastWasSep = TRUE;
     152              60 :         while((ch = *pszPtr) != '\0')
     153                 :         {
     154              48 :             if (ch == ' ' || ch == ',' || ch == '\t' || ch == ';')
     155                 :             {
     156              12 :                 if (!bLastWasSep)
     157              12 :                     nCol ++;
     158              12 :                 bLastWasSep = TRUE;
     159                 :             }
     160                 :             else
     161                 :             {
     162              24 :                 bLastWasSep = FALSE;
     163                 :             }
     164              36 :             pszPtr ++;
     165                 :         }
     166                 : 
     167                 :         /* Skip empty line */
     168              12 :         if (nCol == 0 && bLastWasSep)
     169               6 :             continue;
     170                 : 
     171               6 :         poGDS->nDataLineNum ++;
     172                 :     }
     173                 : 
     174                 :     int i;
     175           82053 :     for(i=0;i<nBlockXSize;i++)
     176                 :     {
     177                 :         int nCol;
     178                 :         int bLastWasSep;
     179           81612 :         do
     180                 :         {
     181           81612 :             const char* pszLine = CPLReadLine2L(poGDS->fp, 100, 0);
     182           81612 :             if (pszLine == NULL)
     183                 :             {
     184               0 :                 memset(pImage, 0, nBlockXSize * (GDALGetDataTypeSize(eDataType) / 8));
     185               0 :                 return CE_Failure;
     186                 :             }
     187           81612 :             poGDS->nLineNum ++;
     188                 : 
     189           81612 :             const char* pszPtr = pszLine;
     190                 :             char ch;
     191           81612 :             nCol = 0;
     192           81612 :             bLastWasSep = TRUE;
     193         2799048 :             while((ch = *pszPtr) != '\0')
     194                 :             {
     195         2799040 :                 if (ch == ' ' || ch == ',' || ch == '\t' || ch == ';')
     196                 :                 {
     197          163216 :                     if (!bLastWasSep)
     198          163216 :                         nCol ++;
     199          163216 :                     bLastWasSep = TRUE;
     200                 :                 }
     201                 :                 else
     202                 :                 {
     203         2472608 :                     if (bLastWasSep && nCol == poGDS->nZIndex)
     204                 :                     {
     205           81608 :                         double dfZ = CPLAtofM(pszPtr);
     206           81608 :                         if (eDataType == GDT_Float32)
     207                 :                         {
     208           80802 :                             ((float*)pImage)[i] = (float)dfZ;
     209                 :                         }
     210             806 :                         else if (eDataType == GDT_Int32)
     211                 :                         {
     212               0 :                             ((GInt32*)pImage)[i] = (GInt32)dfZ;
     213                 :                         }
     214             806 :                         else if (eDataType == GDT_Int16)
     215                 :                         {
     216               0 :                             ((GInt16*)pImage)[i] = (GInt16)dfZ;
     217                 :                         }
     218                 :                         else
     219                 :                         {
     220             806 :                             ((GByte*)pImage)[i] = (GByte)dfZ;
     221                 :                         }
     222                 :                     }
     223         2472608 :                     bLastWasSep = FALSE;
     224                 :                 }
     225         2635824 :                 pszPtr ++;
     226                 :             }
     227                 : 
     228                 :             /* Skip empty line */
     229                 :         }
     230                 :         while (nCol == 0 && bLastWasSep);
     231                 : 
     232           81608 :         poGDS->nDataLineNum ++;
     233           81608 :         nCol ++;
     234           81608 :         if (nCol < poGDS->nMinTokens)
     235                 :         {
     236               0 :             memset(pImage, 0, nBlockXSize * (GDALGetDataTypeSize(eDataType) / 8));
     237               0 :             return CE_Failure;
     238                 :         }
     239                 :     }
     240             445 :     CPLAssert(poGDS->nDataLineNum == (nBlockYOff + 1) * nBlockXSize);
     241                 : 
     242             445 :     return CE_None;
     243                 : }
     244                 : 
     245                 : /************************************************************************/
     246                 : /*                            ~XYZDataset()                            */
     247                 : /************************************************************************/
     248                 : 
     249              18 : XYZDataset::XYZDataset()
     250                 : {
     251              18 :     fp = NULL;
     252              18 :     nDataLineNum = INT_MAX;
     253              18 :     nLineNum = 0;
     254              18 :     bHasHeaderLine = FALSE;
     255              18 :     nXIndex = -1;
     256              18 :     nYIndex = -1;
     257              18 :     nZIndex = -1;
     258              18 :     nMinTokens = 0;
     259              18 :     adfGeoTransform[0] = 0;
     260              18 :     adfGeoTransform[1] = 1;
     261              18 :     adfGeoTransform[2] = 0;
     262              18 :     adfGeoTransform[3] = 0;
     263              18 :     adfGeoTransform[4] = 0;
     264              18 :     adfGeoTransform[5] = 1;
     265              18 : }
     266                 : 
     267                 : /************************************************************************/
     268                 : /*                            ~XYZDataset()                            */
     269                 : /************************************************************************/
     270                 : 
     271              18 : XYZDataset::~XYZDataset()
     272                 : 
     273                 : {
     274              18 :     FlushCache();
     275              18 :     if (fp)
     276              18 :         VSIFCloseL(fp);
     277              18 : }
     278                 : 
     279                 : /************************************************************************/
     280                 : /*                             Identify()                               */
     281                 : /************************************************************************/
     282                 : 
     283            8238 : int XYZDataset::Identify( GDALOpenInfo * poOpenInfo )
     284                 : {
     285                 :     int bHasHeaderLine;
     286            8238 :     return IdentifyEx(poOpenInfo, bHasHeaderLine);
     287                 : }
     288                 : 
     289                 : /************************************************************************/
     290                 : /*                            IdentifyEx()                              */
     291                 : /************************************************************************/
     292                 : 
     293                 : 
     294            9411 : int XYZDataset::IdentifyEx( GDALOpenInfo * poOpenInfo, int& bHasHeaderLine )
     295                 : 
     296                 : {
     297                 :     int         i;
     298                 : 
     299            9411 :     bHasHeaderLine = FALSE;
     300                 : 
     301            9411 :     CPLString osFilename(poOpenInfo->pszFilename);
     302                 : 
     303            9411 :     GDALOpenInfo* poOpenInfoToDelete = NULL;
     304                 :     /*  GZipped .xyz files are common, so automagically open them */
     305                 :     /*  if the /vsigzip/ has not been explicitely passed */
     306            9411 :     if (strlen(poOpenInfo->pszFilename) > 6 &&
     307                 :         EQUAL(poOpenInfo->pszFilename + strlen(poOpenInfo->pszFilename) - 6, "xyz.gz") &&
     308                 :         !EQUALN(poOpenInfo->pszFilename, "/vsigzip/", 9))
     309                 :     {
     310               0 :         osFilename = "/vsigzip/";
     311               0 :         osFilename += poOpenInfo->pszFilename;
     312                 :         poOpenInfo = poOpenInfoToDelete =
     313                 :                 new GDALOpenInfo(osFilename.c_str(), GA_ReadOnly,
     314               0 :                                  poOpenInfo->papszSiblingFiles);
     315                 :     }
     316                 : 
     317            9411 :     if (poOpenInfo->nHeaderBytes == 0)
     318                 :     {
     319            9236 :         delete poOpenInfoToDelete;
     320            9236 :         return FALSE;
     321                 :     }
     322                 : 
     323                 : /* -------------------------------------------------------------------- */
     324                 : /*      Chech that it looks roughly as a XYZ dataset                    */
     325                 : /* -------------------------------------------------------------------- */
     326             175 :     const char* pszData = (const char*)poOpenInfo->pabyHeader;
     327           13185 :     for(i=0;i<poOpenInfo->nHeaderBytes;i++)
     328                 :     {
     329           13173 :         char ch = pszData[i];
     330           13173 :         if (ch == 13 || ch == 10)
     331                 :         {
     332              18 :             break;
     333                 :         }
     334           13155 :         else if (ch == ' ' || ch == ',' || ch == '\t' || ch == ';')
     335                 :             ;
     336             867 :         else if ((ch >= '0' && ch <= '9') || ch == '.' || ch == '+' ||
     337                 :                  ch == '-' || ch == 'e' || ch == 'E')
     338                 :             ;
     339             461 :         else if (ch == '"' || (ch >= 'a' && ch <= 'z') ||
     340                 :                               (ch >= 'A' && ch <= 'Z'))
     341             158 :             bHasHeaderLine = TRUE;
     342                 :         else
     343                 :         {
     344             145 :             delete poOpenInfoToDelete;
     345             145 :             return FALSE;
     346                 :         }
     347                 :     }
     348              30 :     int bHasFoundNewLine = FALSE;
     349              30 :     int bPrevWasSep = TRUE;
     350              30 :     int nCols = 0;
     351              30 :     int nMaxCols = 0;
     352           16945 :     for(;i<poOpenInfo->nHeaderBytes;i++)
     353                 :     {
     354           16915 :         char ch = pszData[i];
     355           17534 :         if (ch == 13 || ch == 10)
     356                 :         {
     357             619 :             bHasFoundNewLine = TRUE;
     358             619 :             if (!bPrevWasSep)
     359                 :             {
     360             595 :                 nCols ++;
     361             595 :                 if (nCols > nMaxCols)
     362              18 :                     nMaxCols = nCols;
     363                 :             }
     364             619 :             bPrevWasSep = TRUE;
     365             619 :             nCols = 0;
     366                 :         }
     367           17500 :         else if (ch == ' ' || ch == ',' || ch == '\t' || ch == ';')
     368                 :         {
     369            1204 :             if (!bPrevWasSep)
     370                 :             {
     371            1204 :                 nCols ++;
     372            1204 :                 if (nCols > nMaxCols)
     373              36 :                     nMaxCols = nCols;
     374                 :             }
     375            1204 :             bPrevWasSep = TRUE;
     376                 :         }
     377           30184 :         else if ((ch >= '0' && ch <= '9') || ch == '.' || ch == '+' ||
     378                 :                  ch == '-' || ch == 'e' || ch == 'E')
     379                 :         {
     380           15092 :             bPrevWasSep = FALSE;
     381                 :         }
     382                 :         else
     383                 :         {
     384               0 :             delete poOpenInfoToDelete;
     385               0 :             return FALSE;
     386                 :         }
     387                 :     }
     388                 : 
     389              30 :     delete poOpenInfoToDelete;
     390              30 :     return bHasFoundNewLine && nMaxCols >= 3;
     391                 : }
     392                 : 
     393                 : /************************************************************************/
     394                 : /*                                Open()                                */
     395                 : /************************************************************************/
     396                 : 
     397            1173 : GDALDataset *XYZDataset::Open( GDALOpenInfo * poOpenInfo )
     398                 : 
     399                 : {
     400                 :     int         i;
     401                 :     int         bHasHeaderLine;
     402                 : 
     403            1173 :     if (!IdentifyEx(poOpenInfo, bHasHeaderLine))
     404            1155 :         return NULL;
     405                 : 
     406              18 :     CPLString osFilename(poOpenInfo->pszFilename);
     407                 : 
     408                 :     /*  GZipped .xyz files are common, so automagically open them */
     409                 :     /*  if the /vsigzip/ has not been explicitely passed */
     410              18 :     if (strlen(poOpenInfo->pszFilename) > 6 &&
     411                 :         EQUAL(poOpenInfo->pszFilename + strlen(poOpenInfo->pszFilename) - 6, "xyz.gz") &&
     412                 :         !EQUALN(poOpenInfo->pszFilename, "/vsigzip/", 9))
     413                 :     {
     414               0 :         osFilename = "/vsigzip/";
     415               0 :         osFilename += poOpenInfo->pszFilename;
     416                 :     }
     417                 : 
     418                 : /* -------------------------------------------------------------------- */
     419                 : /*      Find dataset characteristics                                    */
     420                 : /* -------------------------------------------------------------------- */
     421              18 :     FILE* fp = VSIFOpenL(osFilename.c_str(), "rb");
     422              18 :     if (fp == NULL)
     423              18 :         return NULL;
     424                 : 
     425                 :     /* For better performance of CPLReadLine2L() we create a buffered reader */
     426                 :     /* (except for /vsigzip/ since it has one internally) */
     427              18 :     if (!EQUALN(poOpenInfo->pszFilename, "/vsigzip/", 9))
     428              18 :         fp = (FILE*) VSICreateBufferedReaderHandle((VSIVirtualHandle*)fp);
     429                 :     
     430                 :     const char* pszLine;
     431              18 :     int nXIndex = -1, nYIndex = -1, nZIndex = -1;
     432              18 :     int nMinTokens = 0;
     433                 :     
     434                 : /* -------------------------------------------------------------------- */
     435                 : /*      Parse header line                                               */
     436                 : /* -------------------------------------------------------------------- */
     437              18 :     if (bHasHeaderLine)
     438                 :     {
     439               4 :         pszLine = CPLReadLine2L(fp, 100, NULL);
     440               4 :         if (pszLine == NULL)
     441                 :         {
     442               0 :             VSIFCloseL(fp);
     443               0 :             return NULL;
     444                 :         }
     445                 :         char** papszTokens = CSLTokenizeString2( pszLine, " ,\t;",
     446               4 :                                                  CSLT_HONOURSTRINGS );
     447               4 :         int nTokens = CSLCount(papszTokens);
     448               4 :         if (nTokens < 3)
     449                 :         {
     450                 :             CPLError(CE_Failure, CPLE_AppDefined,
     451                 :                      "At line %d, found %d tokens. Expected 3 at least",
     452               0 :                       1, nTokens);
     453               0 :             CSLDestroy(papszTokens);
     454               0 :             VSIFCloseL(fp);
     455               0 :             return NULL;
     456                 :         }
     457                 :         int i;
     458              16 :         for(i=0;i<nTokens;i++)
     459                 :         {
     460              16 :             if (EQUAL(papszTokens[i], "x") ||
     461                 :                 EQUALN(papszTokens[i], "lon", 3) ||
     462                 :                 EQUALN(papszTokens[i], "east", 4))
     463               4 :                 nXIndex = i;
     464              12 :             else if (EQUAL(papszTokens[i], "y") ||
     465                 :                      EQUALN(papszTokens[i], "lat", 3) ||
     466                 :                      EQUALN(papszTokens[i], "north", 5))
     467               4 :                 nYIndex = i;
     468               4 :             else if (EQUAL(papszTokens[i], "z") ||
     469                 :                      EQUALN(papszTokens[i], "alt", 3) ||
     470                 :                      EQUAL(papszTokens[i], "height"))
     471               4 :                 nZIndex = i;
     472                 :         }
     473               4 :         CSLDestroy(papszTokens);
     474               4 :         papszTokens = NULL;
     475               4 :         if (nXIndex < 0 || nYIndex < 0 || nZIndex < 0)
     476                 :         {
     477                 :             CPLError(CE_Warning, CPLE_AppDefined,
     478               0 :                      "Could not find one of the X, Y or Z column names in header line. Defaulting to the first 3 columns");
     479               0 :             nXIndex = 0;
     480               0 :             nYIndex = 1;
     481               0 :             nZIndex = 2;
     482                 :         }
     483               4 :         nMinTokens = 1 + MAX(MAX(nXIndex, nYIndex), nZIndex);
     484                 :     }
     485                 :     else
     486                 :     {
     487              14 :         nXIndex = 0;
     488              14 :         nYIndex = 1;
     489              14 :         nZIndex = 2;
     490              14 :         nMinTokens = 3;
     491                 :     }
     492                 :     
     493                 : /* -------------------------------------------------------------------- */
     494                 : /*      Parse data lines                                                */
     495                 : /* -------------------------------------------------------------------- */
     496                 : 
     497              18 :     int nXSize = 0, nYSize = 0;
     498              18 :     int nLineNum = 0;
     499              18 :     int nDataLineNum = 0;
     500              18 :     double dfFirstX = 0;
     501              18 :     double dfX = 0, dfY = 0, dfZ = 0;
     502              18 :     double dfMinX = 0, dfMinY = 0, dfMaxX = 0, dfMaxY = 0;
     503              18 :     double dfLastX = 0, dfLastY = 0;
     504              18 :     double dfStepX = 0, dfStepY = 0;
     505              18 :     GDALDataType eDT = GDT_Byte;
     506          123551 :     while((pszLine = CPLReadLine2L(fp, 100, NULL)) != NULL)
     507                 :     {
     508          123515 :         nLineNum ++;
     509                 : 
     510          123515 :         const char* pszPtr = pszLine;
     511                 :         char ch;
     512          123515 :         int nCol = 0;
     513          123515 :         int bLastWasSep = TRUE;
     514         4241668 :         while((ch = *pszPtr) != '\0')
     515                 :         {
     516         4241656 :             if (ch == ' ' || ch == ',' || ch == '\t' || ch == ';')
     517                 :             {
     518          247018 :                 if (!bLastWasSep)
     519          247018 :                     nCol ++;
     520          247018 :                 bLastWasSep = TRUE;
     521                 :             }
     522                 :             else
     523                 :             {
     524         3747620 :                 if (bLastWasSep)
     525                 :                 {
     526          370527 :                     if (nCol == nXIndex)
     527          123509 :                         dfX = CPLAtofM(pszPtr);
     528          247018 :                     else if (nCol == nYIndex)
     529          123509 :                         dfY = CPLAtofM(pszPtr);
     530          123509 :                     else if (nCol == nZIndex && eDT != GDT_Float32)
     531                 :                     {
     532           15131 :                         dfZ = CPLAtofM(pszPtr);
     533           15131 :                         int nZ = (int)dfZ;
     534           15131 :                         if ((double)nZ != dfZ)
     535                 :                         {
     536               3 :                             eDT = GDT_Float32;
     537                 :                         }
     538           15128 :                         else if ((eDT == GDT_Byte || eDT == GDT_Int16) && (nZ < 0 || nZ > 255))
     539                 :                         {
     540               0 :                             if (nZ < -32768 || nZ > 32767)
     541               0 :                                 eDT = GDT_Int32;
     542                 :                             else
     543               0 :                                 eDT = GDT_Int16;
     544                 :                         }
     545                 :                     }
     546                 :                 }
     547         3747620 :                 bLastWasSep = FALSE;
     548                 :             }
     549         3994638 :             pszPtr ++;
     550                 :         }
     551                 :         /* skip empty lines */
     552          123515 :         if (bLastWasSep && nCol == 0)
     553                 :         {
     554               6 :             continue;
     555                 :         }
     556          123509 :         nDataLineNum ++;
     557          123509 :         nCol ++;
     558          123509 :         if (nCol < nMinTokens)
     559                 :         {
     560                 :             CPLError(CE_Failure, CPLE_AppDefined,
     561                 :                      "At line %d, found %d tokens. Expected %d at least",
     562               0 :                       nLineNum, nCol, nMinTokens);
     563               0 :             VSIFCloseL(fp);
     564               0 :             return NULL;
     565                 :         }
     566                 : 
     567          123509 :         if (nDataLineNum == 1)
     568                 :         {
     569              18 :             dfFirstX = dfMinX = dfMaxX = dfX;
     570              18 :             dfMinY = dfMaxY = dfY;
     571                 :         }
     572                 :         else
     573                 :         {
     574          123491 :             if (dfX < dfMinX) dfMinX = dfX;
     575          123491 :             if (dfX > dfMaxX) dfMaxX = dfX;
     576          123491 :             if (dfY < dfMinY) dfMinY = dfY;
     577          123491 :             if (dfY > dfMaxY) dfMaxY = dfY;
     578                 :         }
     579          123509 :         if (nDataLineNum == 2)
     580                 :         {
     581              18 :             dfStepX = dfX - dfLastX;
     582              18 :             if (dfStepX <= 0)
     583                 :             {
     584                 :                 CPLError(CE_Failure, CPLE_AppDefined,
     585                 :                          "Ungridded dataset: At line %d, X spacing was %f. Expected >0 value",
     586               0 :                          nLineNum, dfStepX);
     587               0 :                 VSIFCloseL(fp);
     588               0 :                 return NULL;
     589                 :             }
     590                 :         }
     591          123491 :         else if (nDataLineNum > 2)
     592                 :         {
     593          123473 :             double dfNewStepX = dfX - dfLastX;
     594          123473 :             double dfNewStepY = dfY - dfLastY;
     595          123473 :             if (dfNewStepY != 0)
     596                 :             {
     597             758 :                 nYSize ++;
     598             758 :                 if (dfStepY == 0)
     599                 :                 {
     600              18 :                     nXSize = nDataLineNum - 1;
     601              18 :                     double dfAdjustedStepX = (dfMaxX - dfMinX) / (nXSize - 1);
     602              18 :                     if (fabs(dfStepX - dfAdjustedStepX) > 1e-8)
     603                 :                     {
     604               0 :                         CPLDebug("XYZ", "Adjusting stepx from %f to %f", dfStepX, dfAdjustedStepX);
     605                 :                     }
     606              18 :                     dfStepX = dfAdjustedStepX;
     607                 :                 }
     608             758 :                 if (dfStepY != 0 && fabs(dfX - dfFirstX) > 1e-8)
     609                 :                 {
     610                 :                     CPLError(CE_Failure, CPLE_AppDefined,
     611                 :                              "Ungridded dataset: At line %d, X is %f, where as %f was expected",
     612               0 :                              nLineNum, dfX, dfFirstX);
     613               0 :                     VSIFCloseL(fp);
     614               0 :                     return NULL;
     615                 :                 }
     616             758 :                 if (dfStepY != 0 && fabs(dfLastX - dfMaxX) > 1e-8)
     617                 :                 {
     618                 :                     CPLError(CE_Failure, CPLE_AppDefined,
     619                 :                              "Ungridded dataset: At line %d, X is %f, where as %f was expected",
     620               0 :                              nLineNum - 1, dfLastX, dfMaxX);
     621               0 :                     VSIFCloseL(fp);
     622               0 :                     return NULL;
     623                 :                 }
     624                 :                 /*if (dfStepY != 0 && fabs(dfNewStepY - dfStepY) > 1e-8)
     625                 :                 {
     626                 :                     CPLError(CE_Failure, CPLE_AppDefined,
     627                 :                              "Ungridded dataset: At line %d, Y spacing was %f, whereas it was %f before",
     628                 :                              nLineNum, dfNewStepY, dfStepY);
     629                 :                     VSIFCloseL(fp);
     630                 :                     return NULL;
     631                 :                 }*/
     632             758 :                 dfStepY = dfNewStepY;
     633                 :             }
     634                 :             else if (dfNewStepX != 0)
     635                 :             {
     636                 :                 /*if (dfStepX != 0 && fabs(dfNewStepX - dfStepX) > 1e-8)
     637                 :                 {
     638                 :                     CPLError(CE_Failure, CPLE_AppDefined,
     639                 :                              "At line %d, X spacing was %f, whereas it was %f before",
     640                 :                              nLineNum, dfNewStepX, dfStepX);
     641                 :                     VSIFCloseL(fp);
     642                 :                     return NULL;
     643                 :                 }*/
     644                 :             }
     645                 :         }
     646          123509 :         dfLastX = dfX;
     647          123509 :         dfLastY = dfY;
     648                 :     }
     649              18 :     nYSize ++;
     650                 : 
     651              18 :     if (dfStepX == 0)
     652                 :     {
     653               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Couldn't determine X spacing");
     654               0 :         VSIFCloseL(fp);
     655               0 :         return NULL;
     656                 :     }
     657                 : 
     658              18 :     if (dfStepY == 0)
     659                 :     {
     660               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Couldn't determine Y spacing");
     661               0 :         VSIFCloseL(fp);
     662               0 :         return NULL;
     663                 :     }
     664                 : 
     665              18 :     double dfAdjustedStepY = ((dfStepY < 0) ? -1 : 1) * (dfMaxY - dfMinY) / (nYSize - 1);
     666              18 :     if (fabs(dfStepY - dfAdjustedStepY) > 1e-8)
     667                 :     {
     668               0 :         CPLDebug("XYZ", "Adjusting stepy from %f to %f", dfStepY, dfAdjustedStepY);
     669                 :     }
     670              18 :     dfStepY = dfAdjustedStepY;
     671                 : 
     672                 :     //CPLDebug("XYZ", "minx=%f maxx=%f stepx=%f", dfMinX, dfMaxX, dfStepX);
     673                 :     //CPLDebug("XYZ", "miny=%f maxy=%f stepy=%f", dfMinY, dfMaxY, dfStepY);
     674                 : 
     675              18 :     if (nDataLineNum != nXSize * nYSize)
     676                 :     {
     677                 :         CPLError(CE_Failure, CPLE_AppDefined, "Found %d lines. Expected %d",
     678               0 :                  nDataLineNum,nXSize * nYSize);
     679               0 :         VSIFCloseL(fp);
     680               0 :         return NULL;
     681                 :     }
     682                 :     
     683              18 :     if (poOpenInfo->eAccess == GA_Update)
     684                 :     {
     685                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     686                 :                   "The XYZ driver does not support update access to existing"
     687               0 :                   " datasets.\n" );
     688               0 :         VSIFCloseL(fp);
     689               0 :         return NULL;
     690                 :     }
     691                 : 
     692                 : /* -------------------------------------------------------------------- */
     693                 : /*      Create a corresponding GDALDataset.                             */
     694                 : /* -------------------------------------------------------------------- */
     695                 :     XYZDataset         *poDS;
     696                 : 
     697              18 :     poDS = new XYZDataset();
     698              18 :     poDS->fp = fp;
     699              18 :     poDS->bHasHeaderLine = bHasHeaderLine;
     700              18 :     poDS->nXIndex = nXIndex;
     701              18 :     poDS->nYIndex = nYIndex;
     702              18 :     poDS->nZIndex = nZIndex;
     703              18 :     poDS->nMinTokens = nMinTokens;
     704              18 :     poDS->nRasterXSize = nXSize;
     705              18 :     poDS->nRasterYSize = nYSize;
     706              18 :     poDS->adfGeoTransform[0] = dfMinX - dfStepX / 2;
     707              18 :     poDS->adfGeoTransform[1] = dfStepX;
     708                 :     poDS->adfGeoTransform[3] = (dfStepY < 0) ? dfMaxY - dfStepY / 2 :
     709              35 :                                                dfMinY - dfStepY / 2;
     710              18 :     poDS->adfGeoTransform[5] = dfStepY;
     711                 : 
     712              18 :     if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize))
     713                 :     {
     714               0 :         delete poDS;
     715               0 :         return NULL;
     716                 :     }
     717                 : 
     718                 : /* -------------------------------------------------------------------- */
     719                 : /*      Create band information objects.                                */
     720                 : /* -------------------------------------------------------------------- */
     721              18 :     poDS->nBands = 1;
     722              36 :     for( i = 0; i < poDS->nBands; i++ )
     723              18 :         poDS->SetBand( i+1, new XYZRasterBand( poDS, i+1, eDT ) );
     724                 : 
     725                 : /* -------------------------------------------------------------------- */
     726                 : /*      Initialize any PAM information.                                 */
     727                 : /* -------------------------------------------------------------------- */
     728              18 :     poDS->SetDescription( poOpenInfo->pszFilename );
     729              18 :     poDS->TryLoadXML();
     730                 : 
     731                 : /* -------------------------------------------------------------------- */
     732                 : /*      Support overviews.                                              */
     733                 : /* -------------------------------------------------------------------- */
     734              18 :     poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
     735              18 :     return( poDS );
     736                 : }
     737                 : 
     738                 : /************************************************************************/
     739                 : /*                             CreateCopy()                             */
     740                 : /************************************************************************/
     741                 : 
     742                 : GDALDataset* XYZDataset::CreateCopy( const char * pszFilename,
     743                 :                                      GDALDataset *poSrcDS, 
     744                 :                                      int bStrict, char ** papszOptions, 
     745                 :                                      GDALProgressFunc pfnProgress,
     746              18 :                                      void * pProgressData )
     747                 : {
     748                 : /* -------------------------------------------------------------------- */
     749                 : /*      Some some rudimentary checks                                    */
     750                 : /* -------------------------------------------------------------------- */
     751              18 :     int nBands = poSrcDS->GetRasterCount();
     752              18 :     if (nBands == 0)
     753                 :     {
     754                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     755               1 :                   "XYZ driver does not support source dataset with zero band.\n");
     756               1 :         return NULL;
     757                 :     }
     758                 : 
     759              17 :     if (nBands != 1)
     760                 :     {
     761                 :         CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, 
     762               4 :                   "XYZ driver only uses the first band of the dataset.\n");
     763               4 :         if (bStrict)
     764               4 :             return NULL;
     765                 :     }
     766                 : 
     767              13 :     if( pfnProgress && !pfnProgress( 0.0, NULL, pProgressData ) )
     768               0 :         return NULL;
     769                 : 
     770                 : /* -------------------------------------------------------------------- */
     771                 : /*      Get source dataset info                                         */
     772                 : /* -------------------------------------------------------------------- */
     773                 : 
     774              13 :     int nXSize = poSrcDS->GetRasterXSize();
     775              13 :     int nYSize = poSrcDS->GetRasterYSize();
     776                 :     double adfGeoTransform[6];
     777              13 :     poSrcDS->GetGeoTransform(adfGeoTransform);
     778              13 :     if (adfGeoTransform[2] != 0 || adfGeoTransform[4] != 0)
     779                 :     {
     780                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     781               0 :                   "XYZ driver does not support CreateCopy() from skewed or rotated dataset.\n");
     782               0 :         return NULL;
     783                 :     }
     784                 : 
     785              13 :     GDALDataType eSrcDT = poSrcDS->GetRasterBand(1)->GetRasterDataType();
     786                 :     GDALDataType eReqDT;
     787              18 :     if (eSrcDT == GDT_Byte || eSrcDT == GDT_Int16 ||
     788                 :         eSrcDT == GDT_UInt16 || eSrcDT == GDT_Int32)
     789               5 :         eReqDT = GDT_Int32;
     790                 :     else
     791               8 :         eReqDT = GDT_Float32;
     792                 : 
     793                 : /* -------------------------------------------------------------------- */
     794                 : /*      Create target file                                              */
     795                 : /* -------------------------------------------------------------------- */
     796                 : 
     797              13 :     FILE* fp = VSIFOpenL(pszFilename, "wb");
     798              13 :     if (fp == NULL)
     799                 :     {
     800                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     801               0 :                   "Cannot create %s", pszFilename );
     802               0 :         return NULL;
     803                 :     }
     804                 : 
     805                 : /* -------------------------------------------------------------------- */
     806                 : /*      Read creation options                                           */
     807                 : /* -------------------------------------------------------------------- */
     808                 :     const char* pszColSep =
     809              13 :             CSLFetchNameValue(papszOptions, "COLUMN_SEPARATOR");
     810              13 :     if (pszColSep == NULL)
     811              12 :         pszColSep = " ";
     812               1 :     else if (EQUAL(pszColSep, "COMMA"))
     813               0 :         pszColSep = ",";
     814               1 :     else if (EQUAL(pszColSep, "SPACE"))
     815               0 :         pszColSep = " ";
     816               1 :     else if (EQUAL(pszColSep, "SEMICOLON"))
     817               0 :         pszColSep = ";";
     818               1 :     else if (EQUAL(pszColSep, "\\t") || EQUAL(pszColSep, "TAB"))
     819               0 :         pszColSep = "\t";
     820                 : 
     821                 :     const char* pszAddHeaderLine =
     822              13 :             CSLFetchNameValue(papszOptions, "ADD_HEADER_LINE");
     823              13 :     if (pszAddHeaderLine != NULL && CSLTestBoolean(pszAddHeaderLine))
     824                 :     {
     825               1 :         VSIFPrintfL(fp, "X%sY%sZ\n", pszColSep, pszColSep);
     826                 :     }
     827                 : 
     828                 : /* -------------------------------------------------------------------- */
     829                 : /*      Copy imagery                                                    */
     830                 : /* -------------------------------------------------------------------- */
     831              13 :     void* pLineBuffer = (void*) CPLMalloc(nXSize * sizeof(int));
     832                 :     int i, j;
     833             344 :     for(j=0;j<nYSize;j++)
     834                 :     {
     835                 :         CPLErr eErr = poSrcDS->GetRasterBand(1)->RasterIO(
     836                 :                                             GF_Read, 0, j, nXSize, 1,
     837                 :                                             pLineBuffer, nXSize, 1,
     838             331 :                                             eReqDT, 0, 0);
     839             331 :         if (eErr != CE_None)
     840               0 :             break;
     841             331 :         double dfY = adfGeoTransform[3] + (j + 0.5) * adfGeoTransform[5];
     842           42232 :         for(i=0;i<nXSize;i++)
     843                 :         {
     844           41901 :             double dfX = adfGeoTransform[0] + (i + 0.5) * adfGeoTransform[1];
     845           41901 :             VSIFPrintfL(fp, "%.18g%s%.18g%s", dfX, pszColSep, dfY, pszColSep);
     846           41901 :             if (eReqDT == GDT_Int32)
     847             800 :                 VSIFPrintfL(fp, "%d\n", ((int*)pLineBuffer)[i]);
     848                 :             else
     849           41101 :                 VSIFPrintfL(fp, "%.18g\n", ((float*)pLineBuffer)[i]);
     850                 :         }
     851             331 :         if (!pfnProgress( (j+1) * 1.0 / nYSize, NULL, pProgressData))
     852               0 :             break;
     853                 :     }
     854              13 :     CPLFree(pLineBuffer);
     855              13 :     VSIFCloseL(fp);
     856                 : 
     857              13 :     return (GDALDataset*) GDALOpen(pszFilename, GA_ReadOnly);
     858                 : }
     859                 : 
     860                 : /************************************************************************/
     861                 : /*                          GetGeoTransform()                           */
     862                 : /************************************************************************/
     863                 : 
     864               1 : CPLErr XYZDataset::GetGeoTransform( double * padfTransform )
     865                 : 
     866                 : {
     867               1 :     memcpy(padfTransform, adfGeoTransform, 6 * sizeof(double));
     868                 : 
     869               1 :     return( CE_None );
     870                 : }
     871                 : 
     872                 : /************************************************************************/
     873                 : /*                         GDALRegister_XYZ()                           */
     874                 : /************************************************************************/
     875                 : 
     876             409 : void GDALRegister_XYZ()
     877                 : 
     878                 : {
     879                 :     GDALDriver  *poDriver;
     880                 : 
     881             409 :     if( GDALGetDriverByName( "XYZ" ) == NULL )
     882                 :     {
     883             392 :         poDriver = new GDALDriver();
     884                 :         
     885             392 :         poDriver->SetDescription( "XYZ" );
     886                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     887             392 :                                    "ASCII Gridded XYZ" );
     888                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
     889             392 :                                    "frmt_xyz.html" );
     890             392 :         poDriver->SetMetadataItem( GDAL_DMD_EXTENSION, "xyz" );
     891                 :         poDriver->SetMetadataItem( GDAL_DMD_CREATIONOPTIONLIST,
     892                 : "<CreationOptionList>"
     893                 : "   <Option name='COLUMN_SEPARATOR' type='string' default=' ' description='Separator between fields.'/>"
     894                 : "   <Option name='ADD_HEADER_LINE' type='boolean' default='false' description='Add an header line with column names.'/>"
     895             392 : "</CreationOptionList>");
     896                 : 
     897             392 :         poDriver->SetMetadataItem( GDAL_DCAP_VIRTUALIO, "YES" );
     898                 : 
     899             392 :         poDriver->pfnOpen = XYZDataset::Open;
     900             392 :         poDriver->pfnIdentify = XYZDataset::Identify;
     901             392 :         poDriver->pfnCreateCopy = XYZDataset::CreateCopy;
     902                 : 
     903             392 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     904                 :     }
     905             409 : }
     906                 : 

Generated by: LTP GCOV extension version 1.5