LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/sdts - ogrsdtslayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 153 135 88.2 %
Date: 2012-04-28 Functions: 11 6 54.5 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrsdtslayer.cpp 19952 2010-07-02 05:44:18Z warmerdam $
       3                 :  *
       4                 :  * Project:  SDTSReader
       5                 :  * Purpose:  Implements OGRSDTSLayer class.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 1999, Frank Warmerdam
      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_sdts.h"
      31                 : #include "cpl_conv.h"
      32                 : #include "cpl_string.h"
      33                 : 
      34                 : CPL_CVSID("$Id: ogrsdtslayer.cpp 19952 2010-07-02 05:44:18Z warmerdam $");
      35                 : 
      36                 : /************************************************************************/
      37                 : /*                            OGRSDTSLayer()                            */
      38                 : /*                                                                      */
      39                 : /*      Note that the OGRSDTSLayer assumes ownership of the passed      */
      40                 : /*      OGRFeatureDefn object.                                          */
      41                 : /************************************************************************/
      42                 : 
      43              16 : OGRSDTSLayer::OGRSDTSLayer( SDTSTransfer * poTransferIn, int iLayerIn,
      44              16 :                             OGRSDTSDataSource * poDSIn )
      45                 : 
      46                 : {
      47              16 :     poDS = poDSIn;
      48                 : 
      49              16 :     poTransfer = poTransferIn;
      50              16 :     iLayer = iLayerIn;
      51                 : 
      52              16 :     poReader = poTransfer->GetLayerIndexedReader( iLayer );
      53                 : 
      54                 : /* -------------------------------------------------------------------- */
      55                 : /*      Define the feature.                                             */
      56                 : /* -------------------------------------------------------------------- */
      57              16 :     int         iCATDEntry = poTransfer->GetLayerCATDEntry( iLayer );
      58                 :     
      59                 :     poFeatureDefn =
      60              16 :         new OGRFeatureDefn(poTransfer->GetCATD()->GetEntryModule(iCATDEntry));
      61              16 :     poFeatureDefn->Reference();
      62                 : 
      63              16 :     OGRFieldDefn oRecId( "RCID", OFTInteger );
      64              16 :     poFeatureDefn->AddFieldDefn( &oRecId );
      65                 : 
      66              16 :     if( poTransfer->GetLayerType(iLayer) == SLTPoint )
      67                 :     {
      68               6 :         poFeatureDefn->SetGeomType( wkbPoint );
      69                 :     }
      70              10 :     else if( poTransfer->GetLayerType(iLayer) == SLTLine )
      71                 :     {
      72               2 :         poFeatureDefn->SetGeomType( wkbLineString );
      73                 : 
      74               2 :         oRecId.SetName( "SNID" );
      75               2 :         poFeatureDefn->AddFieldDefn( &oRecId );
      76                 : 
      77               2 :         oRecId.SetName( "ENID" );
      78               2 :         poFeatureDefn->AddFieldDefn( &oRecId );
      79                 :     }
      80               8 :     else if( poTransfer->GetLayerType(iLayer) == SLTPoly )
      81                 :     {
      82               2 :         poFeatureDefn->SetGeomType( wkbPolygon );
      83                 :     }
      84               6 :     else if( poTransfer->GetLayerType(iLayer) == SLTAttr )
      85                 :     {
      86               6 :         poFeatureDefn->SetGeomType( wkbNone );
      87                 :     }
      88                 : 
      89                 : /* -------------------------------------------------------------------- */
      90                 : /*      Add schema from referenced attribute records.                   */
      91                 : /* -------------------------------------------------------------------- */
      92              16 :     char        **papszATIDRefs = NULL;
      93                 :     
      94              16 :     if( poTransfer->GetLayerType(iLayer) != SLTAttr )
      95              10 :         papszATIDRefs = poReader->ScanModuleReferences();
      96                 :     else
      97                 :         papszATIDRefs = CSLAddString( papszATIDRefs, 
      98               6 :                                       poTransfer->GetCATD()->GetEntryModule(iCATDEntry) );
      99                 : 
     100              40 :     for( int iTable = 0;
     101              16 :          papszATIDRefs != NULL && papszATIDRefs[iTable] != NULL;
     102                 :          iTable++ )
     103                 :     {
     104                 :         SDTSAttrReader  *poAttrReader;
     105                 :         DDFFieldDefn    *poFDefn;
     106                 :         
     107                 : /* -------------------------------------------------------------------- */
     108                 : /*      Get the attribute table reader, and the associated user         */
     109                 : /*      attribute field.                                                */
     110                 : /* -------------------------------------------------------------------- */
     111                 :         poAttrReader = (SDTSAttrReader *)
     112                 :             poTransfer->GetLayerIndexedReader(
     113               8 :                 poTransfer->FindLayer( papszATIDRefs[iTable] ) );
     114                 : 
     115               8 :         if( poAttrReader == NULL )
     116               0 :             continue;
     117                 : 
     118               8 :         poFDefn = poAttrReader->GetModule()->FindFieldDefn( "ATTP" );
     119               8 :         if( poFDefn == NULL )
     120               0 :             poFDefn = poAttrReader->GetModule()->FindFieldDefn( "ATTS" );
     121               8 :         if( poFDefn == NULL )
     122               0 :             continue;
     123                 :         
     124                 : /* -------------------------------------------------------------------- */
     125                 : /*      Process each user subfield on the attribute table into an       */
     126                 : /*      OGR field definition.                                           */
     127                 : /* -------------------------------------------------------------------- */
     128             128 :         for( int iSF=0; iSF < poFDefn->GetSubfieldCount(); iSF++ )
     129                 :         {
     130             120 :             DDFSubfieldDefn     *poSFDefn = poFDefn->GetSubfield( iSF );
     131             120 :             int                 nWidth = poSFDefn->GetWidth();
     132                 :             char                *pszFieldName;
     133                 : 
     134             120 :             if( poFeatureDefn->GetFieldIndex( poSFDefn->GetName() ) != -1 )
     135                 :                 pszFieldName = CPLStrdup( CPLSPrintf( "%s_%s",
     136                 :                                                       papszATIDRefs[iTable],
     137               0 :                                                       poSFDefn->GetName() ) );
     138                 :             else
     139             120 :                 pszFieldName = CPLStrdup( poSFDefn->GetName() );
     140                 :             
     141             120 :             switch( poSFDefn->GetType() )
     142                 :             {
     143                 :               case DDFString:
     144                 :               {
     145              88 :                   OGRFieldDefn  oStrField( pszFieldName, OFTString );
     146                 : 
     147              88 :                   if( nWidth != 0 )
     148              88 :                       oStrField.SetWidth( nWidth );
     149                 : 
     150              88 :                   poFeatureDefn->AddFieldDefn( &oStrField );
     151                 :               }
     152              88 :               break;
     153                 : 
     154                 :               case DDFInt:
     155                 :               {
     156               8 :                   OGRFieldDefn  oIntField( pszFieldName, OFTInteger );
     157                 : 
     158               8 :                   if( nWidth != 0 )
     159               8 :                       oIntField.SetWidth( nWidth );
     160                 : 
     161               8 :                   poFeatureDefn->AddFieldDefn( &oIntField );
     162                 :               }
     163               8 :               break;
     164                 : 
     165                 :               case DDFFloat:
     166                 :               {
     167              24 :                   OGRFieldDefn  oRealField( pszFieldName, OFTReal );
     168                 : 
     169                 :                   // We don't have a precision in DDF files, so we never even
     170                 :                   // use the width.  Otherwise with a precision of zero the
     171                 :                   // result would look like an integer.
     172                 : 
     173              24 :                   poFeatureDefn->AddFieldDefn( &oRealField );
     174                 :               }
     175                 :               break;
     176                 : 
     177                 :               default:
     178                 :                 break;
     179                 :             }
     180                 : 
     181             120 :             CPLFree( pszFieldName );
     182                 :             
     183                 :         } /* next iSF (subfield) */
     184                 :     } /* next iTable */
     185              16 :     CSLDestroy( papszATIDRefs );
     186              16 : }
     187                 : 
     188                 : /************************************************************************/
     189                 : /*                           ~OGRSDTSLayer()                           */
     190                 : /************************************************************************/
     191                 : 
     192              16 : OGRSDTSLayer::~OGRSDTSLayer()
     193                 : 
     194                 : {
     195              16 :     if( m_nFeaturesRead > 0 && poFeatureDefn != NULL )
     196                 :     {
     197                 :         CPLDebug( "SDTS", "%d features read on layer '%s'.",
     198                 :                   (int) m_nFeaturesRead, 
     199              16 :                   poFeatureDefn->GetName() );
     200                 :     }
     201                 : 
     202              16 :     if( poFeatureDefn )
     203              16 :         poFeatureDefn->Release();
     204              16 : }
     205                 : 
     206                 : /************************************************************************/
     207                 : /*                            ResetReading()                            */
     208                 : /************************************************************************/
     209                 : 
     210              32 : void OGRSDTSLayer::ResetReading()
     211                 : 
     212                 : {
     213              32 :     poReader->Rewind();
     214              32 : }
     215                 : 
     216                 : /************************************************************************/
     217                 : /*                     AssignAttrRecordToFeature()                      */
     218                 : /************************************************************************/
     219                 : 
     220                 : static void
     221             390 : AssignAttrRecordToFeature( OGRFeature * poFeature, SDTSTransfer * poTransfer, 
     222                 :                            DDFField * poSR )
     223                 : 
     224                 : {
     225                 : /* -------------------------------------------------------------------- */
     226                 : /*      Process each subfield in the record.                            */
     227                 : /* -------------------------------------------------------------------- */
     228             390 :     DDFFieldDefn        *poFDefn = poSR->GetFieldDefn();
     229                 :         
     230            6054 :     for( int iSF=0; iSF < poFDefn->GetSubfieldCount(); iSF++ )
     231                 :     {
     232            5664 :         DDFSubfieldDefn *poSFDefn = poFDefn->GetSubfield( iSF );
     233                 :         int                     iField;
     234                 :         int                     nMaxBytes;
     235                 :         const char *    pachData = poSR->GetSubfieldData(poSFDefn,
     236            5664 :                                                          &nMaxBytes);
     237                 : /* -------------------------------------------------------------------- */
     238                 : /*      Indentify this field on the feature.                            */
     239                 : /* -------------------------------------------------------------------- */
     240            5664 :         iField = poFeature->GetFieldIndex( poSFDefn->GetName() );
     241                 : 
     242                 : /* -------------------------------------------------------------------- */
     243                 : /*      Handle each of the types.                                       */
     244                 : /* -------------------------------------------------------------------- */
     245            5664 :         switch( poSFDefn->GetType() )
     246                 :         {
     247                 :           case DDFString:
     248                 :             const char  *pszValue;
     249                 : 
     250                 :             pszValue = poSFDefn->ExtractStringData(pachData, nMaxBytes,
     251            4932 :                                                    NULL);
     252                 : 
     253            4932 :             if( iField != -1 )
     254            4932 :                 poFeature->SetField( iField, pszValue );
     255            4932 :             break;
     256                 : 
     257                 :           case DDFFloat:
     258                 :             double      dfValue;
     259                 : 
     260                 :             dfValue = poSFDefn->ExtractFloatData(pachData, nMaxBytes,
     261              48 :                                                  NULL);
     262                 : 
     263              48 :             if( iField != -1 )
     264              48 :                 poFeature->SetField( iField, dfValue );
     265              48 :             break;
     266                 : 
     267                 :           case DDFInt:
     268                 :             int         nValue;
     269                 : 
     270             684 :             nValue = poSFDefn->ExtractIntData(pachData, nMaxBytes, NULL);
     271                 : 
     272             684 :             if( iField != -1 )
     273             684 :                 poFeature->SetField( iField, nValue );
     274                 :             break;
     275                 : 
     276                 :           default:
     277                 :             break;
     278                 :         }
     279                 :     } /* next subfield */
     280             390 : }
     281                 : 
     282                 : /************************************************************************/
     283                 : /*                      GetNextUnfilteredFeature()                      */
     284                 : /************************************************************************/
     285                 : 
     286             780 : OGRFeature * OGRSDTSLayer::GetNextUnfilteredFeature()
     287                 : 
     288                 : {
     289                 : /* -------------------------------------------------------------------- */
     290                 : /*      If not done before we need to assemble the geometry for a       */
     291                 : /*      polygon layer.                                                  */
     292                 : /* -------------------------------------------------------------------- */
     293             780 :     if( poTransfer->GetLayerType(iLayer) == SLTPoly )
     294                 :     {
     295              74 :         ((SDTSPolygonReader *) poReader)->AssembleRings(poTransfer,iLayer);
     296                 :     }
     297                 : 
     298                 : /* -------------------------------------------------------------------- */
     299                 : /*      Fetch the next sdts style feature object from the reader.       */
     300                 : /* -------------------------------------------------------------------- */
     301             780 :     SDTSFeature *poSDTSFeature = poReader->GetNextFeature();
     302                 :     OGRFeature  *poFeature;
     303                 : 
     304             780 :     if( poSDTSFeature == NULL )
     305              16 :         return NULL;
     306                 : 
     307                 : /* -------------------------------------------------------------------- */
     308                 : /*      Create the OGR feature.                                         */
     309                 : /* -------------------------------------------------------------------- */
     310             764 :     poFeature = new OGRFeature( poFeatureDefn );
     311                 : 
     312             764 :     m_nFeaturesRead++;
     313                 : 
     314             764 :     switch( poTransfer->GetLayerType(iLayer) )
     315                 :     {
     316                 : /* -------------------------------------------------------------------- */
     317                 : /*      Translate point feature specific information and geometry.      */
     318                 : /* -------------------------------------------------------------------- */
     319                 :       case SLTPoint:
     320                 :       {
     321             258 :           SDTSRawPoint  *poPoint = (SDTSRawPoint *) poSDTSFeature;
     322                 :           
     323                 :           poFeature->SetGeometryDirectly( new OGRPoint( poPoint->dfX,
     324                 :                                                         poPoint->dfY,
     325             258 :                                                         poPoint->dfZ ) );
     326                 :       }
     327             258 :       break;
     328                 : 
     329                 : /* -------------------------------------------------------------------- */
     330                 : /*      Translate line feature specific information and geometry.       */
     331                 : /* -------------------------------------------------------------------- */
     332                 :       case SLTLine:
     333                 :       {
     334              56 :           SDTSRawLine   *poLine = (SDTSRawLine *) poSDTSFeature;
     335              56 :           OGRLineString *poOGRLine = new OGRLineString();
     336                 : 
     337                 :           poOGRLine->setPoints( poLine->nVertices,
     338              56 :                                 poLine->padfX, poLine->padfY, poLine->padfZ );
     339              56 :           poFeature->SetGeometryDirectly( poOGRLine );
     340              56 :           poFeature->SetField( "SNID", (int) poLine->oStartNode.nRecord );
     341              56 :           poFeature->SetField( "ENID", (int) poLine->oEndNode.nRecord );
     342                 :       }
     343              56 :       break;
     344                 : 
     345                 : /* -------------------------------------------------------------------- */
     346                 : /*      Translate polygon feature specific information and geometry.    */
     347                 : /* -------------------------------------------------------------------- */
     348                 :       case SLTPoly:
     349                 :       {
     350              72 :           SDTSRawPolygon *poPoly = (SDTSRawPolygon *) poSDTSFeature;
     351              72 :           OGRPolygon *poOGRPoly = new OGRPolygon();
     352                 : 
     353             108 :           for( int iRing = 0; iRing < poPoly->nRings; iRing++ )
     354                 :           {
     355              36 :               OGRLinearRing *poRing = new OGRLinearRing();
     356                 :               int           nVertices;
     357                 : 
     358              36 :               if( iRing == poPoly->nRings - 1 )
     359              28 :                   nVertices = poPoly->nVertices - poPoly->panRingStart[iRing];
     360                 :               else
     361               8 :                   nVertices = poPoly->panRingStart[iRing+1]
     362               8 :                             - poPoly->panRingStart[iRing];
     363                 : 
     364                 :               poRing->setPoints( nVertices,
     365              36 :                                  poPoly->padfX + poPoly->panRingStart[iRing],
     366              36 :                                  poPoly->padfY + poPoly->panRingStart[iRing],
     367             108 :                                  poPoly->padfZ + poPoly->panRingStart[iRing] );
     368                 : 
     369              36 :               poOGRPoly->addRingDirectly( poRing );
     370                 :           }
     371                 : 
     372              72 :           poFeature->SetGeometryDirectly( poOGRPoly );
     373                 :       }
     374                 :       break;
     375                 : 
     376                 :       default:
     377                 :         break;
     378                 :     }
     379                 : 
     380                 : /* -------------------------------------------------------------------- */
     381                 : /*      Set attributes for any indicated attribute records.             */
     382                 : /* -------------------------------------------------------------------- */
     383                 :     int         iAttrRecord;
     384                 :     
     385             776 :     for( iAttrRecord = 0; 
     386                 :          iAttrRecord < poSDTSFeature->nAttributes; 
     387                 :          iAttrRecord++)
     388                 :     {
     389                 :         DDFField        *poSR;
     390                 : 
     391              12 :         poSR = poTransfer->GetAttr( poSDTSFeature->paoATID+iAttrRecord );
     392                 :           
     393              12 :         AssignAttrRecordToFeature( poFeature, poTransfer, poSR );
     394                 :     }
     395                 : 
     396                 : /* -------------------------------------------------------------------- */
     397                 : /*      If this record is an attribute record, attach the local         */
     398                 : /*      attributes.                                                     */
     399                 : /* -------------------------------------------------------------------- */
     400             764 :     if( poTransfer->GetLayerType(iLayer) == SLTAttr )
     401                 :     {
     402                 :         AssignAttrRecordToFeature( poFeature, poTransfer, 
     403             378 :                                    ((SDTSAttrRecord *) poSDTSFeature)->poATTR);
     404                 :     }
     405                 :     
     406                 : /* -------------------------------------------------------------------- */
     407                 : /*      Translate the record id.                                        */
     408                 : /* -------------------------------------------------------------------- */
     409             764 :     poFeature->SetFID( poSDTSFeature->oModId.nRecord );
     410             764 :     poFeature->SetField( 0, (int) poSDTSFeature->oModId.nRecord );
     411             764 :     if( poFeature->GetGeometryRef() != NULL )
     412                 :         poFeature->GetGeometryRef()->assignSpatialReference(
     413             386 :             poDS->GetSpatialRef() );
     414                 : 
     415             764 :     if( !poReader->IsIndexed() )
     416             692 :         delete poSDTSFeature;
     417                 : 
     418             764 :     return poFeature;
     419                 : }
     420                 : 
     421                 : 
     422                 : /************************************************************************/
     423                 : /*                           GetNextFeature()                           */
     424                 : /************************************************************************/
     425                 : 
     426             780 : OGRFeature *OGRSDTSLayer::GetNextFeature()
     427                 : 
     428                 : {
     429             780 :     OGRFeature  *poFeature = NULL;
     430                 :     
     431                 : /* -------------------------------------------------------------------- */
     432                 : /*      Read features till we find one that satisfies our current       */
     433                 : /*      spatial criteria.                                               */
     434                 : /* -------------------------------------------------------------------- */
     435               0 :     while( TRUE )
     436                 :     {
     437             780 :         poFeature = GetNextUnfilteredFeature();
     438             780 :         if( poFeature == NULL )
     439              16 :             break;
     440                 : 
     441             764 :         if( (m_poFilterGeom == NULL
     442                 :              || FilterGeometry( poFeature->GetGeometryRef() ) )
     443                 :             && (m_poAttrQuery == NULL
     444                 :                 || m_poAttrQuery->Evaluate( poFeature )) )
     445             764 :             break;
     446                 : 
     447               0 :         delete poFeature;
     448                 :     }
     449                 : 
     450             780 :     return poFeature;
     451                 : }
     452                 : 
     453                 : /************************************************************************/
     454                 : /*                           TestCapability()                           */
     455                 : /************************************************************************/
     456                 : 
     457               0 : int OGRSDTSLayer::TestCapability( const char * pszCap )
     458                 : 
     459                 : {
     460               0 :     if( EQUAL(pszCap,OLCRandomRead) )
     461               0 :         return FALSE;
     462                 : 
     463               0 :     else if( EQUAL(pszCap,OLCSequentialWrite) 
     464                 :              || EQUAL(pszCap,OLCRandomWrite) )
     465               0 :         return FALSE;
     466                 : 
     467               0 :     else if( EQUAL(pszCap,OLCFastFeatureCount) )
     468               0 :         return FALSE;
     469                 : 
     470               0 :     else if( EQUAL(pszCap,OLCFastSpatialFilter) )
     471               0 :         return FALSE;
     472                 : 
     473                 :     else 
     474               0 :         return FALSE;
     475                 : }
     476                 : 
     477                 : 
     478                 : /************************************************************************/
     479                 : /*                           GetSpatialRef()                            */
     480                 : /************************************************************************/
     481                 : 
     482               0 : OGRSpatialReference * OGRSDTSLayer::GetSpatialRef()
     483                 : 
     484                 : {
     485               0 :     return poDS->GetSpatialRef();
     486                 : }

Generated by: LCOV version 1.7