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

📄 ogr_miattrind.cpp

📁 mitab,读取MapInfo的地图文件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* -------------------------------------------------------------------- */
    if( poINDFile == NULL )
    {
        poINDFile = new TABINDFile();
        if( poINDFile->Open( pszMIINDFilename, "w+" ) != 0 )
        {
            delete poINDFile;
            poINDFile = NULL;
            
            CPLError( CE_Failure, CPLE_OpenFailed, 
                      "Failed to create %s.",
                      pszMIINDFilename );
            return OGRERR_FAILURE;
        }
    }

/* -------------------------------------------------------------------- */
/*      Do we have this field indexed already?                          */
/* -------------------------------------------------------------------- */
    int i;
    OGRFieldDefn *poFldDefn=poLayer->GetLayerDefn()->GetFieldDefn(iField);

    for( i = 0; i < nIndexCount; i++ )
    {
        if( papoIndexList[i]->iField == iField )
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                      "It seems we already have an index for field %d/%s\n"
                      "of layer %s.", 
                      poFldDefn->GetNameRef(),
                      poLayer->GetLayerDefn()->GetName() );
            return OGRERR_FAILURE;
        }
    }

/* -------------------------------------------------------------------- */
/*      What is the corresponding field type in TAB?  Note that we      */
/*      don't allow indexing of any of the list types.                  */
/* -------------------------------------------------------------------- */
    TABFieldType eTABFT;
    int           nFieldWidth = 0;

    switch( poFldDefn->GetType() )
    {
      case OFTInteger:
        eTABFT = TABFInteger;
        break;

      case OFTReal:
        eTABFT = TABFFloat;
        break;

      case OFTString:
        eTABFT = TABFChar;
        if( poFldDefn->GetWidth() > 0 )
            nFieldWidth = poFldDefn->GetWidth();
        else
            nFieldWidth = 64;
        break;

      default:
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Indexing not support for the field type of field %s.",
                  poFldDefn->GetNameRef() );
        return OGRERR_FAILURE;
    }

/* -------------------------------------------------------------------- */
/*      Create the index.                                               */
/* -------------------------------------------------------------------- */
    int iINDIndex;

    iINDIndex = poINDFile->CreateIndex( eTABFT, nFieldWidth );

    // CreateIndex() reports it's own errors.
    if( iINDIndex < 0 )
        return OGRERR_FAILURE;

    AddAttrInd( iField, iINDIndex );

/* -------------------------------------------------------------------- */
/*      Save the new configuration.                                     */
/* -------------------------------------------------------------------- */
    return SaveConfigToXML();
}

/************************************************************************/
/*                             DropIndex()                              */
/*                                                                      */
/*      For now we don't have any capability to remove index data       */
/*      from the MapInfo index file, so we just limit ourselves to      */
/*      ignoring it from now on.                                        */
/************************************************************************/

OGRErr OGRMILayerAttrIndex::DropIndex( int iField )

{
/* -------------------------------------------------------------------- */
/*      Do we have this field indexed already?                          */
/* -------------------------------------------------------------------- */
    int i;
    OGRFieldDefn *poFldDefn=poLayer->GetLayerDefn()->GetFieldDefn(iField);

    for( i = 0; i < nIndexCount; i++ )
    {
        if( papoIndexList[i]->iField == iField )
            break;

    }

    if( i == nIndexCount )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "DROP INDEX on field (%s) that doesn't have an index.",
                  poFldDefn->GetNameRef() );
        return OGRERR_FAILURE;
    }

/* -------------------------------------------------------------------- */
/*      Remove from the list.                                           */
/* -------------------------------------------------------------------- */
    OGRMIAttrIndex *poAI = papoIndexList[i];

    memmove( papoIndexList + i, papoIndexList + i + 1, 
             sizeof(void*) * (nIndexCount - i - 1) );

    delete poAI;

    nIndexCount--;
             
/* -------------------------------------------------------------------- */
/*      Save the new configuration, or if there is nothing left try     */
/*      to clean up the index files.                                    */
/* -------------------------------------------------------------------- */
    if( nIndexCount > 0 )
        return SaveConfigToXML();
    else
    {
        VSIUnlink( pszMetadataFilename );
        VSIUnlink( pszMIINDFilename );

        return OGRERR_NONE;
    }
}

/************************************************************************/
/*                             AddAttrInd()                             */
/************************************************************************/

void OGRMILayerAttrIndex::AddAttrInd( int iField, int iINDIndex )

{
    OGRMIAttrIndex *poAttrInd = new OGRMIAttrIndex( this, iINDIndex, iField);

    nIndexCount++;
    papoIndexList = (OGRMIAttrIndex **) 
        CPLRealloc(papoIndexList, sizeof(void*) * nIndexCount);
    
    papoIndexList[nIndexCount-1] = poAttrInd;
}

/************************************************************************/
/*                         GetFieldAttrIndex()                          */
/************************************************************************/

OGRAttrIndex *OGRMILayerAttrIndex::GetFieldIndex( int iField )

{
    for( int i = 0; i < nIndexCount; i++ )
    {
        if( papoIndexList[i]->iField == iField )
            return papoIndexList[i];
    }

    return NULL;
}

