OGRErr OGRDXFLayer::CollectPolylinePath( OGRGeometryCollection *poGC ) { int nCode; char szLineBuf[257]; DXFSmoothPolyline oSmoothPolyline; double dfBulge = 0.0; double dfX = 0.0, dfY = 0.0; int bHaveX = FALSE, bHaveY = FALSE; int bIsClosed = FALSE; int nVertexCount = -1; int bHaveBulges = FALSE; /* -------------------------------------------------------------------- */ /* Read the boundary path type. */ /* -------------------------------------------------------------------- */ while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 ) { if( nVertexCount > 0 && (int) oSmoothPolyline.size() == nVertexCount ) break; switch( nCode ) { case 93: nVertexCount = atoi(szLineBuf); break; case 72: bHaveBulges = atoi(szLineBuf); break; case 73: bIsClosed = atoi(szLineBuf); break; case 10: if( bHaveX && bHaveY ) { oSmoothPolyline.AddPoint(dfX, dfY, 0.0, dfBulge); dfBulge = 0.0; bHaveY = FALSE; } dfX = CPLAtof(szLineBuf); bHaveX = TRUE; break; case 20: if( bHaveX && bHaveY ) { oSmoothPolyline.AddPoint( dfX, dfY, 0.0, dfBulge ); dfBulge = 0.0; bHaveX = bHaveY = FALSE; } dfY = CPLAtof(szLineBuf); bHaveY = TRUE; if( bHaveX && bHaveY && !bHaveBulges ) { oSmoothPolyline.AddPoint( dfX, dfY, 0.0, dfBulge ); dfBulge = 0.0; bHaveX = bHaveY = FALSE; } break; case 42: dfBulge = CPLAtof(szLineBuf); if( bHaveX && bHaveY ) { oSmoothPolyline.AddPoint( dfX, dfY, 0.0, dfBulge ); dfBulge = 0.0; bHaveX = bHaveY = FALSE; } break; default: break; } } if( nCode != 10 && nCode != 20 && nCode != 42 && nCode >= 0) poDS->UnreadValue(); if( bHaveX && bHaveY ) oSmoothPolyline.AddPoint(dfX, dfY, 0.0, dfBulge); if( bIsClosed ) oSmoothPolyline.Close(); poGC->addGeometryDirectly( oSmoothPolyline.Tesselate() ); /* -------------------------------------------------------------------- */ /* Skip through source boundary objects if present. */ /* -------------------------------------------------------------------- */ nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf)); if( nCode != 97 ) { if (nCode < 0) return OGRERR_FAILURE; poDS->UnreadValue(); } else { int iObj, nObjCount = atoi(szLineBuf); for( iObj = 0; iObj < nObjCount; iObj++ ) { if (poDS->ReadValue( szLineBuf, sizeof(szLineBuf) ) < 0) return OGRERR_FAILURE; } } return OGRERR_NONE; }
static OGRErr DWGCollectBoundaryLoop( OdDbHatchPtr poHatch, int iLoop, OGRGeometryCollection *poGC ) { int i; /* -------------------------------------------------------------------- */ /* Handle simple polyline loops. */ /* -------------------------------------------------------------------- */ if( poHatch->loopTypeAt( iLoop ) & OdDbHatch::kPolyline ) { DXFSmoothPolyline oSmoothPolyline; OdGePoint2dArray vertices; OdGeDoubleArray bulges; poHatch->getLoopAt (iLoop, vertices, bulges); for (i = 0; i < (int) vertices.size(); i++) { if( i >= (int) bulges.size() ) oSmoothPolyline.AddPoint( vertices[i].x, vertices[i].y, 0.0, 0.0 ); else oSmoothPolyline.AddPoint( vertices[i].x, vertices[i].y, 0.0, bulges[i] ); } oSmoothPolyline.Close(); OGRLineString *poLS = (OGRLineString *) oSmoothPolyline.Tesselate(); poGC->addGeometryDirectly( poLS ); return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* Handle an edges array. */ /* -------------------------------------------------------------------- */ EdgeArray oEdges; poHatch->getLoopAt( iLoop, oEdges ); for( i = 0; i < (int) oEdges.size(); i++ ) { OdGeCurve2d* poEdge = oEdges[i]; if( poEdge->type() == OdGe::kLineSeg2d ) { OGRLineString *poLS = new OGRLineString(); OdGePoint2d oStart = poEdge->evalPoint(0.0); OdGePoint2d oEnd = poEdge->evalPoint(1.0); poLS->addPoint( oStart.x, oStart.y ); poLS->addPoint( oEnd.x, oEnd.y ); poGC->addGeometryDirectly( poLS ); } else if( poEdge->type() == OdGe::kCircArc2d ) { OdGeCircArc2d* poCircArc = (OdGeCircArc2d*) poEdge; OdGePoint2d oCenter = poCircArc->center(); double dfStartAngle = poCircArc->startAng() * 180 / PI; double dfEndAngle = poCircArc->endAng() * 180 / PI; if( !poCircArc->isClockWise() ) { dfStartAngle *= -1; dfEndAngle *= -1; } else if( dfStartAngle > dfEndAngle ) { dfEndAngle += 360.0; } OGRLineString *poLS = (OGRLineString *) OGRGeometryFactory::approximateArcAngles( oCenter.x, oCenter.y, 0.0, poCircArc->radius(), poCircArc->radius(), 0.0, dfStartAngle, dfEndAngle, 0.0 ); poGC->addGeometryDirectly( poLS ); } else if( poEdge->type() == OdGe::kEllipArc2d ) { OdGeEllipArc2d* poArc = (OdGeEllipArc2d*) poEdge; OdGePoint2d oCenter = poArc->center(); double dfRatio = poArc->minorRadius() / poArc->majorRadius(); OdGeVector2d oMajorAxis = poArc->majorAxis(); double dfRotation; double dfStartAng, dfEndAng; dfRotation = -1 * atan2( oMajorAxis.y, oMajorAxis.x ) * 180 / PI; dfStartAng = poArc->startAng()*180/PI; dfEndAng = poArc->endAng()*180/PI; if( !poArc->isClockWise() ) { dfStartAng *= -1; dfEndAng *= -1; } else if( dfStartAng > dfEndAng ) { dfEndAng += 360.0; } OGRLineString *poLS = (OGRLineString *) OGRGeometryFactory::approximateArcAngles( oCenter.x, oCenter.y, 0.0, poArc->majorRadius(), poArc->minorRadius(), dfRotation, OGRDWGLayer::AngleCorrect(dfStartAng,dfRatio), OGRDWGLayer::AngleCorrect(dfEndAng,dfRatio), 0.0 ); poGC->addGeometryDirectly( poLS ); } else CPLDebug( "DWG", "Unsupported edge type (%d) in hatch loop.", (int) poEdge->type() ); //case OdGe::kNurbCurve2d : dumpNurbCurveEdge(indent + 1, pEdge); } return OGRERR_NONE; }
OGRErr OGRDXFLayer::CollectPolylinePath( OGRGeometryCollection *poGC, const double dfElevation ) { int nCode = 0; char szLineBuf[257]; DXFSmoothPolyline oSmoothPolyline; double dfBulge = 0.0; double dfX = 0.0; double dfY = 0.0; bool bHaveX = false; bool bHaveY = false; bool bIsClosed = false; int nVertexCount = -1; bool bHaveBulges = false; /* -------------------------------------------------------------------- */ /* Read the boundary path type. */ /* -------------------------------------------------------------------- */ while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 ) { if( nVertexCount > 0 && (int) oSmoothPolyline.size() == nVertexCount ) break; switch( nCode ) { case 93: nVertexCount = atoi(szLineBuf); break; case 72: bHaveBulges = CPL_TO_BOOL(atoi(szLineBuf)); break; case 73: bIsClosed = CPL_TO_BOOL(atoi(szLineBuf)); break; case 10: if( bHaveX && bHaveY ) { oSmoothPolyline.AddPoint(dfX, dfY, dfElevation, dfBulge); dfBulge = 0.0; bHaveY = false; } dfX = CPLAtof(szLineBuf); bHaveX = true; break; case 20: if( bHaveX && bHaveY ) { oSmoothPolyline.AddPoint( dfX, dfY, dfElevation, dfBulge ); dfBulge = 0.0; bHaveX = false; } dfY = CPLAtof(szLineBuf); bHaveY = true; if( bHaveX && bHaveY && !bHaveBulges ) { oSmoothPolyline.AddPoint( dfX, dfY, dfElevation, dfBulge ); dfBulge = 0.0; bHaveX = false; bHaveY = false; } break; case 42: dfBulge = CPLAtof(szLineBuf); if( bHaveX && bHaveY ) { oSmoothPolyline.AddPoint( dfX, dfY, dfElevation, dfBulge ); dfBulge = 0.0; bHaveX = false; bHaveY = false; } break; default: break; } } if( nCode < 0 ) { DXF_LAYER_READER_ERROR(); return OGRERR_FAILURE; } if( nCode != 10 && nCode != 20 && nCode != 42 ) poDS->UnreadValue(); if( bHaveX && bHaveY ) oSmoothPolyline.AddPoint(dfX, dfY, dfElevation, dfBulge); if( bIsClosed ) oSmoothPolyline.Close(); if(oSmoothPolyline.IsEmpty()) { return OGRERR_FAILURE; } poGC->addGeometryDirectly( oSmoothPolyline.Tesselate() ); /* -------------------------------------------------------------------- */ /* Skip through source boundary objects if present. */ /* -------------------------------------------------------------------- */ nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf)); if( nCode != 97 ) { if (nCode < 0) return OGRERR_FAILURE; poDS->UnreadValue(); } else { int iObj, nObjCount = atoi(szLineBuf); for( iObj = 0; iObj < nObjCount; iObj++ ) { if (poDS->ReadValue( szLineBuf, sizeof(szLineBuf) ) < 0) return OGRERR_FAILURE; } } return OGRERR_NONE; }