📄 mitab_mapfile.cpp
字号:
if( iEntry >= m_poSpIndexLeaf->GetNumEntries()-1 )
{
TABMAPIndexBlock *poParent = m_poSpIndexLeaf->GetParentRef();
delete m_poSpIndexLeaf;
m_poSpIndexLeaf = poParent;
if( poParent != NULL )
{
poParent->SetCurChildRef( NULL, poParent->GetCurChildIndex() );
}
else
{
m_poSpIndex = NULL;
}
continue;
}
m_poSpIndexLeaf->SetCurChildRef( NULL, ++iEntry );
TABMAPIndexEntry *psEntry = m_poSpIndexLeaf->GetEntry( iEntry );
TABRawBinBlock *poBlock;
if( psEntry->XMax < m_XMinFilter
|| psEntry->YMax < m_YMinFilter
|| psEntry->XMin > m_XMaxFilter
|| psEntry->YMin > m_YMaxFilter )
continue;
poBlock = PushBlock( psEntry->nBlockPtr );
if( poBlock == NULL )
return FALSE;
else if( poBlock->GetBlockType() == TABMAP_OBJECT_BLOCK )
return TRUE;
else
/* continue processing new index block */;
}
return m_poSpIndexLeaf != NULL;
}
/************************************************************************/
/* ResetReading() */
/* */
/* Ensure that any resources related to a spatial traversal of */
/* the file are recovered, and the state reinitialized to the */
/* initial conditions. */
/************************************************************************/
void TABMAPFile::ResetReading()
{
if (m_poSpIndex && m_eAccessMode == TABRead )
{
delete m_poSpIndex;
m_poSpIndex = NULL;
m_poSpIndexLeaf = NULL;
}
}
/************************************************************************/
/* GetNextFeatureId() */
/* */
/* Fetch the next feature id based on a traversal of the */
/* spatial index. */
/************************************************************************/
int TABMAPFile::GetNextFeatureId( int nPrevId )
{
/* -------------------------------------------------------------------- */
/* m_fp is NULL when all geometry are NONE and/or there's */
/* no .map file and/or there's no spatial indexes */
/* -------------------------------------------------------------------- */
if( m_fp == NULL )
return -1;
if( nPrevId == 0 )
nPrevId = -1;
/* -------------------------------------------------------------------- */
/* This should always be true if we are being called properly. */
/* -------------------------------------------------------------------- */
if( nPrevId != -1 && m_nCurObjId != nPrevId )
{
CPLError( CE_Failure, CPLE_AppDefined,
"TABMAPFile::GetNextFeatureId(%d) called out of sequence.",
nPrevId );
return -1;
}
CPLAssert( nPrevId == -1 || m_poCurObjBlock != NULL );
/* -------------------------------------------------------------------- */
/* Ensure things are initialized properly if this is a request */
/* for the first feature. */
/* -------------------------------------------------------------------- */
if( nPrevId == -1 )
{
m_nCurObjId = -1;
}
/* -------------------------------------------------------------------- */
/* Try to advance to the next object in the current object */
/* block. */
/* -------------------------------------------------------------------- */
if( nPrevId == -1
|| m_poCurObjBlock->AdvanceToNextObject(m_poHeader) == -1 )
{
// If not, try to advance to the next object block, and get
// first object from it. Note that some object blocks actually
// have no objects, so we may have to advance to additional
// object blocks till we find a non-empty one.
GBool bFirstCall = (nPrevId == -1);
do
{
if( !LoadNextMatchingObjectBlock( bFirstCall ) )
return -1;
bFirstCall = FALSE;
} while( m_poCurObjBlock->AdvanceToNextObject(m_poHeader) == -1 );
}
m_nCurObjType = m_poCurObjBlock->GetCurObjectType();
m_nCurObjId = m_poCurObjBlock->GetCurObjectId();
m_nCurObjPtr = m_poCurObjBlock->GetStartAddress()
+ m_poCurObjBlock->GetCurObjectOffset();
CPLAssert( m_nCurObjId != -1 );
return m_nCurObjId;
}
/**********************************************************************
* TABMAPFile::Int2Coordsys()
*
* Convert from long integer (internal) to coordinates system units
* as defined in the file's coordsys clause.
*
* Note that the false easting/northing and the conversion factor from
* datum to coordsys units are not included in the calculation.
*
* Returns 0 on success, -1 on error.
**********************************************************************/
int TABMAPFile::Int2Coordsys(GInt32 nX, GInt32 nY, double &dX, double &dY)
{
if (m_poHeader == NULL)
return -1;
return m_poHeader->Int2Coordsys(nX, nY, dX, dY);
}
/**********************************************************************
* TABMAPFile::Coordsys2Int()
*
* Convert from coordinates system units as defined in the file's
* coordsys clause to long integer (internal) coordinates.
*
* Note that the false easting/northing and the conversion factor from
* datum to coordsys units are not included in the calculation.
*
* Returns 0 on success, -1 on error.
**********************************************************************/
int TABMAPFile::Coordsys2Int(double dX, double dY, GInt32 &nX, GInt32 &nY,
GBool bIgnoreOverflow/*=FALSE*/)
{
if (m_poHeader == NULL)
return -1;
return m_poHeader->Coordsys2Int(dX, dY, nX, nY, bIgnoreOverflow);
}
/**********************************************************************
* TABMAPFile::Int2CoordsysDist()
*
* Convert a pair of X,Y size (or distance) values from long integer
* (internal) to coordinates system units as defined in the file's coordsys
* clause.
*
* The difference with Int2Coordsys() is that this function only applies
* the scaling factor: it does not apply the displacement.
*
* Since the calculations on the X and Y values are independent, either
* one can be omitted (i.e. passed as 0)
*
* Returns 0 on success, -1 on error.
**********************************************************************/
int TABMAPFile::Int2CoordsysDist(GInt32 nX, GInt32 nY, double &dX, double &dY)
{
if (m_poHeader == NULL)
return -1;
return m_poHeader->Int2CoordsysDist(nX, nY, dX, dY);
}
/**********************************************************************
* TABMAPFile::Coordsys2IntDist()
*
* Convert a pair of X,Y size (or distance) values from coordinates
* system units as defined in the file's coordsys clause to long
* integer (internal) coordinate units.
*
* The difference with Int2Coordsys() is that this function only applies
* the scaling factor: it does not apply the displacement.
*
* Since the calculations on the X and Y values are independent, either
* one can be omitted (i.e. passed as 0)
*
* Returns 0 on success, -1 on error.
**********************************************************************/
int TABMAPFile::Coordsys2IntDist(double dX, double dY, GInt32 &nX, GInt32 &nY)
{
if (m_poHeader == NULL)
return -1;
return m_poHeader->Coordsys2IntDist(dX, dY, nX, nY);
}
/**********************************************************************
* TABMAPFile::SetCoordsysBounds()
*
* Set projection coordinates bounds of the newly created dataset.
*
* This function must be called after creating a new dataset and before any
* feature can be written to it.
*
* Returns 0 on success, -1 on error.
**********************************************************************/
int TABMAPFile::SetCoordsysBounds(double dXMin, double dYMin,
double dXMax, double dYMax)
{
int nStatus = 0;
if (m_poHeader == NULL)
return -1;
nStatus = m_poHeader->SetCoordsysBounds(dXMin, dYMin, dXMax, dYMax);
if (nStatus == 0)
ResetCoordFilter();
return nStatus;
}
/**********************************************************************
* TABMAPFile::GetMaxObjId()
*
* Return the value of the biggest valid object id.
*
* Note that object ids are positive and start at 1.
*
* Returns a value >= 0 on success, -1 on error.
**********************************************************************/
GInt32 TABMAPFile::GetMaxObjId()
{
if (m_poIdIndex)
return m_poIdIndex->GetMaxObjId();
return -1;
}
/**********************************************************************
* TABMAPFile::MoveToObjId()
*
* Get ready to work with the object with the specified id. The object
* data pointer (inside m_poCurObjBlock) will be moved to the first byte
* of data for this map object.
*
* The object type and id (i.e. table row number) will be accessible
* using GetCurObjType() and GetCurObjId().
*
* Note that object ids are positive and start at 1.
*
* Returns 0 on success, -1 on error.
**********************************************************************/
int TABMAPFile::MoveToObjId(int nObjId)
{
int nFileOffset;
/*-----------------------------------------------------------------
* In read access mode, since the .MAP/.ID are optional, if the
* file is not opened then we can still act as if one existed and
* make any object id look like a TAB_GEOM_NONE
*----------------------------------------------------------------*/
if (m_fp == NULL && m_eAccessMode == TABRead)
{
CPLAssert(m_poIdIndex == NULL && m_poCurObjBlock == NULL);
m_nCurObjPtr = 0;
m_nCurObjId = nObjId;
m_nCurObjType = TAB_GEOM_NONE;
return 0;
}
if (m_poIdIndex == NULL || m_poCurObjBlock == NULL)
{
CPLError(CE_Failure, CPLE_AssertionFailed,
"MoveToObjId(): file not opened!");
m_nCurObjPtr = m_nCurObjId = m_nCurObjType = -1;
return -1;
}
/*-----------------------------------------------------------------
* Move map object pointer to the right location. Fetch location
* from the index file, unless we are already pointing at it.
*----------------------------------------------------------------*/
if( m_nCurObjId == nObjId )
nFileOffset = m_nCurObjPtr;
else
nFileOffset = m_poIdIndex->GetObjPtr(nObjId);
if (nFileOffset == 0)
{
/*---------------------------------------------------------
* Object with no geometry... this is a valid case.
*--------------------------------------------------------*/
m_nCurObjPtr = 0;
m_nCurObjId = nObjId;
m_nCurObjType = TAB_GEOM_NONE;
}
else if ( m_poCurObjBlock->GotoByteInFile(nFileOffset, TRUE) == 0)
{
/*-------------------------------------------------------------
* OK, it worked, read the object type and row id.
*------------------------------------------------------------*/
m_nCurObjPtr = nFileOffset;
m_nCurObjType = m_poCurObjBlock->ReadByte();
m_nCurObjId = m_poCurObjBlock->ReadInt32();
// Do a consistency check...
if (m_nCurObjId != nObjId)
{
CPLError(CE_Failure, CPLE_FileIO,
"Object ID from the .ID file (%d) differs from the value "
"in the .MAP file (%d). File may be corrupt.",
nObjId, m_nCurObjId);
m_nCurObjPtr = m_nCurObjId = m_nCurObjType = -1;
return -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -