📄 ntffilereader.cpp
字号:
/* ReadRecordGroup() *//* *//* Read a group of records that form a single feature. *//************************************************************************/NTFRecord **NTFFileReader::ReadRecordGroup(){ NTFRecord *poRecord; int nRecordCount = 0; ClearCGroup(); /* -------------------------------------------------------------------- *//* Loop, reading records till we think we have a grouping. *//* -------------------------------------------------------------------- */ while( (poRecord = ReadRecord()) != NULL && poRecord->GetType() != NRT_VTR ) { CPLAssert( nRecordCount < MAX_REC_GROUP); if( nRecordCount >= MAX_REC_GROUP ) { CPLError( CE_Failure, CPLE_AppDefined, "Maximum record group size (%d) exceeded.\n", MAX_REC_GROUP ); break; } if( !pfnRecordGrouper( this, apoCGroup, poRecord ) ) break; apoCGroup[nRecordCount++] = poRecord; apoCGroup[nRecordCount] = NULL; } /* -------------------------------------------------------------------- *//* Push the last record back on the input queue. *//* -------------------------------------------------------------------- */ if( poRecord != NULL ) SaveRecord( poRecord );/* -------------------------------------------------------------------- *//* Return the list, or NULL if we didn't get any records. *//* -------------------------------------------------------------------- */ if( nRecordCount == 0 ) return NULL; else return apoCGroup;}/************************************************************************//* GetFeatureClass() *//************************************************************************/int NTFFileReader::GetFeatureClass( int iFCIndex, char ** ppszFCId, char ** ppszFCName ){ if( iFCIndex < 0 || iFCIndex >= nFCCount ) { *ppszFCId = NULL; *ppszFCName = NULL; return FALSE; } else { *ppszFCId = papszFCNum[iFCIndex]; *ppszFCName = papszFCName[iFCIndex]; return TRUE; }}/************************************************************************//* ReadOGRFeature() *//************************************************************************/OGRFeature * NTFFileReader::ReadOGRFeature( OGRNTFLayer * poTargetLayer ){ OGRNTFLayer *poLayer = NULL; NTFRecord **papoGroup; OGRFeature *poFeature = NULL;/* -------------------------------------------------------------------- *//* If this is a raster file, use a custom method to read the *//* feature. *//* -------------------------------------------------------------------- */ if( IsRasterProduct() ) return poRasterLayer->GetNextFeature();/* -------------------------------------------------------------------- *//* Loop looking for a group we can translate, and that if *//* needed matches our layer request. *//* -------------------------------------------------------------------- */ while( TRUE ) { if( GetProductId() == NPC_UNKNOWN && nNTFLevel > 2 ) papoGroup = GetNextIndexedRecordGroup( apoCGroup + 1 ); else papoGroup = ReadRecordGroup(); if( papoGroup == NULL ) break; poLayer = apoTypeTranslation[papoGroup[0]->GetType()]; if( poLayer == NULL ) continue; if( poTargetLayer != NULL && poTargetLayer != poLayer ) { CacheLineGeometryInGroup( papoGroup ); nSavedFeatureId++; continue; } poFeature = poLayer->FeatureTranslate( this, papoGroup ); if( poFeature == NULL ) { // should this be a real error? CPLDebug( "NTF", "FeatureTranslate() failed for a type %d record group\n" "in a %s type file.\n", papoGroup[0]->GetType(), GetProduct() ); } else break; }/* -------------------------------------------------------------------- *//* If we got a feature, set the TILE_REF on it. *//* -------------------------------------------------------------------- */ if( poFeature != NULL ) { int iTileRefField; iTileRefField = poLayer->GetLayerDefn()->GetFieldCount()-1; CPLAssert( EQUAL(poLayer->GetLayerDefn()->GetFieldDefn(iTileRefField)-> GetNameRef(), "TILE_REF") ); poFeature->SetField( iTileRefField, GetTileName() ); poFeature->SetFID( nSavedFeatureId ); nSavedFeatureId++; }/* -------------------------------------------------------------------- *//* If we got to the end we can establish our feature count for *//* the file. *//* -------------------------------------------------------------------- */ else { CPLAssert( nFeatureCount == -1 || nFeatureCount == nSavedFeatureId - nBaseFeatureId ); nFeatureCount = nSavedFeatureId - nBaseFeatureId; } return( poFeature );}/************************************************************************//* TestForLayer() *//* *//* Return indicator of whether this file contains any features *//* of the indicated layer type. *//************************************************************************/int NTFFileReader::TestForLayer( OGRNTFLayer * poLayer ){ for( int i = 0; i < 100; i++ ) { if( apoTypeTranslation[i] == poLayer ) return TRUE; } return FALSE;}/************************************************************************//* FreshenIndex() *//* *//* Rebuild the index if it is needed, and currently missing. *//************************************************************************/void NTFFileReader::FreshenIndex(){ if( !bIndexBuilt && bIndexNeeded ) IndexFile();}/************************************************************************//* IndexFile() *//* *//* Read all records beyond the section header and build an *//* internal index of them. *//************************************************************************/void NTFFileReader::IndexFile(){ NTFRecord *poRecord; Reset(); DestroyIndex(); bIndexNeeded = TRUE; bIndexBuilt = TRUE; bCacheLines = FALSE;/* -------------------------------------------------------------------- *//* Process all records after the section header, and before 99 *//* to put them in the index. *//* -------------------------------------------------------------------- */ while( (poRecord = ReadRecord()) != NULL && poRecord->GetType() != 99 ) { int iType = poRecord->GetType(); int iId = atoi(poRecord->GetField( 3, 8 )); if( iType < 0 || iType >= 100 ) { CPLError( CE_Failure, CPLE_AppDefined, "Illegal type %d record, skipping.", iType ); delete poRecord; continue; }/* -------------------------------------------------------------------- *//* Grow type specific subindex if needed. *//* -------------------------------------------------------------------- */ if( anIndexSize[iType] <= iId ) { int nNewSize = MAX(iId+1,anIndexSize[iType] * 2 + 10); apapoRecordIndex[iType] = (NTFRecord **) CPLRealloc(apapoRecordIndex[iType], sizeof(void *) * nNewSize); for( int i = anIndexSize[iType]; i < nNewSize; i++ ) (apapoRecordIndex[iType])[i] = NULL; anIndexSize[iType] = nNewSize; }/* -------------------------------------------------------------------- *//* Put record into type specific subindex based on it's id as *//* the key. *//* -------------------------------------------------------------------- */ if( apapoRecordIndex[iType][iId] != NULL ) { CPLDebug( "OGR_NTF", "Duplicate record with index %d and type %d\n" "in NTFFileReader::IndexFile().", iId, iType ); delete apapoRecordIndex[iType][iId]; } (apapoRecordIndex[iType])[iId] = poRecord; } if( poRecord != NULL ) delete poRecord;}/************************************************************************//* DestroyIndex() *//************************************************************************/void NTFFileReader::DestroyIndex(){ for( int i = 0; i < 100; i++ ) { for( int iId = 0; iId < anIndexSize[i]; iId++ ) { if( (apapoRecordIndex[i])[iId] != NULL ) delete (apapoRecordIndex[i])[iId]; } CPLFree( apapoRecordIndex[i] ); apapoRecordIndex[i] = NULL; anIndexSize[i] = 0; } bIndexBuilt = FALSE;}/************************************************************************//* GetIndexedRecord() *//************************************************************************/NTFRecord * NTFFileReader::GetIndexedRecord( int iType, int iId ){ if( (iType < 0 || iType > 99) || (iId < 0 || iId >= anIndexSize[iType]) || (apapoRecordIndex[iType])[iId] == NULL ) { /* If NRT_GEOMETRY3D is an acceptable alternative to 2D */ if( iType == NRT_GEOMETRY ) return GetIndexedRecord( NRT_GEOMETRY3D, iId ); else return NULL; } return (apapoRecordIndex[iType])[iId];}/************************************************************************//* AddToIndexGroup() *//************************************************************************/static void AddToIndexGroup( NTFRecord **papoGroup, NTFRecord * poRecord ){ int i; for( i = 1; papoGroup[i] != NULL; i++ ) {} papoGroup[i] = poRecord; papoGroup[i+1] = NULL;}/************************************************************************//* GetNextIndexedRecordGroup() *//************************************************************************/NTFRecord **NTFFileReader::GetNextIndexedRecordGroup( NTFRecord ** papoPrevGroup ){ int nPrevType, nPrevId;/* -------------------------------------------------------------------- *//* What was the identify of our previous anchor record? *//* -------------------------------------------------------------------- */ if( papoPrevGroup == NULL || papoPrevGroup[0] == NULL ) { nPrevType = NRT_POINTREC; nPrevId = 0; FreshenIndex(); } else { nPrevType = papoPrevGroup[0]->GetType(); nPrevId = atoi(papoPrevGroup[0]->GetField(3,8)); }/* -------------------------------------------------------------------- *//* Find the next anchor record. *//* -------------------------------------------------------------------- */ NTFRecord *poAnchor = NULL; while( nPrevType != 99 && poAnchor == NULL ) { nPrevId++; if( nPrevId >= anIndexSize[nPrevType] ) { do {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -