Ticket #1735: gdal-1.4.2-bna.patch

File gdal-1.4.2-bna.patch, 57.5 kB (added by rouault, 1 year ago)
  • gdal-1.4.2.ori/ogr/ogrsf_frmts/bna/GNUmakefile

    old new  
     1 
     2 
     3include ../../../GDALmake.opt 
     4 
     5OBJ     =       ogrbnadriver.o ogrbnadatasource.o ogrbnalayer.o ogrbnaparser.o 
     6 
     7CPPFLAGS        :=      -I.. -I../.. $(GDAL_INCLUDE) $(CPPFLAGS) 
     8 
     9default:        $(O_OBJ) 
     10 
     11clean: 
     12        rm -f *.o $(O_OBJ) 
     13 
     14$(O_OBJ):       ogr_bna.h ogrbnaparser.h 
     15 
  • gdal-1.4.2.ori/ogr/ogrsf_frmts/bna/ogrbnadatasource.cpp

    old new  
     1/****************************************************************************** 
     2 * $Id: ogrbnadatasource.cpp 
     3 * 
     4 * Project:  BNA Translator 
     5 * Purpose:  Implements OGRBNADataSource class 
     6 * Author:   Even Rouault, even dot rouault at mines dash paris dot org 
     7 * 
     8 ****************************************************************************** 
     9 * Copyright (c) 2007, Even Rouault 
     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_bna.h" 
     31#include "cpl_conv.h" 
     32#include "cpl_string.h" 
     33#include "cpl_csv.h" 
     34#include "ogrbnaparser.h" 
     35 
     36/************************************************************************/ 
     37/*                          OGRBNADataSource()                          */ 
     38/************************************************************************/ 
     39 
     40OGRBNADataSource::OGRBNADataSource() 
     41 
     42{ 
     43    papoLayers = NULL; 
     44    nLayers = 0; 
     45 
     46    pszName = NULL; 
     47 
     48    bUpdate = FALSE; 
     49} 
     50 
     51/************************************************************************/ 
     52/*                         ~OGRBNADataSource()                          */ 
     53/************************************************************************/ 
     54 
     55OGRBNADataSource::~OGRBNADataSource() 
     56 
     57{ 
     58    for( int i = 0; i < nLayers; i++ ) 
     59        delete papoLayers[i]; 
     60    CPLFree( papoLayers ); 
     61 
     62    CPLFree( pszName ); 
     63} 
     64 
     65/************************************************************************/ 
     66/*                           TestCapability()                           */ 
     67/************************************************************************/ 
     68 
     69int OGRBNADataSource::TestCapability( const char * pszCap ) 
     70 
     71{ 
     72    if( EQUAL(pszCap,ODsCCreateLayer) ) 
     73        return FALSE; 
     74    else if( EQUAL(pszCap,ODsCDeleteLayer) ) 
     75        return FALSE; 
     76    else 
     77        return FALSE; 
     78} 
     79 
     80/************************************************************************/ 
     81/*                              GetLayer()                              */ 
     82/************************************************************************/ 
     83 
     84OGRLayer *OGRBNADataSource::GetLayer( int iLayer ) 
     85 
     86{ 
     87    if( iLayer < 0 || iLayer >= nLayers ) 
     88        return NULL; 
     89    else 
     90        return papoLayers[iLayer]; 
     91} 
     92 
     93/************************************************************************/ 
     94/*                                Open()                                */ 
     95/************************************************************************/ 
     96 
     97int OGRBNADataSource::Open( const char * pszFilename, int bUpdateIn) 
     98 
     99{ 
     100    int ok = FALSE; 
     101 
     102    pszName = CPLStrdup( pszFilename ); 
     103    bUpdate = bUpdateIn; 
     104 
     105/* -------------------------------------------------------------------- */ 
     106/*      Determine what sort of object this is.                          */ 
     107/* -------------------------------------------------------------------- */ 
     108    VSIStatBufL sStatBuf; 
     109 
     110    if( VSIStatL( pszFilename, &sStatBuf ) != 0 ) 
     111        return FALSE; 
     112     
     113// --------------------------------------------------------------------  
     114//      Does this appear to be an .bna file? 
     115// -------------------------------------------------------------------- 
     116    if( !EQUAL( CPLGetExtension(pszFilename), "bna" ) ) 
     117        return FALSE; 
     118 
     119    FILE* f = VSIFOpen(pszFilename, "rb"); 
     120    if (f) 
     121    { 
     122      BNARecord* record; 
     123      int curLine = 0; 
     124      record = BNA_GetNextRecord(f, &ok, &curLine, 0, BNA_READ_NONE); 
     125      BNA_FreeRecord(record); 
     126 
     127      if (ok) 
     128      { 
     129        nLayers = 4; 
     130 
     131        papoLayers = (OGRBNALayer **) CPLMalloc(nLayers * sizeof(OGRBNALayer*)); 
     132        papoLayers[0] = new OGRBNALayer( pszFilename, "points", BNA_POINT, wkbPoint ); 
     133        papoLayers[1] = new OGRBNALayer( pszFilename, "lines", BNA_POLYLINE, wkbLineString ); 
     134        papoLayers[2] = new OGRBNALayer( pszFilename, "polygons", BNA_POLYGON, wkbMultiPolygon ); 
     135        papoLayers[3] = new OGRBNALayer( pszFilename, "ellipses", BNA_ELLIPSE, wkbPolygon ); 
     136      } 
     137 
     138      VSIFClose(f); 
     139    } 
     140 
     141    return ok; 
     142} 
     143 
  • gdal-1.4.2.ori/ogr/ogrsf_frmts/bna/ogrbnadriver.cpp

    old new  
     1/****************************************************************************** 
     2 * $Id: ogrbnadriver.cpp 
     3 * 
     4 * Project:  BNA Translator 
     5 * Purpose:  Implements OGRBNADriver. 
     6 * Author:   Even Rouault, even dot rouault at mines dash paris dot org 
     7 * 
     8 ****************************************************************************** 
     9 * Copyright (c) 2007, Even Rouault 
     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_bna.h" 
     31#include "cpl_conv.h" 
     32 
     33/************************************************************************/ 
     34/*                           ~OGRBNADriver()                            */ 
     35/************************************************************************/ 
     36 
     37OGRBNADriver::~OGRBNADriver() 
     38 
     39{ 
     40} 
     41 
     42/************************************************************************/ 
     43/*                              GetName()                               */ 
     44/************************************************************************/ 
     45 
     46const char *OGRBNADriver::GetName() 
     47 
     48{ 
     49    return "BNA"; 
     50} 
     51 
     52/************************************************************************/ 
     53/*                                Open()                                */ 
     54/************************************************************************/ 
     55 
     56OGRDataSource *OGRBNADriver::Open( const char * pszFilename, int bUpdate ) 
     57 
     58{ 
     59    OGRBNADataSource   *poDS = new OGRBNADataSource(); 
     60 
     61    if( !poDS->Open( pszFilename, bUpdate ) ) 
     62    { 
     63        delete poDS; 
     64        poDS = NULL; 
     65    } 
     66 
     67    return poDS; 
     68} 
     69 
     70/************************************************************************/ 
     71/*                           TestCapability()                           */ 
     72/************************************************************************/ 
     73 
     74int OGRBNADriver::TestCapability( const char * pszCap ) 
     75 
     76{ 
     77    if( EQUAL(pszCap,ODrCCreateDataSource) ) 
     78        return FALSE; 
     79    else if( EQUAL(pszCap,ODrCDeleteDataSource) ) 
     80        return FALSE; 
     81    else 
     82        return FALSE; 
     83} 
     84 
     85 
     86/************************************************************************/ 
     87/*                           RegisterOGRBNA()                           */ 
     88/************************************************************************/ 
     89 
     90void RegisterOGRBNA() 
     91 
     92{ 
     93    OGRSFDriverRegistrar::GetRegistrar()->RegisterDriver( new OGRBNADriver ); 
     94} 
     95 
  • gdal-1.4.2.ori/ogr/ogrsf_frmts/bna/ogr_bna.h

    old new  
     1/****************************************************************************** 
     2 * $Id: ogr_bna.h 10646 2007-01-18 02:38:10Z warmerdam $ 
     3 * 
     4 * Project:  BNA Translator 
     5 * Purpose:  Definition of classes for OGR .bna driver. 
     6 * Author:   Even Rouault, even dot rouault at mines dash paris dot org 
     7 * 
     8 ****************************************************************************** 
     9 * Copyright (c) 2007, Even Rouault 
     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#ifndef _OGR_BNA_H_INCLUDED 
     31#define _OGR_BNA_H_INLLUDED 
     32 
     33#include "ogrsf_frmts.h" 
     34 
     35#include "ogrbnaparser.h" 
     36 
     37class OGRBNADataSource; 
     38 
     39/************************************************************************/ 
     40/*                             OGRBNALayer                              */ 
     41/************************************************************************/ 
     42 
     43typedef struct 
     44{ 
     45  int   offset; 
     46  int   line; 
     47} OffsetAndLine; 
     48 
     49class OGRBNALayer : public OGRLayer 
     50{ 
     51    OGRFeatureDefn     *poFeatureDefn; 
     52 
     53    int                eof; 
     54    int                failed; 
     55    int                curLine; 
     56    int                nNextFID; 
     57    FILE               *fpBNA; 
     58    int                nFeatures; 
     59    int                partialIndexTable; 
     60    OffsetAndLine*     offsetAndLineFeaturesTable; 
     61 
     62    BNAFeatureType     bnaFeatureType; 
     63     
     64    OGRFeature *       BuildFeatureFromBNARecord (BNARecord* record, long fid); 
     65    void               FastParseUntil ( int interestFID); 
     66  public: 
     67    OGRBNALayer( const char *pszFilename, 
     68                 const char* layerName, 
     69                 BNAFeatureType bnaFeatureType, 
     70                 OGRwkbGeometryType eLayerGeomType ); 
     71    ~OGRBNALayer(); 
     72 
     73    void                ResetReading(); 
     74    OGRFeature *        GetNextFeature(); 
     75 
     76    OGRFeatureDefn *    GetLayerDefn() { return poFeatureDefn; } 
     77     
     78    OGRFeature *        GetFeature( long nFID ); 
     79 
     80    int                 TestCapability( const char * ); 
     81 
     82}; 
     83 
     84/************************************************************************/ 
     85/*                           OGRBNADataSource                           */ 
     86/************************************************************************/ 
     87 
     88class OGRBNADataSource : public OGRDataSource 
     89{ 
     90    char                *pszName; 
     91 
     92    OGRBNALayer       **papoLayers; 
     93    int                 nLayers; 
     94 
     95    int                 bUpdate; 
     96     
     97  public: 
     98                        OGRBNADataSource(); 
     99                        ~OGRBNADataSource(); 
     100 
     101    int                 Open( const char * pszFilename, 
     102                              int bUpdate ); 
     103     
     104    const char          *GetName() { return pszName; } 
     105 
     106    int                 GetLayerCount() { return nLayers; } 
     107    OGRLayer            *GetLayer( int ); 
     108 
     109    int                 TestCapability( const char * ); 
     110}; 
     111 
     112/************************************************************************/ 
     113/*                             OGRBNADriver                             */ 
     114/************************************************************************/ 
     115 
     116class OGRBNADriver : public OGRSFDriver 
     117{ 
     118  public: 
     119                ~OGRBNADriver(); 
     120 
     121    const char *GetName(); 
     122    OGRDataSource *Open( const char *, int ); 
     123    int         TestCapability( const char * ); 
     124     
     125}; 
     126 
     127 
     128#endif /* ndef _OGR_BNA_H_INCLUDED */ 
  • gdal-1.4.2.ori/ogr/ogrsf_frmts/bna/ogrbnalayer.cpp

    old new  
     1/****************************************************************************** 
     2 * $Id: ogrbnalayer.cpp 10646 2007-01-18 02:38:10Z warmerdam $ 
     3 * 
     4 * Project:  BNA Translator 
     5 * Purpose:  Implements OGRBNALayer class. 
     6 * Author:   Even Rouault, even dot rouault at mines dash paris dot org 
     7 * 
     8 ****************************************************************************** 
     9 * Copyright (c) 2007, Even Rouault 
     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_bna.h" 
     31#include "cpl_conv.h" 
     32#include "cpl_string.h" 
     33#include "cpl_csv.h" 
     34 
     35/************************************************************************/ 
     36/*                            OGRBNALayer()                             */ 
     37/*                                                                      */ 
     38/*      Note that the OGRBNALayer assumes ownership of the passed       */ 
     39/*      file pointer.                                                   */ 
     40/************************************************************************/ 
     41 
     42OGRBNALayer::OGRBNALayer( const char *pszFilename, 
     43                          const char* layerName, 
     44                          BNAFeatureType bnaFeatureType, 
     45                          OGRwkbGeometryType eLayerGeomType ) 
     46 
     47{ 
     48    eof = FALSE; 
     49    failed = FALSE; 
     50    curLine = 0; 
     51    nNextFID = 0; 
     52 
     53    nFeatures = 0; 
     54    partialIndexTable = TRUE; 
     55    offsetAndLineFeaturesTable = NULL; 
     56 
     57    const char* iKnowHowToCount[] = { "Primary", "Secondary", "Third", "Fourth", "Fifth" }; 
     58    char tmp[32]; 
     59 
     60    poFeatureDefn = new OGRFeatureDefn( CPLSPrintf("%s_%s",  
     61                                                    CPLGetBasename( pszFilename ) ,  
     62                                                    layerName )); 
     63    poFeatureDefn->Reference(); 
     64    poFeatureDefn->SetGeomType( eLayerGeomType ); 
     65    this->bnaFeatureType = bnaFeatureType; 
     66 
     67    unsigned int i; 
     68    for(i=0;i<NB_MAX_BNA_IDS;i++) 
     69    { 
     70      if (i < sizeof(iKnowHowToCount)/sizeof(iKnowHowToCount[0])) 
     71      { 
     72        sprintf(tmp, "%s ID", iKnowHowToCount[i]); 
     73        OGRFieldDefn oFieldID(tmp, OFTString ); 
     74        poFeatureDefn->AddFieldDefn( &oFieldID ); 
     75      } 
     76      else 
     77      { 
     78        sprintf(tmp, "%dth ID", i+1); 
     79        OGRFieldDefn oFieldID(tmp, OFTString ); 
     80        poFeatureDefn->AddFieldDefn( &oFieldID ); 
     81      } 
     82    } 
     83     
     84    if (bnaFeatureType == BNA_ELLIPSE) 
     85    { 
     86      OGRFieldDefn oFieldMajorRadius( "Major radius", OFTReal ); 
     87      poFeatureDefn->AddFieldDefn( &oFieldMajorRadius ); 
     88       
     89      OGRFieldDefn oFieldMinorRadius( "Minor radius", OFTReal ); 
     90      poFeatureDefn->AddFieldDefn( &oFieldMinorRadius ); 
     91    } 
     92 
     93    fpBNA = VSIFOpen( pszFilename, "rb" ); 
     94    if( fpBNA == NULL ) 
     95        return; 
     96} 
     97 
     98/************************************************************************/ 
     99/*                            ~OGRBNALayer()                            */ 
     100/************************************************************************/ 
     101 
     102OGRBNALayer::~OGRBNALayer() 
     103 
     104{ 
     105    poFeatureDefn->Release(); 
     106 
     107    CPLFree(offsetAndLineFeaturesTable); 
     108 
     109    if (fpBNA) 
     110        VSIFClose( fpBNA ); 
     111} 
     112 
     113/************************************************************************/ 
     114/*                            ResetReading()                            */ 
     115/************************************************************************/ 
     116 
     117void OGRBNALayer::ResetReading() 
     118 
     119{ 
     120    eof = FALSE; 
     121    failed = FALSE; 
     122    curLine = 0; 
     123    nNextFID = 0; 
     124    VSIFSeek( fpBNA, 0, SEEK_SET ); 
     125} 
     126 
     127 
     128/************************************************************************/ 
     129/*                           GetNextFeature()                           */ 
     130/************************************************************************/ 
     131 
     132OGRFeature *OGRBNALayer::GetNextFeature() 
     133{ 
     134    OGRFeature  *poFeature; 
     135    BNARecord* record; 
     136    int offset, line; 
     137 
     138    if (failed || eof) return NULL; 
     139 
     140    while(1) 
     141    { 
     142      int ok = FALSE; 
     143      offset = VSIFTell(fpBNA); 
     144      line = curLine; 
     145      if (nNextFID < nFeatures) 
     146      { 
     147        VSIFSeek( fpBNA, offsetAndLineFeaturesTable[nNextFID].offset, SEEK_SET ); 
     148        curLine = offsetAndLineFeaturesTable[nNextFID].line; 
     149      } 
     150      record =  BNA_GetNextRecord(fpBNA, &ok, &curLine, TRUE, bnaFeatureType); 
     151      if (ok == FALSE) 
     152      { 
     153        failed = TRUE; 
     154        return NULL; 
     155      } 
     156      if (record == NULL) 
     157      { 
     158        /* end of file */ 
     159        eof = TRUE; 
     160         
     161        /* and we have finally build the whole index table */ 
     162        partialIndexTable = FALSE; 
     163        return NULL; 
     164      } 
     165 
     166      if (record->featureType == bnaFeatureType) 
     167      { 
     168        if (nNextFID >= nFeatures) 
     169        { 
     170          nFeatures++; 
     171          offsetAndLineFeaturesTable = 
     172              (OffsetAndLine*)CPLRealloc(offsetAndLineFeaturesTable, nFeatures * sizeof(OffsetAndLine)); 
     173          offsetAndLineFeaturesTable[nFeatures-1].offset = offset; 
     174          offsetAndLineFeaturesTable[nFeatures-1].line = line; 
     175        } 
     176 
     177        poFeature = BuildFeatureFromBNARecord(record, nNextFID++); 
     178 
     179        BNA_FreeRecord(record); 
     180 
     181        if(   (m_poFilterGeom == NULL 
     182            || FilterGeometry( poFeature->GetGeometryRef() ) ) 
     183           && (m_poAttrQuery == NULL 
     184            || m_poAttrQuery->Evaluate( poFeature )) ) 
     185        { 
     186          return poFeature; 
     187        } 
     188 
     189        delete poFeature; 
     190      } 
     191      else 
     192      { 
     193        BNA_FreeRecord(record); 
     194      } 
     195    } 
     196} 
     197 
     198/************************************************************************/ 
     199/*                           BuildFeatureFromBNARecord()                          */ 
     200/************************************************************************/ 
     201OGRFeature *    OGRBNALayer::BuildFeatureFromBNARecord (BNARecord* record, long fid) 
     202{ 
     203    OGRFeature  *poFeature; 
     204    int i; 
     205 
     206    poFeature = new OGRFeature( poFeatureDefn ); 
     207    for(i=0;i<NB_MAX_BNA_IDS;i++) 
     208    { 
     209      poFeature->SetField( i, record->ids[i] ? record->ids[i] : ""); 
     210    } 
     211    poFeature->SetFID( fid ); 
     212    if (bnaFeatureType == BNA_POINT) 
     213    { 
     214      poFeature->SetGeometryDirectly( new OGRPoint( record->tabCoords[0][0], record->tabCoords[0][1] ) ); 
     215    } 
     216    else if (bnaFeatureType == BNA_POLYLINE) 
     217    { 
     218      OGRLineString* lineString = new OGRLineString (); 
     219      lineString->setCoordinateDimension(2); 
     220      lineString->setNumPoints(record->nCoords); 
     221      for(i=0;i<record->nCoords;i++) 
     222      { 
     223        lineString->setPoint(i, record->tabCoords[i][0], record->tabCoords[i][1] ); 
     224      } 
     225      poFeature->SetGeometryDirectly(lineString); 
     226    } 
     227    else if (bnaFeatureType == BNA_POLYGON) 
     228    { 
     229      OGRMultiPolygon* multipolygon = new OGRMultiPolygon(); 
     230 
     231      double firstX = record->tabCoords[0][0]; 
     232      double firstY = record->tabCoords[0][1]; 
     233      double doubleArea = 0; 
     234      int isFirstPolygon = 1; 
     235      double secondaryFirstX = 0, secondaryFirstY = 0; 
     236 
     237      OGRLinearRing* ring = new OGRLinearRing (); 
     238      ring->setCoordinateDimension(2); 
     239      ring->addPoint(record->tabCoords[0][0], record->tabCoords[0][1] ); 
     240 
     241      /* record->nCoords is really a safe upper bound */ 
     242      int nbPolygons = 0; 
     243      OGRPolygon** tabPolygons = 
     244          (OGRPolygon**)CPLMalloc(record->nCoords * sizeof(OGRPolygon*)); 
     245      double* tabPolygonsDoubleSignedArea = 
     246          (double*)CPLMalloc(record->nCoords * sizeof(double)); 
     247 
     248      for(i=1;i<record->nCoords;i++) 
     249      { 
     250        ring->addPoint(record->tabCoords[i][0], record->tabCoords[i][1] ); 
     251        doubleArea += record->tabCoords[i-1][0] * record->tabCoords[i][1] - 
     252                      record->tabCoords[i][0] * record->tabCoords[i-1][1]; 
     253        if (isFirstPolygon == 1 && 
     254            record->tabCoords[i][0] == firstX && 
     255            record->tabCoords[i][1] == firstY) 
     256        { 
     257          /* First polygon : just add it to the multipolygon */ 
     258          OGRPolygon* polygon = new OGRPolygon (); 
     259          polygon->addRingDirectly(ring); 
     260          multipolygon-> addGeometryDirectly (polygon); 
     261          tabPolygons[nbPolygons] = polygon; 
     262          tabPolygonsDoubleSignedArea[nbPolygons] = doubleArea; 
     263          nbPolygons++; 
     264 
     265          if (i == record->nCoords - 1) 
     266          { 
     267            break; 
     268          } 
     269 
     270          isFirstPolygon = 0; 
     271 
     272          doubleArea = 0; 
     273          i ++; 
     274          secondaryFirstX = record->tabCoords[i][0]; 
     275          secondaryFirstY = record->tabCoords[i][1]; 
     276          ring = new OGRLinearRing (); 
     277          ring->setCoordinateDimension(2); 
     278          ring->addPoint(record->tabCoords[i][0], record->tabCoords[i][1] ); 
     279        } 
     280        else if (isFirstPolygon == 0 && 
     281                 record->tabCoords[i][0] == secondaryFirstX && 
     282                 record->tabCoords[i][1] == secondaryFirstY) 
     283        { 
     284          /* More than one polygons in that feature. We must find if this polygon is a 
     285             new one or an internal ring of the smallest enclosing existing polygon of 
     286             opposite winding. 
     287             Assumption : an lake into a polygon appears after the enclosing polygon. 
     288             The BNA 'specification' does not say it, but it seems to be a reasonable 
     289             assumption. 
     290             FIXME? I'm not sure I should trust the BNA winding 
     291          */ 
     292          int j; 
     293          int bestCandidate = -1; 
     294          double bestCandidateArea = 0; 
     295          for(j=0;j<nbPolygons;j++) 
     296          { 
     297            if (tabPolygonsDoubleSignedArea[j] * doubleArea < 0) 
     298            { 
     299              OGRPolygon poly1, poly2; 
     300              poly1.addRing(tabPolygons[j]->getExteriorRing()); 
     301              poly2.addRing(ring); 
     302              if (poly1.Contains(&poly2)) 
     303              { 
     304                if (bestCandidate < 0 || 
     305                    tabPolygonsDoubleSignedArea[j] < bestCandidateArea) 
     306                { 
     307                  bestCandidate = j; 
     308                  bestCandidateArea = tabPolygonsDoubleSignedArea[j]; 
     309                } 
     310              } 
     311            } 
     312          } 
     313          if (bestCandidate >= 0) 
     314          { 
     315            tabPolygons[bestCandidate]->addRingDirectly( ring ); 
     316          } 
     317          else 
     318          { 
     319            OGRPolygon* polygon = new OGRPolygon (); 
     320            polygon->addRingDirectly(ring); 
     321            multipolygon-> addGeometryDirectly (polygon); 
     322            tabPolygons[nbPolygons] = polygon; 
     323            tabPolygonsDoubleSignedArea[nbPolygons] = doubleArea; 
     324            nbPolygons++; 
     325          } 
     326 
     327          if (i < record->nCoords - 1) 
     328          { 
     329            /* After the closing of a subpolygon, the first coordinates of the first polygon */ 
     330            /* should be recalled... in theory */ 
     331            if (record->tabCoords[i+1][0] == firstX &&  record->tabCoords[i+1][1] == firstY) 
     332            { 
     333              if (i + 1 == record->nCoords - 1) 
     334                break; 
     335              i ++; 
     336            } 
     337            else 
     338            { 
     339              CPLError(CE_Warning, CPLE_AppDefined,  
     340                  "Geometry of polygon of fid %d starting at line %d is not strictly conformant. Trying to go on...\n", 
     341                  fid, 
     342                  offsetAndLineFeaturesTable[fid].line); 
     343            } 
     344 
     345            doubleArea = 0; 
     346            i ++; 
     347            secondaryFirstX = record->tabCoords[i][0]; 
     348            secondaryFirstY = record->tabCoords[i][1]; 
     349            ring = new OGRLinearRing (); 
     350            ring->setCoordinateDimension(2); 
     351            ring->addPoint(record->tabCoords[i][0], record->tabCoords[i][1] ); 
     352          } 
     353          else 
     354          { 
     355            CPLError(CE_Warning, CPLE_AppDefined,  
     356                  "Geometry of polygon of fid %d starting at line %d is not strictly conformant. Trying to go on...\n", 
     357                  fid, 
     358                  offsetAndLineFeaturesTable[fid].line); 
     359          } 
     360        } 
     361      } 
     362      if (i == record->nCoords) 
     363      { 
     364        /* Let's be a bit tolerant abount non closing polygons */ 
     365        if (isFirstPolygon) 
     366        { 
     367          OGRPolygon* polygon = new OGRPolygon(); 
     368          ring->addPoint(record->tabCoords[0][0], record->tabCoords[0][1] ); 
     369          polygon->addRingDirectly  (  ring ); 
     370          multipolygon-> addGeometryDirectly (polygon); 
     371        } 
     372      } 
     373       
     374      CPLFree(tabPolygons); 
     375      CPLFree(tabPolygonsDoubleSignedArea); 
     376 
     377      poFeature->SetGeometryDirectly(multipolygon); 
     378    } 
     379    else 
     380    { 
     381      /* Circle or ellipses are not part of the OGR Simple Geometry, so we discretize them 
     382         into polygons by 1 degree step */ 
     383      OGRPolygon* polygon = new OGRPolygon (); 
     384      OGRLinearRing* ring = new OGRLinearRing (); 
     385      ring->setCoordinateDimension(2); 
     386      double center_x = record->tabCoords[0][0]; 
     387      double center_y = record->tabCoords[0][1]; 
     388      double major_radius = record->tabCoords[1][0]; 
     389      double minor_radius = record->tabCoords[1][1]; 
     390      if (minor_radius == 0) 
     391        minor_radius = major_radius; 
     392      for(i=0;i<360;i++) 
     393      { 
     394        ring->addPoint(center_x + major_radius * cos(i * (M_PI / 180)), 
     395                       center_y + minor_radius * sin(i * (M_PI / 180)) ); 
     396      } 
     397      ring->addPoint(center_x + major_radius, center_y); 
     398      polygon->addRingDirectly  (  ring ); 
     399      poFeature->SetGeometryDirectly(polygon); 
     400 
     401      poFeature->SetField( NB_MAX_BNA_IDS, major_radius); 
     402      poFeature->SetField( NB_MAX_BNA_IDS+1, minor_radius); 
     403    } 
     404     
     405    return poFeature; 
     406} 
     407 
     408 
     409/************************************************************************/ 
     410/*                           FastParseUntil()                           */ 
     411/************************************************************************/ 
     412void OGRBNALayer::FastParseUntil ( int interestFID) 
     413{ 
     414  if (partialIndexTable) 
     415  { 
     416    ResetReading(); 
     417 
     418    BNARecord* record; 
     419 
     420    if (nFeatures > 0) 
     421    { 
     422      VSIFSeek( fpBNA, offsetAndLineFeaturesTable[nFeatures-1].offset, SEEK_SET ); 
     423      curLine = offsetAndLineFeaturesTable[nFeatures-1].line; 
     424 
     425      /* Just skip the last read one */ 
     426      int ok = FALSE; 
     427      record =  BNA_GetNextRecord(fpBNA, &ok, &curLine, TRUE, BNA_READ_NONE); 
     428      BNA_FreeRecord(record); 
     429    } 
     430 
     431    while(1) 
     432    { 
     433      int ok = FALSE; 
     434      int offset = VSIFTell(fpBNA); 
     435      int line = curLine; 
     436      record =  BNA_GetNextRecord(fpBNA, &ok, &curLine, TRUE, BNA_READ_NONE); 
     437      if (ok == FALSE) 
     438      { 
     439        failed = TRUE; 
     440        return; 
     441      } 
     442      if (record == NULL) 
     443      { 
     444        /* end of file */ 
     445        eof = TRUE; 
     446         
     447        /* and we have finally build the whole index table */ 
     448        partialIndexTable = FALSE; 
     449        return; 
     450      } 
     451 
     452      if (record->featureType == bnaFeatureType) 
     453      { 
     454        nFeatures++; 
     455        offsetAndLineFeaturesTable = 
     456            (OffsetAndLine*)CPLRealloc(offsetAndLineFeaturesTable, nFeatures * sizeof(OffsetAndLine)); 
     457        offsetAndLineFeaturesTable[nFeatures-1].offset = offset; 
     458        offsetAndLineFeaturesTable[nFeatures-1].line = line; 
     459 
     460        BNA_FreeRecord(record); 
     461 
     462        if (nFeatures - 1 == interestFID) 
     463          return; 
     464      } 
     465      else 
     466      { 
     467        BNA_FreeRecord(record); 
     468      } 
     469 
     470    } 
     471  } 
     472} 
     473 
     474/************************************************************************/ 
     475/*                           GetFeature()                               */ 
     476/************************************************************************/ 
     477 
     478OGRFeature *  OGRBNALayer::GetFeature( long nFID ) 
     479{ 
     480    OGRFeature  *poFeature; 
     481    BNARecord* record; 
     482    int ok; 
     483     
     484    if (nFID < 0) 
     485      return NULL; 
     486 
     487    FastParseUntil(nFID); 
     488 
     489    if (nFID >= nFeatures) 
     490      return NULL; 
     491 
     492    VSIFSeek( fpBNA, offsetAndLineFeaturesTable[nFID].offset, SEEK_SET ); 
     493    curLine = offsetAndLineFeaturesTable[nFID].line; 
     494    record =  BNA_GetNextRecord(fpBNA, &ok, &curLine, TRUE, bnaFeatureType); 
     495 
     496    poFeature = BuildFeatureFromBNARecord(record, nFID); 
     497 
     498    BNA_FreeRecord(record); 
     499 
     500    return poFeature; 
     501} 
     502 
     503/************************************************************************/ 
     504/*                           TestCapability()                           */ 
     505/************************************************************************/ 
     506 
     507int OGRBNALayer::TestCapability( const char * pszCap ) 
     508 
     509{ 
     510    if( EQUAL(pszCap,OLCSequentialWrite) ) 
     511        return FALSE; 
     512    else if( EQUAL(pszCap,OLCCreateField) ) 
     513        return FALSE; 
     514    else 
     515        return FALSE; 
     516} 
     517 
  • gdal-1.4.2.ori/ogr/ogrsf_frmts/bna/ogrbnaparser.c

    old new  
     1/****************************************************************************** 
     2 * $Id: ogrbnadataparser.c 
     3 * 
     4 * Project:  BNA Parser 
     5 * Purpose:  Parse a BNA record 
     6 * Author:   Even Rouault, even dot rouault at mines dash paris dot org 
     7 * 
     8 ****************************************************************************** 
     9 * Copyright (c) 2007, Even Rouault 
     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 "ogrbnaparser.h" 
     31 
     32#include "cpl_conv.h" 
     33#include "cpl_string.h" 
     34 
     35void BNA_FreeRecord(BNARecord* record) 
     36{ 
     37  if (record) 
     38  { 
     39    if (record->ids[0]) VSIFree(record->ids[0]); 
     40    if (record->ids[1]) VSIFree(record->ids[1]); 
     41    if (record->ids[2]) VSIFree(record->ids[2]); 
     42    if (record->tabCoords) CPLFree(record->tabCoords); 
     43    CPLFree(record); 
     44  } 
     45} 
     46 
     47const char* BNA_FeatureTypeToStr(BNAFeatureType featureType) 
     48{ 
     49  switch (featureType) 
     50  { 
     51    case BNA_POINT: 
     52      return "point"; 
     53    case BNA_POLYGON: 
     54      return "polygon"; 
     55    case BNA_POLYLINE: 
     56      return "polyline"; 
     57    case BNA_ELLIPSE: 
     58      return "ellipse"; 
     59    default: 
     60      return "unknown"; 
     61  } 
     62} 
     63 
     64void BNA_Display(BNARecord* record) 
     65{ 
     66  int i; 
     67  fprintf(stderr, "\"%s\", \"%s\", \"%s\", %s\n", 
     68          record->ids[0] ? record->ids[0] : "", 
     69          record->ids[1] ? record->ids[1] : "", 
     70          record->ids[2] ? record->ids[2] : "", 
     71          BNA_FeatureTypeToStr(record->featureType)); 
     72  for(i=0;i<record->nCoords;i++) 
     73    fprintf(stderr, "%f, %f\n", record->tabCoords[i][0], record->tabCoords[i][1]); 
     74} 
     75 
     76/* 
     77For a description of the format, see http://www.softwright.com/faq/support/boundary_file_bna_format.html 
     78and http://64.145.236.125/forum/topic.asp?topic_id=1930&forum_id=1&Topic_Title=how+to+edit+*.bna+files%3F&forum_title=Surfer+Support&M=False 
     79*/ 
     80 
     81/* The following lines are a valid BNA file (for this parser) : 
     82"PID1","SID1",1 
     83-0,0 
     84"PID2","SID2",-2,   -1e-5,-1e2   ,-2,-2 
     85"PID3""a","SID3",4 
     865,5 
     876,5 
     886,6 
     895,5 
     90"PID4","SID4",2 
     9110,10 
     925,4 
     93 
     94"PID4","SID4",2 
     95 
     9610,10 
     975,4 
     98*/ 
     99 
     100/* The following lines are a valid BNA file (for this parser) : 
     101  (small extract from ftp://ftp.ciesin.org/pub/census/usa/tiger/ct/bnablk/b09001.zip) 
     102"090010000.00099A","099A","090010000.00099A","blk",21 
     103-73.049337, 41.125000 -73.093761, 41.157780 -73.107900, 41.168300 
     104-73.106878, 41.166459 -73.095800, 41.146500 -73.114553, 41.146331 
     105-73.138922, 41.147993 -73.166200, 41.154200 -73.198497, 41.085988 
     106-73.232241, 41.029986 -73.229548, 41.030507 -73.183922, 41.041955 
     107-73.178678, 41.043239 -73.177951, 41.043417 -73.147888, 41.050781 
     108-73.118658, 41.057942 -73.052399, 41.074174 -73.024976, 41.080892 
     109-73.000000, 41.087010 -73.035597, 41.114420 -73.049337, 41.125000 
     110*/ 
     111 
     112/* We are (and must be) a bit tolerant : BNA files format has several variations */ 
     113/* and most don't follow strictly the 'specification' */ 
     114/* Extra spaces, tabulations or line feed are accepted and ignored */ 
     115/* We allow one line format and several line format in the same file */ 
     116/* We allow from NB_MIN_BNA_IDS to NB_MAX_BNA_IDS ids */ 
     117/* We allow that couples of coordinates on the same line may be separated only by spaces */ 
     118/* (instead of being separated by a comma) */ 
     119 
     120#define STRING_NOT_TERMINATED      "string not terminated when end of line occured" 
     121#define MISSING_FIELDS             "missing fields" 
     122#define BAD_INTEGER_NUMBER_FORMAT  "bad integer number format" 
     123#define BAD_FLOAT_NUMBER_FORMAT    "bad float number format" 
     124#define PRIMARY_ID_MANDATORY       "primary ID can't be empty or missing" 
     125#define STRING_EXPECTED            "string expected" 
     126#define NUMBER_EXPECTED            "number expected" 
     127#define INTEGER_NUMBER_EXPECTED    "integer number expected" 
     128#define FLOAT_NUMBER_EXPECTED      "float number expected" 
     129#define INVALID_GEOMETRY_TYPE      "invalid geometry type" 
     130#define TOO_LONG_ID                "too long id (> 256 characters)" 
     131#define MAX_BNA_IDS_REACHED        "maximum number of IDs reached" 
     132 
     133#define TMP_BUFFER_SIZE             256 
     134 
     135BNARecord* BNA_GetNextRecord(FILE* f, 
     136                             int* ok, 
     137                             int* curLine, 
     138                             int verbose, 
     139                             BNAFeatureType interestFeatureType) 
     140{ 
     141    BNARecord* record; 
     142    char c; 
     143    int inComma = FALSE; 
     144    int numField = 0; 
     145    const char* ptrBeginningOfNumber = NULL; 
     146&n