/************************************************************************/
/*                             AddToIndex()                             */
/************************************************************************/

OGRErr OGRMILayerAttrIndex::AddToIndex( OGRFeature *poFeature,
                                        int iTargetField )

{
    OGRErr eErr = OGRERR_NONE;

    if( poFeature->GetFID() == OGRNullFID )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Attempt to index feature with no FID." );
        return OGRERR_FAILURE;
    }

    for( int i = 0; i < nIndexCount && eErr == OGRERR_NONE; i++ )
    {
        int iField = papoIndexList[i]->iField;

        if( iTargetField != -1 && iTargetField != iField )
            continue;

        if( !poFeature->IsFieldSet( iField ) )
            continue;

        eErr = 
            papoIndexList[i]->AddEntry( poFeature->GetRawFieldRef( iField ),
                                        poFeature->GetFID() );
    }

    return eErr;
}

/************************************************************************/
/*                          RemoveFromIndex()                           */
/************************************************************************/

OGRErr OGRMILayerAttrIndex::RemoveFromIndex( OGRFeature * /*poFeature*/ )

{
    return OGRERR_UNSUPPORTED_OPERATION;
}

/************************************************************************/
/*                     OGRCreateDefaultLayerIndex()                     */
/************************************************************************/

OGRLayerAttrIndex *OGRCreateDefaultLayerIndex()

{
    return new OGRMILayerAttrIndex();
}

/************************************************************************/
/* ==================================================================== */
/*                            OGRMIAttrIndex                            */
/* ==================================================================== */
/************************************************************************/

/* class declared at top of file */

/************************************************************************/
/*                           OGRMIAttrIndex()                           */
/************************************************************************/

OGRMIAttrIndex::OGRMIAttrIndex( OGRMILayerAttrIndex *poLayerIndex, 
                                int iIndexIn, int iFieldIn )

{
    iIndex = iIndexIn;
    iField = iFieldIn;
    poLIndex = poLayerIndex;
    poINDFile = poLayerIndex->poINDFile;

    poFldDefn = poLayerIndex->GetLayer()->GetLayerDefn()->GetFieldDefn(iField);
}

/************************************************************************/
/*                          ~OGRMIAttrIndex()                           */
/************************************************************************/

OGRMIAttrIndex::~OGRMIAttrIndex()
{
}

/************************************************************************/
/*                              AddEntry()                              */
/************************************************************************/

OGRErr OGRMIAttrIndex::AddEntry( OGRField *psKey, long nFID )

{
    GByte *pabyKey = BuildKey( psKey );

    if( psKey == NULL )
        return OGRERR_FAILURE;

    if( poINDFile->AddEntry( iIndex, pabyKey, nFID+1 ) != 0 )
        return OGRERR_FAILURE;
    else
        return OGRERR_NONE;
}

/************************************************************************/
/*                            RemoveEntry()                             */
/************************************************************************/

OGRErr OGRMIAttrIndex::RemoveEntry( OGRField * /*psKey*/, long /*nFID*/ )

{
    return OGRERR_UNSUPPORTED_OPERATION;
}

/************************************************************************/
/*                              BuildKey()                              */
/************************************************************************/

GByte *OGRMIAttrIndex::BuildKey( OGRField *psKey )

{
    switch( poFldDefn->GetType() )
    {
      case OFTInteger:
        return poINDFile->BuildKey( iIndex, psKey->Integer );
        break;

      case OFTReal:
        return poINDFile->BuildKey( iIndex, psKey->Real );
        break;

      case OFTString:
        return poINDFile->BuildKey( iIndex, psKey->String );
        break;

      default:
        CPLAssert( FALSE );

        return NULL;
    }
}

/************************************************************************/
/*                           GetFirstMatch()                            */
/************************************************************************/

long OGRMIAttrIndex::GetFirstMatch( OGRField *psKey )

{
    GByte *pabyKey = BuildKey( psKey );
    long nFID;

    nFID = poINDFile->FindFirst( iIndex, pabyKey );
    if( nFID < 1 )
        return OGRNullFID;
    else
        return nFID - 1;
}

/************************************************************************/
/*                           GetAllMatches()                            */
/************************************************************************/

long *OGRMIAttrIndex::GetAllMatches( OGRField *psKey )

{
    GByte *pabyKey = BuildKey( psKey );
    long  *panFIDList = NULL, nFID;
    int   nFIDCount=0, nFIDMax=2;

    panFIDList = (long *) CPLMalloc(sizeof(long) * 2);

    nFID = poINDFile->FindFirst( iIndex, pabyKey );
    while( nFID > 0 )
    {
        if( nFIDCount >= nFIDMax-1 )
        {
            nFIDMax = nFIDMax * 2 + 10;
            panFIDList = (long *) CPLRealloc(panFIDList, sizeof(long)*nFIDMax);
        }
        panFIDList[nFIDCount++] = nFID - 1;
        
        nFID = poINDFile->FindNext( iIndex, pabyKey );
    }

    panFIDList[nFIDCount] = OGRNullFID;
    
    return panFIDList;
}

/************************************************************************/
/*                               Clear()                                */
/************************************************************************/

OGRErr OGRMIAttrIndex::Clear()

{
    return OGRERR_UNSUPPORTED_OPERATION;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -