?? ogrshapelayer.cpp
字號:
OGRSpatialReference *OGRShapeLayer::GetSpatialRef(){ return poSRS;}/************************************************************************//* ResetGeomType() *//* *//* Modify the geometry type for this file. Used to convert to *//* a different geometry type when a layer was created with a *//* type of unknown, and we get to the first feature to *//* establish the type. *//************************************************************************/int OGRShapeLayer::ResetGeomType( int nNewGeomType ){ char abyHeader[100]; int nStartPos; if( nTotalShapeCount > 0 ) return FALSE;/* -------------------------------------------------------------------- *//* Update .shp header. *//* -------------------------------------------------------------------- */ nStartPos = ftell( hSHP->fpSHP ); if( fseek( hSHP->fpSHP, 0, SEEK_SET ) != 0 || fread( abyHeader, 100, 1, hSHP->fpSHP ) != 1 ) return FALSE; *((GInt32 *) (abyHeader + 32)) = CPL_LSBWORD32( nNewGeomType ); if( fseek( hSHP->fpSHP, 0, SEEK_SET ) != 0 || fwrite( abyHeader, 100, 1, hSHP->fpSHP ) != 1 ) return FALSE; if( fseek( hSHP->fpSHP, nStartPos, SEEK_SET ) != 0 ) return FALSE;/* -------------------------------------------------------------------- *//* Update .shx header. *//* -------------------------------------------------------------------- */ nStartPos = ftell( hSHP->fpSHX ); if( fseek( hSHP->fpSHX, 0, SEEK_SET ) != 0 || fread( abyHeader, 100, 1, hSHP->fpSHX ) != 1 ) return FALSE; *((GInt32 *) (abyHeader + 32)) = CPL_LSBWORD32( nNewGeomType ); if( fseek( hSHP->fpSHX, 0, SEEK_SET ) != 0 || fwrite( abyHeader, 100, 1, hSHP->fpSHX ) != 1 ) return FALSE; if( fseek( hSHP->fpSHX, nStartPos, SEEK_SET ) != 0 ) return FALSE;/* -------------------------------------------------------------------- *//* Update other information. *//* -------------------------------------------------------------------- */ hSHP->nShapeType = nNewGeomType; return TRUE;}/************************************************************************//* SyncToDisk() *//************************************************************************/OGRErr OGRShapeLayer::SyncToDisk(){ if( bHeaderDirty ) { if( hSHP != NULL ) SHPWriteHeader( hSHP ); if( hDBF != NULL ) DBFUpdateHeader( hDBF ); bHeaderDirty = FALSE; } if( hSHP != NULL ) { fflush( hSHP->fpSHP ); fflush( hSHP->fpSHX ); } if( hDBF != NULL ) fflush( hDBF->fp ); return OGRERR_NONE;}/************************************************************************//* DropSpatialIndex() *//************************************************************************/OGRErr OGRShapeLayer::DropSpatialIndex(){ if( !CheckForQIX() ) { CPLError( CE_Warning, CPLE_AppDefined, "Layer %s has no spatial index, DROP SPATIAL INDEX failed.", poFeatureDefn->GetName() ); return OGRERR_FAILURE; } VSIFClose( fpQIX ); fpQIX = NULL; bCheckedForQIX = FALSE; const char *pszQIXFilename; pszQIXFilename = CPLResetExtension( pszFullName, "qix" ); CPLDebug( "SHAPE", "Unlinking index file %s", pszQIXFilename ); if( VSIUnlink( pszQIXFilename ) != 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to delete file %s.\n%s", pszQIXFilename, VSIStrerror( errno ) ); return OGRERR_FAILURE; } else return OGRERR_NONE;}/************************************************************************//* CreateSpatialIndex() *//************************************************************************/OGRErr OGRShapeLayer::CreateSpatialIndex( int nMaxDepth ){/* -------------------------------------------------------------------- *//* If we have an existing spatial index, blow it away first. *//* -------------------------------------------------------------------- */ if( CheckForQIX() ) DropSpatialIndex(); bCheckedForQIX = FALSE;/* -------------------------------------------------------------------- *//* Build a quadtree structure for this file. *//* -------------------------------------------------------------------- */ SHPTree *psTree; SyncToDisk(); psTree = SHPCreateTree( hSHP, 2, nMaxDepth, NULL, NULL );/* -------------------------------------------------------------------- *//* Trim unused nodes from the tree. *//* -------------------------------------------------------------------- */ SHPTreeTrimExtraNodes( psTree );/* -------------------------------------------------------------------- *//* Dump tree to .qix file. *//* -------------------------------------------------------------------- */ char *pszQIXFilename; pszQIXFilename = CPLStrdup(CPLResetExtension( pszFullName, "qix" )); CPLDebug( "SHAPE", "Creating index file %s", pszQIXFilename ); SHPWriteTree( psTree, pszQIXFilename ); CPLFree( pszQIXFilename );/* -------------------------------------------------------------------- *//* cleanup *//* -------------------------------------------------------------------- */ SHPDestroyTree( psTree ); CheckForQIX(); return OGRERR_NONE;}/************************************************************************//* Repack() *//* *//* Repack the shape and dbf file, dropping deleted records. *//* FIDs may change. *//************************************************************************/OGRErr OGRShapeLayer::Repack(){/* -------------------------------------------------------------------- *//* Build a list of records to be dropped. *//* -------------------------------------------------------------------- */ int *panRecordsToDelete = (int *) CPLMalloc(sizeof(int)*(nTotalShapeCount+1)); int nDeleteCount = 0; int iShape; OGRErr eErr = OGRERR_NONE; for( iShape = 0; iShape < nTotalShapeCount; iShape++ ) { if( DBFIsRecordDeleted( hDBF, iShape ) ) panRecordsToDelete[nDeleteCount++] = iShape; } panRecordsToDelete[nDeleteCount] = -1;/* -------------------------------------------------------------------- *//* If there are no records marked for deletion, we take no *//* action. *//* -------------------------------------------------------------------- */ if( nDeleteCount == 0 ) return OGRERR_NONE;/* -------------------------------------------------------------------- *//* Cleanup any existing spatial index. It will become *//* meaningless when the fids change. *//* -------------------------------------------------------------------- */ if( CheckForQIX() ) DropSpatialIndex();/* -------------------------------------------------------------------- *//* Create a new dbf file, matching the old. *//* -------------------------------------------------------------------- */ DBFHandle hNewDBF; CPLString oTempFile = CPLGetBasename(pszFullName); oTempFile += "_packed.dbf"; hNewDBF = DBFCloneEmpty( hDBF, oTempFile ); if( hNewDBF == NULL ) { CPLFree( panRecordsToDelete ); CPLError( CE_Failure, CPLE_OpenFailed, "Failed to create temp file %s.", oTempFile.c_str() ); return OGRERR_FAILURE; }/* -------------------------------------------------------------------- *//* Copy over all records that are not deleted. *//* -------------------------------------------------------------------- */ int iDestShape = 0; int iNextDeletedShape = 0; for( iShape = 0; iShape < nTotalShapeCount && eErr == OGRERR_NONE; iShape++ ) { if( panRecordsToDelete[iNextDeletedShape] == iShape ) iNextDeletedShape++; else { void *pTuple = (void *) DBFReadTuple( hDBF, iShape ); if( pTuple == NULL ) eErr = OGRERR_FAILURE; else if( !DBFWriteTuple( hNewDBF, iDestShape++, pTuple ) ) eErr = OGRERR_FAILURE; } } if( eErr != OGRERR_NONE ) { CPLFree( panRecordsToDelete ); VSIUnlink( oTempFile ); return eErr; }/* -------------------------------------------------------------------- *//* Cleanup the old .dbf and rename the new one. *//* -------------------------------------------------------------------- */ DBFClose( hDBF ); hDBF = hNewDBF; VSIUnlink( CPLResetExtension( pszFullName, "dbf" ) ); if( VSIRename( oTempFile, CPLResetExtension( pszFullName, "dbf" ) ) != 0 ) return OGRERR_FAILURE;/* -------------------------------------------------------------------- *//* Now create a shapefile matching the old one. *//* -------------------------------------------------------------------- */ if( hSHP != NULL ) { SHPHandle hNewSHP; oTempFile = CPLGetBasename(pszFullName); oTempFile += "_packed.shp"; hNewSHP = SHPCreate( oTempFile, hSHP->nShapeType ); if( hNewSHP == NULL ) return OGRERR_FAILURE;/* -------------------------------------------------------------------- *//* Copy over all records that are not deleted. *//* -------------------------------------------------------------------- */ iNextDeletedShape = 0; for( iShape = 0; iShape < nTotalShapeCount && eErr == OGRERR_NONE; iShape++ ) { if( panRecordsToDelete[iNextDeletedShape] == iShape ) iNextDeletedShape++; else { SHPObject *hObject; hObject = SHPReadObject( hSHP, iShape ); if( hObject == NULL ) eErr = OGRERR_FAILURE; else if( SHPWriteObject( hNewSHP, -1, hObject ) == -1 ) eErr = OGRERR_FAILURE; if( hObject ) SHPDestroyObject( hObject ); } } if( eErr != OGRERR_NONE ) { CPLFree( panRecordsToDelete ); VSIUnlink( CPLResetExtension( oTempFile, "shp" ) ); VSIUnlink( CPLResetExtension( oTempFile, "shx" ) ); return eErr; }/* -------------------------------------------------------------------- *//* Cleanup the old .shp/.shx and rename the new one. *//* -------------------------------------------------------------------- */ SHPClose( hSHP ); hSHP = hNewSHP; VSIUnlink( CPLResetExtension( pszFullName, "shp" ) ); VSIUnlink( CPLResetExtension( pszFullName, "shx" ) ); if( VSIRename( oTempFile, CPLResetExtension( pszFullName, "shp" ) ) != 0 ) return OGRERR_FAILURE; oTempFile = CPLResetExtension( oTempFile, "shx" ); if( VSIRename( oTempFile, CPLResetExtension( pszFullName, "shx" ) ) != 0 ) return OGRERR_FAILURE; }/* -------------------------------------------------------------------- *//* Update total shape count. *//* -------------------------------------------------------------------- */ nTotalShapeCount = hDBF->nRecords; CPLFree( panRecordsToDelete ); return OGRERR_NONE;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -