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 3 include ../../../GDALmake.opt 4 5 OBJ = ogrbnadriver.o ogrbnadatasource.o ogrbnalayer.o ogrbnaparser.o 6 7 CPPFLAGS := -I.. -I../.. $(GDAL_INCLUDE) $(CPPFLAGS) 8 9 default: $(O_OBJ) 10 11 clean: 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 40 OGRBNADataSource::OGRBNADataSource() 41 42 { 43 papoLayers = NULL; 44 nLayers = 0; 45 46 pszName = NULL; 47 48 bUpdate = FALSE; 49 } 50 51 /************************************************************************/ 52 /* ~OGRBNADataSource() */ 53 /************************************************************************/ 54 55 OGRBNADataSource::~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 69 int 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 84 OGRLayer *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 97 int 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 37 OGRBNADriver::~OGRBNADriver() 38 39 { 40 } 41 42 /************************************************************************/ 43 /* GetName() */ 44 /************************************************************************/ 45 46 const char *OGRBNADriver::GetName() 47 48 { 49 return "BNA"; 50 } 51 52 /************************************************************************/ 53 /* Open() */ 54 /************************************************************************/ 55 56 OGRDataSource *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 74 int 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 90 void 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 37 class OGRBNADataSource; 38 39 /************************************************************************/ 40 /* OGRBNALayer */ 41 /************************************************************************/ 42 43 typedef struct 44 { 45 int offset; 46 int line; 47 } OffsetAndLine; 48 49 class 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 88 class 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 116 class 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 42 OGRBNALayer::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 102 OGRBNALayer::~OGRBNALayer() 103 104 { 105 poFeatureDefn->Release(); 106 107 CPLFree(offsetAndLineFeaturesTable); 108 109 if (fpBNA) 110 VSIFClose( fpBNA ); 111 } 112 113 /************************************************************************/ 114 /* ResetReading() */ 115 /************************************************************************/ 116 117 void 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 132 OGRFeature *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 /************************************************************************/ 201 OGRFeature * 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 /************************************************************************/ 412 void 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 478 OGRFeature * 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 507 int 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 35 void 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 47 const 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 64 void 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 /* 77 For a description of the format, see http://www.softwright.com/faq/support/boundary_file_bna_format.html 78 and 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 86 5,5 87 6,5 88 6,6 89 5,5 90 "PID4","SID4",2 91 10,10 92 5,4 93 94 "PID4","SID4",2 95 96 10,10 97 5,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 135 BNARecord* 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
