Changeset 11894
- Timestamp:
- 08/17/07 15:43:44 (1 year ago)
- Files:
-
- trunk/gdal/ogr/ogr_core.h (modified) (1 diff)
- trunk/gdal/ogr/ogrsf_frmts/bna/GNUmakefile (modified) (1 diff)
- trunk/gdal/ogr/ogrsf_frmts/bna/drv_bna.html (added)
- trunk/gdal/ogr/ogrsf_frmts/bna/makefile.vc (modified) (1 diff)
- trunk/gdal/ogr/ogrsf_frmts/bna/ogr_bna.h (modified) (5 diffs)
- trunk/gdal/ogr/ogrsf_frmts/bna/ogrbnadatasource.cpp (modified) (7 diffs)
- trunk/gdal/ogr/ogrsf_frmts/bna/ogrbnadriver.cpp (modified) (2 diffs)
- trunk/gdal/ogr/ogrsf_frmts/bna/ogrbnalayer.cpp (modified) (19 diffs)
- trunk/gdal/ogr/ogrsf_frmts/bna/ogrbnaparser.cpp (modified) (9 diffs)
- trunk/gdal/ogr/ogrsf_frmts/bna/ogrbnaparser.h (modified) (1 diff)
- trunk/gdal/ogr/ogrsf_frmts/ogr_formats.html (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/gdal/ogr/ogr_core.h
r11873 r11894 86 86 MinY = MaxY = dfY; 87 87 } 88 } 89 90 int Intersects(OGREnvelope& other) 91 { 92 return MinX <= other.MaxX && MaxX >= other.MinX && 93 MinY <= other.MaxY && MaxY >= other.MinY; 94 } 95 96 int Contains(OGREnvelope& other) 97 { 98 return MinX <= other.MinX && MinY <= other.MinY && 99 MaxX >= other.MaxX && MaxY >= other.MaxY; 88 100 } 89 101 }; trunk/gdal/ogr/ogrsf_frmts/bna/GNUmakefile
r11853 r11894 4 4 5 5 OBJ = ogrbnadriver.o ogrbnadatasource.o ogrbnalayer.o ogrbnaparser.o 6 7 ifeq ($(HAVE_GEOS),yes) 8 CPPFLAGS := -DHAVE_GEOS=1 $(GEOS_CFLAGS) $(CPPFLAGS) 9 endif 6 10 7 11 CPPFLAGS := -I.. -I../.. $(GDAL_INCLUDE) $(CPPFLAGS) trunk/gdal/ogr/ogrsf_frmts/bna/makefile.vc
r11857 r11894 3 3 ogrbnaparser.obj 4 4 5 EXTRAFLAGS = -I.. -I..\.. 5 EXTRAFLAGS = -I.. -I..\.. $(GEOS_CFLAGS) 6 6 7 7 GDAL_ROOT = ..\..\.. trunk/gdal/ogr/ogrsf_frmts/bna/ogr_bna.h
r11853 r11894 49 49 class OGRBNALayer : public OGRLayer 50 50 { 51 OGRFeatureDefn *poFeatureDefn; 51 OGRFeatureDefn* poFeatureDefn; 52 53 OGRBNADataSource* poDS; 54 int bWriter; 52 55 56 int nIDs; 53 57 int eof; 54 58 int failed; 55 59 int curLine; 56 60 int nNextFID; 57 FILE *fpBNA;61 FILE* fpBNA; 58 62 int nFeatures; 59 63 int partialIndexTable; … … 61 65 62 66 BNAFeatureType bnaFeatureType; 63 67 64 68 OGRFeature * BuildFeatureFromBNARecord (BNARecord* record, long fid); 65 69 void FastParseUntil ( int interestFID); 70 void WriteFeatureAttributes(FILE* fp, OGRFeature *poFeature); 71 66 72 public: 67 OGRBNALayer( const char *pszFilename, 68 const char* layerName, 69 BNAFeatureType bnaFeatureType, 70 OGRwkbGeometryType eLayerGeomType ); 71 ~OGRBNALayer(); 73 OGRBNALayer(const char *pszFilename, 74 const char* layerName, 75 BNAFeatureType bnaFeatureType, 76 OGRwkbGeometryType eLayerGeomType, 77 int bWriter, 78 OGRBNADataSource* poDS, 79 int nIDs = NB_MAX_BNA_IDS); 80 ~OGRBNALayer(); 81 82 void SetFeatureIndexTable(int nFeatures, 83 OffsetAndLine* offsetAndLineFeaturesTable, 84 int partialIndexTable); 72 85 73 86 void ResetReading(); 74 87 OGRFeature * GetNextFeature(); 88 89 OGRErr CreateFeature( OGRFeature *poFeature ); 90 OGRErr CreateField( OGRFieldDefn *poField, int bApproxOK ); 75 91 76 92 OGRFeatureDefn * GetLayerDefn() { return poFeatureDefn; } 77 78 int GetFeatureCount( int );79 93 80 94 OGRFeature * GetFeature( long nFID ); … … 90 104 class OGRBNADataSource : public OGRDataSource 91 105 { 92 char *pszName;106 char* pszName; 93 107 94 OGRBNALayer **papoLayers;108 OGRBNALayer** papoLayers; 95 109 int nLayers; 96 110 97 111 int bUpdate; 112 113 /* Export related */ 114 FILE *fpOutput; 115 int bUseCRLF; 116 int bMultiLine; 117 int nbOutID; 118 int bEllipsesAsEllipses; 119 int nbPairPerLine; 120 int coordinatePrecision; 121 char* pszCoordinateSeparator; 98 122 99 123 public: … … 101 125 ~OGRBNADataSource(); 102 126 127 FILE *GetOutputFP() { return fpOutput; } 128 int GetUseCRLF() { return bUseCRLF; } 129 int GetMultiLine() { return bMultiLine; } 130 int GetNbOutId() { return nbOutID; } 131 int GetEllipsesAsEllipses() { return bEllipsesAsEllipses; } 132 int GetNbPairPerLine() { return nbPairPerLine; } 133 int GetCoordinatePrecision() { return coordinatePrecision; } 134 const char* GetCoordinateSeparator() { return pszCoordinateSeparator; } 135 103 136 int Open( const char * pszFilename, 104 137 int bUpdate ); 105 138 106 const char *GetName() { return pszName; } 139 int Create( const char *pszFilename, 140 char **papszOptions ); 141 142 const char* GetName() { return pszName; } 107 143 108 144 int GetLayerCount() { return nLayers; } 109 OGRLayer *GetLayer( int ); 145 OGRLayer* GetLayer( int ); 146 147 OGRLayer * CreateLayer( const char * pszLayerName, 148 OGRSpatialReference *poSRS, 149 OGRwkbGeometryType eType, 150 char ** papszOptions ); 110 151 111 152 int TestCapability( const char * ); … … 121 162 ~OGRBNADriver(); 122 163 123 const char *GetName(); 124 OGRDataSource *Open( const char *, int ); 125 int TestCapability( const char * ); 164 const char* GetName(); 165 OGRDataSource* Open( const char *, int ); 166 OGRDataSource* CreateDataSource( const char * pszName, char **papszOptions ); 167 int DeleteDataSource( const char *pszFilename ); 168 int TestCapability( const char * ); 126 169 127 170 }; trunk/gdal/ogr/ogrsf_frmts/bna/ogrbnadatasource.cpp
r11853 r11894 43 43 papoLayers = NULL; 44 44 nLayers = 0; 45 46 fpOutput = NULL; 45 47 46 48 pszName = NULL; 49 50 pszCoordinateSeparator = NULL; 47 51 48 52 bUpdate = FALSE; … … 56 60 57 61 { 62 if ( fpOutput != NULL ) 63 { 64 VSIFClose( fpOutput); 65 } 66 58 67 for( int i = 0; i < nLayers; i++ ) 59 68 delete papoLayers[i]; 60 69 CPLFree( papoLayers ); 70 71 CPLFree( pszCoordinateSeparator ); 61 72 62 73 CPLFree( pszName ); … … 71 82 { 72 83 if( EQUAL(pszCap,ODsCCreateLayer) ) 73 return FALSE;84 return TRUE; 74 85 else if( EQUAL(pszCap,ODsCDeleteLayer) ) 75 86 return FALSE; … … 89 100 else 90 101 return papoLayers[iLayer]; 102 } 103 104 /************************************************************************/ 105 /* CreateLayer() */ 106 /************************************************************************/ 107 108 OGRLayer * OGRBNADataSource::CreateLayer( const char * pszLayerName, 109 OGRSpatialReference *poSRS, 110 OGRwkbGeometryType eType, 111 char ** papszOptions ) 112 113 { 114 BNAFeatureType bnaFeatureType; 115 116 switch(eType) 117 { 118 case wkbPolygon: 119 case wkbPolygon25D: 120 case wkbMultiPolygon: 121 case wkbMultiPolygon25D: 122 bnaFeatureType = BNA_POLYGON; 123 break; 124 125 case wkbPoint: 126 case wkbPoint25D: 127 bnaFeatureType = BNA_POINT; 128 break; 129 130 case wkbLineString: 131 case wkbLineString25D: 132 bnaFeatureType = BNA_POLYLINE; 133 break; 134 135 default: 136 CPLError( CE_Failure, CPLE_NotSupported, 137 "Geometry type of `%s' not supported in BNAs.\n", 138 OGRGeometryTypeToName(eType) ); 139 return NULL; 140 } 141 142 nLayers++; 143 papoLayers = (OGRBNALayer **) CPLRealloc(papoLayers, nLayers * sizeof(OGRBNALayer*)); 144 papoLayers[nLayers-1] = new OGRBNALayer( pszName, pszLayerName, bnaFeatureType, eType, TRUE, this ); 145 146 return papoLayers[nLayers-1]; 91 147 } 92 148 … … 116 172 if( !EQUAL( CPLGetExtension(pszFilename), "bna" ) ) 117 173 return FALSE; 118 119 FILE* f = VSIFOpen(pszFilename, "rb");120 if (f )174 175 FILE* fp = VSIFOpen(pszFilename, "r"); 176 if (fp) 121 177 { 122 178 BNARecord* record; 123 179 int curLine = 0; 124 record = BNA_GetNextRecord(f, &ok, &curLine, 0, BNA_READ_NONE); 180 const char* layerRadixName[] = { "points", "polygons", "lines", "ellipses"}; 181 OGRwkbGeometryType wkbGeomTypes[] = { wkbPoint, wkbMultiPolygon, wkbLineString, wkbPolygon }; 182 int i; 183 #if defined(BNA_FAST_DS_OPEN) 184 record = BNA_GetNextRecord(fp, &ok, &curLine, FALSE, BNA_READ_NONE); 125 185 BNA_FreeRecord(record); 126 186 … … 130 190 131 191 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); 192 for(i=0;i<4;i++) 193 papoLayers[i] = new OGRBNALayer( pszFilename, 194 layerRadixName[i], 195 (BNAFeatureType)i, wkbGeomTypes[i], FALSE, this ); 196 } 197 #else 198 int nFeatures[4] = { 0, 0, 0, 0 }; 199 OffsetAndLine* offsetAndLineFeaturesTable[4] = { NULL, NULL, NULL, NULL }; 200 int nIDs[4] = {0, 0, 0, 0}; 201 int partialIndexTable = TRUE; 202 203 while(1) 204 { 205 int offset = VSIFTell(fp); 206 int line = curLine; 207 record = BNA_GetNextRecord(fp, &ok, &curLine, FALSE, BNA_READ_NONE); 208 if (ok == FALSE) 209 { 210 BNA_FreeRecord(record); 211 if (line != 0) 212 ok = TRUE; 213 break; 214 } 215 if (record == NULL) 216 { 217 /* end of file */ 218 ok = TRUE; 219 220 /* and we have finally build the whole index table */ 221 partialIndexTable = FALSE; 222 break; 223 } 224 225 if (record->nIDs > nIDs[record->featureType]) 226 nIDs[record->featureType] = record->nIDs; 227 228 nFeatures[record->featureType]++; 229 offsetAndLineFeaturesTable[record->featureType] = 230 (OffsetAndLine*)CPLRealloc(offsetAndLineFeaturesTable[record->featureType], 231 nFeatures[record->featureType] * sizeof(OffsetAndLine)); 232 offsetAndLineFeaturesTable[record->featureType][nFeatures[record->featureType]-1].offset = offset; 233 offsetAndLineFeaturesTable[record->featureType][nFeatures[record->featureType]-1].line = line; 234 235 BNA_FreeRecord(record); 236 } 237 238 nLayers = (nFeatures[0] != 0) + (nFeatures[1] != 0) + (nFeatures[2] != 0) + (nFeatures[3] != 0); 239 papoLayers = (OGRBNALayer **) CPLMalloc(nLayers * sizeof(OGRBNALayer*)); 240 int iLayer = 0; 241 for(i=0;i<4;i++) 242 { 243 if (nFeatures[i]) 244 { 245 papoLayers[iLayer] = new OGRBNALayer( pszFilename, 246 layerRadixName[i], 247 (BNAFeatureType)i, 248 wkbGeomTypes[i], 249 FALSE, 250 this, 251 nIDs[i]); 252 papoLayers[iLayer]->SetFeatureIndexTable(nFeatures[i], 253 offsetAndLineFeaturesTable[i], 254 partialIndexTable); 255 iLayer++; 256 } 257 } 258 #endif 259 VSIFClose(fp); 139 260 } 140 261 … … 142 263 } 143 264 265 266 /************************************************************************/ 267 /* Create() */ 268 /************************************************************************/ 269 270 int OGRBNADataSource::Create( const char *pszFilename, 271 char **papszOptions ) 272 { 273 if( fpOutput != NULL) 274 { 275 CPLAssert( FALSE ); 276 return FALSE; 277 } 278 279 /* -------------------------------------------------------------------- */ 280 /* Do not override exiting file. */ 281 /* -------------------------------------------------------------------- */ 282 VSIStatBufL sStatBuf; 283 284 if( VSIStatL( pszFilename, &sStatBuf ) == 0 ) 285 return FALSE; 286 287 /* -------------------------------------------------------------------- */ 288 /* Create the output file. */ 289 /* -------------------------------------------------------------------- */ 290 pszName = CPLStrdup( pszFilename ); 291 292 if( EQUAL(pszFilename,"stdout") ) 293 fpOutput = stdout; 294 else 295 fpOutput = VSIFOpen( pszFilename, "w" ); 296 if( fpOutput == NULL ) 297 { 298 CPLError( CE_Failure, CPLE_OpenFailed, 299 "Failed to create BNA file %s.", 300 pszFilename ); 301 return FALSE; 302 } 303 304 /* EOL token */ 305 const char *pszCRLFFormat = CSLFetchNameValue( papszOptions, "LINEFORMAT"); 306 307 if( pszCRLFFormat == NULL ) 308 { 309 #ifdef WIN32 310 bUseCRLF = TRUE; 311 #else 312 bUseCRLF = FALSE; 313 #endif 314 } 315 else if( EQUAL(pszCRLFFormat,"CRLF") ) 316 bUseCRLF = TRUE; 317 else if( EQUAL(pszCRLFFormat,"LF") ) 318 bUseCRLF = FALSE; 319 else 320 { 321 CPLError( CE_Warning, CPLE_AppDefined, 322 "LINEFORMAT=%s not understood, use one of CRLF or LF.", 323 pszCRLFFormat ); 324 #ifdef WIN32 325 bUseCRLF = TRUE; 326 #else 327 bUseCRLF = FALSE; 328 #endif 329 } 330 331 /* Multi line or single line format ? */ 332 bMultiLine = CSLFetchBoolean( papszOptions, "MULTILINE", TRUE); 333 334 /* Number of identifiers per record */ 335 const char* pszNbOutID = CSLFetchNameValue ( papszOptions, "NB_IDS"); 336 if (pszNbOutID == NULL) 337 { 338 nbOutID = NB_MIN_BNA_IDS; 339 } 340 else if (EQUAL(pszNbOutID, "NB_SOURCE_FIELDS")) 341 { 342 nbOutID = -1; 343 } 344 else 345 { 346 nbOutID = atoi(pszNbOutID); 347 if (nbOutID <= 0) 348 { 349 CPLError( CE_Warning, CPLE_AppDefined, 350 "NB_ID=%s not understood. Must be >=%d and <=%d or equal to NB_SOURCE_FIELDS", 351 pszNbOutID, NB_MIN_BNA_IDS, NB_MAX_BNA_IDS ); 352 nbOutID = NB_MIN_BNA_IDS; 353 } 354 if (nbOutID > NB_MAX_BNA_IDS) 355 { 356 CPLError( CE_Warning, CPLE_AppDefined, 357 "NB_ID=%s not understood. Must be >=%d and <=%d or equal to NB_SOURCE_FIELDS", 358 pszNbOutID, NB_MIN_BNA_IDS, NB_MAX_BNA_IDS ); 359 nbOutID = NB_MAX_BNA_IDS; 360 } 361 } 362 363 /* Ellipses export as ellipses or polygons ? */ 364 bEllipsesAsEllipses = CSLFetchBoolean( papszOptions, "ELLIPSES_AS_ELLIPSES", TRUE); 365 366 /* Number of coordinate pairs per line */ 367 const char* pszNbPairPerLine = CSLFetchNameValue( papszOptions, "NB_PAIRS_PER_LINE"); 368 if (pszNbPairPerLine) 369 { 370 nbPairPerLine = atoi(pszNbPairPerLine); 371 if (nbPairPerLine <= 0) 372 nbPairPerLine = (bMultiLine == FALSE) ? 1000000000 : 1; 373 if (bMultiLine == FALSE) 374 { 375 CPLError( CE_Warning, CPLE_AppDefined, "NB_PAIR_PER_LINE option is ignored when MULTILINE=NO"); 376 } 377 } 378 else 379 { 380 nbPairPerLine = (bMultiLine == FALSE) ? 1000000000 : 1; 381 } 382 383 /* Coordinate precision */ 384 const char* pszCoordinatePrecision = CSLFetchNameValue( papszOptions, "COORDINATE_PRECISION"); 385 if (pszCoordinatePrecision) 386 { 387 coordinatePrecision = atoi(pszCoordinatePrecision); 388 if (coordinatePrecision <= 0) 389 coordinatePrecision = 0; 390 else if (coordinatePrecision >= 20) 391 coordinatePrecision = 20; 392 } 393 else 394 { 395 coordinatePrecision = 10; 396 } 397 398 pszCoordinateSeparator = (char*)CSLFetchNameValue( papszOptions, "COORDINATE_SEPARATOR"); 399 if (pszCoordinateSeparator == NULL) 400 pszCoordinateSeparator = CPLStrdup(","); 401 else 402 pszCoordinateSeparator = CPLStrdup(pszCoordinateSeparator); 403 404 return TRUE; 405 } trunk/gdal/ogr/ogrsf_frmts/bna/ogrbnadriver.cpp
r11853 r11894 69 69 70 70 /************************************************************************/ 71 /* CreateDataSource() */ 72 /************************************************************************/ 73 74 OGRDataSource *OGRBNADriver::CreateDataSource( const char * pszName, 75 char **papszOptions ) 76 77 { 78 OGRBNADataSource *poDS = new OGRBNADataSource(); 79 80 if( !poDS->Create( pszName, papszOptions ) ) 81 { 82 delete poDS; 83 poDS = NULL; 84 } 85 86 return poDS; 87 } 88 89 /************************************************************************/ 90 /* DeleteDataSource() */ 91 /************************************************************************/ 92 93 OGRErr OGRBNADriver::DeleteDataSource( const char *pszFilename ) 94 95 { 96 if( VSIUnlink( pszFilename ) == 0 ) 97 return OGRERR_NONE; 98 else 99 return OGRERR_FAILURE; 100 } 101 102 /************************************************************************/ 71 103 /* TestCapability() */ 72 104 /************************************************************************/ … … 76 108 { 77 109 if( EQUAL(pszCap,ODrCCreateDataSource) ) 78 return FALSE;110 return TRUE; 79 111 else if( EQUAL(pszCap,ODrCDeleteDataSource) ) 80 return FALSE;112 return TRUE; 81 113 else 82 114 return FALSE; trunk/gdal/ogr/ogrsf_frmts/bna/ogrbnalayer.cpp
r11867 r11894 1 1 /****************************************************************************** 2 * $Id: ogrbnalayer.cpp 10646 2007-01-18 02:38:10Z warmerdam $2 * $Id: ogrbnalayer.cpp 3 3 * 4 4 * Project: BNA Translator … … 47 47 const char* layerName, 48 48 BNAFeatureType bnaFeatureType, 49 OGRwkbGeometryType eLayerGeomType ) 49 OGRwkbGeometryType eLayerGeomType, 50 int bWriter, 51 OGRBNADataSource* poDS, 52 int nIDs) 50 53 51 54 { … … 54 57 curLine = 0; 55 58 nNextFID = 0; 59 60 this->bWriter = bWriter; 61 this->poDS = poDS; 62 this->nIDs = nIDs; 56 63 57 64 nFeatures = 0; … … 69 76 this->bnaFeatureType = bnaFeatureType; 70 77 71 int i; 72 for(i=0;i<NB_MAX_BNA_IDS;i++) 73 { 74 if (i < (int) (sizeof(iKnowHowToCount)/sizeof(iKnowHowToCount[0])) ) 75 { 76 sprintf(tmp, "%s ID", iKnowHowToCount[i]); 77 OGRFieldDefn oFieldID(tmp, OFTString ); 78 poFeatureDefn->AddFieldDefn( &oFieldID ); 79 } 80 else 81 { 82 sprintf(tmp, "%dth ID", i+1); 83 OGRFieldDefn oFieldID(tmp, OFTString ); 84 poFeatureDefn->AddFieldDefn( &oFieldID ); 85 } 86 } 87 88 if (bnaFeatureType == BNA_ELLIPSE) 89 { 90 OGRFieldDefn oFieldMajorRadius( "Major radius", OFTReal ); 91 poFeatureDefn->AddFieldDefn( &oFieldMajorRadius ); 92 93 OGRFieldDefn oFieldMinorRadius( "Minor radius", OFTReal ); 94 poFeatureDefn->AddFieldDefn( &oFieldMinorRadius ); 95 } 96 97 fpBNA = VSIFOpen( pszFilename, "rb" ); 98 if( fpBNA == NULL ) 99 return; 78 if (! bWriter ) 79 { 80 int i; 81 for(i=0;i<nIDs;i++) 82 { 83 if (i < (int) (sizeof(iKnowHowToCount)/sizeof(iKnowHowToCount[0])) ) 84 { 85 sprintf(tmp, "%s ID", iKnowHowToCount[i]); 86 OGRFieldDefn oFieldID(tmp, OFTString ); 87 poFeatureDefn->AddFieldDefn( &oFieldID ); 88 } 89 else 90 { 91 sprintf(tmp, "%dth ID", i+1); 92 OGRFieldDefn oFieldID(tmp, OFTString ); 93 poFeatureDefn->AddFieldDefn( &oFieldID ); 94 } 95 } 96 97 if (bnaFeatureType == BNA_ELLIPSE) 98 { 99 OGRFieldDefn oFieldMajorRadius( "Major radius", OFTReal ); 100 poFeatureDefn->AddFieldDefn( &oFieldMajorRadius ); 101 102 OGRFieldDefn oFieldMinorRadius( "Minor radius", OFTReal ); 103 poFeatureDefn->AddFieldDefn( &oFieldMinorRadius ); 104 } 105 106 fpBNA = VSIFOpen( pszFilename, "r" ); 107 if( fpBNA == NULL ) 108 return; 109 } 110 else 111 { 112 fpBNA = NULL; 113 } 100 114 } 101 115 … … 113 127 if (fpBNA) 114 128 VSIFClose( fpBNA ); 129 } 130 131 /************************************************************************/ 132 /* SetFeatureIndexTable() */ 133 /************************************************************************/ 134 void OGRBNALayer::SetFeatureIndexTable(int nFeatures, OffsetAndLine* offsetAndLineFeaturesTable, int partialIndexTable) 135 { 136 this->nFeatures = nFeatures; 137 this->offsetAndLineFeaturesTable = offsetAndLineFeaturesTable; 138 this->partialIndexTable = partialIndexTable; 115 139 } 116 140 … … 155 179 if (ok == FALSE) 156 180 { 181 BNA_FreeRecord(record); 157 182 failed = TRUE; 158 183 return NULL; … … 162 187 /* end of file */ 163 188 eof = TRUE; 164 189 165 190 /* and we have finally build the whole index table */ 166 191 partialIndexTable = FALSE; … … 170 195 if (record->featureType == bnaFeatureType) 171 196 { 197 if (nNextFID >= nFeatures) 198 { 199 nFeatures++; 200 offsetAndLineFeaturesTable = 201 (OffsetAndLine*)CPLRealloc(offsetAndLineFeaturesTable, nFeatures * sizeof(OffsetAndLine)); 202 offsetAndLineFeaturesTable[nFeatures-1].offset = offset; 203 offsetAndLineFeaturesTable[nFeatures-1].line = line; 204 } 205 206 poFeature = BuildFeatureFromBNARecord(record, nNextFID++); 207 208 BNA_FreeRecord(record); 209 210 if( (m_poFilterGeom == NULL 211 || FilterGeometry( poFeature->GetGeometryRef() ) ) 212 && (m_poAttrQuery == NULL 213 || m_poAttrQuery->Evaluate( poFeature )) ) 214 { 215 return poFeature; 216 } 217 218 delete poFeature; 219 } 220 else 221 { 222 BNA_FreeRecord(record); 223 } 224 } 225 } 226 227 228 void OGRBNALayer::WriteFeatureAttributes(FILE* fp, OGRFeature *poFeature ) 229 { 230 int i; 231 OGRFieldDefn *poField; 232 int nbOutID = poDS->GetNbOutId(); 233 if (nbOutID < 0) 234 nbOutID = poFeatureDefn->GetFieldCount(); 235 for(i=0;i<nbOutID;i++) 236 { 237 if (i < poFeatureDefn->GetFieldCount()) 238 { 239 poField = poFeatureDefn->GetFieldDefn( i ); 240 if( poFeature->IsFieldSet( i ) ) 241 { 242 const char *pszRaw = poFeature->GetFieldAsString( i ); 243 VSIFPrintf( fp, "\"%s\",", pszRaw); 244 } 245 else 246 { 247 VSIFPrintf( fp, "\"\","); 248 } 249 } 250 else 251 { 252 VSIFPrintf( fp, "\"\","); 253 } 254 } 255 } 256 257 /************************************************************************/ 258 /* CreateFeature() */ 259 /************************************************************************/ 260 261 OGRErr OGRBNALayer::CreateFeature( OGRFeature *poFeature ) 262 263 { 264 int i,j,k,n; 265 OGRGeometry *poGeom = poFeature->GetGeometryRef(); 266 char eol[3]; 267 const char* partialEol = (poDS->GetMultiLine()) ? eol : poDS->GetCoordinateSeparator(); 268 269 if (poDS->GetUseCRLF()) 270 { 271 eol[0] = 13; 272 eol[1] = 10; 273 eol[2] = 0; 274 } 275 else 276 { 277 eol[0] = 10; 278 eol[1] = 0; 279 } 280 281 if ( ! bWriter ) 282 { 283 return OGRERR_FAILURE; 284 } 285 286 if( poFeature->GetFID() == OGRNullFID ) 287 poFeature->SetFID( nFeatures++ ); 288 289 FILE* fp = poDS->GetOutputFP(); 290 int nbPairPerLine = poDS->GetNbPairPerLine(); 291 char formatCoordinates[32]; 292 sprintf(formatCoordinates, "%%s%%.%df%s%%.%df", 293 poDS->GetCoordinatePrecision(), poDS->GetCoordinateSeparator(), poDS->GetCoordinatePrecision()); 294 295 switch( poGeom->getGeometryType() ) 296 { 297 case wkbPoint: 298 case wkbPoint25D: 299 { 300 OGRPoint* point = (OGRPoint*)poGeom; 301 WriteFeatureAttributes(fp, poFeature); 302 VSIFPrintf( fp, "1"); 303 VSIFPrintf( fp, formatCoordinates, partialEol, point->getX(), point->getY()); 304 VSIFPrintf( fp, "%s", eol); 172 305 break; 173 306 } 307 308 case wkbPolygon: 309 case wkbPolygon25D: 310 { 311 OGRPolygon* polygon = (OGRPolygon*)poGeom; 312 OGRLinearRing* ring = polygon->getExteriorRing(); 313 double firstX = ring->getX(0); 314 double firstY = ring->getY(0); 315 int nBNAPoints = ring->getNumPoints(); 316 int is_ellipse = FALSE; 317 318 /* This code tries to detect an ellipse in a polygon geometry */ 319 /* This will only work presumably on ellipses already read from a BNA file */ 320 /* Mostly a BNA to BNA feature... */ 321 if (poDS->GetEllipsesAsEllipses() && 322 polygon->getNumInteriorRings() == 0 && 323 nBNAPoints == 361) 324 { 325 double oppositeX = ring->getX(180); 326 double oppositeY = ring->getY(180); 327 double quarterX = ring->getX(90); 328 double quarterY = ring->getY(90); 329 double antiquarterX = ring->getX(270); 330 double antiquarterY = ring->getY(270); 331 double center1X = 0.5*(firstX + oppositeX); 332 double center1Y = 0.5*(firstY + oppositeY); 333 double center2X = 0.5*(quarterX + antiquarterX); 334 double center2Y = 0.5*(quarterY + antiquarterY); 335 if (fabs(center1X - center2X) < 1e-5 && fabs(center1Y - center2Y) < 1e-5 && 336 fabs(oppositeY - firstY) < 1e-5 && 337 fabs(quarterX - antiquarterX) < 1e-5) 338 { 339 double major_radius = fabs(firstX - center1X); 340 double minor_radius = fabs(quarterY - center1Y); 341 is_ellipse = TRUE; 342 for(i=0;i<360;i++) 343 { 344 if (!(fabs(center1X + major_radius * cos(i * (M_PI / 180)) - ring->getX(i)) < 1e-5 && 345 fabs(center1Y + minor_radius * sin(i * (M_PI / 180)) - ring->getY(i)) < 1e-5)) 346 { 347 is_ellipse = FALSE; 348 break; 349 } 350 } 351 if ( is_ellipse == TRUE ) 352 { 353 WriteFeatureAttributes(fp, poFeature); 354 VSIFPrintf( fp, "2"); 355 VSIFPrintf( fp, formatCoordinates, partialEol, center1X, center1Y); 356 VSIFPrintf( fp, formatCoordinates, partialEol, major_radius, minor_radius); 357 VSIFPrintf( fp, "%s", eol); 358 } 359 } 360 } 361 362 if ( is_ellipse == FALSE) 363 { 364 int nInteriorRings = polygon->getNumInteriorRings(); 365 for(i=0;i<nInteriorRings;i++) 366 { 367 nBNAPoints += polygon->getInteriorRing(i)->getNumPoints() + 1; 368 } 369 if (nBNAPoints <= 3) 370 { 371 CPLError( CE_Failure, CPLE_AppDefined, "Invalid geometry" ); 372 return OGRERR_FAILURE; 373 } 374 WriteFeatureAttributes(fp, poFeature); 375 VSIFPrintf( fp, "%d", nBNAPoints); 376 n = ring->getNumPoints(); 377 int nbPair = 0; 378 for(i=0;i<n;i++) 379 { 380 VSIFPrintf( fp, formatCoordinates, 381 ((nbPair % nbPairPerLine) == 0) ? partialEol : " ", ring->getX(i), ring->getY(i)); 382 nbPair++; 383 } 384 for(i=0;i<nInteriorRings;i++) 385 { 386 ring = polygon->getInteriorRing(i); 387 n = ring->getNumPoints(); 388 for(j=0;i<n;i++) 389 { 390 VSIFPrintf( fp, formatCoordinates, 391 ((nbPair % nbPairPerLine) == 0) ? partialEol : " ", ring->getX(j), ring->getY(j)); 392 nbPair++; 393 } 394 VSIFPrintf( fp, formatCoordinates, 395 ((nbPair % nbPairPerLine) == 0) ? partialEol : " ", firstX, firstY); 396 nbPair++; 397 } 398 VSIFPrintf( fp, "%s", eol); 399 } 400 break; 401 } 402 403 case wkbMultiPolygon: 404 case wkbMultiPolygon25D: 405 { 406 OGRMultiPolygon* multipolygon = (OGRMultiPolygon*)poGeom; 407 int N = multipolygon->getNumGeometries(); 408 int nBNAPoints = 0; 409 double firstX = 0, firstY = 0; 410 for(i=0;i<N;i++) 411 { 412 OGRPolygon* polygon = (OGRPolygon*)multipolygon->getGeometryRef(i); 413 OGRLinearRing* ring = polygon->getExteriorRing(); 414 if (nBNAPoints) 415 nBNAPoints ++; 416 else 417 { 418 firstX = ring->getX(0); 419 firstY = ring->getY(0); 420 } 421 nBNAPoints += ring->getNumPoints(); 422 int nInteriorRings = polygon->getNumInteriorRings(); 423 for(j=0;j<nInteriorRings;j++) 424 { 425 nBNAPoints += polygon->getInteriorRing(j)->getNumPoints() + 1; 426 } 427 } 428 if (nBNAPoints <= 3) 429 { 430 CPLError( CE_Failure, CPLE_AppDefined, "Invalid geometry" ); 431  
