?? mitab_mapfile.cpp
字號(hào):
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) // Nothing will get written to the object block until CommitToFile() // is called. m_poCurObjBlock->WriteZeros(m_poHeader->GetMapObjectSize(nObjType) - 5); /*----------------------------------------------------------------- * Update .ID Index *----------------------------------------------------------------*/ m_poIdIndex->SetObjPtr(m_nCurObjId, m_nCurObjPtr); /*----------------------------------------------------------------- * Prepare Coords block... * create a new TABMAPCoordBlock if it was not done yet. * Note that in write mode, TABCollections require read/write access * to the coord block. *----------------------------------------------------------------*/ if (m_poHeader->MapObjectUsesCoordBlock(m_nCurObjType)) { if (m_poCurCoordBlock == NULL) { m_poCurCoordBlock = new TABMAPCoordBlock(m_eAccessMode==TABWrite? TABReadWrite: m_eAccessMode); m_poCurCoordBlock->InitNewBlock(m_fp, 512, m_oBlockManager.AllocNewBlock()); m_poCurCoordBlock->SetMAPBlockManagerRef(&m_oBlockManager); // Set the references to this coord block in the MAPObjBlock m_poCurObjBlock->AddCoordBlockRef(m_poCurCoordBlock-> GetStartAddress()); } if (m_poCurCoordBlock->GetNumUnusedBytes() < 4) { int nNewBlockOffset = m_oBlockManager.AllocNewBlock(); m_poCurCoordBlock->SetNextCoordBlock(nNewBlockOffset); m_poCurCoordBlock->CommitToFile(); m_poCurCoordBlock->InitNewBlock(m_fp, 512, nNewBlockOffset); } } if (CPLGetLastErrorNo() != 0 && CPLGetLastErrorType() == CE_Failure) return -1; return 0;}/********************************************************************** * TABMAPFile::CommitObjBlock() * * Commit the TABMAPObjBlock and TABMAPCoordBlock to disk after updating * the references to each other and in the TABMAPIndex block. * * After the Commit() call, the ObjBlock and others will be reinitialized * and ready to receive new objects. (only if bInitNewBlock==TRUE) * * Returns 0 on success, -1 on error. **********************************************************************/int TABMAPFile::CommitObjBlock(GBool bInitNewBlock /*=TRUE*/){ int nStatus = 0; /*----------------------------------------------------------------- * First check that a objBlock has been created. It is possible to have * no object block in files that contain only "NONE" geometries. *----------------------------------------------------------------*/ if (m_poCurObjBlock == NULL) return 0; if (m_eAccessMode != TABWrite) { CPLError(CE_Failure, CPLE_AssertionFailed, "CommitObjBlock() failed: file not opened for write access."); return -1; } /*----------------------------------------------------------------- * We need to flush the coord block if there was one * since a list of coord blocks can belong to only one obj. block *----------------------------------------------------------------*/ if (m_poCurCoordBlock) { // Update the m_nMaxCoordBufSize member in the header block // int nTotalCoordSize = m_poCurCoordBlock->GetNumBlocksInChain()*512; if (nTotalCoordSize > m_poHeader->m_nMaxCoordBufSize) m_poHeader->m_nMaxCoordBufSize = nTotalCoordSize; // Update the references to this coord block in the MAPObjBlock // m_poCurObjBlock->AddCoordBlockRef(m_poCurCoordBlock-> GetStartAddress()); nStatus = m_poCurCoordBlock->CommitToFile(); delete m_poCurCoordBlock; m_poCurCoordBlock = NULL; } /*----------------------------------------------------------------- * Commit the obj block. *----------------------------------------------------------------*/ if (nStatus == 0) nStatus = m_poCurObjBlock->CommitToFile(); /*----------------------------------------------------------------- * Update the spatial index * * Spatial index will be created here if it was not done yet. *----------------------------------------------------------------*/ if (nStatus == 0) { GInt32 nXMin, nYMin, nXMax, nYMax; if (m_poSpIndex == NULL) { // Spatial Index not created yet... m_poSpIndex = new TABMAPIndexBlock(m_eAccessMode); m_poSpIndex->InitNewBlock(m_fp, 512, m_oBlockManager.AllocNewBlock()); m_poSpIndex->SetMAPBlockManagerRef(&m_oBlockManager); m_poHeader->m_nFirstIndexBlock = m_poSpIndex->GetNodeBlockPtr(); } m_poCurObjBlock->GetMBR(nXMin, nYMin, nXMax, nYMax); nStatus = m_poSpIndex->AddEntry(nXMin, nYMin, nXMax, nYMax, m_poCurObjBlock->GetStartAddress()); m_poHeader->m_nMaxSpIndexDepth = MAX(m_poHeader->m_nMaxSpIndexDepth, m_poSpIndex->GetCurMaxDepth()+1); } /*----------------------------------------------------------------- * Reinitialize the obj block only if requested *----------------------------------------------------------------*/ if (bInitNewBlock && nStatus == 0) { nStatus = m_poCurObjBlock->InitNewBlock(m_fp,512, m_oBlockManager.AllocNewBlock()); } return nStatus;}/********************************************************************** * TABMAPFile::GetCurObjType() * * Return the MapInfo object type of the object that the m_poCurObjBlock * is pointing to. This value is set after a call to MoveToObjId(). * * Returns a value >= 0 on success, -1 on error. **********************************************************************/int TABMAPFile::GetCurObjType(){ return m_nCurObjType;}/********************************************************************** * TABMAPFile::GetCurObjId() * * Return the MapInfo object id of the object that the m_poCurObjBlock * is pointing to. This value is set after a call to MoveToObjId(). * * Returns a value >= 0 on success, -1 on error. **********************************************************************/int TABMAPFile::GetCurObjId(){ return m_nCurObjId;}/********************************************************************** * TABMAPFile::GetCurObjBlock() * * Return the m_poCurObjBlock. If MoveToObjId() has previously been * called then m_poCurObjBlock points to the beginning of the current * object data. * * Returns a reference to an object owned by this TABMAPFile object, or * NULL on error. **********************************************************************/TABMAPObjectBlock *TABMAPFile::GetCurObjBlock(){ return m_poCurObjBlock;}/********************************************************************** * TABMAPFile::GetCurCoordBlock() * * Return the m_poCurCoordBlock. This function should be used after * PrepareNewObj() to get the reference to the coord block that has * just been initialized. * * Returns a reference to an object owned by this TABMAPFile object, or * NULL on error. **********************************************************************/TABMAPCoordBlock *TABMAPFile::GetCurCoordBlock(){ return m_poCurCoordBlock;}/********************************************************************** * TABMAPFile::GetCoordBlock() * * Return a TABMAPCoordBlock object ready to read coordinates from it. * The block that contains nFileOffset will automatically be * loaded, and if nFileOffset is the beginning of a new block then the * pointer will be moved to the beginning of the data. * * The contents of the returned object is only valid until the next call * to GetCoordBlock(). * * Returns a reference to an object owned by this TABMAPFile object, or * NULL on error. **********************************************************************/TABMAPCoordBlock *TABMAPFile::GetCoordBlock(int nFileOffset){ if (m_eAccessMode != TABRead) return NULL; if (m_poCurCoordBlock == NULL) { m_poCurCoordBlock = new TABMAPCoordBlock(m_eAccessMode); m_poCurCoordBlock->InitNewBlock(m_fp, 512); } /*----------------------------------------------------------------- * Use GotoByteInFile() to go to the requested location. This will * force loading the block if necessary and reading its header. * If nFileOffset is at the beginning of the requested block, then * we make sure to move the read pointer past the 8 bytes header * to be ready to read coordinates data *----------------------------------------------------------------*/ if ( m_poCurCoordBlock->GotoByteInFile(nFileOffset) != 0) { // Failed... an error has already been reported. return NULL; } if (nFileOffset % 512 == 0) m_poCurCoordBlock->GotoByteInBlock(8); // Skip Header return m_poCurCoordBlock;}/********************************************************************** * TABMAPFile::GetHeaderBlock() * * Return a reference to the MAP file's header block. * * The returned pointer is a reference to an object owned by this TABMAPFile * object and should not be deleted by the caller. * * Return NULL if file has not been opened yet. **********************************************************************/TABMAPHeaderBlock *TABMAPFile::GetHeaderBlock(){ return m_poHeader;}/********************************************************************** * TABMAPFile::GetIDFileRef() * * Return a reference to the .ID file attached to this .MAP file * * The returned pointer is a reference to an object owned by this TABMAPFile * object and should not be deleted by the caller. * * Return NULL if file has not been opened yet. **********************************************************************/TABIDFile *TABMAPFile::GetIDFileRef(){ return m_poIdIndex;}/********************************************************************** * TABMAPFile::GetIndexBlock() * * Return a reference to the requested index or object block.. * * Ownership of the returned block is turned over to the caller, who should * delete it when no longer needed. The type of the block can be determined * with the GetBlockType() method. * * @param nFileOffset the offset in the map file of the spatial index * block or object block to load. * * @return The requested TABMAPIndexBlock, TABMAPObjectBlock or NULL if the * read fails for some reason. **********************************************************************/TABRawBinBlock *TABMAPFile::GetIndexObjectBlock( int nFileOffset ){ /*---------------------------------------------------------------- * Read from the file *---------------------------------------------------------------*/ GByte abyData[512]; if (VSIFSeek(m_fp, nFileOffset, SEEK_SET) != 0 || VSIFRead(abyData, sizeof(GByte), 512, m_fp) != 512 ) { CPLError(CE_Failure, CPLE_FileIO, "GetIndexBlock() failed reading %d bytes at offset %d.", 512, nFileOffset); return NULL; }/* -------------------------------------------------------------------- *//* Create and initialize depending on the block type. *//* -------------------------------------------------------------------- */ int nBlockType = abyData[0]; TABRawBinBlock *poBlock; if( nBlockType == TABMAP_INDEX_BLOCK ) poBlock = new TABMAPIndexBlock(); else poBlock = new TABMAPObjectBlock(); if( poBlock->InitBlockFromData(abyData,512,TRUE,m_fp,nFileOffset) == -1 ) { delete poBlock; poBlock = NULL; } return poBlock;}/********************************************************************** * TABMAPFile::InitDrawingTools() * * Init the drawing tools for this file. * * In Read mode, this will load the drawing tools from the file. * * In Write mode, this function will init an empty the tool def table. * * Reutrns 0 on success, -1 on error. **********************************************************************/int TABMAPFile::InitDrawingTools()
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -