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

       1                 : /******************************************************************************
       2                 :  * $Id: ogravcbinlayer.cpp 10645 2007-01-18 02:22:39Z warmerdam $
       3                 :  *
       4                 :  * Project:  OGR
       5                 :  * Purpose:  Implements OGRAVCBinLayer class.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2002, Frank Warmerdam <warmerdam@pobox.com>
      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_avc.h"
      31                 : #include "ogr_api.h"
      32                 : #include "cpl_conv.h"
      33                 : #include "cpl_string.h"
      34                 : 
      35                 : CPL_CVSID("$Id: ogravcbinlayer.cpp 10645 2007-01-18 02:22:39Z warmerdam $");
      36                 : 
      37                 : /************************************************************************/
      38                 : /*                           OGRAVCBinLayer()                           */
      39                 : /************************************************************************/
      40                 : 
      41               2 : OGRAVCBinLayer::OGRAVCBinLayer( OGRAVCBinDataSource *poDSIn,
      42                 :                                 AVCE00Section *psSectionIn )
      43               2 :         : OGRAVCLayer( psSectionIn->eType, poDSIn )
      44                 : 
      45                 : {
      46               2 :     psSection = psSectionIn;
      47               2 :     hFile = NULL;
      48               2 :     poArcLayer = NULL;
      49               2 :     bNeedReset = FALSE;
      50               2 :     nNextFID = 1;
      51                 : 
      52               2 :     hTable = NULL;
      53               2 :     nTableBaseField = -1;
      54               2 :     nTableAttrIndex = -1;
      55                 : 
      56               2 :     SetupFeatureDefinition( psSection->pszName );
      57                 :     
      58               2 :     szTableName[0] = '\0';
      59               2 :     if( psSection->eType == AVCFilePAL )
      60               0 :         sprintf( szTableName, "%s.PAT", poDS->GetCoverageName() );
      61               2 :     else if( psSection->eType == AVCFileRPL )
      62                 :         sprintf( szTableName, "%s.PAT%s", poDS->GetCoverageName(),
      63               0 :                  psSectionIn->pszName );
      64               2 :     else if( psSection->eType == AVCFileARC )
      65               1 :         sprintf( szTableName, "%s.AAT", poDS->GetCoverageName() );
      66               1 :     else if( psSection->eType == AVCFileLAB )
      67                 :     {
      68               1 :         AVCE00ReadPtr psInfo = ((OGRAVCBinDataSource *) poDS)->GetInfo();
      69                 : 
      70               1 :         sprintf( szTableName, "%s.PAT", poDS->GetCoverageName() );
      71                 : 
      72              13 :         for( int iSection = 0; iSection < psInfo->numSections; iSection++ )
      73                 :         {
      74              12 :             if( psInfo->pasSections[iSection].eType == AVCFilePAL )
      75               0 :                 nTableAttrIndex = poFeatureDefn->GetFieldIndex( "PolyId" );
      76                 :         }
      77                 :     }
      78                 : 
      79               2 :     CheckSetupTable();
      80               2 : }
      81                 : 
      82                 : /************************************************************************/
      83                 : /*                          ~OGRAVCBinLayer()                           */
      84                 : /************************************************************************/
      85                 : 
      86               4 : OGRAVCBinLayer::~OGRAVCBinLayer()
      87                 : 
      88                 : {
      89               2 :     ResetReading();
      90               4 : }
      91                 : 
      92                 : /************************************************************************/
      93                 : /*                            ResetReading()                            */
      94                 : /************************************************************************/
      95                 : 
      96               4 : void OGRAVCBinLayer::ResetReading()
      97                 : 
      98                 : {
      99               4 :     if( hFile != NULL )
     100                 :     {
     101               2 :         AVCBinReadClose( hFile );
     102               2 :         hFile = NULL;
     103                 :     }
     104                 : 
     105               4 :     bNeedReset = FALSE;
     106               4 :     nNextFID = 1;
     107                 : 
     108               4 :     if( hTable != NULL )
     109                 :     {
     110               0 :         AVCBinReadClose( hTable );
     111               0 :         hTable = NULL;
     112                 :     }
     113               4 : }
     114                 : 
     115                 : /************************************************************************/
     116                 : /*                             GetFeature()                             */
     117                 : /************************************************************************/
     118                 : 
     119               9 : OGRFeature *OGRAVCBinLayer::GetFeature( long nFID )
     120                 : 
     121                 : {
     122                 : /* -------------------------------------------------------------------- */
     123                 : /*      If we haven't started yet, open the file now.                   */
     124                 : /* -------------------------------------------------------------------- */
     125               9 :     if( hFile == NULL )
     126                 :     {
     127               2 :         AVCE00ReadPtr psInfo = ((OGRAVCBinDataSource *) poDS)->GetInfo();
     128                 : 
     129                 :         hFile = AVCBinReadOpen(psInfo->pszCoverPath, 
     130                 :                                psSection->pszFilename, 
     131                 :                                psInfo->eCoverType, 
     132                 :                                psSection->eType,
     133               2 :                                psInfo->psDBCSInfo);
     134                 :     }
     135                 : 
     136                 : /* -------------------------------------------------------------------- */
     137                 : /*      Read the raw feature - the -3 fid is a special flag             */
     138                 : /*      indicating serial access.                                       */
     139                 : /* -------------------------------------------------------------------- */
     140                 :     void *pFeature;
     141                 : 
     142               9 :     if( nFID == -3 )
     143                 :     {
     144              18 :         while( (pFeature = AVCBinReadNextObject( hFile )) != NULL
     145                 :                && !MatchesSpatialFilter( pFeature ) )
     146                 :         {
     147               0 :             nNextFID++;
     148                 :         }
     149                 :     }
     150                 :     else
     151                 :     {
     152               0 :         bNeedReset = TRUE;
     153               0 :         pFeature = AVCBinReadObject( hFile, nFID );
     154                 :     }
     155                 :         
     156               9 :     if( pFeature == NULL )
     157               1 :         return NULL;
     158                 : 
     159                 : /* -------------------------------------------------------------------- */
     160                 : /*      Translate the feature.                                          */
     161                 : /* -------------------------------------------------------------------- */
     162                 :     OGRFeature *poFeature;
     163                 : 
     164               8 :     poFeature = TranslateFeature( pFeature );
     165               8 :     if( poFeature == NULL )
     166               0 :         return NULL;
     167                 : 
     168                 : /* -------------------------------------------------------------------- */
     169                 : /*      LAB's we have to assign the FID to directly, since it           */
     170                 : /*      doesn't seem to be stored in the file structure.                */
     171                 : /* -------------------------------------------------------------------- */
     172               8 :     if( psSection->eType == AVCFileLAB )
     173                 :     {
     174               0 :         if( nFID == -3 )
     175               0 :             poFeature->SetFID( nNextFID++ );
     176                 :         else
     177               0 :             poFeature->SetFID( nFID );
     178                 :     }
     179                 : 
     180                 : /* -------------------------------------------------------------------- */
     181                 : /*      If this is a polygon layer, try to assemble the arcs to form    */
     182                 : /*      the whole polygon geometry.                                     */
     183                 : /* -------------------------------------------------------------------- */
     184               8 :     if( psSection->eType == AVCFilePAL 
     185                 :         || psSection->eType == AVCFileRPL )
     186               0 :         FormPolygonGeometry( poFeature, (AVCPal *) pFeature );
     187                 : 
     188                 : /* -------------------------------------------------------------------- */
     189                 : /*      If we have an attribute table, append the attributes now.       */
     190                 : /* -------------------------------------------------------------------- */
     191               8 :     AppendTableFields( poFeature );
     192                 : 
     193               8 :     return poFeature;
     194                 : }
     195                 : 
     196                 : /************************************************************************/
     197                 : /*                           GetNextFeature()                           */
     198                 : /************************************************************************/
     199                 : 
     200               9 : OGRFeature *OGRAVCBinLayer::GetNextFeature()
     201                 : 
     202                 : {
     203               9 :     if( bNeedReset )
     204               0 :         ResetReading();
     205                 : 
     206               9 :     OGRFeature *poFeature = GetFeature( -3 );
     207                 : 
     208                 :     // Skip universe polygon.
     209               9 :     if( poFeature != NULL && poFeature->GetFID() == 1 
     210                 :         && psSection->eType == AVCFilePAL )
     211                 :     {
     212               0 :         OGRFeature::DestroyFeature( poFeature );
     213               0 :         poFeature = GetFeature( -3 );
     214                 :     }
     215                 : 
     216              18 :     while( poFeature != NULL 
     217                 :            && ((m_poAttrQuery != NULL
     218                 :                 && !m_poAttrQuery->Evaluate( poFeature ) )
     219                 :                || !FilterGeometry( poFeature->GetGeometryRef() ) ) )
     220                 :     {
     221               0 :         OGRFeature::DestroyFeature( poFeature );
     222               0 :         poFeature = GetFeature( -3 );
     223                 :     }
     224                 : 
     225               9 :     if( poFeature == NULL )
     226               1 :         ResetReading();
     227                 : 
     228               9 :     return poFeature;
     229                 : }
     230                 : 
     231                 : /************************************************************************/
     232                 : /*                           TestCapability()                           */
     233                 : /************************************************************************/
     234                 : 
     235               0 : int OGRAVCBinLayer::TestCapability( const char * pszCap )
     236                 : 
     237                 : {
     238               0 :     if( eSectionType == AVCFileARC && EQUAL(pszCap,OLCRandomRead) )
     239               0 :         return TRUE;
     240                 :     else 
     241               0 :         return OGRAVCLayer::TestCapability( pszCap );
     242                 : }
     243                 : 
     244                 : /************************************************************************/
     245                 : /*                        FormPolygonGeometry()                         */
     246                 : /*                                                                      */
     247                 : /*      Collect all the arcs forming edges to this polygon and form     */
     248                 : /*      them into the appropriate OGR geometry on the target feature.   */
     249                 : /************************************************************************/
     250                 : 
     251               0 : int OGRAVCBinLayer::FormPolygonGeometry( OGRFeature *poFeature, 
     252                 :                                          AVCPal *psPAL )
     253                 : 
     254                 : {
     255                 : /* -------------------------------------------------------------------- */
     256                 : /*      Try to find the corresponding ARC layer if not already          */
     257                 : /*      recorded.                                                       */
     258                 : /* -------------------------------------------------------------------- */
     259               0 :     if( poArcLayer == NULL )
     260                 :     {
     261                 :         int i;
     262                 : 
     263               0 :         for( i = 0; i < poDS->GetLayerCount(); i++ )
     264                 :         {
     265               0 :             OGRAVCBinLayer *poLayer = (OGRAVCBinLayer *) poDS->GetLayer(i);
     266                 : 
     267               0 :             if( poLayer->eSectionType == AVCFileARC )
     268               0 :                 poArcLayer = poLayer;
     269                 :         }
     270                 : 
     271               0 :         if( poArcLayer == NULL )
     272               0 :             return FALSE;
     273                 :     }
     274                 : 
     275                 : /* -------------------------------------------------------------------- */
     276                 : /*  Read all the arcs related to this polygon, making a working */
     277                 : /*  copy of them since the one returned by AVC is temporary.  */
     278                 : /* -------------------------------------------------------------------- */
     279               0 :     OGRGeometryCollection oArcs;
     280                 :     int   iArc;
     281                 : 
     282               0 :     for( iArc = 0; iArc < psPAL->numArcs; iArc++ )
     283                 :     {
     284                 :         OGRFeature *poArc;
     285                 : 
     286               0 :         if( psPAL->pasArcs[iArc].nArcId == 0 )
     287               0 :             continue;
     288                 : 
     289                 :         // If the other side of the line is the same polygon then this
     290                 :         // arc is a "bridge" arc and can be discarded.  If we don't discard
     291                 :         // it, then we should double it as bridge arcs seem to only appear
     292                 :         // once.  But by discarding it we ensure a multi-ring polygon will be
     293                 :         // properly formed. 
     294               0 :         if( psPAL->pasArcs[iArc].nAdjPoly == psPAL->nPolyId )
     295               0 :             continue;
     296                 : 
     297               0 :         poArc = poArcLayer->GetFeature( ABS(psPAL->pasArcs[iArc].nArcId) );
     298                 : 
     299               0 :         if( poArc == NULL )
     300               0 :             return FALSE;
     301                 : 
     302               0 :         if( poArc->GetGeometryRef() == NULL )
     303               0 :             return FALSE;
     304                 : 
     305               0 :         oArcs.addGeometry( poArc->GetGeometryRef() );
     306               0 :         OGRFeature::DestroyFeature( poArc );
     307                 :     }
     308                 : 
     309                 :     OGRErr  eErr;
     310                 :     OGRPolygon *poPolygon;
     311                 : 
     312                 :     poPolygon = (OGRPolygon *) 
     313                 :         OGRBuildPolygonFromEdges( (OGRGeometryH) &oArcs, TRUE, FALSE,  
     314               0 :                                   0.0, &eErr );
     315               0 :     if( poPolygon != NULL )
     316               0 :         poFeature->SetGeometryDirectly( poPolygon );
     317                 : 
     318               0 :     return eErr == OGRERR_NONE;
     319                 : }
     320                 : 
     321                 : /************************************************************************/
     322                 : /*                          CheckSetupTable()                           */
     323                 : /*                                                                      */
     324                 : /*      Check if the named table exists, and if so, setup access to     */
     325                 : /*      it (open it), and add it's fields to the feature class          */
     326                 : /*      definition.                                                     */
     327                 : /************************************************************************/
     328                 : 
     329               2 : int OGRAVCBinLayer::CheckSetupTable()
     330                 : 
     331                 : {
     332               2 :     if( szTableName[0] == '\0' )
     333               0 :         return FALSE;
     334                 : 
     335                 : /* -------------------------------------------------------------------- */
     336                 : /*      Scan for the indicated section.                                 */
     337                 : /* -------------------------------------------------------------------- */
     338               2 :     AVCE00ReadPtr psInfo = ((OGRAVCBinDataSource *) poDS)->GetInfo();
     339                 :     int           iSection;
     340               2 :     AVCE00Section *psSection = NULL;
     341                 :     char    szPaddedName[65];
     342                 :     
     343               2 :     sprintf( szPaddedName, "%s%32s", szTableName, " " );
     344               2 :     szPaddedName[32] = '\0';
     345                 : 
     346              26 :     for( iSection = 0; iSection < psInfo->numSections; iSection++ )
     347                 :     {
     348              24 :         if( EQUAL(szPaddedName,psInfo->pasSections[iSection].pszName) 
     349               0 :             && psInfo->pasSections[iSection].eType == AVCFileTABLE )
     350               0 :             psSection = psInfo->pasSections + iSection;
     351                 :     }
     352                 : 
     353               2 :     if( psSection == NULL )
     354                 :     {
     355               2 :         szTableName[0] = '\0';
     356               2 :         return FALSE;
     357                 :     }
     358                 : 
     359                 : /* -------------------------------------------------------------------- */
     360                 : /*      Try opening the table.                                          */
     361                 : /* -------------------------------------------------------------------- */
     362                 :     hTable = AVCBinReadOpen( psInfo->pszInfoPath,  szTableName,
     363                 :                              psInfo->eCoverType, AVCFileTABLE,
     364               0 :                              psInfo->psDBCSInfo);
     365                 :     
     366               0 :     if( hTable == NULL )
     367                 :     {
     368               0 :         szTableName[0] = '\0';
     369               0 :         return FALSE;
     370                 :     }
     371                 :     
     372                 : /* -------------------------------------------------------------------- */
     373                 : /*      Setup attributes.                                               */
     374                 : /* -------------------------------------------------------------------- */
     375               0 :     nTableBaseField = poFeatureDefn->GetFieldCount();
     376                 :     
     377               0 :     AppendTableDefinition( hTable->hdr.psTableDef );
     378                 : 
     379                 : /* -------------------------------------------------------------------- */
     380                 : /*      Close table so we don't have to many files open at once.        */
     381                 : /* -------------------------------------------------------------------- */
     382               0 :     AVCBinReadClose( hTable );
     383                 : 
     384               0 :     hTable = NULL;
     385                 : 
     386               0 :     return TRUE;
     387                 : }
     388                 : 
     389                 : /************************************************************************/
     390                 : /*                         AppendTableFields()                          */
     391                 : /************************************************************************/
     392                 : 
     393               8 : int OGRAVCBinLayer::AppendTableFields( OGRFeature *poFeature )
     394                 : 
     395                 : {
     396               8 :     AVCE00ReadPtr psInfo = ((OGRAVCBinDataSource *) poDS)->GetInfo();
     397                 : 
     398               8 :     if( szTableName[0] == '\0' )
     399               8 :         return FALSE;
     400                 : 
     401                 : /* -------------------------------------------------------------------- */
     402                 : /*      Open the table if it is currently closed.                       */
     403                 : /* -------------------------------------------------------------------- */
     404               0 :     if( hTable == NULL )
     405                 :     {
     406                 :         hTable = AVCBinReadOpen( psInfo->pszInfoPath,  szTableName,
     407                 :                                  psInfo->eCoverType, AVCFileTABLE,
     408               0 :                                  psInfo->psDBCSInfo);
     409                 :     }
     410                 : 
     411               0 :     if( hTable == NULL )
     412               0 :         return FALSE;
     413                 : 
     414                 : /* -------------------------------------------------------------------- */
     415                 : /*      Read the info record.                                           */
     416                 : /*                                                                      */
     417                 : /*      We usually assume the FID of the feature is the key but in a    */
     418                 : /*      polygon coverage we need to use the PolyId attribute of LAB     */
     419                 : /*      features to lookup the related attributes.  In this case        */
     420                 : /*      nTableAttrIndex will already be setup to refer to the           */
     421                 : /*      PolyId field.                                                   */
     422                 : /* -------------------------------------------------------------------- */
     423                 :     int nRecordId;
     424                 :     void *hRecord;
     425                 : 
     426               0 :     if( nTableAttrIndex == -1 )
     427               0 :         nRecordId = poFeature->GetFID();
     428                 :     else
     429               0 :         nRecordId = poFeature->GetFieldAsInteger( nTableAttrIndex );
     430                 : 
     431               0 :     hRecord = AVCBinReadObject( hTable, nRecordId );
     432               0 :     if( hRecord == NULL )
     433               0 :         return FALSE;
     434                 : 
     435                 : /* -------------------------------------------------------------------- */
     436                 : /*      Translate it.                                                   */
     437                 : /* -------------------------------------------------------------------- */
     438                 :     return TranslateTableFields( poFeature, nTableBaseField, 
     439                 :                                  hTable->hdr.psTableDef, 
     440               0 :                                  (AVCField *) hRecord );
     441                 : }
     442                 : 
     443                 : 
     444                 : 
     445                 : 
     446                 : 

Generated by: LCOV version 1.7