📄 tabregion.cpp
字号:
// tabregion.cpp: implementation of the TABRegion class.////////////////////////////////////////////////////////////////////////#include "tabregion.h"#include "ugk_errhandle.h"#include "ugk_memopr.h"#include "ugk_string.h"#include "ugkmultipolygon.h"#include "tabmapobjpline.h"/********************************************************************** * TABRegion::TABRegion() * * Constructor. **********************************************************************/TABRegion::TABRegion(UGKFeatureDefn *poDefnIn): TABFeature(poDefnIn){ m_bCenterIsSet = FALSE; m_bSmooth = FALSE;}/********************************************************************** * TABRegion::~TABRegion() * * Destructor. **********************************************************************/TABRegion::~TABRegion(){}/********************************************************************** * TABRegion::CloneTABFeature() * * Duplicate feature, including stuff specific to each TABFeature type. * * This method calls the generic TABFeature::CopyTABFeatureBase() and * then copies any members specific to its own type. **********************************************************************/TABFeature *TABRegion::CloneTABFeature(UGKFeatureDefn *poNewDefn/*=NULL*/){ /*----------------------------------------------------------------- * Alloc new feature and copy the base stuff *----------------------------------------------------------------*/ TABRegion *poNew = new TABRegion(poNewDefn ? poNewDefn : GetDefnRef()); CopyTABFeatureBase(poNew); /*----------------------------------------------------------------- * And members specific to this class *----------------------------------------------------------------*/ // ITABFeaturePen *(poNew->GetPenDefRef()) = *GetPenDefRef(); // ITABFeatureBrush *(poNew->GetBrushDefRef()) = *GetBrushDefRef(); poNew->m_bSmooth = m_bSmooth; poNew->m_bCenterIsSet = m_bCenterIsSet; poNew->m_dCenterX = m_dCenterX; poNew->m_dCenterY = m_dCenterY; return poNew;}/********************************************************************** * TABRegion::ValidateMapInfoType() * * Check the feature's geometry part and return the corresponding * mapinfo object type code. The m_nMapInfoType member will also * be updated for further calls to GetMapInfoType(); * * Returns TAB_GEOM_NONE if the geometry is not compatible with what * is expected for this object class. **********************************************************************/int TABRegion::ValidateMapInfoType(TABMAPFile *poMapFile /*=NULL*/){ UGKGeometry *poGeom; /*----------------------------------------------------------------- * Fetch and validate geometry *----------------------------------------------------------------*/ poGeom = GetGeometryRef(); if (poGeom && (wkbFlatten(poGeom->getGeometryType()) == wkbPolygon || wkbFlatten(poGeom->getGeometryType()) == wkbMultiPolygon)) { UGKInt32 numPointsTotal=0, numRings=GetNumRings(); for(int i=0; i<numRings; i++) { UGKLinearRing *poRing = GetRingRef(i); if (poRing) numPointsTotal += poRing->getNumPoints(); } if (numPointsTotal > TAB_300_MAX_VERTICES) m_nMapInfoType = TAB_GEOM_V450_REGION; else m_nMapInfoType = TAB_GEOM_REGION; } else { UGKError(ET_Failure,UGKErr_AssertionFailed, "TABRegion: Missing or Invalid Geometry!"); m_nMapInfoType = TAB_GEOM_NONE; } /*----------------------------------------------------------------- * Decide if coordinates should be compressed or not. *----------------------------------------------------------------*/ ValidateCoordType(poMapFile); return m_nMapInfoType;}/********************************************************************** * TABRegion::ReadGeometryFromMAPFile() * * Fill the geometry and representation (color, etc...) part of the * feature from the contents of the .MAP object pointed to by poMAPFile. * * It is assumed that poMAPFile currently points to the beginning of * a map object. * * Returns 0 on success, -1 on error, in which case CPLError() will have * been called. **********************************************************************/int TABRegion::ReadGeometryFromMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *poObjHdr){ double dX, dY, dXMin, dYMin, dXMax, dYMax; UGKGeometry *poGeometry; UGKLinearRing *poRing; /*----------------------------------------------------------------- * Fetch and validate geometry type *----------------------------------------------------------------*/ m_nMapInfoType = poObjHdr->m_nType; if (m_nMapInfoType == TAB_GEOM_REGION || m_nMapInfoType == TAB_GEOM_REGION_C || m_nMapInfoType == TAB_GEOM_V450_REGION || m_nMapInfoType == TAB_GEOM_V450_REGION_C ) { /*============================================================= * REGION (Similar to PLINE MULTIPLE) *============================================================*/ int i, iSection; UGKInt32 nCoordBlockPtr, numLineSections, nCenterX, nCenterY; UGKInt32 nCoordDataSize, numPointsTotal, *panXY; TABMAPCoordBlock *poCoordBlock; UGKMultiPolygon *poMultiPolygon = NULL; UGKPolygon *poPolygon = NULL; TABMAPCoordSecHdr *pasSecHdrs; UGKBool bComprCoord = poObjHdr->IsCompressedType(); UGKBool bV450 = (m_nMapInfoType == TAB_GEOM_V450_REGION || m_nMapInfoType == TAB_GEOM_V450_REGION_C); /*------------------------------------------------------------- * Copy data from poObjHdr *------------------------------------------------------------*/ TABMAPObjPLine *poPLineHdr = (TABMAPObjPLine *)poObjHdr; nCoordBlockPtr = poPLineHdr->m_nCoordBlockPtr; nCoordDataSize = poPLineHdr->m_nCoordDataSize; numLineSections = poPLineHdr->m_numLineSections; m_bSmooth = poPLineHdr->m_bSmooth; // Centroid/label point poMapFile->Int2Coordsys(poPLineHdr->m_nLabelX, poPLineHdr->m_nLabelY, dX, dY); SetCenter(dX, dY); // Compressed coordinate origin (useful only in compressed case!) nCenterX = poPLineHdr->m_nComprOrgX; nCenterY = poPLineHdr->m_nComprOrgY; // MBR(Minimum Bounding Rectangle). poMapFile->Int2Coordsys(poPLineHdr->m_nMinX, poPLineHdr->m_nMinY, dXMin, dYMin); poMapFile->Int2Coordsys(poPLineHdr->m_nMaxX, poPLineHdr->m_nMaxY, dXMax, dYMax); m_nPenDefIndex = poPLineHdr->m_nPenId; // Pen index poMapFile->ReadPenDef(m_nPenDefIndex, &m_sPenDef); m_nBrushDefIndex = poPLineHdr->m_nBrushId; // Brush index poMapFile->ReadBrushDef(m_nBrushDefIndex, &m_sBrushDef); /*------------------------------------------------------------- * Read data from the coord. block *------------------------------------------------------------*/ pasSecHdrs = (TABMAPCoordSecHdr*)UGK_Malloc(numLineSections* sizeof(TABMAPCoordSecHdr)); poCoordBlock = poMapFile->GetCoordBlock(nCoordBlockPtr); if (poCoordBlock) poCoordBlock->SetComprCoordOrigin(nCenterX, nCenterY); if (poCoordBlock == NULL || poCoordBlock->ReadCoordSecHdrs(bComprCoord, bV450, numLineSections, pasSecHdrs, numPointsTotal) != 0) { UGKError(ET_Failure, UGKErr_FileIO, "Failed reading coordinate data at offset %d", nCoordBlockPtr); UGK_Free(pasSecHdrs); return -1; } panXY = (UGKInt32*)UGK_Malloc(numPointsTotal*2*sizeof(UGKInt32)); if (poCoordBlock->ReadIntCoords(bComprCoord,numPointsTotal,panXY) != 0) { UGKError(ET_Failure, UGKErr_FileIO, "Failed reading coordinate data at offset %d", nCoordBlockPtr); UGK_Free(pasSecHdrs); UGK_Free(panXY); return -1; } /*------------------------------------------------------------- * Decide if we should return an UGKPolygon or an UGKMultiPolygon * depending on the number of outer rings found in CoordSecHdr blocks. * The CoodSecHdr block for each outer ring in the region has a flag * indicating the number of inner rings that follow. * In older versions of the format, the count of inner rings was * always zero, so in this case we would always return MultiPolygons. * * Note: The current implementation assumes that there cannot be * holes inside holes (i.e. multiple levels of inner rings)... if * that case was encountered then we would return an UGKMultiPolygon * in which the topological relationship between the rings would * be lost. *------------------------------------------------------------*/ int numOuterRings = 0; for(iSection=0; iSection<numLineSections; iSection++) { // Count this as an outer ring. numOuterRings++; // Skip inner rings... so loop continues on an outer ring. iSection += pasSecHdrs[iSection].numHoles; } if (numOuterRings > 1) poGeometry = poMultiPolygon = new UGKMultiPolygon; else poGeometry = NULL; // Will be set later /*------------------------------------------------------------- * OK, build the UGKGeometry object. *------------------------------------------------------------*/ int numHolesToRead = 0; poPolygon = NULL; for(iSection=0; iSection<numLineSections; iSection++) { UGKInt32 *pnXYPtr; int numSectionVertices; if (poPolygon == NULL) poPolygon = new UGKPolygon(); if (numHolesToRead < 1) numHolesToRead = pasSecHdrs[iSection].numHoles; else numHolesToRead--; numSectionVertices = pasSecHdrs[iSection].numVertices; pnXYPtr = panXY + (pasSecHdrs[iSection].nVertexOffset * 2); poRing = new UGKLinearRing(); poRing->setNumPoints(numSectionVertices); for(i=0; i<numSectionVertices; i++) { poMapFile->Int2Coordsys(*pnXYPtr, *(pnXYPtr+1), dX, dY); poRing->setPoint(i, dX, dY); pnXYPtr += 2; } poPolygon->addRingDirectly(poRing); poRing = NULL; if (numHolesToRead < 1) { if (numOuterRings > 1) { poMultiPolygon->addGeometryDirectly(poPolygon); } else { poGeometry = poPolygon; assert(iSection == numLineSections-1); } poPolygon = NULL; // We'll alloc a new polygon next loop. } } UGK_Free(pasSecHdrs); UGK_Free(panXY); } else { UGKError(ET_Failure, UGKErr_AssertionFailed, "ReadGeometryFromMAPFile(): unsupported geometry type %d (0x%2.2x)", m_nMapInfoType, m_nMapInfoType); return -1; } SetGeometryDirectly(poGeometry); SetMBR(dXMin, dYMin, dXMax, dYMax); return 0;}/********************************************************************** * TABRegion::WriteGeometryToMAPFile() * * Write the geometry and representation (color, etc...) part of the * feature to the .MAP object pointed to by poMAPFile. * * It is assumed that poMAPFile currently points to a valid map object. * * Returns 0 on success, -1 on error, in which case CPLError() will have * been called. **********************************************************************/int TABRegion::WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *poObjHdr){ UGKInt32 nX, nY; UGKGeometry *poGeom; /*----------------------------------------------------------------- * We assume that ValidateMapInfoType() was called already and that * the type in poObjHdr->m_nType is valid. *----------------------------------------------------------------*/ assert(m_nMapInfoType == poObjHdr->m_nType); /*----------------------------------------------------------------- * Fetch and validate geometry *----------------------------------------------------------------*/ poGeom = GetGeometryRef(); if (poGeom && (wkbFlatten(poGeom->getGeometryType()) == wkbPolygon || wkbFlatten(poGeom->getGeometryType()) == wkbMultiPolygon)) { /*============================================================= * REGIONs are similar to PLINE MULTIPLE * * We accept both UGKPolygons (with one or multiple rings) and * UGKMultiPolygons as input. *============================================================*/ int nStatus=0, i, iRing; int numRingsTotal; UGKUInt32 nCoordDataSize; UGKInt32 nCoordBlockPtr; TABMAPCoordBlock *poCoordBlock; TABMAPCoordSecHdr *pasSecHdrs = NULL; UGKBool bCompressed = poObjHdr->IsCompressedType(); /*------------------------------------------------------------- * Process geometry first... *------------------------------------------------------------*/ poCoordBlock = poMapFile->GetCurCoordBlock(); poCoordBlock->StartNewFeature(); nCoordBlockPtr = poCoordBlock->GetCurAddress(); poCoordBlock->SetComprCoordOrigin(m_nComprOrgX, m_nComprOrgY); /*------------------------------------------------------------- * Fetch total number of rings and build array of coord * sections headers. *------------------------------------------------------------*/ numRingsTotal = ComputeNumRings(&pasSecHdrs, poMapFile); if (numRingsTotal == 0) nStatus = -1; /*------------------------------------------------------------- * Write the Coord. Section Header *------------------------------------------------------------*/ UGKBool bV450 = (m_nMapInfoType == TAB_GEOM_V450_REGION || m_nMapInfoType == TAB_GEOM_V450_REGION_C); if (nStatus == 0) nStatus = poCoordBlock->WriteCoordSecHdrs(bV450, numRingsTotal, pasSecHdrs, bCompressed); UGK_Free(pasSecHdrs); pasSecHdrs = NULL; if (nStatus != 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -