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

📄 mitab_mapfile.cpp

📁 GIS系统支持库Geospatial Data Abstraction Library代码.GDAL is a translator library for raster geospatial dat
💻 CPP
📖 第 1 页 / 共 5 页
字号:
 * 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) == 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;        }    }    else    {        /*---------------------------------------------------------         * Failed positioning input file... CPLError has been called.         *--------------------------------------------------------*/        m_nCurObjPtr = m_nCurObjId = m_nCurObjType = -1;        return -1;    }    return 0;}/********************************************************************** *                   TABMAPFile::PrepareNewObj() * * Get ready to write a new object of the specified type and with the  * specified id.   * * m_poCurObjBlock will be set to be ready to receive the new object, and * a new block will be created if necessary (in which case the current  * block contents will be committed to disk, etc.)  The object type and  * row ID will be written to the m_poCurObjBlock, so it will be ready to * receive the first byte of data for this map object.   * * If this object type uses coordinate blocks, then the coordinate block * will be prepared to receive coordinates. * * This function will also take care of updating the .ID index entry for * the new object. * * Note that object ids are positive and start at 1. * * Returns 0 on success, -1 on error. **********************************************************************/int   TABMAPFile::PrepareNewObj(int nObjId, GByte nObjType){    int nObjSize;    m_nCurObjPtr = m_nCurObjId = m_nCurObjType = -1;    if (m_eAccessMode != TABWrite ||         m_poIdIndex == NULL || m_poHeader == NULL)    {        CPLError(CE_Failure, CPLE_AssertionFailed,                 "PrepareNewObj() failed: file not opened for write access.");        return -1;    }    /*-----------------------------------------------------------------     * For objects with no geometry, we just update the .ID file and return     *----------------------------------------------------------------*/    if (nObjType == TAB_GEOM_NONE)    {        m_nCurObjType = nObjType;        m_nCurObjId   = nObjId;        m_nCurObjPtr  = 0;        m_poIdIndex->SetObjPtr(m_nCurObjId, 0);        return 0;    }    /*-----------------------------------------------------------------     * Update count of objects by type in the header block     *----------------------------------------------------------------*/    if (nObjType == TAB_GEOM_SYMBOL ||        nObjType == TAB_GEOM_FONTSYMBOL ||        nObjType == TAB_GEOM_CUSTOMSYMBOL ||        nObjType == TAB_GEOM_SYMBOL_C ||        nObjType == TAB_GEOM_FONTSYMBOL_C ||        nObjType == TAB_GEOM_CUSTOMSYMBOL_C)    {        m_poHeader->m_numPointObjects++;    }    else if (nObjType == TAB_GEOM_LINE ||             nObjType == TAB_GEOM_PLINE ||             nObjType == TAB_GEOM_MULTIPLINE ||             nObjType == TAB_GEOM_V450_MULTIPLINE ||             nObjType == TAB_GEOM_ARC ||             nObjType == TAB_GEOM_LINE_C ||             nObjType == TAB_GEOM_PLINE_C ||             nObjType == TAB_GEOM_MULTIPLINE_C ||             nObjType == TAB_GEOM_V450_MULTIPLINE_C ||             nObjType == TAB_GEOM_ARC_C)    {        m_poHeader->m_numLineObjects++;    }    else if (nObjType == TAB_GEOM_REGION ||             nObjType == TAB_GEOM_V450_REGION ||             nObjType == TAB_GEOM_RECT ||             nObjType == TAB_GEOM_ROUNDRECT ||             nObjType == TAB_GEOM_ELLIPSE ||             nObjType == TAB_GEOM_REGION_C ||             nObjType == TAB_GEOM_V450_REGION_C ||             nObjType == TAB_GEOM_RECT_C ||             nObjType == TAB_GEOM_ROUNDRECT_C ||             nObjType == TAB_GEOM_ELLIPSE_C)    {        m_poHeader->m_numRegionObjects++;    }    else if (nObjType == TAB_GEOM_TEXT ||             nObjType == TAB_GEOM_TEXT_C)    {        m_poHeader->m_numTextObjects++;    }    /*-----------------------------------------------------------------     * Check for V450-specific object types and minimum TAB file version number     *----------------------------------------------------------------*/    if (m_nMinTABVersion < 450 &&        (nObjType == TAB_GEOM_V450_REGION ||         nObjType == TAB_GEOM_V450_MULTIPLINE ||         nObjType == TAB_GEOM_V450_REGION_C ||         nObjType == TAB_GEOM_V450_MULTIPLINE_C) )    {        m_nMinTABVersion = 450;    }    /*-----------------------------------------------------------------     * Check for V460-specific object types (multipoint and collection)     *----------------------------------------------------------------*/    if (m_nMinTABVersion < 650 &&        (nObjType == TAB_GEOM_MULTIPOINT   ||         nObjType == TAB_GEOM_MULTIPOINT_C ||         nObjType == TAB_GEOM_COLLECTION   ||         nObjType == TAB_GEOM_COLLECTION_C    ) )    {        m_nMinTABVersion = 650;    }    /*-----------------------------------------------------------------     * OK, looks like we will need object block... check if it exists and     * create it if it has not been created yet (first time for this file).     * We do not create the object block in the open() call because     * files that contained only "NONE" geometries ended up with empty     * object and spatial index blocks.     * Note: A coord block will be created only if needed later.     *----------------------------------------------------------------*/    if (m_poCurObjBlock == NULL)    {        m_poCurObjBlock = new TABMAPObjectBlock(m_eAccessMode);        int nBlockOffset = m_oBlockManager.AllocNewBlock();        m_poCurObjBlock->InitNewBlock(m_fp, 512, nBlockOffset);        // The reference to the first object block should         // actually go through the index blocks... this will be         // updated when file is closed.        m_poHeader->m_nFirstIndexBlock = nBlockOffset;    }    /*-----------------------------------------------------------------     * Fetch new object size, make sure there is enough room in obj.      * block for new object, and save/create a new one if necessary.     *----------------------------------------------------------------*/    nObjSize = m_poHeader->GetMapObjectSize(nObjType);    if (m_poCurObjBlock->GetNumUnusedBytes() < nObjSize )    {        /*-------------------------------------------------------------         * OK, the new object won't fit in the current block.  Commit         * the current block to disk, and init a new one.         *         * __TODO__ To create an optimum file, we should split the object         * block at this point and update the index blocks... however the         * file should still be usable even if we don't do it.         *------------------------------------------------------------*/        CommitObjBlock(TRUE);    }    /*-----------------------------------------------------------------     * Init member vars and write new object type/id     *----------------------------------------------------------------*/    m_nCurObjType = nObjType;    m_nCurObjId   = nObjId;    m_nCurObjPtr = m_poCurObjBlock->GetFirstUnusedByteOffset();    m_poCurObjBlock->GotoByteInFile(m_nCurObjPtr);    m_poCurObjBlock->WriteByte(m_nCurObjType);    m_poCurObjBlock->WriteInt32(m_nCurObjId);    // Move write pointer to start location of next object (padding with zeros)

⌨️ 快捷键说明

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