OGRFeature *OGRDWGLayer::TranslateHATCH( OdDbEntityPtr poEntity ) { OGRFeature *poFeature = new OGRFeature( poFeatureDefn ); OdDbHatchPtr poHatch = OdDbHatch::cast( poEntity ); OGRGeometryCollection oGC; TranslateGenericProperties( poFeature, poEntity ); poFeature->SetField( "Text", (const char *) poHatch->patternName() ); /* -------------------------------------------------------------------- */ /* Collect the loops. */ /* -------------------------------------------------------------------- */ for( int i = 0; i < poHatch->numLoops(); i++ ) { DWGCollectBoundaryLoop( poHatch, i, &oGC ); } /* -------------------------------------------------------------------- */ /* Try to turn the set of lines into something useful. */ /* -------------------------------------------------------------------- */ OGRErr eErr; OGRGeometryH hFinalGeom = OGRBuildPolygonFromEdges( (OGRGeometryH) &oGC, TRUE, TRUE, 0.0000001, &eErr ); poFeature->SetGeometryDirectly( (OGRGeometry *) hFinalGeom ); /* -------------------------------------------------------------------- */ /* Work out the color for this feature. For now we just assume */ /* solid fill. We cannot trivially translate the various sorts */ /* of hatching. */ /* -------------------------------------------------------------------- */ CPLString osLayer = poFeature->GetFieldAsString("Layer"); int nColor = 256; if( oStyleProperties.count("Color") > 0 ) nColor = atoi(oStyleProperties["Color"]); // Use layer color? if( nColor < 1 || nColor > 255 ) { const char *pszValue = poDS->LookupLayerProperty( osLayer, "Color" ); if( pszValue != NULL ) nColor = atoi(pszValue); } /* -------------------------------------------------------------------- */ /* Setup the style string. */ /* -------------------------------------------------------------------- */ if( nColor >= 1 && nColor <= 255 ) { CPLString osStyle; const unsigned char *pabyDWGColors = ACGetColorTable(); osStyle.Printf( "BRUSH(fc:#%02x%02x%02x)", pabyDWGColors[nColor*3+0], pabyDWGColors[nColor*3+1], pabyDWGColors[nColor*3+2] ); poFeature->SetStyleString( osStyle ); } return poFeature; }
int OGRAVCBinLayer::FormPolygonGeometry( OGRFeature *poFeature, AVCPal *psPAL ) { /* -------------------------------------------------------------------- */ /* Try to find the corresponding ARC layer if not already */ /* recorded. */ /* -------------------------------------------------------------------- */ if( poArcLayer == NULL ) { int i; for( i = 0; i < poDS->GetLayerCount(); i++ ) { OGRAVCBinLayer *poLayer = (OGRAVCBinLayer *) poDS->GetLayer(i); if( poLayer->eSectionType == AVCFileARC ) poArcLayer = poLayer; } if( poArcLayer == NULL ) return FALSE; } /* -------------------------------------------------------------------- */ /* Read all the arcs related to this polygon, making a working */ /* copy of them since the one returned by AVC is temporary. */ /* -------------------------------------------------------------------- */ OGRGeometryCollection oArcs; int iArc; for( iArc = 0; iArc < psPAL->numArcs; iArc++ ) { OGRFeature *poArc; if( psPAL->pasArcs[iArc].nArcId == 0 ) continue; // If the other side of the line is the same polygon then this // arc is a "bridge" arc and can be discarded. If we don't discard // it, then we should double it as bridge arcs seem to only appear // once. But by discarding it we ensure a multi-ring polygon will be // properly formed. if( psPAL->pasArcs[iArc].nAdjPoly == psPAL->nPolyId ) continue; poArc = poArcLayer->GetFeature( ABS(psPAL->pasArcs[iArc].nArcId) ); if( poArc == NULL ) return FALSE; if( poArc->GetGeometryRef() == NULL ) return FALSE; oArcs.addGeometry( poArc->GetGeometryRef() ); OGRFeature::DestroyFeature( poArc ); } OGRErr eErr; OGRPolygon *poPolygon; poPolygon = (OGRPolygon *) OGRBuildPolygonFromEdges( (OGRGeometryH) &oArcs, TRUE, FALSE, 0.0, &eErr ); if( poPolygon != NULL ) poFeature->SetGeometryDirectly( poPolygon ); return eErr == OGRERR_NONE; }
OGRFeature *OGRDXFLayer::TranslateHATCH() { char szLineBuf[257]; int nCode; OGRFeature *poFeature = new OGRFeature( poFeatureDefn ); CPLString osHatchPattern; int nFillFlag = 0; OGRGeometryCollection oGC; while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 ) { switch( nCode ) { case 70: nFillFlag = atoi(szLineBuf); break; case 2: osHatchPattern = szLineBuf; poFeature->SetField( "Text", osHatchPattern.c_str() ); break; case 91: { int nBoundaryPathCount = atoi(szLineBuf); int iBoundary; for( iBoundary = 0; iBoundary < nBoundaryPathCount; iBoundary++ ) { if (CollectBoundaryPath( &oGC ) != OGRERR_NONE) break; } } break; default: TranslateGenericProperty( poFeature, nCode, szLineBuf ); break; } } if( nCode == 0 ) poDS->UnreadValue(); /* -------------------------------------------------------------------- */ /* Try to turn the set of lines into something useful. */ /* -------------------------------------------------------------------- */ OGRErr eErr; OGRGeometry* poFinalGeom = (OGRGeometry *) OGRBuildPolygonFromEdges( (OGRGeometryH) &oGC, TRUE, TRUE, 0.0000001, &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; } ApplyOCSTransformer( poFinalGeom ); poFeature->SetGeometryDirectly( poFinalGeom ); /* -------------------------------------------------------------------- */ /* Work out the color for this feature. For now we just assume */ /* solid fill. We cannot trivially translate the various sorts */ /* of hatching. */ /* -------------------------------------------------------------------- */ CPLString osLayer = poFeature->GetFieldAsString("Layer"); int nColor = 256; if( oStyleProperties.count("Color") > 0 ) nColor = atoi(oStyleProperties["Color"]); // Use layer color? if( nColor < 1 || nColor > 255 ) { const char *pszValue = poDS->LookupLayerProperty( osLayer, "Color" ); if( pszValue != NULL ) nColor = atoi(pszValue); } /* -------------------------------------------------------------------- */ /* Setup the style string. */ /* -------------------------------------------------------------------- */ if( nColor >= 1 && nColor <= 255 ) { CPLString osStyle; const unsigned char *pabyDXFColors = ACGetColorTable(); osStyle.Printf( "BRUSH(fc:#%02x%02x%02x)", pabyDXFColors[nColor*3+0], pabyDXFColors[nColor*3+1], pabyDXFColors[nColor*3+2] ); poFeature->SetStyleString( osStyle ); } return poFeature; }
OGRFeature *OGRDXFLayer::TranslateHATCH() { char szLineBuf[257]; int nCode; OGRFeature *poFeature = new OGRFeature( poFeatureDefn ); CPLString osHatchPattern; int nFillFlag = 0; OGRGeometryCollection oGC; while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 ) { switch( nCode ) { case 70: nFillFlag = atoi(szLineBuf); break; case 2: osHatchPattern = szLineBuf; poFeature->SetField( "Text", osHatchPattern.c_str() ); break; case 91: { int nBoundaryPathCount = atoi(szLineBuf); int iBoundary; for( iBoundary = 0; iBoundary < nBoundaryPathCount; iBoundary++ ) { CollectBoundaryPath( &oGC ); } } break; default: TranslateGenericProperty( poFeature, nCode, szLineBuf ); break; } } if( nCode == 0 ) poDS->UnreadValue(); /* -------------------------------------------------------------------- */ /* Try to turn the set of lines into something useful. */ /* -------------------------------------------------------------------- */ OGRErr eErr; OGRGeometryH hFinalGeom = OGRBuildPolygonFromEdges( (OGRGeometryH) &oGC, TRUE, TRUE, 0.0000001, &eErr ); poFeature->SetGeometryDirectly( (OGRGeometry *) hFinalGeom ); /* -------------------------------------------------------------------- */ /* We ought to try and make some useful translation of the fill */ /* style but I'll leave that for another time. */ /* -------------------------------------------------------------------- */ return poFeature; }
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; }
OGRFeature *OGRDGNLayer::ElementToFeature( DGNElemCore *psElement ) { OGRFeature *poFeature = new OGRFeature( poFeatureDefn ); poFeature->SetFID( psElement->element_id ); poFeature->SetField( "Type", psElement->type ); poFeature->SetField( "Level", psElement->level ); poFeature->SetField( "GraphicGroup", psElement->graphic_group ); poFeature->SetField( "ColorIndex", psElement->color ); poFeature->SetField( "Weight", psElement->weight ); poFeature->SetField( "Style", psElement->style ); m_nFeaturesRead++; /* -------------------------------------------------------------------- */ /* Collect linkage information */ /* -------------------------------------------------------------------- */ #define MAX_LINK 100 int anEntityNum[MAX_LINK], anMSLink[MAX_LINK]; unsigned char *pabyData; int iLink=0, nLinkCount=0; anEntityNum[0] = 0; anMSLink[0] = 0; pabyData = DGNGetLinkage( hDGN, psElement, iLink, NULL, anEntityNum+iLink, anMSLink+iLink, NULL ); while( pabyData && nLinkCount < MAX_LINK ) { iLink++; if( anEntityNum[nLinkCount] != 0 || anMSLink[nLinkCount] != 0 ) nLinkCount++; anEntityNum[nLinkCount] = 0; anMSLink[nLinkCount] = 0; pabyData = DGNGetLinkage( hDGN, psElement, iLink, NULL, anEntityNum+nLinkCount, anMSLink+nLinkCount, NULL ); } /* -------------------------------------------------------------------- */ /* Apply attribute linkage to feature. */ /* -------------------------------------------------------------------- */ if( nLinkCount > 0 ) { if( EQUAL(pszLinkFormat,"FIRST") ) { poFeature->SetField( "EntityNum", anEntityNum[0] ); poFeature->SetField( "MSLink", anMSLink[0] ); } else if( EQUAL(pszLinkFormat,"LIST") ) { poFeature->SetField( "EntityNum", nLinkCount, anEntityNum ); poFeature->SetField( "MSLink", nLinkCount, anMSLink ); } else if( EQUAL(pszLinkFormat,"STRING") ) { char szEntityList[MAX_LINK*9], szMSLinkList[MAX_LINK*9]; int nEntityLen = 0, nMSLinkLen = 0; for( iLink = 0; iLink < nLinkCount; iLink++ ) { if( iLink != 0 ) { szEntityList[nEntityLen++] = ','; szMSLinkList[nMSLinkLen++] = ','; } sprintf( szEntityList + nEntityLen, "%d", anEntityNum[iLink]); sprintf( szMSLinkList + nMSLinkLen, "%d", anMSLink[iLink] ); nEntityLen += strlen(szEntityList + nEntityLen ); nMSLinkLen += strlen(szMSLinkList + nMSLinkLen ); } poFeature->SetField( "EntityNum", szEntityList ); poFeature->SetField( "MSLink", szMSLinkList ); } } /* -------------------------------------------------------------------- */ /* Lookup color. */ /* -------------------------------------------------------------------- */ char gv_color[128]; int gv_red, gv_green, gv_blue; char szFSColor[128], szPen[256]; szFSColor[0] = '\0'; if( DGNLookupColor( hDGN, psElement->color, &gv_red, &gv_green, &gv_blue ) ) { sprintf( gv_color, "%f %f %f 1.0", gv_red / 255.0, gv_green / 255.0, gv_blue / 255.0 ); sprintf( szFSColor, "c:#%02x%02x%02x", gv_red, gv_green, gv_blue ); } /* -------------------------------------------------------------------- */ /* Generate corresponding PEN style. */ /* -------------------------------------------------------------------- */ if( psElement->style == DGNS_SOLID ) sprintf( szPen, "PEN(id:\"ogr-pen-0\"" ); else if( psElement->style == DGNS_DOTTED ) sprintf( szPen, "PEN(id:\"ogr-pen-5\"" ); else if( psElement->style == DGNS_MEDIUM_DASH ) sprintf( szPen, "PEN(id:\"ogr-pen-2\"" ); else if( psElement->style == DGNS_LONG_DASH ) sprintf( szPen, "PEN(id:\"ogr-pen-4\"" ); else if( psElement->style == DGNS_DOT_DASH ) sprintf( szPen, "PEN(id:\"ogr-pen-6\"" ); else if( psElement->style == DGNS_SHORT_DASH ) sprintf( szPen, "PEN(id:\"ogr-pen-3\"" ); else if( psElement->style == DGNS_DASH_DOUBLE_DOT ) sprintf( szPen, "PEN(id:\"ogr-pen-7\"" ); else if( psElement->style == DGNS_LONG_DASH_SHORT_DASH ) sprintf( szPen, "PEN(p:\"10px 5px 4px 5px\"" ); else sprintf( szPen, "PEN(id:\"ogr-pen-0\"" ); if( strlen(szFSColor) > 0 ) sprintf( szPen+strlen(szPen), ",%s", szFSColor ); if( psElement->weight > 1 ) sprintf( szPen+strlen(szPen), ",w:%dpx", psElement->weight ); strcat( szPen, ")" ); switch( psElement->stype ) { case DGNST_MULTIPOINT: if( psElement->type == DGNT_SHAPE ) { OGRLinearRing *poLine = new OGRLinearRing(); OGRPolygon *poPolygon = new OGRPolygon(); DGNElemMultiPoint *psEMP = (DGNElemMultiPoint *) psElement; poLine->setNumPoints( psEMP->num_vertices ); for( int i = 0; i < psEMP->num_vertices; i++ ) { poLine->setPoint( i, psEMP->vertices[i].x, psEMP->vertices[i].y, psEMP->vertices[i].z ); } poPolygon->addRingDirectly( poLine ); poFeature->SetGeometryDirectly( poPolygon ); ConsiderBrush( psElement, szPen, poFeature ); } else if( psElement->type == DGNT_CURVE ) { DGNElemMultiPoint *psEMP = (DGNElemMultiPoint *) psElement; OGRLineString *poLine = new OGRLineString(); DGNPoint *pasPoints; int nPoints; nPoints = 5 * psEMP->num_vertices; pasPoints = (DGNPoint *) CPLMalloc(sizeof(DGNPoint) * nPoints); DGNStrokeCurve( hDGN, psEMP, nPoints, pasPoints ); poLine->setNumPoints( nPoints ); for( int i = 0; i < nPoints; i++ ) { poLine->setPoint( i, pasPoints[i].x, pasPoints[i].y, pasPoints[i].z ); } poFeature->SetGeometryDirectly( poLine ); CPLFree( pasPoints ); poFeature->SetStyleString( szPen ); } else { OGRLineString *poLine = new OGRLineString(); DGNElemMultiPoint *psEMP = (DGNElemMultiPoint *) psElement; if( psEMP->num_vertices > 0 ) { poLine->setNumPoints( psEMP->num_vertices ); for( int i = 0; i < psEMP->num_vertices; i++ ) { poLine->setPoint( i, psEMP->vertices[i].x, psEMP->vertices[i].y, psEMP->vertices[i].z ); } poFeature->SetGeometryDirectly( poLine ); } poFeature->SetStyleString( szPen ); } break; case DGNST_ARC: { OGRLineString *poLine = new OGRLineString(); DGNElemArc *psArc = (DGNElemArc *) psElement; DGNPoint asPoints[90]; int nPoints; nPoints = (int) (MAX(1,ABS(psArc->sweepang) / 5) + 1); DGNStrokeArc( hDGN, psArc, nPoints, asPoints ); poLine->setNumPoints( nPoints ); for( int i = 0; i < nPoints; i++ ) { poLine->setPoint( i, asPoints[i].x, asPoints[i].y, asPoints[i].z ); } poFeature->SetGeometryDirectly( poLine ); poFeature->SetStyleString( szPen ); } break; case DGNST_TEXT: { OGRPoint *poPoint = new OGRPoint(); DGNElemText *psText = (DGNElemText *) psElement; char *pszOgrFS; poPoint->setX( psText->origin.x ); poPoint->setY( psText->origin.y ); poPoint->setZ( psText->origin.z ); poFeature->SetGeometryDirectly( poPoint ); pszOgrFS = (char *) CPLMalloc(strlen(psText->string) + 150); // setup the basic label. sprintf( pszOgrFS, "LABEL(t:\"%s\"", psText->string ); // set the color if we have it. if( strlen(szFSColor) > 0 ) sprintf( pszOgrFS+strlen(pszOgrFS), ",%s", szFSColor ); // Add the size info in ground units. if( ABS(psText->height_mult) >= 6.0 ) sprintf( pszOgrFS+strlen(pszOgrFS), ",s:%dg", (int) psText->height_mult ); else if( ABS(psText->height_mult) > 0.1 ) sprintf( pszOgrFS+strlen(pszOgrFS), ",s:%.3fg", psText->height_mult ); else sprintf( pszOgrFS+strlen(pszOgrFS), ",s:%.12fg", psText->height_mult ); // Add the font name. Name it MstnFont<FONTNUMBER> if not available // in the font list. #3392 static const char *papszFontList[] = { "STANDARD", "WORKING", "FANCY", "ENGINEERING", "NEWZERO", "STENCEL", //0-5 "USTN_FANCY", "COMPRESSED", "STENCEQ", NULL, "hand", "ARCH", //6-11 "ARCHB", NULL, NULL, "IGES1001", "IGES1002", "IGES1003", //12-17 "CENTB", "MICROS", NULL, NULL, "ISOFRACTIONS", "ITALICS", //18-23 "ISO30", NULL, "GREEK", "ISOREC", "Isoeq", NULL, //24-29 "ISO_FONTLEFT", "ISO_FONTRIGHT", "INTL_ENGINEERING", "INTL_WORKING", "ISOITEQ", NULL, //30-35 "USTN FONT 26", NULL, NULL, NULL, NULL, "ARCHITECTURAL", //36-41 "BLOCK_OUTLINE", "LOW_RES_FILLED", NULL, NULL, NULL, NULL, //42-47 NULL, NULL, "UPPERCASE", NULL, NULL, NULL, //48-53 NULL, NULL, NULL, NULL, NULL, NULL, //54-49 "FONT060", "din", "dinit", "helvl", "HELVLIT", "helv", //60-65 "HELVIT", "cent", "CENTIT", "SCRIPT", NULL, NULL, //66-71 NULL, NULL, NULL, NULL, "MICROQ", "dotfont", //72-77 "DOTIT", NULL, NULL, NULL, NULL, NULL, //78-83 NULL, NULL, NULL, NULL, NULL, NULL, //84-89 NULL, NULL, "FONT092", NULL, "FONT094", NULL, //90-95 NULL, NULL, NULL, NULL, "ANSI_SYMBOLS", "FEATURE_CONTROL_SYSMBOLS", //96-101 "SYMB_FAST", NULL, NULL, "INTL_ISO", "INTL_ISO_EQUAL", "INTL_ISO_ITALIC", //102-107 "INTL_ISO_ITALIC_EQUAL" }; //108 if(psText->font_id <= 108 && papszFontList[psText->font_id] != NULL ) { sprintf( pszOgrFS+strlen(pszOgrFS), ",f:%s", papszFontList[psText->font_id] ); } else { sprintf( pszOgrFS+strlen(pszOgrFS), ",f:MstnFont%d", psText->font_id ); } // Add the angle, if not horizontal if( psText->rotation != 0.0 ) sprintf( pszOgrFS+strlen(pszOgrFS), ",a:%d", (int) (psText->rotation+0.5) ); strcat( pszOgrFS, ")" ); poFeature->SetStyleString( pszOgrFS ); CPLFree( pszOgrFS ); poFeature->SetField( "Text", psText->string ); } break; case DGNST_COMPLEX_HEADER: { DGNElemComplexHeader *psHdr = (DGNElemComplexHeader *) psElement; int iChild; OGRMultiLineString oChildren; /* collect subsequent child geometries. */ // we should disable the spatial filter ... add later. for( iChild = 0; iChild < psHdr->numelems; iChild++ ) { OGRFeature *poChildFeature = NULL; DGNElemCore *psChildElement; psChildElement = DGNReadElement( hDGN ); // should verify complex bit set, not another header. if( psChildElement != NULL ) { poChildFeature = ElementToFeature( psChildElement ); DGNFreeElement( hDGN, psChildElement ); } if( poChildFeature != NULL && poChildFeature->GetGeometryRef() != NULL ) { OGRGeometry *poGeom; poGeom = poChildFeature->GetGeometryRef(); if( wkbFlatten(poGeom->getGeometryType()) == wkbLineString ) oChildren.addGeometry( poGeom ); } if( poChildFeature != NULL ) delete poChildFeature; } // Try to assemble into polygon geometry. OGRGeometry *poGeom; if( psElement->type == DGNT_COMPLEX_SHAPE_HEADER ) poGeom = (OGRPolygon *) OGRBuildPolygonFromEdges( (OGRGeometryH) &oChildren, TRUE, TRUE, 100000, NULL ); else poGeom = oChildren.clone(); if( poGeom != NULL ) poFeature->SetGeometryDirectly( poGeom ); ConsiderBrush( psElement, szPen, poFeature ); } break; default: break; } /* -------------------------------------------------------------------- */ /* Fixup geometry dimension. */ /* -------------------------------------------------------------------- */ if( poFeature->GetGeometryRef() != NULL ) poFeature->GetGeometryRef()->setCoordinateDimension( DGNGetDimension( hDGN ) ); return poFeature; }