void addstylestring2kml ( const char *pszStyleString, StylePtr poKmlStyle, KmlFactory * poKmlFactory, PlacemarkPtr poKmlPlacemark, OGRFeature * poOgrFeat ) { LineStylePtr poKmlLineStyle = NULL; PolyStylePtr poKmlPolyStyle = NULL; IconStylePtr poKmlIconStyle = NULL; LabelStylePtr poKmlLabelStyle = NULL; /***** just bail now if stylestring is empty *****/ if ( !pszStyleString || !*pszStyleString ) { return; } /***** create and init a style mamager with the style string *****/ OGRStyleMgr *poOgrSM = new OGRStyleMgr; poOgrSM->InitStyleString ( pszStyleString ); /***** loop though the style parts *****/ int i; for ( i = 0; i < poOgrSM->GetPartCount ( NULL ); i++ ) { OGRStyleTool *poOgrST = poOgrSM->GetPart ( i, NULL ); if ( !poOgrST ) { continue; } switch ( poOgrST->GetType ( ) ) { case OGRSTCPen: { GBool nullcheck; poKmlLineStyle = poKmlFactory->CreateLineStyle ( ); OGRStylePen *poStylePen = ( OGRStylePen * ) poOgrST; /***** pen color *****/ int nR, nG, nB, nA; const char *pszcolor = poStylePen->Color ( nullcheck ); if ( !nullcheck && poStylePen->GetRGBFromString ( pszcolor, nR, nG, nB, nA ) ) { poKmlLineStyle->set_color ( Color32 ( nA, nB, nG, nR ) ); } double dfWidth = poStylePen->Width ( nullcheck ); if ( nullcheck ) dfWidth = 1.0; poKmlLineStyle->set_width ( dfWidth ); break; } case OGRSTCBrush: { GBool nullcheck; poKmlPolyStyle = poKmlFactory->CreatePolyStyle ( ); OGRStyleBrush *poStyleBrush = ( OGRStyleBrush * ) poOgrST; /***** brush color *****/ int nR, nG, nB, nA; const char *pszcolor = poStyleBrush->ForeColor ( nullcheck ); if ( !nullcheck && poStyleBrush->GetRGBFromString ( pszcolor, nR, nG, nB, nA ) ) { poKmlPolyStyle->set_color ( Color32 ( nA, nB, nG, nR ) ); } break; } case OGRSTCSymbol: { GBool nullcheck; GBool nullcheck2; OGRStyleSymbol *poStyleSymbol = ( OGRStyleSymbol * ) poOgrST; /***** id (kml icon) *****/ const char *pszId = poStyleSymbol->Id ( nullcheck ); if ( !nullcheck ) { if ( !poKmlIconStyle) poKmlIconStyle = poKmlFactory->CreateIconStyle ( ); /***** split it at the ,'s *****/ char **papszTokens = CSLTokenizeString2 ( pszId, ",", CSLT_HONOURSTRINGS | CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES ); if ( papszTokens ) { /***** for lack of a better solution just take the first one *****/ //todo come up with a better idea if ( papszTokens[0] ) { IconStyleIconPtr poKmlIcon = poKmlFactory->CreateIconStyleIcon ( ); poKmlIcon->set_href ( papszTokens[0] ); poKmlIconStyle->set_icon ( poKmlIcon ); } CSLDestroy ( papszTokens ); } } /***** heading *****/ double heading = poStyleSymbol->Angle ( nullcheck ); if ( !nullcheck ) { if ( !poKmlIconStyle) poKmlIconStyle = poKmlFactory->CreateIconStyle ( ); poKmlIconStyle->set_heading ( heading ); } /***** scale *****/ double dfScale = poStyleSymbol->Size ( nullcheck ); if ( !nullcheck ) { if ( !poKmlIconStyle) poKmlIconStyle = poKmlFactory->CreateIconStyle ( ); poKmlIconStyle->set_scale ( dfScale ); } /***** color *****/ int nR, nG, nB, nA; const char *pszcolor = poStyleSymbol->Color ( nullcheck ); if ( !nullcheck && poOgrST->GetRGBFromString ( pszcolor, nR, nG, nB, nA ) ) { poKmlIconStyle->set_color ( Color32 ( nA, nB, nG, nR ) ); } /***** hotspot *****/ double dfDx = poStyleSymbol->SpacingX ( nullcheck ); double dfDy = poStyleSymbol->SpacingY ( nullcheck2 ); if ( !nullcheck && !nullcheck2 ) { if ( !poKmlIconStyle) poKmlIconStyle = poKmlFactory->CreateIconStyle ( ); HotSpotPtr poKmlHotSpot = poKmlFactory->CreateHotSpot ( ); poKmlHotSpot->set_x ( dfDx ); poKmlHotSpot->set_y ( dfDy ); poKmlIconStyle->set_hotspot ( poKmlHotSpot ); } break; } case OGRSTCLabel: { GBool nullcheck; GBool nullcheck2; poKmlLabelStyle = poKmlFactory->CreateLabelStyle ( ); OGRStyleLabel *poStyleLabel = ( OGRStyleLabel * ) poOgrST; /***** color *****/ int nR, nG, nB, nA; const char *pszcolor = poStyleLabel->ForeColor ( nullcheck ); if ( !nullcheck && poStyleLabel->GetRGBFromString ( pszcolor, nR, nG, nB, nA ) ) { poKmlLabelStyle->set_color ( Color32 ( nA, nB, nG, nR ) ); } /***** scale *****/ double dfScale = poStyleLabel->Stretch ( nullcheck ); if ( !nullcheck ) { dfScale /= 100.0; poKmlLabelStyle->set_scale ( dfScale ); } /***** heading *****/ double heading = poStyleLabel->Angle ( nullcheck ); if ( !nullcheck ) { if ( !poKmlIconStyle) { poKmlIconStyle = poKmlFactory->CreateIconStyle ( ); IconStyleIconPtr poKmlIcon = poKmlFactory->CreateIconStyleIcon ( ); poKmlIconStyle->set_icon ( poKmlIcon ); } poKmlIconStyle->set_heading ( heading ); } /***** hotspot *****/ double dfDx = poStyleLabel->SpacingX ( nullcheck ); double dfDy = poStyleLabel->SpacingY ( nullcheck2 ); if ( !nullcheck && !nullcheck2 ) { if ( !poKmlIconStyle) { poKmlIconStyle = poKmlFactory->CreateIconStyle ( ); IconStyleIconPtr poKmlIcon = poKmlFactory->CreateIconStyleIcon ( ); poKmlIconStyle->set_icon ( poKmlIcon ); } HotSpotPtr poKmlHotSpot = poKmlFactory->CreateHotSpot ( ); poKmlHotSpot->set_x ( dfDx ); poKmlHotSpot->set_y ( dfDy ); poKmlIconStyle->set_hotspot ( poKmlHotSpot ); } /***** label text *****/ const char *pszText = poStyleLabel->TextString ( nullcheck ); if ( !nullcheck ) { if ( poKmlPlacemark ) { poKmlPlacemark->set_name( pszText ); } } break; } case OGRSTCNone: default: break; } delete poOgrST; } if ( poKmlLineStyle ) poKmlStyle->set_linestyle ( poKmlLineStyle ); if ( poKmlPolyStyle ) poKmlStyle->set_polystyle ( poKmlPolyStyle ); if ( poKmlIconStyle ) poKmlStyle->set_iconstyle ( poKmlIconStyle ); if ( poKmlLabelStyle ) poKmlStyle->set_labelstyle ( poKmlLabelStyle ); delete poOgrSM; }
OGRErr OGRDXFWriterLayer::WriteHATCH( OGRFeature *poFeature, OGRGeometry *poGeom ) { /* -------------------------------------------------------------------- */ /* For now we handle multipolygons by writing a series of */ /* entities. */ /* -------------------------------------------------------------------- */ if( poGeom == nullptr ) poGeom = poFeature->GetGeometryRef(); if ( poGeom->IsEmpty() ) { return OGRERR_NONE; } if( wkbFlatten(poGeom->getGeometryType()) == wkbMultiPolygon ) { OGRErr eErr = OGRERR_NONE; for( auto&& poMember: poGeom->toMultiPolygon() ) { eErr = WriteHATCH( poFeature, poMember ); if( eErr != OGRERR_NONE ) break; } return eErr; } /* -------------------------------------------------------------------- */ /* Do we now have a geometry we can work with? */ /* -------------------------------------------------------------------- */ if( wkbFlatten(poGeom->getGeometryType()) != wkbPolygon && wkbFlatten(poGeom->getGeometryType()) != wkbTriangle ) { return OGRERR_UNSUPPORTED_GEOMETRY_TYPE; } /* -------------------------------------------------------------------- */ /* Write as a hatch. */ /* -------------------------------------------------------------------- */ WriteValue( 0, "HATCH" ); WriteCore( poFeature ); WriteValue( 100, "AcDbEntity" ); WriteValue( 100, "AcDbHatch" ); // Figure out "average" elevation OGREnvelope3D oEnv; poGeom->getEnvelope( &oEnv ); WriteValue( 10, 0 ); // elevation point X = 0 WriteValue( 20, 0 ); // elevation point Y = 0 // elevation point Z = constant elevation WriteValue( 30, oEnv.MinZ + ( oEnv.MaxZ - oEnv.MinZ ) / 2 ); WriteValue(210, 0 ); // extrusion direction X WriteValue(220, 0 ); // extrusion direction Y WriteValue(230,1.0); // extrusion direction Z WriteValue( 2, "SOLID" ); // fill pattern WriteValue( 70, 1 ); // solid fill WriteValue( 71, 0 ); // associativity /* -------------------------------------------------------------------- */ /* Do we have styling information? */ /* -------------------------------------------------------------------- */ OGRStyleTool *poTool = nullptr; OGRStyleMgr oSM; if( poFeature->GetStyleString() != nullptr ) { oSM.InitFromFeature( poFeature ); if( oSM.GetPartCount() > 0 ) poTool = oSM.GetPart(0); } // Write style brush fore color if( poTool && poTool->GetType() == OGRSTCBrush ) { OGRStyleBrush *poBrush = (OGRStyleBrush *) poTool; GBool bDefault; if( poBrush->ForeColor(bDefault) != nullptr && !bDefault ) WriteValue( 62, ColorStringToDXFColor( poBrush->ForeColor(bDefault) ) ); } delete poTool; /* -------------------------------------------------------------------- */ /* Handle a PEN tool to control drawing color and width. */ /* Perhaps one day also dottedness, etc. */ /* -------------------------------------------------------------------- */ #ifdef notdef if( poTool && poTool->GetType() == OGRSTCPen ) { OGRStylePen *poPen = (OGRStylePen *) poTool; GBool bDefault; if( poPen->Color(bDefault) != NULL && !bDefault ) WriteValue( 62, ColorStringToDXFColor( poPen->Color(bDefault) ) ); double dfWidthInMM = poPen->Width(bDefault); if( !bDefault ) WriteValue( 370, (int) floor(dfWidthInMM * 100 + 0.5) ); } /* -------------------------------------------------------------------- */ /* Do we have a Linetype for the feature? */ /* -------------------------------------------------------------------- */ CPLString osLineType = poFeature->GetFieldAsString( "Linetype" ); if( !osLineType.empty() && (poDS->oHeaderDS.LookupLineType( osLineType ) != NULL || oNewLineTypes.count(osLineType) > 0 ) ) { // Already define -> just reference it. WriteValue( 6, osLineType ); } else if( poTool != NULL && poTool->GetType() == OGRSTCPen ) { CPLString osDefinition = PrepareLineTypeDefinition( poFeature, poTool ); if( osDefinition != "" && osLineType == "" ) { // Is this definition already created and named? std::map<CPLString,CPLString>::iterator it; for( it = oNewLineTypes.begin(); it != oNewLineTypes.end(); it++ ) { if( (*it).second == osDefinition ) { osLineType = (*it).first; break; } } // create an automatic name for it. if( osLineType == "" ) { do { osLineType.Printf( "AutoLineType-%d", nNextAutoID++ ); } while( poDS->oHeaderDS.LookupLineType(osLineType) != NULL ); } } // If it isn't already defined, add it now. if( osDefinition != "" && oNewLineTypes.count(osLineType) == 0 ) { oNewLineTypes[osLineType] = osDefinition; WriteValue( 6, osLineType ); } } delete poTool; #endif /* -------------------------------------------------------------------- */ /* Process the loops (rings). */ /* -------------------------------------------------------------------- */ OGRPolygon *poPoly = poGeom->toPolygon(); WriteValue( 91, poPoly->getNumInteriorRings() + 1 ); for( auto&& poLR: *poPoly ) { WriteValue( 92, 2 ); // Polyline WriteValue( 72, 0 ); // has bulge WriteValue( 73, 1 ); // is closed WriteValue( 93, poLR->getNumPoints() ); for( int iVert = 0; iVert < poLR->getNumPoints(); iVert++ ) { WriteValue( 10, poLR->getX(iVert) ); WriteValue( 20, poLR->getY(iVert) ); } WriteValue( 97, 0 ); // 0 source boundary objects } WriteValue( 75, 0 ); // hatch style = Hatch "odd parity" area (Normal style) WriteValue( 76, 1 ); // hatch pattern type = predefined WriteValue( 98, 0 ); // 0 seed points return OGRERR_NONE; #ifdef notdef /* -------------------------------------------------------------------- */ /* Alternate unmaintained implementation as a polyline entity. */ /* -------------------------------------------------------------------- */ WriteValue( 0, "POLYLINE" ); WriteCore( poFeature ); WriteValue( 100, "AcDbEntity" ); WriteValue( 100, "AcDbPolyline" ); if( EQUAL( poGeom->getGeometryName(), "LINEARRING" ) ) WriteValue( 70, 1 ); else WriteValue( 70, 0 ); WriteValue( 66, "1" ); for( int iVert = 0; iVert < poLS->getNumPoints(); iVert++ ) { WriteValue( 0, "VERTEX" ); WriteValue( 8, "0" ); WriteValue( 10, poLS->getX(iVert) ); if( !WriteValue( 20, poLS->getY(iVert) ) ) return OGRERR_FAILURE; if( poLS->getGeometryType() == wkbLineString25D ) { if( !WriteValue( 30, poLS->getZ(iVert) ) ) return OGRERR_FAILURE; } } WriteValue( 0, "SEQEND" ); WriteValue( 8, "0" ); return OGRERR_NONE; #endif }