OGRDXFFeature *OGRDXFBlocksLayer::GetNextUnfilteredFeature() { OGRDXFFeature *poFeature = nullptr; /* -------------------------------------------------------------------- */ /* If we have pending features, return one of them. */ /* -------------------------------------------------------------------- */ if( !apoPendingFeatures.empty() ) { poFeature = apoPendingFeatures.front(); apoPendingFeatures.pop(); poFeature->SetFID( iNextFID++ ); poFeature->SetField( "Block", osBlockName.c_str() ); if( poFeature->GetAttributeTag() != "" ) { poFeature->SetField( "AttributeTag", poFeature->GetAttributeTag() ); } m_nFeaturesRead++; return poFeature; } /* -------------------------------------------------------------------- */ /* Are we out of features? */ /* -------------------------------------------------------------------- */ while( oIt != poDS->GetBlockMap().end() ) { poFeature = new OGRDXFFeature( poFeatureDefn ); // Let's insert this block at the origin with no rotation and scale. OGRDXFLayer oTempLayer(poDS); poFeature = oTempLayer.InsertBlockInline( oIt->first, OGRDXFInsertTransformer(), poFeature, apoPendingFeatures, false, poDS->ShouldMergeBlockGeometries() ); osBlockName = oIt->first; ++oIt; if( !poFeature ) { if ( apoPendingFeatures.empty() ) { // This block must have been empty. Move onto the next block continue; } else { poFeature = apoPendingFeatures.front(); apoPendingFeatures.pop(); } } poFeature->SetFID( iNextFID++ ); poFeature->SetField( "Block", osBlockName.c_str() ); if( poFeature->GetAttributeTag() != "" ) { poFeature->SetField( "AttributeTag", poFeature->GetAttributeTag() ); } m_nFeaturesRead++; return poFeature; } // No more blocks left. return nullptr; }
OGRDXFFeature *OGRDXFLayer::TranslateHATCH() { char szLineBuf[257]; int nCode = 0; OGRDXFFeature *poFeature = new OGRDXFFeature( poFeatureDefn ); CPLString osHatchPattern; double dfElevation = 0.0; // Z value to be used for EVERY point /* int nFillFlag = 0; */ OGRGeometryCollection oGC; while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 ) { switch( nCode ) { case 30: // Constant elevation. dfElevation = CPLAtof( szLineBuf ); break; case 70: /* nFillFlag = atoi(szLineBuf); */ break; case 2: osHatchPattern = szLineBuf; poFeature->SetField( "Text", osHatchPattern.c_str() ); break; case 91: { int nBoundaryPathCount = atoi(szLineBuf); for( int iBoundary = 0; iBoundary < nBoundaryPathCount; iBoundary++ ) { if (CollectBoundaryPath( &oGC, dfElevation ) != OGRERR_NONE) break; } } break; default: TranslateGenericProperty( poFeature, nCode, szLineBuf ); break; } } if( nCode < 0 ) { DXF_LAYER_READER_ERROR(); delete poFeature; return nullptr; } if( nCode == 0 ) poDS->UnreadValue(); /* -------------------------------------------------------------------- */ /* Obtain a tolerance value used when building the polygon. */ /* -------------------------------------------------------------------- */ double dfTolerance = atof( CPLGetConfigOption( "DXF_HATCH_TOLERANCE", "-1" ) ); if( dfTolerance < 0 ) { // If the configuration variable isn't set, compute the bounding box // and work out a tolerance from that OGREnvelope oEnvelope; oGC.getEnvelope( &oEnvelope ); dfTolerance = std::max( oEnvelope.MaxX - oEnvelope.MinX, oEnvelope.MaxY - oEnvelope.MinY ) * 1e-7; } /* -------------------------------------------------------------------- */ /* Try to turn the set of lines into something useful. */ /* -------------------------------------------------------------------- */ OGRErr eErr; OGRGeometry* poFinalGeom = (OGRGeometry *) OGRBuildPolygonFromEdges( (OGRGeometryH) &oGC, TRUE, TRUE, dfTolerance, &eErr ); if( eErr != OGRERR_NONE ) { delete poFinalGeom; OGRMultiLineString* poMLS = new OGRMultiLineString(); for(int i=0;i<oGC.getNumGeometries();i++) poMLS->addGeometry(oGC.getGeometryRef(i)); poFinalGeom = poMLS; } poFeature->ApplyOCSTransformer( poFinalGeom ); poFeature->SetGeometryDirectly( poFinalGeom ); PrepareBrushStyle( poFeature ); return poFeature; }