📄 tabmapfile.cpp
字号:
* 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) { assert(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) { UGKError(ET_Failure, UGKErr_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)//$zgq { /*------------------------------------------------------------- * 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) { UGKError(ET_Failure, UGKErr_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, UGKByte nObjType){ int nObjSize; m_nCurObjPtr = m_nCurObjId = m_nCurObjType = -1; if (m_eAccessMode != TABWrite || m_poIdIndex == NULL || m_poHeader == NULL) { UGKError(ET_Failure, UGKErr_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) // 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. *----------------------------------------------------------------*/ if (m_poHeader->MapObjectUsesCoordBlock(m_nCurObjType)) { if (m_poCurCoordBlock == NULL) { m_poCurCoordBlock = new TABMAPCoordBlock(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 (UGKGetLastErrorNo() != 0 && UGKGetLastErrorType() == ET_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(UGKBool 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) { UGKError(ET_Failure, UGKErr_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) { UGKInt32 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -