⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ogrshapelayer.cpp

📁 用于读取TAB、MIF、SHP文件的类
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        iNewField =            DBFAddNativeFieldType( hDBF, poField->GetNameRef(), 'D', 8, 0 );        if( iNewField != -1 )            poFeatureDefn->AddFieldDefn( poField );    }    else    {        CPLError( CE_Failure, CPLE_NotSupported,                  "Can't create fields of type %s on shapefile layers.\n",                  OGRFieldDefn::GetFieldTypeName(poField->GetType()) );        return OGRERR_FAILURE;    }    if( iNewField != -1 )    {        return OGRERR_NONE;    }    else            {        CPLError( CE_Failure, CPLE_AppDefined,                  "Can't create field %s in Shape DBF file, reason unknown.\n",                  poField->GetNameRef() );        return OGRERR_FAILURE;    }}/************************************************************************//*                           GetSpatialRef()                            *//************************************************************************/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 + -