void OGRBNALayer::FastParseUntil ( int interestFID) { if (partialIndexTable) { ResetReading(); BNARecord* record; if (nFeatures > 0) { VSIFSeekL( fpBNA, offsetAndLineFeaturesTable[nFeatures-1].offset, SEEK_SET ); curLine = offsetAndLineFeaturesTable[nFeatures-1].line; /* Just skip the last read one */ int ok = FALSE; record = BNA_GetNextRecord(fpBNA, &ok, &curLine, TRUE, BNA_READ_NONE); BNA_FreeRecord(record); } while(1) { int ok = FALSE; int offset = (int) VSIFTellL(fpBNA); int line = curLine; record = BNA_GetNextRecord(fpBNA, &ok, &curLine, TRUE, BNA_READ_NONE); if (ok == FALSE) { failed = TRUE; return; } if (record == NULL) { /* end of file */ eof = TRUE; /* and we have finally build the whole index table */ partialIndexTable = FALSE; return; } if (record->featureType == bnaFeatureType) { nFeatures++; offsetAndLineFeaturesTable = (OffsetAndLine*)CPLRealloc(offsetAndLineFeaturesTable, nFeatures * sizeof(OffsetAndLine)); offsetAndLineFeaturesTable[nFeatures-1].offset = offset; offsetAndLineFeaturesTable[nFeatures-1].line = line; BNA_FreeRecord(record); if (nFeatures - 1 == interestFID) return; } else { BNA_FreeRecord(record); } } } }
OGRFeature * OGRBNALayer::GetFeature( long nFID ) { OGRFeature *poFeature; BNARecord* record; int ok; if (nFID < 0) return NULL; FastParseUntil(nFID); if (nFID >= nFeatures) return NULL; VSIFSeekL( fpBNA, offsetAndLineFeaturesTable[nFID].offset, SEEK_SET ); curLine = offsetAndLineFeaturesTable[nFID].line; record = BNA_GetNextRecord(fpBNA, &ok, &curLine, TRUE, bnaFeatureType); poFeature = BuildFeatureFromBNARecord(record, nFID); BNA_FreeRecord(record); return poFeature; }
OGRFeature * OGRBNALayer::GetFeature( GIntBig nFID ) { if (nFID < 0 || !CPL_INT64_FITS_ON_INT32(nFID)) return NULL; FastParseUntil( static_cast<int>( nFID ) ); if (nFID >= nFeatures) return NULL; int ok; if( VSIFSeekL( fpBNA, offsetAndLineFeaturesTable[nFID].offset, SEEK_SET ) < 0 ) return NULL; curLine = offsetAndLineFeaturesTable[nFID].line; BNARecord* record = BNA_GetNextRecord(fpBNA, &ok, &curLine, TRUE, bnaFeatureType); OGRFeature *poFeature = BuildFeatureFromBNARecord(record, (int)nFID); BNA_FreeRecord(record); return poFeature; }
OGRFeature *OGRBNALayer::GetNextFeature() { OGRFeature *poFeature; BNARecord* record; int offset, line; if (failed || eof) return NULL; while(1) { int ok = FALSE; offset = (int) VSIFTellL(fpBNA); line = curLine; if (nNextFID < nFeatures) { VSIFSeekL( fpBNA, offsetAndLineFeaturesTable[nNextFID].offset, SEEK_SET ); curLine = offsetAndLineFeaturesTable[nNextFID].line; } record = BNA_GetNextRecord(fpBNA, &ok, &curLine, TRUE, bnaFeatureType); if (ok == FALSE) { BNA_FreeRecord(record); failed = TRUE; return NULL; } if (record == NULL) { /* end of file */ eof = TRUE; /* and we have finally build the whole index table */ partialIndexTable = FALSE; return NULL; } if (record->featureType == bnaFeatureType) { if (nNextFID >= nFeatures) { nFeatures++; offsetAndLineFeaturesTable = (OffsetAndLine*)CPLRealloc(offsetAndLineFeaturesTable, nFeatures * sizeof(OffsetAndLine)); offsetAndLineFeaturesTable[nFeatures-1].offset = offset; offsetAndLineFeaturesTable[nFeatures-1].line = line; } poFeature = BuildFeatureFromBNARecord(record, nNextFID++); BNA_FreeRecord(record); if( (m_poFilterGeom == NULL || FilterGeometry( poFeature->GetGeometryRef() ) ) && (m_poAttrQuery == NULL || m_poAttrQuery->Evaluate( poFeature )) ) { return poFeature; } delete poFeature; } else { BNA_FreeRecord(record); } } }
int OGRBNADataSource::Open( const char * pszFilename, int bUpdateIn) { int ok = FALSE; pszName = CPLStrdup( pszFilename ); bUpdate = bUpdateIn; /* -------------------------------------------------------------------- */ /* Determine what sort of object this is. */ /* -------------------------------------------------------------------- */ VSIStatBufL sStatBuf; if( VSIStatL( pszFilename, &sStatBuf ) != 0 ) return FALSE; // -------------------------------------------------------------------- // Does this appear to be a .bna file? // -------------------------------------------------------------------- if( !(EQUAL( CPLGetExtension(pszFilename), "bna" ) || ((EQUALN( pszFilename, "/vsigzip/", 9) || EQUALN( pszFilename, "/vsizip/", 8)) && (strstr( pszFilename, ".bna") || strstr( pszFilename, ".BNA")))) ) return FALSE; VSILFILE* fp = VSIFOpenL(pszFilename, "rb"); if (fp) { BNARecord* record; int curLine = 0; const char* layerRadixName[] = { "points", "polygons", "lines", "ellipses"}; OGRwkbGeometryType wkbGeomTypes[] = { wkbPoint, wkbMultiPolygon, wkbLineString, wkbPolygon }; int i; #if defined(BNA_FAST_DS_OPEN) record = BNA_GetNextRecord(fp, &ok, &curLine, FALSE, BNA_READ_NONE); BNA_FreeRecord(record); if (ok) { nLayers = 4; papoLayers = (OGRBNALayer **) CPLMalloc(nLayers * sizeof(OGRBNALayer*)); for(i=0;i<4;i++) papoLayers[i] = new OGRBNALayer( pszFilename, layerRadixName[i], (BNAFeatureType)i, wkbGeomTypes[i], FALSE, this ); } #else int nFeatures[4] = { 0, 0, 0, 0 }; OffsetAndLine* offsetAndLineFeaturesTable[4] = { NULL, NULL, NULL, NULL }; int nIDs[4] = {0, 0, 0, 0}; int partialIndexTable = TRUE; while(1) { int offset = VSIFTellL(fp); int line = curLine; record = BNA_GetNextRecord(fp, &ok, &curLine, FALSE, BNA_READ_NONE); if (ok == FALSE) { BNA_FreeRecord(record); if (line != 0) ok = TRUE; break; } if (record == NULL) { /* end of file */ ok = TRUE; /* and we have finally build the whole index table */ partialIndexTable = FALSE; break; } if (record->nIDs > nIDs[record->featureType]) nIDs[record->featureType] = record->nIDs; nFeatures[record->featureType]++; offsetAndLineFeaturesTable[record->featureType] = (OffsetAndLine*)CPLRealloc(offsetAndLineFeaturesTable[record->featureType], nFeatures[record->featureType] * sizeof(OffsetAndLine)); offsetAndLineFeaturesTable[record->featureType][nFeatures[record->featureType]-1].offset = offset; offsetAndLineFeaturesTable[record->featureType][nFeatures[record->featureType]-1].line = line; BNA_FreeRecord(record); } nLayers = (nFeatures[0] != 0) + (nFeatures[1] != 0) + (nFeatures[2] != 0) + (nFeatures[3] != 0); papoLayers = (OGRBNALayer **) CPLMalloc(nLayers * sizeof(OGRBNALayer*)); int iLayer = 0; for(i=0;i<4;i++) { if (nFeatures[i]) { papoLayers[iLayer] = new OGRBNALayer( pszFilename, layerRadixName[i], (BNAFeatureType)i, wkbGeomTypes[i], FALSE, this, nIDs[i]); papoLayers[iLayer]->SetFeatureIndexTable(nFeatures[i], offsetAndLineFeaturesTable[i], partialIndexTable); iLayer++; } } #endif VSIFCloseL(fp); } return ok; }
int OGRBNADataSource::Open( const char * pszFilename ) { int ok = FALSE; pszName = CPLStrdup( pszFilename ); VSILFILE* fp = VSIFOpenL(pszFilename, "rb"); if (fp) { int curLine = 0; static const char* const layerRadixName[] = { "points", "polygons", "lines", "ellipses"}; static const OGRwkbGeometryType wkbGeomTypes[] = { wkbPoint, wkbMultiPolygon, wkbLineString, wkbPolygon }; #if defined(BNA_FAST_DS_OPEN) BNARecord* record = BNA_GetNextRecord(fp, &ok, &curLine, FALSE, BNA_READ_NONE); BNA_FreeRecord(record); if (ok) { nLayers = 4; papoLayers = static_cast<OGRBNALayer **>( CPLMalloc(nLayers * sizeof(OGRBNALayer*))); for( i = 0; i < 4; i++ ) papoLayers[i] = new OGRBNALayer( pszFilename, layerRadixName[i], static_cast<BNAFeatureType>( i ), wkbGeomTypes[i], FALSE, this ); } #else int nFeatures[4] = { 0, 0, 0, 0 }; OffsetAndLine* offsetAndLineFeaturesTable[4] = { nullptr, nullptr, nullptr, nullptr }; int nIDs[4] = {0, 0, 0, 0}; bool partialIndexTable = true; BNARecord* record = nullptr; while(1) { int offset = static_cast<int>( VSIFTellL(fp) ); int line = curLine; record = BNA_GetNextRecord(fp, &ok, &curLine, FALSE, BNA_READ_NONE); if (ok == FALSE) { BNA_FreeRecord(record); if (line != 0) ok = TRUE; break; } if (record == nullptr) { /* end of file */ ok = TRUE; /* and we have finally build the whole index table */ partialIndexTable = false; break; } if (record->nIDs > nIDs[record->featureType]) nIDs[record->featureType] = record->nIDs; nFeatures[record->featureType]++; offsetAndLineFeaturesTable[record->featureType] = static_cast<OffsetAndLine *>( CPLRealloc( offsetAndLineFeaturesTable[record->featureType], nFeatures[record->featureType] * sizeof(OffsetAndLine) ) ); offsetAndLineFeaturesTable[record->featureType][nFeatures[record->featureType]-1].offset = offset; offsetAndLineFeaturesTable[record->featureType][nFeatures[record->featureType]-1].line = line; BNA_FreeRecord(record); } nLayers = (nFeatures[0] != 0) + (nFeatures[1] != 0) + (nFeatures[2] != 0) + (nFeatures[3] != 0); papoLayers = static_cast<OGRBNALayer **>( CPLMalloc(nLayers * sizeof(OGRBNALayer*)) ); int iLayer = 0; for( int i = 0; i < 4; i++ ) { if (nFeatures[i]) { papoLayers[iLayer] = new OGRBNALayer( pszFilename, layerRadixName[i], (BNAFeatureType)i, wkbGeomTypes[i], FALSE, this, nIDs[i]); papoLayers[iLayer]->SetFeatureIndexTable(nFeatures[i], offsetAndLineFeaturesTable[i], partialIndexTable); iLayer++; } } #endif VSIFCloseL(fp); } return ok; }