LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/avc - ogravce00layer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 160 58 36.2 %
Date: 2010-01-09 Functions: 10 8 80.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogravce00layer.cpp 10645 2007-01-18 02:22:39Z warmerdam $
       3                 :  *
       4                 :  * Project:  OGR
       5                 :  * Purpose:  Implements OGRAVCE00Layer class.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *           James Flemer <jflemer@alum.rpi.edu>
       8                 :  *
       9                 :  ******************************************************************************
      10                 :  * Copyright (c) 2002, Frank Warmerdam <warmerdam@pobox.com>
      11                 :  * Copyright (c) 2006, James Flemer <jflemer@alum.rpi.edu>
      12                 :  *
      13                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      14                 :  * copy of this software and associated documentation files (the "Software"),
      15                 :  * to deal in the Software without restriction, including without limitation
      16                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      17                 :  * and/or sell copies of the Software, and to permit persons to whom the
      18                 :  * Software is furnished to do so, subject to the following conditions:
      19                 :  *
      20                 :  * The above copyright notice and this permission notice shall be included
      21                 :  * in all copies or substantial portions of the Software.
      22                 :  *
      23                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      24                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      25                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      26                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      27                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      28                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      29                 :  * DEALINGS IN THE SOFTWARE.
      30                 :  ****************************************************************************/
      31                 : 
      32                 : #include "ogr_avc.h"
      33                 : #include "ogr_api.h"
      34                 : #include "cpl_conv.h"
      35                 : #include "cpl_string.h"
      36                 : 
      37                 : CPL_CVSID("$Id: ogravce00layer.cpp 10645 2007-01-18 02:22:39Z warmerdam $");
      38                 : 
      39                 : /************************************************************************/
      40                 : /*                           OGRAVCE00Layer()                           */
      41                 : /************************************************************************/
      42                 : 
      43               2 : OGRAVCE00Layer::OGRAVCE00Layer( OGRAVCDataSource *poDSIn,
      44                 :                                 AVCE00Section *psSectionIn )
      45                 :         : OGRAVCLayer( psSectionIn->eType, poDSIn ),
      46                 :           psSection(psSectionIn),
      47                 :           psRead(NULL),
      48                 :           poArcLayer(NULL),
      49                 :           nFeatureCount(-1),
      50                 :           bNeedReset(0),
      51                 :           nNextFID(1),
      52                 :       psTableSection(NULL),
      53                 :           psTableRead(NULL),
      54                 :           pszTableFilename(NULL),
      55                 :           nTablePos(0),
      56                 :       nTableBaseField(0),
      57               2 :           nTableAttrIndex(-1)
      58                 : {
      59               2 :     SetupFeatureDefinition( psSection->pszName );
      60                 :     /* psRead = AVCE00ReadOpenE00(psSection->pszFilename); */
      61                 :     
      62                 : #if 0
      63                 :     szTableName[0] = '\0';
      64                 :     if( psSection->eType == AVCFilePAL )
      65                 :         sprintf( szTableName, "%s.PAT", poDS->GetCoverageName() );
      66                 :     else if( psSection->eType == AVCFileRPL )
      67                 :         sprintf( szTableName, "%s.PAT%s", poDS->GetCoverageName(),
      68                 :                  psSectionIn->pszName );
      69                 :     else if( psSection->eType == AVCFileARC )
      70                 :         sprintf( szTableName, "%s.AAT", poDS->GetCoverageName() );
      71                 :     else if( psSection->eType == AVCFileLAB )
      72                 :     {
      73                 :         AVCE00ReadPtr psInfo = ((OGRAVCE00DataSource *) poDS)->GetInfo();
      74                 : 
      75                 :         sprintf( szTableName, "%s.PAT", poDS->GetCoverageName() );
      76                 : 
      77                 :         for( int iSection = 0; iSection < psInfo->numSections; iSection++ )
      78                 :         {
      79                 :             if( psInfo->pasSections[iSection].eType == AVCFilePAL )
      80                 :                 nTableAttrIndex = poFeatureDefn->GetFieldIndex( "PolyId" );
      81                 :         }
      82                 :     }
      83                 : 
      84                 : #endif
      85               2 : }
      86                 : 
      87                 : /************************************************************************/
      88                 : /*                          ~OGRAVCE00Layer()                           */
      89                 : /************************************************************************/
      90                 : 
      91               4 : OGRAVCE00Layer::~OGRAVCE00Layer()
      92                 : 
      93                 : {
      94               2 :     if (psRead)
      95                 :     {
      96               1 :         AVCE00ReadCloseE00(psRead);
      97               1 :         psRead = NULL;
      98                 :     }
      99                 : 
     100               2 :     if (psTableRead)
     101                 :     {
     102               0 :         AVCE00ReadCloseE00(psTableRead);
     103               0 :         psTableRead = NULL;
     104                 :     }
     105                 : 
     106               2 :     if (pszTableFilename)
     107                 :     {
     108               0 :         CPLFree(pszTableFilename);
     109               0 :         pszTableFilename = NULL;
     110                 :     }
     111               4 : }
     112                 : 
     113                 : /************************************************************************/
     114                 : /*                            ResetReading()                            */
     115                 : /************************************************************************/
     116                 : 
     117               2 : void OGRAVCE00Layer::ResetReading()
     118                 : 
     119                 : {
     120               2 :     if (psRead)
     121                 :     {
     122               2 :         AVCE00ReadGotoSectionE00(psRead, psSection, 0);
     123                 :     }
     124                 : 
     125               2 :     if (psTableRead)
     126                 :     {
     127               0 :         AVCE00ReadGotoSectionE00(psTableRead, psTableSection, 0);
     128                 :     }
     129                 : 
     130               2 :     bNeedReset = FALSE;
     131               2 :     nNextFID = 1;
     132               2 : }
     133                 : 
     134                 : /************************************************************************/
     135                 : /*                             GetFeature()                             */
     136                 : /************************************************************************/
     137                 : 
     138               9 : OGRFeature *OGRAVCE00Layer::GetFeature( long nFID )
     139                 : 
     140                 : {
     141                 : /* -------------------------------------------------------------------- */
     142                 : /*      If we haven't started yet, open the file now.                   */
     143                 : /* -------------------------------------------------------------------- */
     144               9 :     if( psRead == NULL )
     145                 :     {
     146               1 :         psRead = AVCE00ReadOpenE00(psSection->pszFilename);
     147               1 :         if (psRead == NULL)
     148               0 :             return NULL;
     149                 :         /* advance to the specified line number */
     150               1 :         if (AVCE00ReadGotoSectionE00(psRead, psSection, 0) != 0)
     151               0 :             return NULL;
     152               1 :         nNextFID = 1;
     153                 :     }
     154                 : 
     155                 : /* -------------------------------------------------------------------- */
     156                 : /*      Read the raw feature - the -3 fid is a special flag             */
     157                 : /*      indicating serial access.                                       */
     158                 : /* -------------------------------------------------------------------- */
     159                 :     void *pFeature;
     160                 : 
     161               9 :     if( nFID == -3 )
     162                 :     {
     163              18 :         while( (pFeature = AVCE00ReadNextObjectE00(psRead)) != NULL
     164                 :                && psRead->hParseInfo->eFileType != AVCFileUnknown
     165                 :                && !MatchesSpatialFilter( pFeature ) )
     166                 :         {
     167               0 :             nNextFID++;
     168                 :         }
     169                 :     }
     170                 :     else
     171                 :     {
     172               0 :         bNeedReset = TRUE;
     173                 : 
     174               0 :         if (nNextFID > nFID)
     175                 :         {
     176                 :             /* advance to the specified line number */
     177               0 :             if (AVCE00ReadGotoSectionE00(psRead, psSection, 0) != 0)
     178               0 :                 return NULL;
     179                 :         }
     180                 : 
     181               0 :         do
     182                 :         {
     183               0 :             pFeature = AVCE00ReadNextObjectE00(psRead);
     184               0 :             ++nNextFID;
     185                 :         }
     186                 :         while (NULL != pFeature && nNextFID <= nFID);
     187                 :     }
     188                 :         
     189               9 :     if( pFeature == NULL )
     190               1 :         return NULL;
     191                 : 
     192                 : /* -------------------------------------------------------------------- */
     193                 : /*      Translate the feature.                                          */
     194                 : /* -------------------------------------------------------------------- */
     195                 :     OGRFeature *poFeature;
     196                 : 
     197               8 :     poFeature = TranslateFeature( pFeature );
     198               8 :     if( poFeature == NULL )
     199               0 :         return NULL;
     200                 : 
     201                 : /* -------------------------------------------------------------------- */
     202                 : /*      LAB's we have to assign the FID to directly, since it           */
     203                 : /*      doesn't seem to be stored in the file structure.                */
     204                 : /* -------------------------------------------------------------------- */
     205               8 :     if( psSection->eType == AVCFileLAB )
     206                 :     {
     207               0 :         if( nFID == -3 )
     208               0 :             poFeature->SetFID( nNextFID++ );
     209                 :         else
     210               0 :             poFeature->SetFID( nFID );
     211                 :     }
     212                 : 
     213                 : /* -------------------------------------------------------------------- */
     214                 : /*      If this is a polygon layer, try to assemble the arcs to form    */
     215                 : /*      the whole polygon geometry.                                     */
     216                 : /* -------------------------------------------------------------------- */
     217               8 :     if( psSection->eType == AVCFilePAL 
     218                 :         || psSection->eType == AVCFileRPL )
     219                 :     {
     220               0 :         FormPolygonGeometry( poFeature, (AVCPal *) pFeature );
     221                 :     }
     222                 : 
     223                 : /* -------------------------------------------------------------------- */
     224                 : /*      If we have an attribute table, append the attributes now.       */
     225                 : /* -------------------------------------------------------------------- */
     226               8 :     AppendTableFields( poFeature );
     227                 : 
     228               8 :     return poFeature;
     229                 : }
     230                 : 
     231                 : /************************************************************************/
     232                 : /*                           GetNextFeature()                           */
     233                 : /************************************************************************/
     234                 : 
     235               9 : OGRFeature *OGRAVCE00Layer::GetNextFeature()
     236                 : 
     237                 : {
     238               9 :     if( bNeedReset )
     239               0 :         ResetReading();
     240                 : 
     241               9 :     OGRFeature *poFeature = GetFeature( -3 );
     242                 : 
     243                 :     // Skip universe polygon.
     244               9 :     if( poFeature != NULL && poFeature->GetFID() == 1 
     245                 :         && psSection->eType == AVCFilePAL )
     246                 :     {
     247               0 :         OGRFeature::DestroyFeature( poFeature );
     248               0 :         poFeature = GetFeature( -3 );
     249                 :     }
     250                 : 
     251              18 :     while( poFeature != NULL 
     252                 :            && ((m_poAttrQuery != NULL
     253                 :                 && !m_poAttrQuery->Evaluate( poFeature ) )
     254                 :                || !FilterGeometry( poFeature->GetGeometryRef() ) ) )
     255                 :     {
     256               0 :         OGRFeature::DestroyFeature( poFeature );
     257               0 :         poFeature = GetFeature( -3 );
     258                 :     }
     259                 : 
     260               9 :     if( poFeature == NULL )
     261               1 :         ResetReading();
     262                 : 
     263               9 :     return poFeature;
     264                 : }
     265                 : 
     266                 : /************************************************************************/
     267                 : /*                           TestCapability()                           */
     268                 : /************************************************************************/
     269                 : 
     270                 : #if 0
     271                 : int OGRAVCE00Layer::TestCapability( const char * pszCap )
     272                 : 
     273                 : {
     274                 :     if( eSectionType == AVCFileARC && EQUAL(pszCap,OLCRandomRead) )
     275                 :         return TRUE;
     276                 :     else 
     277                 :         return OGRAVCLayer::TestCapability( pszCap );
     278                 : }
     279                 : #endif
     280                 : 
     281                 : /************************************************************************/
     282                 : /*                        FormPolygonGeometry()                         */
     283                 : /*                                                                      */
     284                 : /*      Collect all the arcs forming edges to this polygon and form     */
     285                 : /*      them into the appropriate OGR geometry on the target feature.   */
     286                 : /************************************************************************/
     287                 : 
     288               0 : int OGRAVCE00Layer::FormPolygonGeometry( OGRFeature *poFeature, 
     289                 :                                          AVCPal *psPAL )
     290                 : {
     291                 : /* -------------------------------------------------------------------- */
     292                 : /*      Try to find the corresponding ARC layer if not already          */
     293                 : /*      recorded.                                                       */
     294                 : /* -------------------------------------------------------------------- */
     295               0 :     if( poArcLayer == NULL )
     296                 :     {
     297                 :         int i;
     298                 : 
     299               0 :         for( i = 0; i < poDS->GetLayerCount(); i++ )
     300                 :         {
     301               0 :             OGRAVCE00Layer *poLayer = (OGRAVCE00Layer *) poDS->GetLayer(i);
     302                 : 
     303               0 :             if( poLayer->eSectionType == AVCFileARC )
     304               0 :                 poArcLayer = poLayer;
     305                 :         }
     306                 : 
     307               0 :         if( poArcLayer == NULL )
     308               0 :             return FALSE;
     309                 :     }
     310                 : 
     311                 : /* -------------------------------------------------------------------- */
     312                 : /*  Read all the arcs related to this polygon, making a working         */
     313                 : /*  copy of them since the one returned by AVC is temporary.            */
     314                 : /* -------------------------------------------------------------------- */
     315               0 :     OGRGeometryCollection oArcs;
     316                 :     int iArc;
     317                 : 
     318               0 :     for( iArc = 0; iArc < psPAL->numArcs; iArc++ )
     319                 :     {
     320                 :         OGRFeature *poArc;
     321                 : 
     322               0 :         if( psPAL->pasArcs[iArc].nArcId == 0 )
     323               0 :             continue;
     324                 : 
     325                 :         // If the other side of the line is the same polygon then this
     326                 :         // arc is a "bridge" arc and can be discarded.  If we don't discard
     327                 :         // it, then we should double it as bridge arcs seem to only appear
     328                 :         // once.  But by discarding it we ensure a multi-ring polygon will be
     329                 :         // properly formed. 
     330               0 :         if( psPAL->pasArcs[iArc].nAdjPoly == psPAL->nPolyId )
     331               0 :             continue;
     332                 : 
     333               0 :         poArc = poArcLayer->GetFeature( ABS(psPAL->pasArcs[iArc].nArcId) );
     334                 : 
     335               0 :         if( poArc == NULL )
     336               0 :             return FALSE;
     337                 : 
     338               0 :         if( poArc->GetGeometryRef() == NULL )
     339               0 :             return FALSE;
     340                 : 
     341               0 :         oArcs.addGeometry( poArc->GetGeometryRef() );
     342               0 :         OGRFeature::DestroyFeature( poArc );
     343                 :     }
     344                 : 
     345                 :     OGRErr  eErr;
     346                 :     OGRPolygon *poPolygon;
     347                 : 
     348                 :     poPolygon = (OGRPolygon *) 
     349                 :         OGRBuildPolygonFromEdges( (OGRGeometryH) &oArcs, TRUE, FALSE,  
     350               0 :                                   0.0, &eErr );
     351               0 :     if( poPolygon != NULL )
     352               0 :         poFeature->SetGeometryDirectly( poPolygon );
     353                 : 
     354               0 :     return eErr == OGRERR_NONE;
     355                 : }
     356                 : 
     357                 : /************************************************************************/
     358                 : /*                          CheckSetupTable()                           */
     359                 : /*                                                                      */
     360                 : /*      Check if the named table exists, and if so, setup access to     */
     361                 : /*      it (open it), and add it's fields to the feature class          */
     362                 : /*      definition.                                                     */
     363                 : /************************************************************************/
     364                 : 
     365               8 : int OGRAVCE00Layer::CheckSetupTable(AVCE00Section *psTblSectionIn)
     366                 : {
     367               8 :     if (psTableRead)
     368               0 :         return FALSE;
     369                 : 
     370               8 :     const char *pszTableType = NULL;
     371               8 :     switch (eSectionType)
     372                 :     {
     373                 :     case AVCFileARC:
     374               4 :         pszTableType = ".AAT";
     375               4 :         break;
     376                 : 
     377                 :     case AVCFilePAL:
     378                 :     case AVCFileLAB:
     379               4 :         pszTableType = ".PAT";
     380                 :         break;
     381                 : 
     382                 :     default:
     383                 :         break;
     384                 :     }
     385                 : 
     386                 : /* -------------------------------------------------------------------- */
     387                 : /*      Is the table type found anywhere in the section pszName?  Do    */
     388                 : /*      a case insensitive check.                                       */
     389                 : /* -------------------------------------------------------------------- */
     390               8 :     if( pszTableType == NULL )
     391               0 :         return FALSE;
     392                 :     
     393                 :     int iCheckOff;
     394             528 :     for( iCheckOff = 0; 
     395             264 :          psTblSectionIn->pszName[iCheckOff] != '\0'; 
     396                 :          iCheckOff++ )
     397                 :     {
     398             256 :         if( EQUALN(psTblSectionIn->pszName + iCheckOff, 
     399                 :                    pszTableType, strlen(pszTableType) ) )
     400               0 :             break;
     401                 :     }
     402                 : 
     403               8 :     if( psTblSectionIn->pszName[iCheckOff] == '\0' )
     404               8 :         return FALSE;
     405                 : 
     406               0 :     psTableSection = psTblSectionIn;
     407                 : 
     408                 : /* -------------------------------------------------------------------- */
     409                 : /*      Try opening the table.                                          */
     410                 : /* -------------------------------------------------------------------- */
     411               0 :     psTableRead = AVCE00ReadOpenE00(psTblSectionIn->pszFilename);
     412               0 :     if (psTableRead == NULL)
     413               0 :         return FALSE;
     414                 : 
     415                 :     /* advance to the specified line number */
     416               0 :     if (AVCE00ReadGotoSectionE00(psTableRead, psTableSection, 0) != 0)
     417                 :     {
     418               0 :         AVCE00ReadCloseE00(psTableRead);
     419               0 :         psTableRead = NULL;
     420               0 :         return FALSE;
     421                 :     }
     422                 :     
     423               0 :     AVCE00ReadNextObjectE00(psTableRead);
     424               0 :     bNeedReset = 1;
     425                 : 
     426               0 :     pszTableFilename = CPLStrdup(psTblSectionIn->pszFilename);
     427               0 :     nTableBaseField = poFeatureDefn->GetFieldCount();
     428                 : 
     429               0 :   if (eSectionType == AVCFileLAB)
     430                 :   {
     431               0 :         AVCE00ReadE00Ptr psInfo = ((OGRAVCE00DataSource *) poDS)->GetInfo();
     432               0 :         for( int iSection = 0; iSection < psInfo->numSections; iSection++ )
     433                 :         {
     434               0 :             if( psInfo->pasSections[iSection].eType == AVCFilePAL )
     435               0 :                 nTableAttrIndex = poFeatureDefn->GetFieldIndex( "PolyId" );
     436                 :         }
     437                 :   }
     438                 : 
     439                 : /* -------------------------------------------------------------------- */
     440                 : /*      Setup attributes.                                               */
     441                 : /* -------------------------------------------------------------------- */
     442               0 :     AppendTableDefinition( psTableRead->hParseInfo->hdr.psTableDef );
     443                 : 
     444                 : /* -------------------------------------------------------------------- */
     445                 : /*      Close table so we don't have to many files open at once.        */
     446                 : /* -------------------------------------------------------------------- */
     447                 :     /* AVCE00ReadCloseE00( psTableRead ); */
     448                 : 
     449               0 :     return TRUE;
     450                 : }
     451                 : 
     452                 : /************************************************************************/
     453                 : /*                         AppendTableFields()                          */
     454                 : /************************************************************************/
     455                 : 
     456               8 : int OGRAVCE00Layer::AppendTableFields( OGRFeature *poFeature )
     457                 : 
     458                 : {
     459               8 :     if (psTableRead == NULL)
     460               8 :         return FALSE;
     461                 : 
     462                 : /* -------------------------------------------------------------------- */
     463                 : /*      Open the table if it is currently closed.                       */
     464                 : /* -------------------------------------------------------------------- */
     465               0 :     if (psTableRead == NULL)
     466                 :     {
     467               0 :         psTableRead = AVCE00ReadOpenE00(pszTableFilename);
     468               0 :         if (psTableRead == NULL)
     469               0 :             return FALSE;
     470                 : 
     471                 :         /* advance to the specified line number */
     472               0 :       if (AVCE00ReadGotoSectionE00(psTableRead, psTableSection, 0) != 0)
     473                 :         {
     474               0 :             AVCE00ReadCloseE00(psTableRead);
     475               0 :             psTableRead = NULL;
     476               0 :             return FALSE;
     477                 :         }
     478               0 :         nTablePos = 0;
     479                 :     }
     480                 : 
     481                 : /* -------------------------------------------------------------------- */
     482                 : /*      Read the info record.                                           */
     483                 : /*                                                                      */
     484                 : /*      We usually assume the FID of the feature is the key but in a    */
     485                 : /*      polygon coverage we need to use the PolyId attribute of LAB     */
     486                 : /*      features to lookup the related attributes.  In this case        */
     487                 : /*      nTableAttrIndex will already be setup to refer to the           */
     488                 : /*      PolyId field.                                                   */
     489                 : /* -------------------------------------------------------------------- */
     490                 :     int nRecordId;
     491                 :     void *hRecord;
     492                 : 
     493               0 :     if( nTableAttrIndex == -1 )
     494               0 :         nRecordId = poFeature->GetFID();
     495                 :     else
     496               0 :         nRecordId = poFeature->GetFieldAsInteger( nTableAttrIndex );
     497                 : 
     498               0 :     if (nRecordId <= nTablePos)
     499                 :     {
     500               0 :       if (AVCE00ReadGotoSectionE00(psTableRead, psTableSection, 0) != 0)
     501               0 :       return FALSE;
     502               0 :         nTablePos = 0;
     503                 :     }
     504                 : 
     505               0 :     do
     506                 :     {
     507               0 :         hRecord = AVCE00ReadNextObjectE00(psTableRead);
     508               0 :         ++nTablePos;
     509                 :     }
     510                 :     while (NULL != hRecord && nTablePos < nRecordId);
     511                 : 
     512               0 :     if( hRecord == NULL )
     513               0 :         return FALSE;
     514                 : 
     515                 : 
     516                 : /* -------------------------------------------------------------------- */
     517                 : /*      Translate it.                                                   */
     518                 : /* -------------------------------------------------------------------- */
     519                 :     return TranslateTableFields( poFeature, nTableBaseField, 
     520                 :                                  psTableRead->hParseInfo->hdr.psTableDef, 
     521               0 :                                  (AVCField *) hRecord );
     522                 : }
     523                 : 
     524                 : 
     525               0 : int OGRAVCE00Layer::GetFeatureCount(int bForce)
     526                 : {
     527               0 :     if (bForce && nFeatureCount < 0)
     528                 :     {
     529               0 :         if (psSection->nFeatureCount < 0)
     530                 :         {
     531               0 :             nFeatureCount = OGRLayer::GetFeatureCount(bForce);
     532                 :         }
     533                 :         else
     534                 :         {
     535               0 :             nFeatureCount = psSection->nFeatureCount;
     536               0 :             if (psSection->eType == AVCFilePAL)
     537               0 :                 --nFeatureCount;
     538                 :         }
     539                 :     }
     540               0 :     return nFeatureCount;
     541                 : }

Generated by: LCOV version 1.7