LTP GCOV extension - code coverage report
Current view: directory - ogr/ogrsf_frmts/ntf - ntf_generic.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 309
Code covered: 7.4 % Executed lines: 23

       1                 : /******************************************************************************
       2                 :  * $Id: ntf_generic.cpp 10645 2007-01-18 02:22:39Z warmerdam $
       3                 :  *
       4                 :  * Project:  NTF Translator
       5                 :  * Purpose:  Handle NTF products that aren't recognised generically.
       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 <stdarg.h>
      31                 : #include "ntf.h"
      32                 : #include "cpl_string.h"
      33                 : 
      34                 : CPL_CVSID("$Id: ntf_generic.cpp 10645 2007-01-18 02:22:39Z warmerdam $");
      35                 : 
      36                 : #define MAX_LINK        5000
      37                 : 
      38                 : /************************************************************************/
      39                 : /* ==================================================================== */
      40                 : /*                          NTFGenericClass                             */
      41                 : /*                                                                      */
      42                 : /*      The NTFGenericClass class exists to hold aggregated             */
      43                 : /*      information for each type of record encountered in a set of     */
      44                 : /*      NTF files, primarily the list of attributes actually            */
      45                 : /*      encountered.                                                    */
      46                 : /* ==================================================================== */
      47                 : /************************************************************************/
      48                 : 
      49                 : /************************************************************************/
      50                 : /*                           NTFGenericClass                            */
      51                 : /************************************************************************/
      52                 : 
      53           29700 : NTFGenericClass::NTFGenericClass()
      54                 : {
      55           29700 :     nFeatureCount = 0;
      56                 : 
      57           29700 :     b3D = FALSE;
      58           29700 :     nAttrCount = 0;
      59           29700 :     papszAttrNames = NULL;
      60           29700 :     papszAttrFormats = NULL;
      61           29700 :     panAttrMaxWidth = NULL;
      62           29700 :     pabAttrMultiple = NULL;
      63           29700 : }
      64                 : 
      65                 : /************************************************************************/
      66                 : /*                           ~NTFGenericClass                           */
      67                 : /************************************************************************/
      68                 : 
      69           29700 : NTFGenericClass::~NTFGenericClass()
      70                 : 
      71                 : {
      72           29700 :     CSLDestroy( papszAttrNames );
      73           29700 :     CSLDestroy( papszAttrFormats );
      74           29700 :     CPLFree( panAttrMaxWidth );
      75           29700 :     CPLFree( pabAttrMultiple );
      76           29700 : }
      77                 : 
      78                 : /************************************************************************/
      79                 : /*                            CheckAddAttr()                            */
      80                 : /*                                                                      */
      81                 : /*      Check if an attribute already exists.  If not add it with       */
      82                 : /*      it's format.  Note we don't check for format conflicts at       */
      83                 : /*      this time.                                                      */
      84                 : /************************************************************************/
      85                 : 
      86                 : void NTFGenericClass::CheckAddAttr( const char * pszName,
      87                 :                                     const char * pszFormat,
      88               0 :                                     int nWidth )
      89                 : 
      90                 : {
      91                 :     int         iAttrOffset;
      92                 : 
      93               0 :     if( EQUAL(pszName,"TX") )
      94               0 :         pszName = "TEXT";
      95               0 :     if( EQUAL(pszName,"FC") )
      96               0 :         pszName = "FEAT_CODE";
      97                 : 
      98               0 :     iAttrOffset = CSLFindString( papszAttrNames, pszName );
      99                 :     
     100               0 :     if( iAttrOffset == -1 )
     101                 :     {
     102               0 :         nAttrCount++;
     103                 : 
     104               0 :         papszAttrNames = CSLAddString( papszAttrNames, pszName );
     105               0 :         papszAttrFormats = CSLAddString( papszAttrFormats, pszFormat );
     106                 : 
     107                 :         panAttrMaxWidth = (int *)
     108               0 :             CPLRealloc( panAttrMaxWidth, sizeof(int) * nAttrCount );
     109                 : 
     110               0 :         panAttrMaxWidth[nAttrCount-1] = nWidth;
     111                 : 
     112                 :         pabAttrMultiple = (int *)
     113               0 :             CPLRealloc( pabAttrMultiple, sizeof(int) * nAttrCount );
     114                 : 
     115               0 :         pabAttrMultiple[nAttrCount-1] = FALSE;
     116                 :     }
     117                 :     else
     118                 :     {
     119               0 :         if( panAttrMaxWidth[iAttrOffset] < nWidth )
     120               0 :             panAttrMaxWidth[iAttrOffset] = nWidth;
     121                 :     }
     122               0 : }
     123                 : 
     124                 : /************************************************************************/
     125                 : /*                            SetMultiple()                             */
     126                 : /*                                                                      */
     127                 : /*      Mark this attribute as appearing multiple times on some         */
     128                 : /*      features.                                                       */
     129                 : /************************************************************************/
     130                 : 
     131               0 : void NTFGenericClass::SetMultiple( const char *pszName )
     132                 : 
     133                 : {
     134                 :     int         iAttrOffset;
     135                 : 
     136               0 :     if( EQUAL(pszName,"TX") )
     137               0 :         pszName = "TEXT";
     138               0 :     if( EQUAL(pszName,"FC") )
     139               0 :         pszName = "FEAT_CODE";
     140                 : 
     141               0 :     iAttrOffset = CSLFindString( papszAttrNames, pszName );
     142               0 :     if( iAttrOffset == -1 )
     143               0 :         return;
     144                 : 
     145               0 :     pabAttrMultiple[iAttrOffset] = TRUE;
     146                 : }
     147                 : 
     148                 : /************************************************************************/
     149                 : /*                           WorkupGeneric()                            */
     150                 : /*                                                                      */
     151                 : /*      Scan a whole file, in order to build up a list of attributes    */
     152                 : /*      for the generic types.                                          */
     153                 : /************************************************************************/
     154                 : 
     155               0 : void OGRNTFDataSource::WorkupGeneric( NTFFileReader * poReader )
     156                 : 
     157                 : {
     158               0 :     NTFRecord   **papoGroup = NULL;
     159                 : 
     160               0 :     if( poReader->GetNTFLevel() > 2 )
     161                 :     {
     162               0 :         poReader->IndexFile();
     163               0 :         if( CPLGetLastErrorType() == CE_Failure )
     164               0 :             return;
     165                 :     }
     166                 :     else
     167               0 :         poReader->Reset();
     168                 : 
     169                 : /* ==================================================================== */
     170                 : /*      Read all record groups in the file.                             */
     171                 : /* ==================================================================== */
     172               0 :     while( TRUE )
     173                 :     {
     174                 : /* -------------------------------------------------------------------- */
     175                 : /*      Read a record group                                             */
     176                 : /* -------------------------------------------------------------------- */
     177               0 :         if( poReader->GetNTFLevel() > 2 )
     178               0 :             papoGroup = poReader->GetNextIndexedRecordGroup(papoGroup);
     179                 :         else
     180               0 :             papoGroup = poReader->ReadRecordGroup();
     181                 : 
     182               0 :         if( papoGroup == NULL || papoGroup[0]->GetType() == 99 )
     183               0 :             break;
     184                 :         
     185                 : /* -------------------------------------------------------------------- */
     186                 : /*      Get the class corresponding to the anchor record.               */
     187                 : /* -------------------------------------------------------------------- */
     188               0 :         NTFGenericClass *poClass = GetGClass( papoGroup[0]->GetType() );
     189               0 :         char           **papszFullAttList = NULL;
     190                 : 
     191               0 :         poClass->nFeatureCount++;
     192                 :         
     193                 : /* -------------------------------------------------------------------- */
     194                 : /*      Loop over constituent records collecting attributes.            */
     195                 : /* -------------------------------------------------------------------- */
     196               0 :         for( int iRec = 0; papoGroup[iRec] != NULL; iRec++ )
     197                 :         {
     198               0 :             NTFRecord   *poRecord = papoGroup[iRec];
     199                 : 
     200               0 :             switch( poRecord->GetType() )
     201                 :             {
     202                 :               case NRT_ATTREC:
     203                 :               {
     204                 :                   char  **papszTypes, **papszValues;
     205                 : 
     206                 :                   poReader->ProcessAttRec( poRecord, NULL,
     207               0 :                                            &papszTypes, &papszValues );
     208                 : 
     209               0 :                   for( int iAtt = 0; papszTypes[iAtt] != NULL; iAtt++ )
     210                 :                   {
     211                 :                       NTFAttDesc        *poAttDesc;
     212                 : 
     213               0 :                       poAttDesc = poReader->GetAttDesc( papszTypes[iAtt] );
     214               0 :                       if( poAttDesc != NULL )
     215                 :                       {
     216                 :                           poClass->CheckAddAttr( poAttDesc->val_type,
     217                 :                                                  poAttDesc->finter,
     218               0 :                                                  strlen(papszValues[iAtt]) );
     219                 :                       }
     220                 : 
     221               0 :                       if( CSLFindString( papszFullAttList, 
     222                 :                                          papszTypes[iAtt] ) == -1 )
     223                 :                           papszFullAttList = 
     224                 :                               CSLAddString( papszFullAttList, 
     225               0 :                                             papszTypes[iAtt] );
     226                 :                       else
     227               0 :                           poClass->SetMultiple( poAttDesc->val_type );
     228                 :                   }
     229                 : 
     230               0 :                   CSLDestroy( papszTypes );
     231               0 :                   CSLDestroy( papszValues );
     232                 :               }
     233               0 :               break;
     234                 : 
     235                 :               case NRT_TEXTREP:
     236                 :               case NRT_NAMEPOSTN:
     237               0 :                 poClass->CheckAddAttr( "FONT", "I4", 4 );
     238               0 :                 poClass->CheckAddAttr( "TEXT_HT", "R3,1", 3 );
     239               0 :                 poClass->CheckAddAttr( "TEXT_HT_GROUND", "R9,3", 9 );
     240               0 :                 poClass->CheckAddAttr( "TEXT_HT", "R3,1", 3 );
     241               0 :                 poClass->CheckAddAttr( "DIG_POSTN", "I1", 1 );
     242               0 :                 poClass->CheckAddAttr( "ORIENT", "R4,1", 4 );
     243               0 :                 break;
     244                 : 
     245                 :               case NRT_NAMEREC:
     246                 :                 poClass->CheckAddAttr( "TEXT", "A*",
     247               0 :                                        atoi(poRecord->GetField(13,14)) );
     248               0 :                 break;
     249                 : 
     250                 :               case NRT_GEOMETRY:
     251                 :               case NRT_GEOMETRY3D:
     252               0 :                   if( atoi(poRecord->GetField(3,8)) != 0 )
     253               0 :                       poClass->CheckAddAttr( "GEOM_ID", "I6", 6 );
     254               0 :                   if( poRecord->GetType() == NRT_GEOMETRY3D )
     255               0 :                       poClass->b3D = TRUE;
     256               0 :                   break;
     257                 : 
     258                 :               case NRT_POINTREC:
     259                 :               case NRT_LINEREC:
     260               0 :                 if( poReader->GetNTFLevel() < 3 )
     261                 :                 {
     262                 :                     NTFAttDesc  *poAttDesc;
     263                 :                       
     264               0 :                     poAttDesc = poReader->GetAttDesc(poRecord->GetField(9,10));
     265               0 :                     if( poAttDesc != NULL )
     266                 :                         poClass->CheckAddAttr( poAttDesc->val_type,
     267               0 :                                                poAttDesc->finter, 6 );
     268                 : 
     269               0 :                     if( !EQUAL(poRecord->GetField(17,20),"    ") )
     270               0 :                         poClass->CheckAddAttr( "FEAT_CODE", "A4", 4 );
     271                 :                 }
     272                 :                 break;
     273                 :                 
     274                 :               default:
     275                 :                 break;
     276                 :             }
     277                 :         }
     278                 : 
     279               0 :         CSLDestroy( papszFullAttList );
     280                 :     }
     281                 : 
     282               0 :     if( GetOption("CACHING") != NULL
     283                 :         && EQUAL(GetOption("CACHING"),"OFF") )
     284               0 :         poReader->DestroyIndex();
     285                 : 
     286               0 :     poReader->Reset();
     287                 : }
     288                 : 
     289                 : /************************************************************************/
     290                 : /*                        AddGenericAttributes()                        */
     291                 : /************************************************************************/
     292                 : 
     293                 : static void AddGenericAttributes( NTFFileReader * poReader,
     294                 :                                   NTFRecord **papoGroup,
     295               0 :                                   OGRFeature * poFeature )
     296                 : 
     297                 : {
     298                 :     char        **papszTypes, **papszValues;
     299                 : 
     300               0 :     if( !poReader->ProcessAttRecGroup( papoGroup, &papszTypes, &papszValues ) )
     301               0 :         return;
     302                 : 
     303               0 :     for( int iAtt = 0; papszTypes != NULL && papszTypes[iAtt] != NULL; iAtt++ )
     304                 :     {
     305                 :         int             iField;
     306                 :         
     307               0 :         if( EQUAL(papszTypes[iAtt],"TX") )
     308               0 :             iField = poFeature->GetFieldIndex("TEXT");
     309               0 :         else if( EQUAL(papszTypes[iAtt],"FC") )
     310               0 :             iField = poFeature->GetFieldIndex("FEAT_CODE");
     311                 :         else
     312               0 :             iField = poFeature->GetFieldIndex(papszTypes[iAtt]);
     313                 : 
     314               0 :         if( iField == -1 )
     315               0 :             continue;
     316                 : 
     317                 :         poReader->ApplyAttributeValue( poFeature, iField, papszTypes[iAtt],
     318               0 :                                        papszTypes, papszValues );
     319                 : 
     320                 : /* -------------------------------------------------------------------- */
     321                 : /*      Do we have a corresponding list field we should be              */
     322                 : /*      accumulating this into?                                         */
     323                 : /* -------------------------------------------------------------------- */
     324                 :         char  szListName[128];
     325                 :         int   iListField;
     326                 : 
     327                 :         sprintf( szListName, "%s_LIST", 
     328               0 :                  poFeature->GetFieldDefnRef(iField)->GetNameRef() );
     329               0 :         iListField = poFeature->GetFieldIndex( szListName );
     330                 : 
     331                 : /* -------------------------------------------------------------------- */
     332                 : /*      Yes, so perform processing similar to ApplyAttributeValue(),    */
     333                 : /*      and append to list value.                                       */
     334                 : /* -------------------------------------------------------------------- */
     335               0 :         if( iListField != -1 )
     336                 :         {
     337                 :             char        *pszAttLongName, *pszAttValue, *pszCodeDesc;
     338                 :             
     339                 :             poReader->ProcessAttValue( papszTypes[iAtt], papszValues[iAtt],
     340                 :                                        &pszAttLongName, &pszAttValue, 
     341               0 :                                        &pszCodeDesc );
     342                 : 
     343               0 :             if( poFeature->IsFieldSet( iListField ) )
     344                 :             {
     345                 :                 poFeature->SetField( iListField, 
     346                 :                     CPLSPrintf( "%s,%s", 
     347                 :                                 poFeature->GetFieldAsString( iListField ), 
     348               0 :                                 pszAttValue ) );
     349                 :             }
     350                 :             else
     351                 :             {
     352               0 :                 poFeature->SetField( iListField, pszAttValue );
     353                 :             }
     354                 :         }
     355                 :     }
     356                 : 
     357               0 :     CSLDestroy( papszTypes );
     358               0 :     CSLDestroy( papszValues );
     359                 : }
     360                 : 
     361                 : /************************************************************************/
     362                 : /*                        TranslateGenericNode()                        */
     363                 : /************************************************************************/
     364                 : 
     365                 : static OGRFeature *TranslateGenericNode( NTFFileReader *poReader,
     366                 :                                          OGRNTFLayer *poLayer,
     367               0 :                                          NTFRecord **papoGroup )
     368                 : 
     369                 : {
     370               0 :     if( CSLCount((char **) papoGroup) < 2
     371                 :         || papoGroup[0]->GetType() != NRT_NODEREC
     372                 :         || (papoGroup[1]->GetType() != NRT_GEOMETRY
     373                 :             && papoGroup[1]->GetType() != NRT_GEOMETRY3D) )
     374                 :     {
     375               0 :         return NULL;
     376                 :     }
     377                 :         
     378               0 :     OGRFeature  *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
     379                 : 
     380                 :     // NODE_ID
     381               0 :     poFeature->SetField( "NODE_ID", atoi(papoGroup[0]->GetField( 3, 8 )) );
     382                 : 
     383                 :     // Geometry
     384               0 :     poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1]));
     385               0 :     poFeature->SetField( "GEOM_ID", papoGroup[1]->GetField(3,8) );
     386                 : 
     387                 :     // NUM_LINKS
     388               0 :     int         nLinkCount=0;
     389               0 :     int         *panLinks = NULL;
     390                 : 
     391               0 :     if( papoGroup[0]->GetLength() > 18 )
     392                 :     {
     393               0 :         nLinkCount = atoi(papoGroup[0]->GetField(15,18));
     394               0 :         panLinks = (int *) CPLCalloc(sizeof(int),nLinkCount);
     395                 :     }
     396                 : 
     397               0 :     poFeature->SetField( "NUM_LINKS", nLinkCount );
     398                 : 
     399                 :     // GEOM_ID_OF_LINK
     400                 :     int      iLink;
     401               0 :     for( iLink = 0; iLink < nLinkCount; iLink++ )
     402                 :         panLinks[iLink] = atoi(papoGroup[0]->GetField(20+iLink*12,
     403               0 :                                                       25+iLink*12));
     404                 : 
     405               0 :     poFeature->SetField( "GEOM_ID_OF_LINK", nLinkCount, panLinks );
     406                 : 
     407                 :     // DIR
     408               0 :     for( iLink = 0; iLink < nLinkCount; iLink++ )
     409                 :         panLinks[iLink] = atoi(papoGroup[0]->GetField(19+iLink*12,
     410               0 :                                                       19+iLink*12));
     411                 : 
     412               0 :     poFeature->SetField( "DIR", nLinkCount, panLinks );
     413                 : 
     414                 :     // should we add LEVEL and/or ORIENT?
     415                 : 
     416               0 :     CPLFree( panLinks );
     417                 : 
     418               0 :     return poFeature;
     419                 : }
     420                 : 
     421                 : /************************************************************************/
     422                 : /*                     TranslateGenericCollection()                     */
     423                 : /************************************************************************/
     424                 : 
     425                 : static OGRFeature *TranslateGenericCollection( NTFFileReader *poReader,
     426                 :                                                OGRNTFLayer *poLayer,
     427               0 :                                                NTFRecord **papoGroup )
     428                 : 
     429                 : {
     430               0 :     if( CSLCount((char **) papoGroup) < 1 
     431                 :         || papoGroup[0]->GetType() != NRT_COLLECT )
     432               0 :         return NULL;
     433                 :         
     434               0 :     OGRFeature  *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
     435                 : 
     436                 :     // COLL_ID
     437               0 :     poFeature->SetField( "COLL_ID", atoi(papoGroup[0]->GetField( 3, 8 )) );
     438                 : 
     439                 :     // NUM_PARTS
     440               0 :     int         nPartCount=0;
     441               0 :     int         *panParts = NULL;
     442                 : 
     443               0 :     if( papoGroup[0]->GetLength() > 18 )
     444                 :     {
     445               0 :         nPartCount = atoi(papoGroup[0]->GetField(9,12));
     446               0 :         panParts = (int *) CPLCalloc(sizeof(int),nPartCount);
     447                 :     }
     448                 : 
     449               0 :     poFeature->SetField( "NUM_PARTS", nPartCount );
     450                 : 
     451                 :     // TYPE
     452                 :     int      iPart;
     453               0 :     for( iPart = 0; iPart < nPartCount; iPart++ )
     454                 :         panParts[iPart] = atoi(papoGroup[0]->GetField(13+iPart*8,
     455               0 :                                                       14+iPart*8));
     456                 : 
     457               0 :     poFeature->SetField( "TYPE", nPartCount, panParts );
     458                 : 
     459                 :     // ID
     460               0 :     for( iPart = 0; iPart < nPartCount; iPart++ )
     461                 :         panParts[iPart] = atoi(papoGroup[0]->GetField(15+iPart*8,
     462               0 :                                                       20+iPart*8));
     463                 : 
     464               0 :     poFeature->SetField( "ID", nPartCount, panParts );
     465                 : 
     466               0 :     CPLFree( panParts );
     467                 : 
     468                 :     // ATTREC Attributes
     469               0 :     AddGenericAttributes( poReader, papoGroup, poFeature );
     470                 : 
     471               0 :     return poFeature;
     472                 : }
     473                 : 
     474                 : /************************************************************************/
     475                 : /*                        TranslateGenericText()                        */
     476                 : /************************************************************************/
     477                 : 
     478                 : static OGRFeature *TranslateGenericText( NTFFileReader *poReader,
     479                 :                                          OGRNTFLayer *poLayer,
     480               0 :                                          NTFRecord **papoGroup )
     481                 : 
     482                 : {
     483                 :     int         iRec;
     484                 :     
     485               0 :     if( CSLCount((char **) papoGroup) < 2
     486                 :         || papoGroup[0]->GetType() != NRT_TEXTREC )
     487               0 :         return NULL;
     488                 :         
     489               0 :     OGRFeature  *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
     490                 : 
     491                 :     // TEXT_ID
     492               0 :     poFeature->SetField( "TEXT_ID", atoi(papoGroup[0]->GetField( 3, 8 )) );
     493                 : 
     494                 :     // Geometry
     495               0 :     for( iRec = 0; papoGroup[iRec] != NULL; iRec++ )
     496                 :     {
     497               0 :         if( papoGroup[iRec]->GetType() == NRT_GEOMETRY
     498                 :             || papoGroup[iRec]->GetType() == NRT_GEOMETRY3D )
     499                 :         {
     500                 :             poFeature->SetGeometryDirectly(
     501               0 :                 poReader->ProcessGeometry(papoGroup[iRec]));
     502               0 :             poFeature->SetField( "GEOM_ID", papoGroup[iRec]->GetField(3,8) );
     503               0 :             break;
     504                 :         }
     505                 :     }
     506                 : 
     507                 :     // ATTREC Attributes
     508               0 :     AddGenericAttributes( poReader, papoGroup, poFeature );
     509                 : 
     510                 :     // TEXTREP information
     511               0 :     for( iRec = 0; papoGroup[iRec] != NULL; iRec++ )
     512                 :     {
     513               0 :         NTFRecord       *poRecord = papoGroup[iRec];
     514                 :         
     515               0 :         if( poRecord->GetType() == NRT_TEXTREP )
     516                 :         {
     517               0 :             poFeature->SetField( "FONT", atoi(poRecord->GetField(9,12)) );
     518                 :             poFeature->SetField( "TEXT_HT",
     519               0 :                                  atoi(poRecord->GetField(13,15)) * 0.1 );
     520                 :             poFeature->SetField( "TEXT_HT_GROUND",
     521                 :                                  atoi(poRecord->GetField(13,15))
     522               0 :                                  * 0.1 * poReader->GetPaperToGround() );
     523                 :             poFeature->SetField( "DIG_POSTN",
     524               0 :                                  atoi(poRecord->GetField(16,16)) );
     525                 :             poFeature->SetField( "ORIENT",
     526               0 :                                  atoi(poRecord->GetField(17,20)) * 0.1 );
     527               0 :             break;
     528                 :         }
     529                 :     }
     530                 : 
     531               0 :     return poFeature;
     532                 : }
     533                 : 
     534                 : /************************************************************************/
     535                 : /*                        TranslateGenericName()                        */
     536                 : /************************************************************************/
     537                 : 
     538                 : static OGRFeature *TranslateGenericName( NTFFileReader *poReader,
     539                 :                                          OGRNTFLayer *poLayer,
     540               0 :                                          NTFRecord **papoGroup )
     541                 : 
     542                 : {
     543                 :     int         iRec;
     544                 :     
     545               0 :     if( CSLCount((char **) papoGroup) < 2
     546                 :         || papoGroup[0]->GetType() != NRT_NAMEREC )
     547               0 :         return NULL;
     548                 :         
     549               0 :     OGRFeature  *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
     550                 : 
     551                 :     // NAME_ID
     552               0 :     poFeature->SetField( "NAME_ID", atoi(papoGroup[0]->GetField( 3, 8 )) );
     553                 : 
     554                 :     // TEXT_CODE
     555               0 :     poFeature->SetField( "TEXT_CODE", papoGroup[0]->GetField( 8, 12 ) );
     556                 : 
     557                 :     // TEXT
     558               0 :     int nNumChar = atoi(papoGroup[0]->GetField(13,14));
     559                 : 
     560               0 :     poFeature->SetField( "TEXT", papoGroup[0]->GetField( 15, 15+nNumChar-1));
     561                 : 
     562                 :     // Geometry
     563               0 :     for( iRec = 0; papoGroup[iRec] != NULL; iRec++ )
     564                 :     {
     565               0 :         if( papoGroup[iRec]->GetType() == NRT_GEOMETRY
     566                 :             || papoGroup[iRec]->GetType() == NRT_GEOMETRY3D )
     567                 :         {
     568                 :             poFeature->SetGeometryDirectly(
     569               0 :                 poReader->ProcessGeometry(papoGroup[iRec]));
     570               0 :             poFeature->SetField( "GEOM_ID", papoGroup[iRec]->GetField(3,8) );
     571               0 :             break;
     572                 :         }
     573                 :     }
     574                 : 
     575                 :     // ATTREC Attributes
     576               0 :     AddGenericAttributes( poReader, papoGroup, poFeature );
     577                 : 
     578                 :     // NAMEPOSTN information
     579               0 :     for( iRec = 0; papoGroup[iRec] != NULL; iRec++ )
     580                 :     {
     581               0 :         NTFRecord       *poRecord = papoGroup[iRec];
     582                 :         
     583               0 :         if( poRecord->GetType() == NRT_NAMEPOSTN )
     584                 :         {
     585               0 :             poFeature->SetField( "FONT", atoi(poRecord->GetField(3,6)) );
     586                 :             poFeature->SetField( "TEXT_HT",
     587               0 :                                  atoi(poRecord->GetField(7,9)) * 0.1 );
     588                 :             poFeature->SetField( "TEXT_HT_GROUND",
     589                 :                                  atoi(poRecord->GetField(7,9))
     590               0 :                                  * 0.1 * poReader->GetPaperToGround() );
     591                 :             poFeature->SetField( "DIG_POSTN",
     592               0 :                                  atoi(poRecord->GetField(10,10)) );
     593                 :             poFeature->SetField( "ORIENT",
     594               0 :                                  atoi(poRecord->GetField(11,14)) * 0.1 );
     595               0 :             break;
     596                 :         }
     597                 :     }
     598                 : 
     599               0 :     return poFeature;
     600                 : }
     601                 : 
     602                 : /************************************************************************/
     603                 : /*                       TranslateGenericPoint()                        */
     604                 : /************************************************************************/
     605                 : 
     606                 : static OGRFeature *TranslateGenericPoint( NTFFileReader *poReader,
     607                 :                                           OGRNTFLayer *poLayer,
     608               0 :                                           NTFRecord **papoGroup )
     609                 : 
     610                 : {
     611               0 :     if( CSLCount((char **) papoGroup) < 2
     612                 :         || papoGroup[0]->GetType() != NRT_POINTREC
     613                 :         || (papoGroup[1]->GetType() != NRT_GEOMETRY
     614                 :             && papoGroup[1]->GetType() != NRT_GEOMETRY3D) )
     615                 :     {
     616               0 :         return NULL;
     617                 :     }
     618                 :         
     619               0 :     OGRFeature  *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
     620                 : 
     621                 :     // POINT_ID
     622               0 :     poFeature->SetField( "POINT_ID", atoi(papoGroup[0]->GetField( 3, 8 )) );
     623                 : 
     624                 :     // Geometry
     625               0 :     poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1]));
     626               0 :     poFeature->SetField( "GEOM_ID", papoGroup[1]->GetField(3,8) );
     627                 : 
     628                 :     // ATTREC Attributes
     629               0 :     AddGenericAttributes( poReader, papoGroup, poFeature );
     630                 : 
     631                 :     // Handle singular attribute in pre-level 3 POINTREC.
     632               0 :     if( poReader->GetNTFLevel() < 3 )
     633                 :     {
     634                 :         char    szValType[3];
     635                 : 
     636               0 :         strcpy( szValType, papoGroup[0]->GetField(9,10) );
     637               0 :         if( !EQUAL(szValType,"  ") )
     638                 :         {
     639                 :             char        *pszProcessedValue;
     640                 : 
     641               0 :             if( poReader->ProcessAttValue(szValType,
     642                 :                                           papoGroup[0]->GetField(11,16),
     643                 :                                           NULL, &pszProcessedValue, NULL ) )
     644               0 :                 poFeature->SetField(szValType, pszProcessedValue);
     645                 :         }
     646                 : 
     647               0 :         if( !EQUAL(papoGroup[0]->GetField(17,20),"    ") )
     648                 :         {
     649               0 :             poFeature->SetField("FEAT_CODE",papoGroup[0]->GetField(17,20));
     650                 :         }
     651                 :     }
     652                 : 
     653               0 :     return poFeature;
     654                 : }
     655                 : 
     656                 : /************************************************************************/
     657                 : /*                        TranslateGenericLine()                        */
     658                 : /************************************************************************/
     659                 : 
     660                 : static OGRFeature *TranslateGenericLine( NTFFileReader *poReader,
     661                 :                                          OGRNTFLayer *poLayer,
     662               0 :                                          NTFRecord **papoGroup )
     663                 : 
     664                 : {
     665               0 :     if( CSLCount((char **) papoGroup) < 2
     666                 :         || papoGroup[0]->GetType() != NRT_LINEREC
     667                 :         || (papoGroup[1]->GetType() != NRT_GEOMETRY
     668                 :             && papoGroup[1]->GetType() != NRT_GEOMETRY3D) )
     669               0 :         return NULL;
     670                 :         
     671               0 :     OGRFeature  *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
     672                 : 
     673                 :     // LINE_ID
     674               0 :     poFeature->SetField( "LINE_ID", atoi(papoGroup[0]->GetField( 3, 8 )) );
     675                 : 
     676                 :     // Geometry
     677               0 :     poFeature->SetGeometryDirectly(poReader->ProcessGeometry(papoGroup[1]));
     678               0 :     poFeature->SetField( "GEOM_ID", papoGroup[1]->GetField(3,8) );
     679                 : 
     680                 :     // ATTREC Attributes
     681               0 :     AddGenericAttributes( poReader, papoGroup, poFeature );
     682                 : 
     683                 :     // Handle singular attribute in pre-level 3 LINEREC.
     684               0 :     if( poReader->GetNTFLevel() < 3 )
     685                 :     {
     686                 :         char    szValType[3];
     687                 : 
     688               0 :         strcpy( szValType, papoGroup[0]->GetField(9,10) );
     689               0 :         if( !EQUAL(szValType,"  ") )
     690                 :         {
     691                 :             char        *pszProcessedValue;
     692                 : 
     693               0 :             if( poReader->ProcessAttValue(szValType,
     694                 :                                           papoGroup[0]->GetField(11,16),
     695                 :                                           NULL, &pszProcessedValue, NULL ) )
     696               0 :                 poFeature->SetField(szValType, pszProcessedValue);
     697                 :         }
     698                 : 
     699               0 :         if( !EQUAL(papoGroup[0]->GetField(17,20),"    ") )
     700                 :         {
     701               0 :             poFeature->SetField("FEAT_CODE",papoGroup[0]->GetField(17,20));
     702                 :         }
     703                 :     }
     704                 : 
     705               0 :     return poFeature;
     706                 : }
     707                 : 
     708                 : /************************************************************************/
     709                 : /*                        TranslateGenericPoly()                        */
     710                 : /************************************************************************/
     711                 : 
     712                 : static OGRFeature *TranslateGenericPoly( NTFFileReader *poReader,
     713                 :                                          OGRNTFLayer *poLayer,
     714               0 :                                          NTFRecord **papoGroup )
     715                 : 
     716                 : {
     717                 : /* ==================================================================== */
     718                 : /*      Traditional POLYGON record groups.                              */
     719                 : /* ==================================================================== */
     720               0 :     if( CSLCount((char **) papoGroup) >= 2 
     721                 :         && papoGroup[0]->GetType() == NRT_POLYGON
     722                 :         && papoGroup[1]->GetType() == NRT_CHAIN )
     723                 :     {
     724               0 :         OGRFeature      *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
     725                 : 
     726                 :         // POLY_ID
     727               0 :         poFeature->SetField( 0, atoi(papoGroup[0]->GetField( 3, 8 )) );
     728                 : 
     729                 :         // NUM_PARTS
     730               0 :         int             nNumLinks = atoi(papoGroup[1]->GetField( 9, 12 ));
     731                 :     
     732               0 :         if( nNumLinks > MAX_LINK )
     733                 :         {
     734                 :             CPLError( CE_Failure, CPLE_AppDefined, 
     735               0 :                       "MAX_LINK exceeded in ntf_generic.cpp." );
     736               0 :             return poFeature;
     737                 :         }
     738                 :     
     739               0 :         poFeature->SetField( "NUM_PARTS", nNumLinks );
     740                 : 
     741                 :         // DIR
     742                 :         int             i, anList[MAX_LINK];
     743                 : 
     744               0 :         for( i = 0; i < nNumLinks; i++ )
     745               0 :             anList[i] = atoi(papoGroup[1]->GetField( 19+i*7, 19+i*7 ));
     746                 : 
     747               0 :         poFeature->SetField( "DIR", nNumLinks, anList );
     748                 : 
     749                 :         // GEOM_ID_OF_LINK
     750               0 :         for( i = 0; i < nNumLinks; i++ )
     751               0 :             anList[i] = atoi(papoGroup[1]->GetField( 13+i*7, 18+i*7 ));
     752                 : 
     753               0 :         poFeature->SetField( "GEOM_ID_OF_LINK", nNumLinks, anList );
     754                 : 
     755                 :         // RingStart
     756               0 :         int     nRingList = 0;
     757               0 :         poFeature->SetField( "RingStart", 1, &nRingList );
     758                 : 
     759                 :         // ATTREC Attributes
     760               0 :         AddGenericAttributes( poReader, papoGroup, poFeature );
     761                 : 
     762                 :         // Read point geometry
     763               0 :         if( papoGroup[2] != NULL
     764                 :             && (papoGroup[2]->GetType() == NRT_GEOMETRY
     765                 :                 || papoGroup[2]->GetType() == NRT_GEOMETRY3D) )
     766                 :         {
     767                 :             poFeature->SetGeometryDirectly(
     768               0 :                 poReader->ProcessGeometry(papoGroup[2]));
     769               0 :             poFeature->SetField( "GEOM_ID", papoGroup[2]->GetField(3,8) );
     770                 :         }
     771                 : 
     772               0 :         return poFeature;
     773                 :     }
     774                 : 
     775               0 :     return NULL;
     776                 : }
     777                 : 
     778                 : /************************************************************************/
     779                 : /*                       TranslateGenericCPoly()                        */
     780                 : /************************************************************************/
     781                 : 
     782                 : static OGRFeature *TranslateGenericCPoly( NTFFileReader *poReader,
     783                 :                                           OGRNTFLayer *poLayer,
     784               0 :                                           NTFRecord **papoGroup )
     785                 : 
     786                 : {
     787                 : /* -------------------------------------------------------------------- */
     788                 : /*      First we do validation of the grouping.                         */
     789                 : /* -------------------------------------------------------------------- */
     790               0 :     if( papoGroup[0]->GetType() != NRT_CPOLY )
     791               0 :         return NULL;
     792                 :     
     793               0 :     if( papoGroup[1] == NULL || 
     794                 :         (papoGroup[1]->GetType() != NRT_GEOMETRY 
     795                 :          && papoGroup[1]->GetType() != NRT_GEOMETRY3D) ) 
     796               0 :         return NULL;
     797                 :     
     798               0 :     if( papoGroup[1] != NULL 
     799                 :         && papoGroup[2]->GetType() != NRT_ATTREC )
     800               0 :         return NULL;
     801                 : 
     802                 : /* -------------------------------------------------------------------- */
     803                 : /*      collect information for whole complex polygon.                  */
     804                 : /* -------------------------------------------------------------------- */
     805               0 :     OGRFeature  *poFeature = new OGRFeature( poLayer->GetLayerDefn() );
     806                 : 
     807                 :     // CPOLY_ID
     808               0 :     poFeature->SetField( "CPOLY_ID", atoi(papoGroup[0]->GetField( 3, 8 )) );
     809                 :     
     810                 :     // ATTREC Attributes
     811               0 :     AddGenericAttributes( poReader, papoGroup, poFeature );
     812                 :     
     813                 :     // Read point geometry
     814               0 :     if( papoGroup[1] != NULL 
     815                 :         && (papoGroup[1]->GetType() == NRT_GEOMETRY
     816                 :             || papoGroup[1]->GetType() == NRT_GEOMETRY3D) )
     817                 :     {
     818                 :         poFeature->SetGeometryDirectly(
     819               0 :             poReader->ProcessGeometry(papoGroup[1]));
     820                 :         poFeature->SetField( "GEOM_ID", 
     821               0 :                              atoi(papoGroup[1]->GetField(3,8)) );
     822                 :     }
     823                 :     
     824                 : /* -------------------------------------------------------------------- */
     825                 : /*      Collect the chains for each of the rings, and just aggregate    */
     826                 : /*      these into the master list without any concept of where the     */
     827                 : /*      boundaries are.  The boundary information will be emmitted      */
     828                 : /*      in the RingStart field.                                         */
     829                 : /* -------------------------------------------------------------------- */
     830               0 :     int         nNumLink = 0, iLink;
     831                 :     int         anPolyId[MAX_LINK*2];
     832                 : 
     833               0 :     nNumLink = atoi(papoGroup[0]->GetField(9,12));
     834               0 :     for( iLink = 0; iLink < nNumLink; iLink++ )
     835                 :     {
     836                 :         anPolyId[iLink] = atoi(papoGroup[0]->GetField(13 + iLink*7,
     837               0 :                                                       18 + iLink*7));
     838                 :     }
     839                 : 
     840                 :     // NUM_PARTS
     841               0 :     poFeature->SetField( "NUM_PARTS", nNumLink );
     842                 : 
     843                 :     // POLY_ID
     844               0 :     poFeature->SetField( "POLY_ID", nNumLink, anPolyId );
     845                 : 
     846               0 :     return poFeature;
     847                 : }
     848                 : 
     849                 : /************************************************************************/
     850                 : /*                       EstablishGenericLayers()                       */
     851                 : /************************************************************************/
     852                 : 
     853               2 : void OGRNTFDataSource::EstablishGenericLayers()
     854                 : 
     855                 : {
     856                 :     int         iType;
     857                 :     
     858                 : /* -------------------------------------------------------------------- */
     859                 : /*      Pick an initial NTFFileReader to build the layers against.      */
     860                 : /* -------------------------------------------------------------------- */
     861               4 :     for( int iFile = 0; iFile < nNTFFileCount; iFile++ )
     862                 :     {
     863               2 :         NTFFileReader   *poPReader = NULL;
     864               2 :         int             n3DFlag = 0;
     865                 :         
     866               2 :         poPReader = papoNTFFileReader[iFile];
     867               2 :         if( poPReader->GetProductId() != NPC_UNKNOWN )
     868               2 :             continue;
     869                 : 
     870                 : /* -------------------------------------------------------------------- */
     871                 : /*      If any of the generic classes are 3D, then assume all our       */
     872                 : /*      geometry should be marked as 3D.                                */
     873                 : /* -------------------------------------------------------------------- */
     874               0 :         for( iType = 0; iType < 99; iType++ )
     875                 :         {
     876               0 :             NTFGenericClass     *poClass = aoGenericClass + iType;
     877                 :         
     878               0 :             if( poClass->nFeatureCount > 0 && poClass->b3D )
     879               0 :                 n3DFlag = wkb25DBit;
     880                 :         }
     881                 :         
     882                 : /* -------------------------------------------------------------------- */
     883                 : /*      Create layers for all recognised layer types with features.     */
     884                 : /* -------------------------------------------------------------------- */
     885               0 :         for( iType = 0; iType < 99; iType++ )
     886                 :         {
     887               0 :             NTFGenericClass     *poClass = aoGenericClass + iType;
     888                 :         
     889               0 :             if( poClass->nFeatureCount == 0 )
     890               0 :                 continue;
     891                 : 
     892               0 :             if( iType == NRT_POINTREC )
     893                 :             {
     894                 :                 poPReader->
     895                 :                     EstablishLayer( "GENERIC_POINT", 
     896                 :                                     (OGRwkbGeometryType) (wkbPoint | n3DFlag),
     897                 :                                     TranslateGenericPoint,
     898                 :                                     NRT_POINTREC, poClass,
     899                 :                                     "POINT_ID", OFTInteger, 6, 0,
     900               0 :                                     NULL );
     901                 :             }
     902               0 :             else if( iType == NRT_LINEREC )
     903                 :             {
     904                 :                 poPReader->
     905                 :                     EstablishLayer( "GENERIC_LINE", 
     906                 :                                     (OGRwkbGeometryType) 
     907                 :                                     (wkbLineString | n3DFlag),
     908                 :                                     TranslateGenericLine,
     909                 :                                     NRT_LINEREC, poClass,
     910                 :                                     "LINE_ID", OFTInteger, 6, 0,
     911               0 :                                     NULL );
     912                 :             }
     913               0 :             else if( iType == NRT_TEXTREC )
     914                 :             {
     915                 :                 poPReader->
     916                 :                     EstablishLayer( "GENERIC_TEXT", 
     917                 :                                     (OGRwkbGeometryType) 
     918                 :                                     (wkbPoint | n3DFlag),
     919                 :                                     TranslateGenericText,
     920                 :                                     NRT_TEXTREC, poClass,
     921                 :                                     "TEXT_ID", OFTInteger, 6, 0,
     922               0 :                                     NULL );
     923                 :             }
     924               0 :             else if( iType == NRT_NAMEREC )
     925                 :             {
     926                 :                 poPReader->
     927                 :                     EstablishLayer( "GENERIC_NAME", 
     928                 :                                     (OGRwkbGeometryType) 
     929                 :                                     (wkbPoint | n3DFlag),
     930                 :                                     TranslateGenericName,
     931                 :                                     NRT_NAMEREC, poClass,
     932                 :                                     "NAME_ID", OFTInteger, 6, 0,
     933               0 :                                     NULL );
     934                 :             }
     935               0 :             else if( iType == NRT_NODEREC )
     936                 :             {
     937                 :                 poPReader->
     938                 :                     EstablishLayer( "GENERIC_NODE",
     939                 :                                     (OGRwkbGeometryType) 
     940                 :                                     (wkbPoint | n3DFlag),
     941                 :                                     TranslateGenericNode,
     942                 :                                     NRT_NODEREC, poClass,
     943                 :                                     "NODE_ID", OFTInteger, 6, 0,
     944                 :                                     "NUM_LINKS", OFTInteger, 4, 0,
     945                 :                                     "GEOM_ID_OF_LINK", OFTIntegerList, 6, 0,
     946                 :                                     "DIR", OFTIntegerList, 1, 0,
     947               0 :                                     NULL );
     948                 :             }
     949               0 :             else if( iType == NRT_COLLECT )
     950                 :             {
     951                 :                 poPReader->
     952                 :                     EstablishLayer( "GENERIC_COLLECTION", wkbNone,
     953                 :                                     TranslateGenericCollection,
     954                 :                                     NRT_COLLECT, poClass,
     955                 :                                     "COLL_ID", OFTInteger, 6, 0,
     956                 :                                     "NUM_PARTS", OFTInteger, 4, 0,
     957                 :                                     "TYPE", OFTIntegerList, 2, 0,
     958                 :                                     "ID", OFTIntegerList, 6, 0,
     959               0 :                                     NULL );
     960                 :             }
     961               0 :             else if( iType == NRT_POLYGON )
     962                 :             {
     963                 :                 poPReader->
     964                 :                     EstablishLayer( "GENERIC_POLY", 
     965                 :                                     (OGRwkbGeometryType) (wkbPoint | n3DFlag),
     966                 :                                     TranslateGenericPoly,
     967                 :                                     NRT_POLYGON, poClass,
     968                 :                                     "POLY_ID", OFTInteger, 6, 0,
     969                 :                                     "NUM_PARTS", OFTInteger, 4, 0, 
     970                 :                                     "DIR", OFTIntegerList, 1, 0,
     971                 :                                     "GEOM_ID_OF_LINK", OFTIntegerList, 6, 0,
     972                 :                                     "RingStart", OFTIntegerList, 6, 0,
     973               0 :                                     NULL );
     974                 :             }
     975               0 :             else if( iType == NRT_CPOLY )
     976                 :             {
     977                 :                 poPReader->
     978                 :                     EstablishLayer( "GENERIC_CPOLY", 
     979                 :                                     (OGRwkbGeometryType) (wkbPoint | n3DFlag),
     980                 :                                     TranslateGenericCPoly,
     981                 :                                     NRT_CPOLY, poClass,
     982                 :                                     "CPOLY_ID", OFTInteger, 6, 0,
     983                 :                                     "NUM_PARTS", OFTInteger, 4, 0, 
     984                 :                                     "POLY_ID", OFTIntegerList, 1, 0,
     985               0 :                                     NULL );
     986                 :             }
     987                 :         }
     988                 :     }
     989               2 : }
     990                 : 

Generated by: LTP GCOV extension version 1.5