📄 ogr_miattrind.cpp
字号:
/* -------------------------------------------------------------------- */
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 + -