📄 mitab_tabfile.cpp
字号:
fprintf(fp, " Type NATIVE Charset \"%s\"\n", m_pszCharset);
fprintf(fp, " Fields %d\n", m_poDefn->GetFieldCount());
for(iField=0; iField<m_poDefn->GetFieldCount(); iField++)
{
poFieldDefn = m_poDefn->GetFieldDefn(iField);
switch(GetNativeFieldType(iField))
{
case TABFChar:
pszFieldType = CPLSPrintf("Char (%d)",
poFieldDefn->GetWidth());
break;
case TABFDecimal:
pszFieldType = CPLSPrintf("Decimal (%d,%d)",
poFieldDefn->GetWidth(),
poFieldDefn->GetPrecision());
break;
case TABFInteger:
pszFieldType = "Integer";
break;
case TABFSmallInt:
pszFieldType = "SmallInt";
break;
case TABFFloat:
pszFieldType = "Float";
break;
case TABFLogical:
pszFieldType = "Logical";
break;
case TABFDate:
pszFieldType = "Date";
break;
case TABFTime:
pszFieldType = "Time";
break;
case TABFDateTime:
pszFieldType = "DateTime";
break;
default:
// Unsupported field type!!! This should never happen.
CPLError(CE_Failure, CPLE_AssertionFailed,
"WriteTABFile(): Unsupported field type");
VSIFClose(fp);
return -1;
}
if (GetFieldIndexNumber(iField) == 0)
{
fprintf(fp, " %s %s ;\n", poFieldDefn->GetNameRef(),
pszFieldType );
}
else
{
fprintf(fp, " %s %s Index %d ;\n",
poFieldDefn->GetNameRef(), pszFieldType,
GetFieldIndexNumber(iField) );
}
}
}
else
{
fprintf(fp, "Definition Table\n");
fprintf(fp, " Type NATIVE Charset \"%s\"\n", m_pszCharset);
fprintf(fp, " Fields 1\n");
fprintf(fp, " FID Integer ;\n" );
}
VSIFClose(fp);
}
else
{
CPLError(CE_Failure, CPLE_FileIO,
"Failed to create file `%s'", m_pszFname);
return -1;
}
return 0;
}
/**********************************************************************
* TABFile::Close()
*
* Close current file, and release all memory used.
*
* Returns 0 on success, -1 on error.
**********************************************************************/
int TABFile::Close()
{
// Commit the latest changes to the file...
// In Write access, it's time to write the .TAB file.
if (m_eAccessMode == TABWrite && m_poMAPFile)
{
// First update file version number...
int nMapObjVersion = m_poMAPFile->GetMinTABFileVersion();
m_nVersion = MAX(m_nVersion, nMapObjVersion);
WriteTABFile();
}
if (m_poMAPFile)
{
m_poMAPFile->Close();
delete m_poMAPFile;
m_poMAPFile = NULL;
}
if (m_poDATFile)
{
m_poDATFile->Close();
delete m_poDATFile;
m_poDATFile = NULL;
}
if (m_poINDFile)
{
m_poINDFile->Close();
delete m_poINDFile;
m_poINDFile = NULL;
}
if (m_poCurFeature)
{
delete m_poCurFeature;
m_poCurFeature = NULL;
}
/*-----------------------------------------------------------------
* Note: we have to check the reference count before deleting
* m_poSpatialRef and m_poDefn
*----------------------------------------------------------------*/
if (m_poDefn )
{
int nRefCount = m_poDefn->Dereference();
CPLAssert( nRefCount >= 0 );
if( nRefCount == 0 )
delete m_poDefn;
m_poDefn = NULL;
}
if (m_poSpatialRef && m_poSpatialRef->Dereference() == 0)
delete m_poSpatialRef;
m_poSpatialRef = NULL;
CSLDestroy(m_papszTABFile);
m_papszTABFile = NULL;
CPLFree(m_pszFname);
m_pszFname = NULL;
CPLFree(m_pszCharset);
m_pszCharset = NULL;
CPLFree(m_panIndexNo);
m_panIndexNo = NULL;
return 0;
}
/**********************************************************************
* TABFile::SetQuickSpatialIndexMode()
*
* Select "quick spatial index mode".
*
* The default behavior of MITAB is to generate an optimized spatial index,
* but this results in slower write speed.
*
* Applications that want faster write speed and do not care
* about the performance of spatial queries on the resulting file can
* use SetQuickSpatialIndexMode() to require the creation of a non-optimal
* spatial index (actually emulating the type of spatial index produced
* by MITAB before version 1.6.0). In this mode writing files can be
* about 5 times faster, but spatial queries can be up to 30 times slower.
*
* Returns 0 on success, -1 on error.
**********************************************************************/
int TABFile::SetQuickSpatialIndexMode(GBool bQuickSpatialIndexMode/*=TRUE*/)
{
if (m_eAccessMode != TABWrite || m_poMAPFile == NULL)
{
CPLError(CE_Failure, CPLE_AssertionFailed,
"SetQuickSpatialIndexMode() failed: file not opened for write access.");
return -1;
}
return m_poMAPFile->SetQuickSpatialIndexMode(bQuickSpatialIndexMode);
}
/**********************************************************************
* TABFile::GetNextFeatureId()
*
* Returns feature id that follows nPrevId, or -1 if it is the
* last feature id. Pass nPrevId=-1 to fetch the first valid feature id.
**********************************************************************/
int TABFile::GetNextFeatureId(int nPrevId)
{
if (m_eAccessMode != TABRead)
{
CPLError(CE_Failure, CPLE_NotSupported,
"GetNextFeatureId() can be used only with Read access.");
return -1;
}
/*-----------------------------------------------------------------
* Are we using spatial rather than .ID based traversal?
*----------------------------------------------------------------*/
if( bUseSpatialTraversal )
return m_poMAPFile->GetNextFeatureId( nPrevId );
/*-----------------------------------------------------------------
* Establish what the next logical feature ID should be
*----------------------------------------------------------------*/
int nFeatureId = -1;
if (nPrevId <= 0 && m_nLastFeatureId > 0)
nFeatureId = 1; // Feature Ids start at 1
else if (nPrevId > 0 && nPrevId < m_nLastFeatureId)
nFeatureId = nPrevId + 1;
else
{
// This was the last feature
return OGRNullFID;
}
/*-----------------------------------------------------------------
* Skip any feature with NONE geometry and a deleted attribute record
*----------------------------------------------------------------*/
while(nFeatureId <= m_nLastFeatureId)
{
if ( m_poMAPFile->MoveToObjId(nFeatureId) != 0 ||
m_poDATFile->GetRecordBlock(nFeatureId) == NULL )
{
CPLError(CE_Failure, CPLE_IllegalArg,
"GetNextFeatureId() failed: unable to set read pointer "
"to feature id %d", nFeatureId);
return -1;
}
// __TODO__ Add a test here to check if object is deleted,
// i.e. 0x40 set on object_id in object block
if (m_poMAPFile->GetCurObjType() != TAB_GEOM_NONE ||
m_poDATFile->IsCurrentRecordDeleted() == FALSE)
{
// This feature contains at least a geometry or some attributes...
// return its id.
return nFeatureId;
}
nFeatureId++;
}
// If we reached this point, then we kept skipping deleted features
// and stopped when EOF was reached.
return -1;
}
/**********************************************************************
* TABFile::GetNextFeatureId_Spatial()
*
* Returns feature id that follows nPrevId, or -1 if it is the
* last feature id, but by traversing the spatial tree instead of the
* direct object index. Generally speaking the feature id's will be
* returned in an unordered fashion.
**********************************************************************/
int TABFile::GetNextFeatureId_Spatial(int nPrevId)
{
if (m_eAccessMode != TABRead)
{
CPLError(CE_Failure, CPLE_NotSupported,
"GetNextFeatureId_Spatial() can be used only with Read access.");
return -1;
}
if( m_poMAPFile == NULL )
{
CPLError(CE_Failure, CPLE_NotSupported,
"GetNextFeatureId_Spatial() requires availability of .MAP file." );
return -1;
}
return m_poMAPFile->GetNextFeatureId( nPrevId );
}
/**********************************************************************
* TABFile::GetFeatureRef()
*
* Fill and return a TABFeature object for the specified feature id.
*
* The retruned pointer is a reference to an object owned and maintained
* by this TABFile object. It should not be altered or freed by the
* caller and its contents is guaranteed to be valid only until the next
* call to GetFeatureRef() or Close().
*
* Returns NULL if the specified feature id does not exist of if an
* error happened. In any case, CPLError() will have been called to
* report the reason of the failure.
*
* If an unsupported object type is encountered (likely from a newer version
* of MapInfo) then a valid feature will be returned with a NONE geometry,
* and a warning will be produced with code TAB_WarningFeatureTypeNotSupported
* CPLGetLastErrorNo() should be used to detect that case.
**********************************************************************/
TABFeature *TABFile::GetFeatureRef(int nFeatureId)
{
CPLErrorReset();
if (m_eAccessMode != TABRead)
{
CPLError(CE_Failure, CPLE_NotSupported,
"GetFeatureRef() can be used only with Read access.");
return NULL;
}
/*-----------------------------------------------------------------
* Make sure file is opened and Validate feature id by positioning
* the read pointers for the .MAP and .DAT files to this feature id.
*----------------------------------------------------------------*/
if (m_poMAPFile == NULL)
{
CPLError(CE_Failure, CPLE_IllegalArg,
"GetFeatureRef() failed: file is not opened!");
return NULL;
}
if (nFeatureId <= 0 || nFeatureId > m_nLastFeatureId ||
m_poMAPFile->MoveToObjId(nFeatureId) != 0 ||
m_poDATFile->GetRecordBlock(nFeatureId) == NULL )
{
// CPLError(CE_Failure, CPLE_IllegalArg,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -