LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/idrisi - ogridrisilayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 152 128 84.2 %
Date: 2011-12-18 Functions: 12 9 75.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogridrisilayer.cpp 23388 2011-11-18 23:34:35Z rouault $
       3                 :  *
       4                 :  * Project:  Idrisi Translator
       5                 :  * Purpose:  Implements OGRIdrisiLayer class.
       6                 :  * Author:   Even Rouault, <even dot rouault at mines dash paris dot org>
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2011, Even Rouault <even dot rouault at mines dash paris dot org>
      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 "ogr_idrisi.h"
      31                 : #include "cpl_conv.h"
      32                 : #include "cpl_string.h"
      33                 : #include "ogr_p.h"
      34                 : #include "ogr_srs_api.h"
      35                 : 
      36                 : CPL_CVSID("$Id: ogridrisilayer.cpp 23388 2011-11-18 23:34:35Z rouault $");
      37                 : 
      38                 : /************************************************************************/
      39                 : /*                         OGRIdrisiLayer()                             */
      40                 : /************************************************************************/
      41                 : 
      42               3 : OGRIdrisiLayer::OGRIdrisiLayer( const char* pszLayerName, VSILFILE* fp,
      43                 :                                 OGRwkbGeometryType eGeomType,
      44               3 :                                 const char* pszWTKString )
      45                 : 
      46                 : {
      47               3 :     this->fp = fp;
      48               3 :     this->eGeomType = eGeomType;
      49               3 :     nNextFID = 1;
      50               3 :     bEOF = FALSE;
      51                 : 
      52               3 :     if (pszWTKString)
      53                 :     {
      54               3 :         poSRS = new OGRSpatialReference();
      55               3 :         char* pszTmp = (char*)pszWTKString;
      56               3 :         poSRS->importFromWkt(&pszTmp);
      57                 :     }
      58                 :     else
      59               0 :         poSRS = NULL;
      60                 : 
      61               3 :     poFeatureDefn = new OGRFeatureDefn( pszLayerName );
      62               3 :     poFeatureDefn->Reference();
      63               3 :     poFeatureDefn->SetGeomType( eGeomType );
      64                 : 
      65               3 :     OGRFieldDefn oFieldDefn("id", OFTReal);
      66               3 :     poFeatureDefn->AddFieldDefn( &oFieldDefn );
      67                 : 
      68               3 :     bExtentValid = FALSE;
      69               3 :     dfMinX = dfMinY = dfMaxX = dfMaxY = 0.0;
      70                 : 
      71               3 :     VSIFSeekL( fp, 1, SEEK_SET );
      72               3 :     if (VSIFReadL( &nTotalFeatures, sizeof(unsigned int), 1, fp ) != 1)
      73               0 :         nTotalFeatures = 0;
      74                 :     CPL_LSBPTR32(&nTotalFeatures);
      75                 : 
      76               3 :     ResetReading();
      77               3 : }
      78                 : 
      79                 : /************************************************************************/
      80                 : /*                          ~OGRIdrisiLayer()                           */
      81                 : /************************************************************************/
      82                 : 
      83               3 : OGRIdrisiLayer::~OGRIdrisiLayer()
      84                 : 
      85                 : {
      86               3 :     if( poSRS != NULL )
      87               3 :         poSRS->Release();
      88                 : 
      89               3 :     poFeatureDefn->Release();
      90                 : 
      91               3 :     VSIFCloseL( fp );
      92               3 : }
      93                 : 
      94                 : /************************************************************************/
      95                 : /*                            ResetReading()                            */
      96                 : /************************************************************************/
      97                 : 
      98              11 : void OGRIdrisiLayer::ResetReading()
      99                 : 
     100                 : {
     101              11 :     nNextFID = 1;
     102              11 :     bEOF = FALSE;
     103              11 :     VSIFSeekL( fp, 0x105, SEEK_SET );
     104              11 : }
     105                 : 
     106                 : /************************************************************************/
     107                 : /*                           GetNextFeature()                           */
     108                 : /************************************************************************/
     109                 : 
     110               9 : OGRFeature *OGRIdrisiLayer::GetNextFeature()
     111                 : {
     112                 :     OGRFeature  *poFeature;
     113                 : 
     114               0 :     while(TRUE)
     115                 :     {
     116               9 :         if (bEOF)
     117               0 :             return NULL;
     118                 : 
     119               9 :         poFeature = GetNextRawFeature();
     120               9 :         if (poFeature == NULL)
     121                 :         {
     122               3 :             bEOF = TRUE;
     123               3 :             return NULL;
     124                 :         }
     125                 : 
     126               6 :         if((m_poFilterGeom == NULL
     127                 :             || FilterGeometry( poFeature->GetGeometryRef() ) )
     128                 :         && (m_poAttrQuery == NULL
     129                 :             || m_poAttrQuery->Evaluate( poFeature )) )
     130                 :         {
     131               6 :             return poFeature;
     132                 :         }
     133                 :         else
     134               0 :             delete poFeature;
     135                 :     }
     136                 : }
     137                 : 
     138                 : /************************************************************************/
     139                 : /*                           TestCapability()                           */
     140                 : /************************************************************************/
     141                 : 
     142               6 : int OGRIdrisiLayer::TestCapability( const char * pszCap )
     143                 : 
     144                 : {
     145               6 :     if (EQUAL(pszCap, OLCFastFeatureCount))
     146               3 :         return m_poFilterGeom == NULL && m_poAttrQuery == NULL;
     147                 : 
     148               3 :     if (EQUAL(pszCap, OLCFastGetExtent))
     149               3 :         return bExtentValid;
     150                 : 
     151               0 :     return FALSE;
     152                 : }
     153                 : 
     154                 : /************************************************************************/
     155                 : /*                         GetNextRawFeature()                          */
     156                 : /************************************************************************/
     157                 : 
     158              15 : OGRFeature *OGRIdrisiLayer::GetNextRawFeature()
     159                 : {
     160               6 :     while(TRUE)
     161                 :     {
     162              15 :         if (eGeomType == wkbPoint)
     163                 :         {
     164                 :             double dfId;
     165                 :             double dfX, dfY;
     166               7 :             if (VSIFReadL(&dfId, sizeof(double), 1, fp) != 1 ||
     167                 :                 VSIFReadL(&dfX, sizeof(double), 1, fp) != 1 ||
     168                 :                 VSIFReadL(&dfY, sizeof(double), 1, fp) != 1)
     169                 :             {
     170               1 :                 return NULL;
     171                 :             }
     172                 :             CPL_LSBPTR64(&dfId);
     173                 :             CPL_LSBPTR64(&dfX);
     174                 :             CPL_LSBPTR64(&dfY);
     175                 : 
     176               6 :             if (m_poFilterGeom != NULL &&
     177                 :                 (dfX < m_sFilterEnvelope.MinX ||
     178                 :                  dfX > m_sFilterEnvelope.MaxX ||
     179                 :                  dfY < m_sFilterEnvelope.MinY ||
     180                 :                  dfY > m_sFilterEnvelope.MaxY))
     181                 :             {
     182               3 :                 nNextFID ++;
     183               3 :                 continue;
     184                 :             }
     185                 : 
     186               3 :             OGRPoint* poGeom = new OGRPoint(dfX, dfY);
     187               3 :             if (poSRS)
     188               3 :                 poGeom->assignSpatialReference(poSRS);
     189               3 :             OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
     190               3 :             poFeature->SetField(0, dfId);
     191               3 :             poFeature->SetFID(nNextFID ++);
     192               3 :             poFeature->SetGeometryDirectly(poGeom);
     193               3 :             return poFeature;
     194                 :         }
     195               8 :         else if (eGeomType == wkbLineString)
     196                 :         {
     197                 :             double dfId;
     198                 :             double dfMinXShape, dfMaxXShape, dfMinYShape, dfMaxYShape;
     199                 :             unsigned int nNodes;
     200                 : 
     201               5 :             if (VSIFReadL(&dfId, sizeof(double), 1, fp) != 1 ||
     202                 :                 VSIFReadL(&dfMinXShape, sizeof(double), 1, fp) != 1 ||
     203                 :                 VSIFReadL(&dfMaxXShape, sizeof(double), 1, fp) != 1 ||
     204                 :                 VSIFReadL(&dfMinYShape, sizeof(double), 1, fp) != 1 ||
     205                 :                 VSIFReadL(&dfMaxYShape, sizeof(double), 1, fp) != 1)
     206                 :             {
     207               1 :                 return NULL;
     208                 :             }
     209                 :             CPL_LSBPTR64(&dfId);
     210                 :             CPL_LSBPTR64(&dfMinXShape);
     211                 :             CPL_LSBPTR64(&dfMaxXShape);
     212                 :             CPL_LSBPTR64(&dfMinYShape);
     213                 :             CPL_LSBPTR64(&dfMaxYShape);
     214                 : 
     215               4 :             if (VSIFReadL(&nNodes, sizeof(unsigned int), 1, fp) != 1)
     216                 :             {
     217               0 :                 return NULL;
     218                 :             }
     219                 :             CPL_LSBPTR32(&nNodes);
     220                 : 
     221               4 :             if (nNodes > 100 * 1000 * 1000)
     222               0 :                 return NULL;
     223                 : 
     224               4 :             if (m_poFilterGeom != NULL &&
     225                 :                 (dfMaxXShape < m_sFilterEnvelope.MinX ||
     226                 :                  dfMinXShape > m_sFilterEnvelope.MaxX ||
     227                 :                  dfMaxYShape < m_sFilterEnvelope.MinY ||
     228                 :                  dfMinYShape > m_sFilterEnvelope.MaxY))
     229                 :             {
     230               2 :                 nNextFID ++;
     231               2 :                 VSIFSeekL(fp, sizeof(OGRRawPoint) * nNodes, SEEK_CUR);
     232               2 :                 continue;
     233                 :             }
     234                 : 
     235               2 :             OGRRawPoint* poRawPoints = (OGRRawPoint*)VSIMalloc2(sizeof(OGRRawPoint), nNodes);
     236               2 :             if (poRawPoints == NULL)
     237                 :             {
     238               0 :                 return NULL;
     239                 :             }
     240                 : 
     241               2 :             if ((unsigned int)VSIFReadL(poRawPoints, sizeof(OGRRawPoint), nNodes, fp) != nNodes)
     242                 :             {
     243               0 :                 VSIFree(poRawPoints);
     244               0 :                 return NULL;
     245                 :             }
     246                 : 
     247                 : #if defined(CPL_MSB)
     248                 :             for(unsigned int iNode=0; iNode<nNodes; iNode++)
     249                 :             {
     250                 :                 CPL_LSBPTR64(&poRawPoints[iNode].x);
     251                 :                 CPL_LSBPTR64(&poRawPoints[iNode].y);
     252                 :             }
     253                 : #endif
     254                 : 
     255               2 :             OGRLineString* poGeom = new OGRLineString();
     256               2 :             poGeom->setPoints(nNodes, poRawPoints, NULL);
     257                 : 
     258               2 :             VSIFree(poRawPoints);
     259                 : 
     260               2 :             if (poSRS)
     261               2 :                 poGeom->assignSpatialReference(poSRS);
     262               2 :             OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
     263               2 :             poFeature->SetField(0, dfId);
     264               2 :             poFeature->SetFID(nNextFID ++);
     265               2 :             poFeature->SetGeometryDirectly(poGeom);
     266               2 :             return poFeature;
     267                 :         }
     268                 :         else /* if (eGeomType == wkbPolygon) */
     269                 :         {
     270                 :             double dfId;
     271                 :             double dfMinXShape, dfMaxXShape, dfMinYShape, dfMaxYShape;
     272                 :             unsigned int nParts;
     273                 :             unsigned int nTotalNodes;
     274                 : 
     275               3 :             if (VSIFReadL(&dfId, sizeof(double), 1, fp) != 1 ||
     276                 :                 VSIFReadL(&dfMinXShape, sizeof(double), 1, fp) != 1 ||
     277                 :                 VSIFReadL(&dfMaxXShape, sizeof(double), 1, fp) != 1 ||
     278                 :                 VSIFReadL(&dfMinYShape, sizeof(double), 1, fp) != 1 ||
     279                 :                 VSIFReadL(&dfMaxYShape, sizeof(double), 1, fp) != 1)
     280                 :             {
     281               1 :                 return NULL;
     282                 :             }
     283                 :             CPL_LSBPTR64(&dfId);
     284                 :             CPL_LSBPTR64(&dfMinXShape);
     285                 :             CPL_LSBPTR64(&dfMaxXShape);
     286                 :             CPL_LSBPTR64(&dfMinYShape);
     287                 :             CPL_LSBPTR64(&dfMaxYShape);
     288               2 :             if (VSIFReadL(&nParts, sizeof(unsigned int), 1, fp) != 1 ||
     289                 :                 VSIFReadL(&nTotalNodes, sizeof(unsigned int), 1, fp) != 1)
     290                 :             {
     291               0 :                 return NULL;
     292                 :             }
     293                 :             CPL_LSBPTR32(&nParts);
     294                 :             CPL_LSBPTR32(&nTotalNodes);
     295                 : 
     296               2 :             if (nParts > 100000 || nTotalNodes > 100 * 1000 * 1000)
     297               0 :                 return NULL;
     298                 : 
     299               2 :             if (m_poFilterGeom != NULL &&
     300                 :                 (dfMaxXShape < m_sFilterEnvelope.MinX ||
     301                 :                  dfMinXShape > m_sFilterEnvelope.MaxX ||
     302                 :                  dfMaxYShape < m_sFilterEnvelope.MinY ||
     303                 :                  dfMinYShape > m_sFilterEnvelope.MaxY))
     304                 :             {
     305                 :                 unsigned int iPart;
     306               3 :                 for(iPart = 0; iPart < nParts; iPart ++)
     307                 :                 {
     308                 :                     unsigned int nNodes;
     309               2 :                     if (VSIFReadL(&nNodes, sizeof(unsigned int), 1, fp) != 1)
     310               0 :                         return NULL;
     311                 :                     CPL_LSBPTR32(&nNodes);
     312               2 :                     if (nNodes > nTotalNodes)
     313               0 :                         return NULL;
     314               2 :                     VSIFSeekL(fp, sizeof(OGRRawPoint) * nNodes, SEEK_CUR);
     315                 :                 }
     316               1 :                 nNextFID ++;
     317               1 :                 continue;
     318                 :             }
     319                 : 
     320               1 :             OGRRawPoint* poRawPoints = (OGRRawPoint*)VSIMalloc2(sizeof(OGRRawPoint), nTotalNodes);
     321               1 :             if (poRawPoints == NULL)
     322                 :             {
     323               0 :                 return NULL;
     324                 :             }
     325                 : 
     326                 :             unsigned int iPart;
     327               1 :             OGRPolygon* poGeom = new OGRPolygon();
     328               6 :             for(iPart = 0; iPart < nParts; iPart ++)
     329                 :             {
     330                 :                 unsigned int nNodes;
     331               2 :                 if (VSIFReadL(&nNodes, sizeof(unsigned int), 1, fp) != 1)
     332                 :                 {
     333               0 :                     VSIFree(poRawPoints);
     334               0 :                     delete poGeom;
     335               0 :                     return NULL;
     336                 :                 }
     337                 :                 CPL_LSBPTR32(&nNodes);
     338                 : 
     339               2 :                 if (nNodes > nTotalNodes ||
     340                 :                     (unsigned int)VSIFReadL(poRawPoints, sizeof(OGRRawPoint), nNodes, fp) != nNodes)
     341                 :                 {
     342               0 :                     VSIFree(poRawPoints);
     343               0 :                     delete poGeom;
     344               0 :                     return NULL;
     345                 :                 }
     346                 : 
     347                 : #if defined(CPL_MSB)
     348                 :                 for(unsigned int iNode=0; iNode<nNodes; iNode++)
     349                 :                 {
     350                 :                     CPL_LSBPTR64(&poRawPoints[iNode].x);
     351                 :                     CPL_LSBPTR64(&poRawPoints[iNode].y);
     352                 :                 }
     353                 : #endif
     354                 : 
     355               2 :                 OGRLinearRing* poLR = new OGRLinearRing();
     356               2 :                 poGeom->addRingDirectly(poLR);
     357               2 :                 poLR->setPoints(nNodes, poRawPoints, NULL);
     358                 :             }
     359                 : 
     360               1 :             VSIFree(poRawPoints);
     361                 : 
     362               1 :             if (poSRS)
     363               1 :                 poGeom->assignSpatialReference(poSRS);
     364               1 :             OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
     365               1 :             poFeature->SetField(0, dfId);
     366               1 :             poFeature->SetFID(nNextFID ++);
     367               1 :             poFeature->SetGeometryDirectly(poGeom);
     368               1 :             return poFeature;
     369                 :         }
     370                 :     }
     371                 : }
     372                 : 
     373                 : /************************************************************************/
     374                 : /*                             SetExtent()                              */
     375                 : /************************************************************************/
     376                 : 
     377               3 : void OGRIdrisiLayer::SetExtent(double dfMinX, double dfMinY, double dfMaxX, double dfMaxY)
     378                 : {
     379               3 :     bExtentValid = TRUE;
     380               3 :     this->dfMinX = dfMinX;
     381               3 :     this->dfMinY = dfMinY;
     382               3 :     this->dfMaxX = dfMaxX;
     383               3 :     this->dfMaxY = dfMaxY;
     384               3 : }
     385                 : 
     386                 : /************************************************************************/
     387                 : /*                             GetExtent()                              */
     388                 : /************************************************************************/
     389                 : 
     390               3 : OGRErr OGRIdrisiLayer::GetExtent(OGREnvelope *psExtent, int bForce)
     391                 : {
     392               3 :     if (!bExtentValid)
     393               0 :         return OGRLayer::GetExtent(psExtent, bForce);
     394                 : 
     395               3 :     psExtent->MinX = dfMinX;
     396               3 :     psExtent->MinY = dfMinY;
     397               3 :     psExtent->MaxX = dfMaxX;
     398               3 :     psExtent->MaxY = dfMaxY;
     399               3 :     return OGRERR_NONE;
     400                 : }
     401                 : 
     402                 : /************************************************************************/
     403                 : /*                          GetFeatureCount()                           */
     404                 : /************************************************************************/
     405                 : 
     406               3 : int OGRIdrisiLayer::GetFeatureCount( int bForce )
     407                 : {
     408               3 :     if (nTotalFeatures > 0 && m_poFilterGeom == NULL && m_poAttrQuery == NULL)
     409               3 :         return nTotalFeatures;
     410                 : 
     411               0 :     return OGRLayer::GetFeatureCount(bForce);
     412                 : }

Generated by: LCOV version 1.7