tabmapcoordblock.cpp

来自「linux下一款GIS程序源码」· C++ 代码 · 共 757 行 · 第 1/2 页

CPP
757
字号
// tabmapcoordblock.cpp: implementation of the TABMAPCoordBlock class.////////////////////////////////////////////////////////////////////////#include "tabmapcoordblock.h"#include "ugk_errhandle.h"#include "ugk_memopr.h"#define MAP_COORD_HEADER_SIZE   8/********************************************************************** *                   TABMAPCoordBlock::TABMAPCoordBlock() * * Constructor. **********************************************************************/TABMAPCoordBlock::TABMAPCoordBlock(TABAccess eAccessMode /*= TABRead*/):    TABRawBinBlock(eAccessMode, TRUE){    m_nComprOrgX = m_nComprOrgY = m_nNextCoordBlock = m_numDataBytes = 0;    m_numBlocksInChain = 1;  // Current block counts as 1     m_poBlockManagerRef = NULL;    m_nTotalDataSize = 0;    m_nFeatureDataSize = 0;    m_nFeatureXMin = m_nMinX = 1000000000;    m_nFeatureYMin = m_nMinY = 1000000000;    m_nFeatureXMax = m_nMaxX = -1000000000;    m_nFeatureYMax = m_nMaxY = -1000000000;}/********************************************************************** *                   TABMAPCoordBlock::~TABMAPCoordBlock() * * Destructor. **********************************************************************/TABMAPCoordBlock::~TABMAPCoordBlock(){}/********************************************************************** *                   TABMAPCoordBlock::InitBlockFromData() * * Perform some initialization on the block after its binary data has * been set or changed (or loaded from a file). * * Returns 0 if succesful or -1 if an error happened, in which case  * UGKError() will have been called. **********************************************************************/int     TABMAPCoordBlock::InitBlockFromData(UGKByte *pabyBuf, int nSize,                                          UGKBool bMakeCopy /* = TRUE */,                                         FILE *fpSrc /* = NULL */,                                          int nOffset /* = 0 */){    int nStatus;    /*-----------------------------------------------------------------     * First of all, we must call the base class' InitBlockFromData()     *----------------------------------------------------------------*/    nStatus = TABRawBinBlock::InitBlockFromData(pabyBuf, nSize, bMakeCopy,                                            fpSrc, nOffset);    if (nStatus != 0)           return nStatus;    /*-----------------------------------------------------------------     * Validate block type     *----------------------------------------------------------------*/    if (m_nBlockType != TABMAP_COORD_BLOCK)    {        UGKError(ET_Failure, UGKErr_FileIO,                  "InitBlockFromData(): Invalid Block Type: got %d expected %d",                  m_nBlockType, TABMAP_COORD_BLOCK);        UGK_Free(m_pabyBuf);                return -1;    }    /*-----------------------------------------------------------------     * Init member variables     *----------------------------------------------------------------*/    GotoByteInBlock(0x002);    m_numDataBytes = ReadInt16();       /* Excluding 8 bytes header */    m_nNextCoordBlock = ReadInt32();    /*-----------------------------------------------------------------     * The read ptr is now located at the beginning of the data part.     *----------------------------------------------------------------*/    GotoByteInBlock(MAP_COORD_HEADER_SIZE);    return 0;}/********************************************************************** *                   TABMAPCoordBlock::CommitToFile() * * Commit the current state of the binary block to the file to which  * it has been previously attached. * * This method makes sure all values are properly set in the map object * block header and then calls TABRawBinBlock::CommitToFile() to do * the actual writing to disk. * * Returns 0 if succesful or -1 if an error happened, in which case  * UGKError() will have been called. **********************************************************************/int     TABMAPCoordBlock::CommitToFile(){    int nStatus = 0;    UGKErrorReset();    if ( m_pabyBuf == NULL )    {        UGKError(ET_Failure, UGKErr_AssertionFailed,                   "CommitToFile(): Block has not been initialized yet!");        return -1;    }    /*-----------------------------------------------------------------     * Make sure 8 bytes block header is up to date.     *----------------------------------------------------------------*/    GotoByteInBlock(0x000);    WriteInt16(TABMAP_COORD_BLOCK);    // Block type code    WriteInt16(m_nSizeUsed - MAP_COORD_HEADER_SIZE); // num. bytes used    WriteInt32(m_nNextCoordBlock);    if( UGKGetLastErrorType() == ET_Failure )        nStatus = UGKGetLastErrorNo();    /*-----------------------------------------------------------------     * OK, call the base class to write the block to disk.     *----------------------------------------------------------------*/    if (nStatus == 0)        nStatus = TABRawBinBlock::CommitToFile();    return nStatus;}/********************************************************************** *                   TABMAPCoordBlock::InitNewBlock() * * Initialize a newly created block so that it knows to which file it * is attached, its block size, etc . and then perform any specific  * initialization for this block type, including writing a default  * block header, etc. and leave the block ready to receive data. * * This is an alternative to calling ReadFromFile() or InitBlockFromData() * that puts the block in a stable state without loading any initial * data in it. * * Returns 0 if succesful or -1 if an error happened, in which case  * UGKError() will have been called. **********************************************************************/int     TABMAPCoordBlock::InitNewBlock(FILE *fpSrc, int nBlockSize,                                         int nFileOffset /* = 0*/){    UGKErrorReset();    /*-----------------------------------------------------------------     * Start with the default initialisation     *----------------------------------------------------------------*/    if ( TABRawBinBlock::InitNewBlock(fpSrc, nBlockSize, nFileOffset) != 0)        return -1;    /*-----------------------------------------------------------------     * And then set default values for the block header.     *     * IMPORTANT: Do not reset m_nComprOrg here because its value needs to be     * maintained between blocks in the same chain.     *----------------------------------------------------------------*/    m_nNextCoordBlock = 0;     m_numDataBytes = 0;    // m_nMin/Max are used to keep track of current block MBR    // FeatureMin/Max should not be reset here since feature coords can    // be split on several blocks    m_nMinX = 1000000000;    m_nMinY = 1000000000;    m_nMaxX = -1000000000;    m_nMaxY = -1000000000;    if (m_eAccess != TABRead)    {        GotoByteInBlock(0x000);        WriteInt16(TABMAP_COORD_BLOCK); // Block type code        WriteInt16(0);                  // num. bytes used, excluding header        WriteInt32(0);                  // Pointer to next coord block    }    if (UGKGetLastErrorType() == ET_Failure )        return -1;    return 0;}/********************************************************************** *                   TABMAPObjectBlock::SetNextCoordBlock() * * Set the address (offset from beginning of file) of the coord. block * that follows the current one. **********************************************************************/void     TABMAPCoordBlock::SetNextCoordBlock(UGKInt32 nNextCoordBlockAddress){    m_nNextCoordBlock = nNextCoordBlockAddress;}/********************************************************************** *                   TABMAPObjectBlock::SetComprCoordOrigin() * * Set the Compressed integer coordinates space origin to be used when * reading compressed coordinates using ReadIntCoord(). **********************************************************************/void     TABMAPCoordBlock::SetComprCoordOrigin(UGKInt32 nX, UGKInt32 nY){    m_nComprOrgX = nX;    m_nComprOrgY = nY;}/********************************************************************** *                   TABMAPObjectBlock::ReadIntCoord() * * Read the next pair of integer coordinates value from the block, and * apply the translation relative to the origin of the coord. space * previously set using SetComprCoordOrigin() if bCompressed=TRUE. * * This means that the returned coordinates are always absolute integer * coordinates, even when the source coords are in compressed form. * * Returns 0 if succesful or -1 if an error happened, in which case  * UGKError() will have been called. **********************************************************************/int     TABMAPCoordBlock::ReadIntCoord(UGKBool bCompressed,                                         UGKInt32 &nX, UGKInt32 &nY){    if (bCompressed)    {           nX = m_nComprOrgX + ReadInt16();        nY = m_nComprOrgY + ReadInt16();    }    else    {        nX = ReadInt32();        nY = ReadInt32();    }    if (UGKGetLastErrorType() == ET_Failure)        return -1;    return 0;}/********************************************************************** *                   TABMAPObjectBlock::ReadIntCoords() * * Read the specified number of pairs of X,Y integer coordinates values * from the block, and apply the translation relative to the origin of * the coord. space previously set using SetComprCoordOrigin() if  * bCompressed=TRUE. * * This means that the returned coordinates are always absolute integer * coordinates, even when the source coords are in compressed form. * * panXY should point to an array big enough to receive the specified * number of coordinates. * * Returns 0 if succesful or -1 if an error happened, in which case  * UGKError() will have been called. **********************************************************************/int     TABMAPCoordBlock::ReadIntCoords(UGKBool bCompressed, int numCoordPairs,                                         UGKInt32 *panXY){    int i, numValues = numCoordPairs*2;    if (bCompressed)    {           for(i=0; i<numValues; i+=2)        {            panXY[i]   = m_nComprOrgX + ReadInt16();            panXY[i+1] = m_nComprOrgY + ReadInt16();            if (UGKGetLastErrorType() != 0)                return -1;        }    }    else    {        for(i=0; i<numValues; i+=2)        {            panXY[i]   = ReadInt32();            panXY[i+1] = ReadInt32();            if (UGKGetLastErrorType() != 0)                return -1;        }    }    return 0;}/********************************************************************** *                   TABMAPObjectBlock::ReadCoordSecHdrs() * * Read a set of coordinate section headers for PLINE MULTIPLE or REGIONs * and store the result in the array of structures pasHdrs[].  It is assumed * that pasHdrs points to an allocated array of at least numSections  * TABMAPCoordSecHdr structures. * * The function will also set the values of numVerticesTotal to the  * total number of coordinates in the object (the sum of all sections  * headers read). * * At the end of the call, this TABMAPCoordBlock object will be located * at the beginning of the coordinate data. * * In V450 the numVertices is stored on an int32 instead of an int16 * * IMPORTANT: This function makes the assumption that coordinates for all *            the sections are grouped together immediately after the *            last section header block (i.e. that the coord. data is not *            located all over the place).  If it is not the case then *            an error will be produced and the code to read region and *            multipline objects will have to be updated.  * * Returns 0 if succesful or -1 if an error happened, in which case  * UGKError() will have been called. **********************************************************************/int     TABMAPCoordBlock::ReadCoordSecHdrs(UGKBool bCompressed,                                            UGKBool bV450Hdr,                                           int numSections,                                           TABMAPCoordSecHdr *pasHdrs,                                           UGKInt32    &numVerticesTotal){    int i, nTotalHdrSizeUncompressed;    UGKErrorReset();    /*-------------------------------------------------------------     * Note about header+vertices size vs compressed coordinates:     * The uncompressed header sections are actually 16 bytes, but the     * offset calculations are based on prior decompression of the      * coordinates.  Our coordinate offset calculations have     * to take this fact into account.     * Also, V450 header section uses int32 instead of int16 for numVertices     * and we add another 2 bytes to align with a 4 bytes boundary.     *------------------------------------------------------------*/	 /* 说明:	 * 对于压缩坐标,如果是V450,header只有18字节,非压缩坐标,也只有26字节	 * 如果不是V450,压缩坐标只有16字节,非压缩坐标有24字节	 * 但是文件中算偏移时估计就是采用的就是下面这种:	 * v450时,header为28字节,非v450时为24字节	 */    if (bV450Hdr)        nTotalHdrSizeUncompressed = 28 * numSections;    else        nTotalHdrSizeUncompressed = 24 * numSections;    numVerticesTotal = 0;

⌨️ 快捷键说明

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