📄 mitab_feature_mif.cpp
字号:
* * Fill the geometry and representation (color, etc...) part of the * feature from the contents of the .MIF file * * Returns 0 on success, -1 on error, in which case CPLError() will have * been called. **********************************************************************/int TABRegion::ReadGeometryFromMIFFile(MIDDATAFile *fp){ double dX, dY; OGRLinearRing *poRing; OGRGeometry *poGeometry = NULL; OGRPolygon *poPolygon = NULL; OGRMultiPolygon *poMultiPolygon = NULL; int i,iSection, numLineSections=0; char **papszToken; const char *pszLine; OGREnvelope sEnvelope; m_bSmooth = FALSE; /*============================================================= * REGION (Similar to PLINE MULTIPLE) *============================================================*/ papszToken = CSLTokenizeString2(fp->GetLastLine(), " \t", CSLT_HONOURSTRINGS); if (CSLCount(papszToken) ==2) numLineSections = atoi(papszToken[1]); CSLDestroy(papszToken); papszToken = NULL; /*------------------------------------------------------------- * For 1-ring regions, we return an OGRPolygon with one single * OGRLinearRing geometry. * * REGIONs with multiple rings are returned as OGRMultiPolygon * instead of as OGRPolygons since OGRPolygons require that the * first ring be the outer ring, and the other all be inner * rings, but this is not guaranteed inside MapInfo files. *------------------------------------------------------------*/ if (numLineSections > 1) poGeometry = poMultiPolygon = new OGRMultiPolygon; else poGeometry = NULL; // Will be set later for(iSection=0; iSection<numLineSections; iSection++) { int numSectionVertices = 0; poPolygon = new OGRPolygon(); if ((pszLine = fp->GetLine()) != NULL) { numSectionVertices = atoi(pszLine); } poRing = new OGRLinearRing(); poRing->setNumPoints(numSectionVertices); for(i=0; i<numSectionVertices; i++) { pszLine = fp->GetLine(); if (pszLine) { papszToken = CSLTokenizeStringComplex(pszLine," ,\t", TRUE,FALSE); if (CSLCount(papszToken) == 2) { dX = fp->GetXTrans(atof(papszToken[0])); dY = fp->GetYTrans(atof(papszToken[1])); poRing->setPoint(i, dX, dY); } CSLDestroy(papszToken); papszToken = NULL; } } poPolygon->addRingDirectly(poRing); poRing = NULL; if (numLineSections > 1) poMultiPolygon->addGeometryDirectly(poPolygon); else poGeometry = poPolygon; poPolygon = NULL; } SetGeometryDirectly(poGeometry); poGeometry->getEnvelope(&sEnvelope); SetMBR(sEnvelope.MinX, sEnvelope.MinY, sEnvelope.MaxX, sEnvelope.MaxY); while (((pszLine = fp->GetLine()) != NULL) && fp->IsValidFeature(pszLine) == FALSE) { papszToken = CSLTokenizeStringComplex(pszLine,"() ,", TRUE,FALSE); if (CSLCount(papszToken) > 1) { if (EQUALN(papszToken[0],"PEN",3)) { if (CSLCount(papszToken) == 4) { SetPenWidthMIF(atoi(papszToken[1])); SetPenPattern(atoi(papszToken[2])); SetPenColor(atoi(papszToken[3])); } } else if (EQUALN(papszToken[0],"BRUSH", 5)) { if (CSLCount(papszToken) >= 3) { SetBrushFGColor(atoi(papszToken[2])); SetBrushPattern(atoi(papszToken[1])); if (CSLCount(papszToken) == 4) SetBrushBGColor(atoi(papszToken[3])); else SetBrushTransparent(TRUE); } } else if (EQUALN(papszToken[0],"CENTER",6)) { if (CSLCount(papszToken) == 3) { SetCenter(fp->GetXTrans(atof(papszToken[1])), fp->GetYTrans(atof(papszToken[2])) ); } } } CSLDestroy(papszToken); papszToken = NULL; } return 0; } /********************************************************************** * TABRegion::WriteGeometryToMIFFile() * * Write the geometry and representation (color, etc...) part of the * feature to the .MIF file * * Returns 0 on success, -1 on error, in which case CPLError() will have * been called. **********************************************************************/int TABRegion::WriteGeometryToMIFFile(MIDDATAFile *fp){ OGRGeometry *poGeom; poGeom = GetGeometryRef(); if (poGeom && (wkbFlatten(poGeom->getGeometryType()) == wkbPolygon || wkbFlatten(poGeom->getGeometryType()) == wkbMultiPolygon ) ) { /*============================================================= * REGIONs are similar to PLINE MULTIPLE * * We accept both OGRPolygons (with one or multiple rings) and * OGRMultiPolygons as input. *============================================================*/ int i, iRing, numRingsTotal, numPoints; numRingsTotal = GetNumRings(); fp->WriteLine("Region %d\n",numRingsTotal); for(iRing=0; iRing < numRingsTotal; iRing++) { OGRLinearRing *poRing; poRing = GetRingRef(iRing); if (poRing == NULL) { CPLError(CE_Failure, CPLE_AssertionFailed, "TABRegion: Object Geometry contains NULL rings!"); return -1; } numPoints = poRing->getNumPoints(); fp->WriteLine(" %d\n",numPoints); for(i=0; i<numPoints; i++) { fp->WriteLine("%.16g %.16g\n",poRing->getX(i), poRing->getY(i)); } } if (GetPenPattern()) fp->WriteLine(" Pen (%d,%d,%d)\n", GetPenWidthMIF(),GetPenPattern(), GetPenColor()); if (GetBrushPattern()) { if (GetBrushTransparent() == 0) fp->WriteLine(" Brush (%d,%d,%d)\n",GetBrushPattern(), GetBrushFGColor(),GetBrushBGColor()); else fp->WriteLine(" Brush (%d,%d)\n",GetBrushPattern(), GetBrushFGColor()); } if (m_bCenterIsSet) { fp->WriteLine(" Center %.16g %.16g\n", m_dCenterX, m_dCenterY); } } else { CPLError(CE_Failure, CPLE_AssertionFailed, "TABRegion: Object contains an invalid Geometry!"); return -1; } return 0; }/********************************************************************** * **********************************************************************/int TABRectangle::ReadGeometryFromMIFFile(MIDDATAFile *fp){ const char *pszLine; char **papszToken; double dXMin, dYMin, dXMax, dYMax; OGRPolygon *poPolygon; OGRLinearRing *poRing; papszToken = CSLTokenizeString2(fp->GetLastLine(), " \t", CSLT_HONOURSTRINGS); if (CSLCount(papszToken) < 5) { CSLDestroy(papszToken); return -1; } dXMin = fp->GetXTrans(atof(papszToken[1])); dXMax = fp->GetXTrans(atof(papszToken[3])); dYMin = fp->GetYTrans(atof(papszToken[2])); dYMax = fp->GetYTrans(atof(papszToken[4])); /*----------------------------------------------------------------- * Call SetMBR() and GetMBR() now to make sure that min values are * really smaller than max values. *----------------------------------------------------------------*/ SetMBR(dXMin, dYMin, dXMax, dYMax); GetMBR(dXMin, dYMin, dXMax, dYMax); m_bRoundCorners = FALSE; m_dRoundXRadius = 0.0; m_dRoundYRadius = 0.0; if (EQUALN(papszToken[0],"ROUNDRECT",9)) { m_bRoundCorners = TRUE; if (CSLCount(papszToken) == 6) m_dRoundXRadius = m_dRoundYRadius = atof(papszToken[5])/2.0; else { CSLDestroy(papszToken); papszToken = CSLTokenizeString2(fp->GetLine(), " \t", CSLT_HONOURSTRINGS); if (CSLCount(papszToken) !=1 ) m_dRoundXRadius = m_dRoundYRadius = atof(papszToken[1])/2.0; } } CSLDestroy(papszToken); papszToken = NULL; /*----------------------------------------------------------------- * Create and fill geometry object *----------------------------------------------------------------*/ poPolygon = new OGRPolygon; poRing = new OGRLinearRing(); if (m_bRoundCorners && m_dRoundXRadius != 0.0 && m_dRoundYRadius != 0.0) { /*------------------------------------------------------------- * For rounded rectangles, we generate arcs with 45 line * segments for each corner. We start with lower-left corner * and proceed counterclockwise * We also have to make sure that rounding radius is not too * large for the MBR however, we * always return the true X/Y radius (not adjusted) since this * is the way MapInfo seems to do it when a radius bigger than * the MBR is passed from TBA to MIF. *------------------------------------------------------------*/ double dXRadius = MIN(m_dRoundXRadius, (dXMax-dXMin)/2.0); double dYRadius = MIN(m_dRoundYRadius, (dYMax-dYMin)/2.0); TABGenerateArc(poRing, 45, dXMin + dXRadius, dYMin + dYRadius, dXRadius, dYRadius, PI, 3.0*PI/2.0); TABGenerateArc(poRing, 45, dXMax - dXRadius, dYMin + dYRadius, dXRadius, dYRadius, 3.0*PI/2.0, 2.0*PI); TABGenerateArc(poRing, 45, dXMax - dXRadius, dYMax - dYRadius, dXRadius, dYRadius, 0.0, PI/2.0); TABGenerateArc(poRing, 45, dXMin + dXRadius, dYMax - dYRadius, dXRadius, dYRadius, PI/2.0, PI); TABCloseRing(poRing); } else { poRing->addPoint(dXMin, dYMin); poRing->addPoint(dXMax, dYMin); poRing->addPoint(dXMax, dYMax); poRing->addPoint(dXMin, dYMax); poRing->addPoint(dXMin, dYMin); } poPolygon->addRingDirectly(poRing); SetGeometryDirectly(poPolygon); while (((pszLine = fp->GetLine()) != NULL) && fp->IsValidFeature(pszLine) == FALSE) { papszToken = CSLTokenizeStringComplex(pszLine,"() ,", TRUE,FALSE); if (CSLCount(papszToken) > 1) { if (EQUALN(papszToken[0],"PEN",3)) { if (CSLCount(papszToken) == 4) { SetPenWidthMIF(atoi(papszToken[1])); SetPenPattern(atoi(papszToken[2])); SetPenColor(atoi(papszToken[3])); } } else if (EQUALN(papszToken[0],"BRUSH", 5)) { if (CSLCount(papszToken) >=3) { SetBrushFGColor(atoi(papszToken[2])); SetBrushPattern(atoi(papszToken[1])); if (CSLCount(papszToken) == 4) SetBrushBGColor(atoi(papszToken[3])); else SetBrushTransparent(TRUE); } } } CSLDestroy(papszToken); papszToken = NULL; } return 0; } /********************************************************************** * **********************************************************************/int TABRectangle::WriteGeometryToMIFFile(MIDDATAFile *fp){ OGRGeometry *poGeom; OGRPolygon *poPolygon; OGREnvelope sEnvelope; /*----------------------------------------------------------------- * Fetch and validate geometry *----------------------------------------------------------------*/ poGeom = GetGeometryRef(); if (poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbPolygon) poPolygon = (OGRPolygon*)poGeom; else { CPLError(CE_Failure, CPLE_AssertionFailed, "TABRectangle: Missing or Invalid Geometry!"); return -1; } /*----------------------------------------------------------------- * Note that we will simply use the rectangle's MBR and don't really * read the polygon geometry... this should be OK unless the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -