OGRErr OGRDXFWriterLayer::WritePOINT( OGRFeature *poFeature ) { WriteValue( 0, "POINT" ); WriteCore( poFeature ); WriteValue( 100, "AcDbEntity" ); WriteValue( 100, "AcDbPoint" ); // Write style pen color OGRStyleTool *poTool = nullptr; OGRStyleMgr oSM; if( poFeature->GetStyleString() != nullptr ) { oSM.InitFromFeature( poFeature ); if( oSM.GetPartCount() > 0 ) poTool = oSM.GetPart(0); } if( poTool && poTool->GetType() == OGRSTCPen ) { OGRStylePen *poPen = (OGRStylePen *) poTool; GBool bDefault; if( poPen->Color(bDefault) != nullptr && !bDefault ) WriteValue( 62, ColorStringToDXFColor( poPen->Color(bDefault) ) ); } delete poTool; OGRPoint *poPoint = poFeature->GetGeometryRef()->toPoint(); WriteValue( 10, poPoint->getX() ); if( !WriteValue( 20, poPoint->getY() ) ) return OGRERR_FAILURE; if( poPoint->getGeometryType() == wkbPoint25D ) { if( !WriteValue( 30, poPoint->getZ() ) ) return OGRERR_FAILURE; } return OGRERR_NONE; }
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; }
void styletable2kml ( OGRStyleTable * poOgrStyleTable, KmlFactory * poKmlFactory, ContainerPtr poKmlContainer, char** papszOptions ) { /***** just return if the styletable is null *****/ if ( !poOgrStyleTable ) return; std::set<CPLString> aoSetNormalStyles; std::set<CPLString> aoSetHighlightStyles; poOgrStyleTable->ResetStyleStringReading ( ); const char *pszStyleString; /* Collect styles that end with _normal or _highlight */ while ( poOgrStyleTable->GetNextStyle ( ) != NULL ) { const char *pszStyleName = poOgrStyleTable->GetLastStyleName ( ); if( strlen(pszStyleName) > strlen("_normal") && EQUAL(pszStyleName + strlen(pszStyleName) - strlen("_normal"), "_normal") ) { CPLString osName(pszStyleName); osName.resize(strlen(pszStyleName) - strlen("_normal")); aoSetNormalStyles.insert(osName); } else if( strlen(pszStyleName) > strlen("_highlight") && EQUAL(pszStyleName + strlen(pszStyleName) - strlen("_highlight"), "_highlight") ) { CPLString osName(pszStyleName); osName.resize(strlen(pszStyleName) - strlen("_highlight")); aoSetHighlightStyles.insert(osName); } } /***** parse the style table *****/ poOgrStyleTable->ResetStyleStringReading ( ); while ( ( pszStyleString = poOgrStyleTable->GetNextStyle ( ) ) != NULL ) { const char *pszStyleName = poOgrStyleTable->GetLastStyleName ( ); if( aoSetNormalStyles.find(pszStyleName) != aoSetNormalStyles.end() && aoSetHighlightStyles.find(pszStyleName) != aoSetHighlightStyles.end() ) { continue; } /***** add the style header to the kml *****/ StylePtr poKmlStyle = poKmlFactory->CreateStyle ( ); poKmlStyle->set_id ( pszStyleName ); /***** parse the style string *****/ addstylestring2kml ( pszStyleString, poKmlStyle, poKmlFactory, NULL ); /***** add balloon style *****/ const char* pszBalloonStyleBgColor = CSLFetchNameValue(papszOptions, CPLSPrintf("%s_balloonstyle_bgcolor", pszStyleName)); const char* pszBalloonStyleText = CSLFetchNameValue(papszOptions, CPLSPrintf("%s_balloonstyle_text", pszStyleName)); int nR, nG, nB, nA; OGRStylePen oStyleTool; if( (pszBalloonStyleBgColor != NULL && oStyleTool.GetRGBFromString ( pszBalloonStyleBgColor, nR, nG, nB, nA ) ) || pszBalloonStyleText != NULL ) { BalloonStylePtr poKmlBalloonStyle = poKmlFactory->CreateBalloonStyle(); if( pszBalloonStyleBgColor != NULL && oStyleTool.GetRGBFromString ( pszBalloonStyleBgColor, nR, nG, nB, nA ) ) poKmlBalloonStyle->set_bgcolor ( Color32 ( static_cast<GByte>(nA), static_cast<GByte>(nB), static_cast<GByte>(nG), static_cast<GByte>(nR) ) ); if( pszBalloonStyleText != NULL ) poKmlBalloonStyle->set_text(pszBalloonStyleText); poKmlStyle->set_balloonstyle ( poKmlBalloonStyle ); } /***** add the style to the container *****/ DocumentPtr poKmlDocument = AsDocument ( poKmlContainer ); poKmlDocument->add_styleselector ( poKmlStyle ); } /* Find style name that end with _normal and _highlight to create */ /* a StyleMap from both */ std::set<CPLString>::iterator aoSetNormalStylesIter = aoSetNormalStyles.begin(); for( ; aoSetNormalStylesIter != aoSetNormalStyles.end(); ++aoSetNormalStylesIter ) { CPLString osStyleName(*aoSetNormalStylesIter); if( aoSetHighlightStyles.find(osStyleName) != aoSetHighlightStyles.end() ) { StyleMapPtr poKmlStyleMap = poKmlFactory->CreateStyleMap ( ); poKmlStyleMap->set_id ( osStyleName ); PairPtr poKmlPairNormal = poKmlFactory->CreatePair ( ); poKmlPairNormal->set_key(STYLESTATE_NORMAL); poKmlPairNormal->set_styleurl(CPLSPrintf("#%s_normal", osStyleName.c_str())); poKmlStyleMap->add_pair(poKmlPairNormal); PairPtr poKmlPairHightlight = poKmlFactory->CreatePair ( ); poKmlPairHightlight->set_key(STYLESTATE_HIGHLIGHT); poKmlPairHightlight->set_styleurl(CPLSPrintf("#%s_highlight", osStyleName.c_str())); poKmlStyleMap->add_pair(poKmlPairHightlight); /***** add the style to the container *****/ DocumentPtr poKmlDocument = AsDocument ( poKmlContainer ); poKmlDocument->add_styleselector ( poKmlStyleMap ); } } return; }
OGRErr OGRDXFWriterLayer::WritePOLYLINE( OGRFeature *poFeature, const OGRGeometry *poGeom ) { /* -------------------------------------------------------------------- */ /* For now we handle multilinestrings by writing a series of */ /* entities. */ /* -------------------------------------------------------------------- */ if( poGeom == nullptr ) poGeom = poFeature->GetGeometryRef(); if ( poGeom->IsEmpty() ) { return OGRERR_NONE; } if( wkbFlatten(poGeom->getGeometryType()) == wkbMultiPolygon || wkbFlatten(poGeom->getGeometryType()) == wkbMultiLineString ) { const OGRGeometryCollection *poGC = poGeom->toGeometryCollection(); OGRErr eErr = OGRERR_NONE; for( auto&& poMember: *poGC ) { eErr = WritePOLYLINE( poFeature, poMember ); if( eErr != OGRERR_NONE ) break; } return eErr; } /* -------------------------------------------------------------------- */ /* Polygons are written with on entity per ring. */ /* -------------------------------------------------------------------- */ if( wkbFlatten(poGeom->getGeometryType()) == wkbPolygon || wkbFlatten(poGeom->getGeometryType()) == wkbTriangle) { const OGRPolygon *poPoly = poGeom->toPolygon(); OGRErr eErr = OGRERR_NONE; for( auto&& poRing: *poPoly ) { eErr = WritePOLYLINE( poFeature, poRing ); if( eErr != OGRERR_NONE ) break; } return eErr; } /* -------------------------------------------------------------------- */ /* Do we now have a geometry we can work with? */ /* -------------------------------------------------------------------- */ if( wkbFlatten(poGeom->getGeometryType()) != wkbLineString ) return OGRERR_UNSUPPORTED_GEOMETRY_TYPE; const OGRLineString *poLS = poGeom->toLineString(); /* -------------------------------------------------------------------- */ /* Write as a lightweight polygon, */ /* or as POLYLINE if the line contains different heights */ /* -------------------------------------------------------------------- */ int bHasDifferentZ = FALSE; if( poLS->getGeometryType() == wkbLineString25D ) { double z0 = poLS->getZ(0); for( int iVert = 0; iVert < poLS->getNumPoints(); iVert++ ) { if (z0 != poLS->getZ(iVert)) { bHasDifferentZ = TRUE; break; } } } WriteValue( 0, bHasDifferentZ ? "POLYLINE" : "LWPOLYLINE" ); WriteCore( poFeature ); WriteValue( 100, "AcDbEntity" ); if( bHasDifferentZ ) { WriteValue( 100, "AcDb3dPolyline" ); WriteValue( 10, 0.0 ); WriteValue( 20, 0.0 ); WriteValue( 30, 0.0 ); } else WriteValue( 100, "AcDbPolyline" ); if( EQUAL( poGeom->getGeometryName(), "LINEARRING" ) ) WriteValue( 70, 1 + (bHasDifferentZ ? 8 : 0) ); else WriteValue( 70, 0 + (bHasDifferentZ ? 8 : 0) ); if( !bHasDifferentZ ) WriteValue( 90, poLS->getNumPoints() ); else WriteValue( 66, "1" ); // Vertex Flag /* -------------------------------------------------------------------- */ /* 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); } /* -------------------------------------------------------------------- */ /* Handle a PEN tool to control drawing color and width. */ /* Perhaps one day also dottedness, etc. */ /* -------------------------------------------------------------------- */ if( poTool && poTool->GetType() == OGRSTCPen ) { OGRStylePen *poPen = (OGRStylePen *) poTool; GBool bDefault; if( poPen->Color(bDefault) != nullptr && !bDefault ) WriteValue( 62, ColorStringToDXFColor( poPen->Color(bDefault) ) ); // we want to fetch the width in ground units. poPen->SetUnit( OGRSTUGround, 1.0 ); const double dfWidth = poPen->Width(bDefault); if( !bDefault ) WriteValue( 370, (int) floor(dfWidth * 100 + 0.5) ); } /* -------------------------------------------------------------------- */ /* Do we have a Linetype for the feature? */ /* -------------------------------------------------------------------- */ CPLString osLineType = poFeature->GetFieldAsString( "Linetype" ); double dfLineTypeScale = 0.0; bool bGotLinetype = false; if( !osLineType.empty() ) { std::vector<double> adfLineType = poDS->oHeaderDS.LookupLineType( osLineType ); if( adfLineType.empty() && oNewLineTypes.count(osLineType) > 0 ) adfLineType = oNewLineTypes[osLineType]; if( !adfLineType.empty() ) { bGotLinetype = true; WriteValue( 6, osLineType ); // If the given linetype is proportional to the linetype data // in the style string, then apply a linetype scale if( poTool != nullptr && poTool->GetType() == OGRSTCPen ) { std::vector<double> adfDefinition = PrepareLineTypeDefinition( static_cast<OGRStylePen *>( poTool ) ); if( !adfDefinition.empty() ) { dfLineTypeScale = IsLineTypeProportional( adfLineType, adfDefinition ); if( dfLineTypeScale != 0.0 && fabs( dfLineTypeScale - 1.0 ) > 1e-4 ) { WriteValue( 48, dfLineTypeScale ); } } } } } if( !bGotLinetype && poTool != nullptr && poTool->GetType() == OGRSTCPen ) { std::vector<double> adfDefinition = PrepareLineTypeDefinition( static_cast<OGRStylePen *>( poTool ) ); if( !adfDefinition.empty() ) { // Is this definition already created and named? for( const auto& oPair : poDS->oHeaderDS.GetLineTypeTable() ) { dfLineTypeScale = IsLineTypeProportional( oPair.second, adfDefinition ); if( dfLineTypeScale != 0.0 ) { osLineType = oPair.first; break; } } if( dfLineTypeScale == 0.0 ) { for( const auto& oPair : oNewLineTypes ) { dfLineTypeScale = IsLineTypeProportional( oPair.second, adfDefinition ); if( dfLineTypeScale != 0.0 ) { osLineType = oPair.first; break; } } } // If not, create an automatic name for it. if( osLineType == "" ) { dfLineTypeScale = 1.0; do { osLineType.Printf( "AutoLineType-%d", nNextAutoID++ ); } while( poDS->oHeaderDS.LookupLineType(osLineType).size() > 0 ); } // If it isn't already defined, add it now. if( poDS->oHeaderDS.LookupLineType( osLineType ).empty() && oNewLineTypes.count( osLineType ) == 0 ) { oNewLineTypes[osLineType] = adfDefinition; } WriteValue( 6, osLineType ); if( dfLineTypeScale != 0.0 && fabs( dfLineTypeScale - 1.0 ) > 1e-4 ) { WriteValue( 48, dfLineTypeScale ); } } } /* -------------------------------------------------------------------- */ /* Write the vertices */ /* -------------------------------------------------------------------- */ if( !bHasDifferentZ && poLS->getGeometryType() == wkbLineString25D ) { // if LWPOLYLINE with Z write it only once if( !WriteValue( 38, poLS->getZ(0) ) ) return OGRERR_FAILURE; } for( int iVert = 0; iVert < poLS->getNumPoints(); iVert++ ) { if( bHasDifferentZ ) { WriteValue( 0, "VERTEX" ); WriteValue( 100, "AcDbEntity" ); WriteValue( 100, "AcDbVertex" ); WriteValue( 100, "AcDb3dPolylineVertex" ); WriteCore( poFeature ); } WriteValue( 10, poLS->getX(iVert) ); if( !WriteValue( 20, poLS->getY(iVert) ) ) return OGRERR_FAILURE; if( bHasDifferentZ ) { if( !WriteValue( 30 , poLS->getZ(iVert) ) ) return OGRERR_FAILURE; WriteValue( 70, 32 ); } } if( bHasDifferentZ ) { WriteValue( 0, "SEQEND" ); WriteCore( poFeature ); WriteValue( 100, "AcDbEntity" ); } delete poTool; 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 }
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 }
OGRErr OGRDXFWriterLayer::WritePOLYLINE( OGRFeature *poFeature, OGRGeometry *poGeom ) { /* -------------------------------------------------------------------- */ /* For now we handle multilinestrings by writing a series of */ /* entities. */ /* -------------------------------------------------------------------- */ if( poGeom == NULL ) poGeom = poFeature->GetGeometryRef(); if ( poGeom->IsEmpty() ) { return OGRERR_NONE; } if( wkbFlatten(poGeom->getGeometryType()) == wkbMultiPolygon || wkbFlatten(poGeom->getGeometryType()) == wkbMultiLineString ) { OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeom; int iGeom; OGRErr eErr = OGRERR_NONE; for( iGeom = 0; eErr == OGRERR_NONE && iGeom < poGC->getNumGeometries(); iGeom++ ) { eErr = WritePOLYLINE( poFeature, poGC->getGeometryRef( iGeom ) ); } return eErr; } /* -------------------------------------------------------------------- */ /* Polygons are written with on entity per ring. */ /* -------------------------------------------------------------------- */ if( wkbFlatten(poGeom->getGeometryType()) == wkbPolygon ) { OGRPolygon *poPoly = (OGRPolygon *) poGeom; int iGeom; OGRErr eErr; eErr = WritePOLYLINE( poFeature, poPoly->getExteriorRing() ); for( iGeom = 0; eErr == OGRERR_NONE && iGeom < poPoly->getNumInteriorRings(); iGeom++ ) { eErr = WritePOLYLINE( poFeature, poPoly->getInteriorRing(iGeom) ); } return eErr; } /* -------------------------------------------------------------------- */ /* Do we now have a geometry we can work with? */ /* -------------------------------------------------------------------- */ if( wkbFlatten(poGeom->getGeometryType()) != wkbLineString ) return OGRERR_UNSUPPORTED_GEOMETRY_TYPE; OGRLineString *poLS = (OGRLineString *) poGeom; /* -------------------------------------------------------------------- */ /* Write as a lightweight polygon, */ /* or as POLYLINE if the line contains different heights */ /* -------------------------------------------------------------------- */ int bHasDifferentZ = FALSE; if( poLS->getGeometryType() == wkbLineString25D ) { double z0 = poLS->getZ(0); for( int iVert = 0; iVert < poLS->getNumPoints(); iVert++ ) { if (z0 != poLS->getZ(iVert)) { bHasDifferentZ = TRUE; break; } } } WriteValue( 0, bHasDifferentZ ? "POLYLINE" : "LWPOLYLINE" ); WriteCore( poFeature ); WriteValue( 100, "AcDbEntity" ); if( bHasDifferentZ ) { WriteValue( 100, "AcDb3dPolyline" ); WriteValue( 10, 0.0 ); WriteValue( 20, 0.0 ); WriteValue( 30, 0.0 ); } else WriteValue( 100, "AcDbPolyline" ); if( EQUAL( poGeom->getGeometryName(), "LINEARRING" ) ) WriteValue( 70, 1 + (bHasDifferentZ ? 8 : 0) ); else WriteValue( 70, 0 + (bHasDifferentZ ? 8 : 0) ); if( !bHasDifferentZ ) WriteValue( 90, poLS->getNumPoints() ); else WriteValue( 66, "1" ); // Vertex Flag /* -------------------------------------------------------------------- */ /* Do we have styling information? */ /* -------------------------------------------------------------------- */ OGRStyleTool *poTool = NULL; OGRStyleMgr oSM; if( poFeature->GetStyleString() != NULL ) { oSM.InitFromFeature( poFeature ); if( oSM.GetPartCount() > 0 ) poTool = oSM.GetPart(0); } /* -------------------------------------------------------------------- */ /* Handle a PEN tool to control drawing color and width. */ /* Perhaps one day also dottedness, etc. */ /* -------------------------------------------------------------------- */ if( poTool && poTool->GetType() == OGRSTCPen ) { OGRStylePen *poPen = (OGRStylePen *) poTool; GBool bDefault; if( poPen->Color(bDefault) != NULL && !bDefault ) WriteValue( 62, ColorStringToDXFColor( poPen->Color(bDefault) ) ); // we want to fetch the width in ground units. poPen->SetUnit( OGRSTUGround, 1.0 ); double dfWidth = poPen->Width(bDefault); if( !bDefault ) WriteValue( 370, (int) floor(dfWidth * 100 + 0.5) ); } /* -------------------------------------------------------------------- */ /* Do we have a Linetype for the feature? */ /* -------------------------------------------------------------------- */ CPLString osLineType = poFeature->GetFieldAsString( "Linetype" ); if( osLineType.size() > 0 && (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 ); } } /* -------------------------------------------------------------------- */ /* Write the vertices */ /* -------------------------------------------------------------------- */ if( !bHasDifferentZ && poLS->getGeometryType() == wkbLineString25D ) { // if LWPOLYLINE with Z write it only once if( !WriteValue( 38, poLS->getZ(0) ) ) return OGRERR_FAILURE; } int iVert; for( iVert = 0; iVert < poLS->getNumPoints(); iVert++ ) { if( bHasDifferentZ ) { WriteValue( 0, "VERTEX" ); WriteValue( 100, "AcDbEntity" ); WriteValue( 100, "AcDbVertex" ); WriteValue( 100, "AcDb3dPolylineVertex" ); WriteCore( poFeature ); } WriteValue( 10, poLS->getX(iVert) ); if( !WriteValue( 20, poLS->getY(iVert) ) ) return OGRERR_FAILURE; if( bHasDifferentZ ) { if( !WriteValue( 30 , poLS->getZ(iVert) ) ) return OGRERR_FAILURE; WriteValue( 70, 32 ); } } if( bHasDifferentZ ) { WriteValue( 0, "SEQEND" ); WriteCore( poFeature ); WriteValue( 100, "AcDbEntity" ); } delete poTool; 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" ); int iVert; for( 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 }
CPLString OGRDXFWriterLayer::PrepareLineTypeDefinition( CPL_UNUSED OGRFeature *poFeature, OGRStyleTool *poTool ) { CPLString osDef; OGRStylePen *poPen = (OGRStylePen *) poTool; GBool bDefault; const char *pszPattern; /* -------------------------------------------------------------------- */ /* Fetch pattern. */ /* -------------------------------------------------------------------- */ pszPattern = poPen->Pattern( bDefault ); if( bDefault || strlen(pszPattern) == 0 ) return ""; /* -------------------------------------------------------------------- */ /* Split into pen up / pen down bits. */ /* -------------------------------------------------------------------- */ char **papszTokens = CSLTokenizeString(pszPattern); int i; double dfTotalLength = 0; for( i = 0; papszTokens != NULL && papszTokens[i] != NULL; i++ ) { const char *pszToken = papszTokens[i]; const char *pszUnit; CPLString osAmount; CPLString osDXFEntry; // Split amount and unit. for( pszUnit = pszToken; strchr( "0123456789.", *pszUnit) != NULL; pszUnit++ ) {} osAmount.assign(pszToken,(int) (pszUnit-pszToken)); // If the unit is other than 'g' we really should be trying to // do some type of transformation - but what to do? Pretty hard. // // Even entries are "pen down" represented as negative in DXF. if( i%2 == 0 ) osDXFEntry.Printf( " 49\n-%s\n 74\n0\n", osAmount.c_str() ); else osDXFEntry.Printf( " 49\n%s\n 74\n0\n", osAmount.c_str() ); osDef += osDXFEntry; dfTotalLength += CPLAtof(osAmount); } /* -------------------------------------------------------------------- */ /* Prefix 73 and 40 items to the definition. */ /* -------------------------------------------------------------------- */ CPLString osPrefix; osPrefix.Printf( " 73\n%d\n 40\n%.6g\n", CSLCount(papszTokens), dfTotalLength ); osDef = osPrefix + osDef; CSLDestroy( papszTokens ); return osDef; }
OGRErr OGRDXFWriterLayer::WriteHATCH( OGRFeature *poFeature, OGRGeometry *poGeom ) { /* -------------------------------------------------------------------- */ /* For now we handle multipolygons by writing a series of */ /* entities. */ /* -------------------------------------------------------------------- */ if( poGeom == NULL ) poGeom = poFeature->GetGeometryRef(); if ( poGeom->IsEmpty() ) { return OGRERR_NONE; } if( wkbFlatten(poGeom->getGeometryType()) == wkbMultiPolygon ) { OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeom; int iGeom; OGRErr eErr = OGRERR_NONE; for( iGeom = 0; eErr == OGRERR_NONE && iGeom < poGC->getNumGeometries(); iGeom++ ) { eErr = WriteHATCH( poFeature, poGC->getGeometryRef( iGeom ) ); } return eErr; } /* -------------------------------------------------------------------- */ /* Do we now have a geometry we can work with? */ /* -------------------------------------------------------------------- */ if( wkbFlatten(poGeom->getGeometryType()) != wkbPolygon ) return OGRERR_UNSUPPORTED_GEOMETRY_TYPE; /* -------------------------------------------------------------------- */ /* Write as a hatch. */ /* -------------------------------------------------------------------- */ WriteValue( 0, "HATCH" ); WriteCore( poFeature ); WriteValue( 100, "AcDbEntity" ); WriteValue( 100, "AcDbHatch" ); WriteValue( 2, "SOLID" ); // fill pattern WriteValue( 70, 1 ); // solid fill WriteValue( 71, 0 ); // associativity /* -------------------------------------------------------------------- */ /* Do we have styling information? */ /* -------------------------------------------------------------------- */ OGRStyleTool *poTool = NULL; OGRStyleMgr oSM; if( poFeature->GetStyleString() != NULL ) { oSM.InitFromFeature( poFeature ); if( oSM.GetPartCount() > 0 ) poTool = oSM.GetPart(0); } /* -------------------------------------------------------------------- */ /* 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.size() > 0 && (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 = (OGRPolygon *) poGeom; WriteValue( 91, poPoly->getNumInteriorRings() + 1 ); for( int iRing = -1; iRing < poPoly->getNumInteriorRings(); iRing++ ) { OGRLinearRing *poLR; if( iRing == -1 ) poLR = poPoly->getExteriorRing(); else poLR = poPoly->getInteriorRing( iRing ); 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) ); } } 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" ); int iVert; for( 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 }
OGRErr OGRKMLLayer::ICreateFeature( OGRFeature* poFeature ) { CPLAssert( NULL != poFeature ); CPLAssert( NULL != poDS_ ); if( !bWriter_ ) return OGRERR_FAILURE; if( bClosedForWriting ) { CPLError(CE_Failure, CPLE_NotSupported, "Interleaved feature adding to different layers is not supported"); return OGRERR_FAILURE; } VSILFILE *fp = poDS_->GetOutputFP(); CPLAssert( NULL != fp ); if( poDS_->GetLayerCount() == 1 && nWroteFeatureCount_ == 0 ) { CPLString osRet = WriteSchema(); if( osRet.size() ) VSIFPrintfL( fp, "%s", osRet.c_str() ); bSchemaWritten_ = TRUE; VSIFPrintfL( fp, "<Folder><name>%s</name>\n", pszName_); } VSIFPrintfL( fp, " <Placemark>\n" ); if( poFeature->GetFID() == OGRNullFID ) poFeature->SetFID( iNextKMLId_++ ); // Find and write the name element if (NULL != poDS_->GetNameField()) { for( int iField = 0; iField < poFeatureDefn_->GetFieldCount(); iField++ ) { OGRFieldDefn *poField = poFeatureDefn_->GetFieldDefn( iField ); if( poFeature->IsFieldSet( iField ) && EQUAL(poField->GetNameRef(), poDS_->GetNameField()) ) { const char *pszRaw = poFeature->GetFieldAsString( iField ); while( *pszRaw == ' ' ) pszRaw++; char *pszEscaped = OGRGetXML_UTF8_EscapedString( pszRaw ); VSIFPrintfL( fp, "\t<name>%s</name>\n", pszEscaped); CPLFree( pszEscaped ); } } } if (NULL != poDS_->GetDescriptionField()) { for( int iField = 0; iField < poFeatureDefn_->GetFieldCount(); iField++ ) { OGRFieldDefn *poField = poFeatureDefn_->GetFieldDefn( iField ); if( poFeature->IsFieldSet( iField ) && EQUAL(poField->GetNameRef(), poDS_->GetDescriptionField()) ) { const char *pszRaw = poFeature->GetFieldAsString( iField ); while( *pszRaw == ' ' ) pszRaw++; char *pszEscaped = OGRGetXML_UTF8_EscapedString( pszRaw ); VSIFPrintfL( fp, "\t<description>%s</description>\n", pszEscaped); CPLFree( pszEscaped ); } } } OGRwkbGeometryType eGeomType = wkbNone; if (poFeature->GetGeometryRef() != NULL) eGeomType = wkbFlatten(poFeature->GetGeometryRef()->getGeometryType()); if ( wkbPolygon == eGeomType || wkbMultiPolygon == eGeomType || wkbLineString == eGeomType || wkbMultiLineString == eGeomType ) { OGRStylePen *poPen = NULL; OGRStyleMgr oSM; if( poFeature->GetStyleString() != NULL ) { oSM.InitFromFeature( poFeature ); int i; for(i=0; i<oSM.GetPartCount();i++) { OGRStyleTool *poTool = oSM.GetPart(i); if (poTool && poTool->GetType() == OGRSTCPen ) { poPen = (OGRStylePen*) poTool; break; } delete poTool; } } VSIFPrintfL( fp, "\t<Style>"); if( poPen != NULL ) { GBool bDefault; int bHasWidth = FALSE; /* Require width to be returned in pixel */ poPen->SetUnit(OGRSTUPixel); double fW = poPen->Width(bDefault); if( bDefault ) fW = 1; else bHasWidth = TRUE; const char* pszColor = poPen->Color(bDefault); int nColorLen = static_cast<int>(CPLStrnlen(pszColor, 10)); if( pszColor != NULL && pszColor[0] == '#' && !bDefault && nColorLen >= 7) { char acColor[9] = {0}; /* Order of KML color is aabbggrr, whereas OGR color is #rrggbb[aa] ! */ if(nColorLen == 9) { acColor[0] = pszColor[7]; /* A */ acColor[1] = pszColor[8]; } else { acColor[0] = 'F'; acColor[1] = 'F'; } acColor[2] = pszColor[5]; /* B */ acColor[3] = pszColor[6]; acColor[4] = pszColor[3]; /* G */ acColor[5] = pszColor[4]; acColor[6] = pszColor[1]; /* R */ acColor[7] = pszColor[2]; VSIFPrintfL( fp, "<LineStyle><color>%s</color>", acColor); if (bHasWidth) VSIFPrintfL( fp, "<width>%g</width>", fW); VSIFPrintfL( fp, "</LineStyle>"); } else VSIFPrintfL( fp, "<LineStyle><color>ff0000ff</color></LineStyle>"); } else VSIFPrintfL( fp, "<LineStyle><color>ff0000ff</color></LineStyle>"); delete poPen; //If we're dealing with a polygon, add a line style that will stand out a bit VSIFPrintfL( fp, "<PolyStyle><fill>0</fill></PolyStyle></Style>\n" ); } int bHasFoundOtherField = FALSE; // Write all fields as SchemaData for( int iField = 0; iField < poFeatureDefn_->GetFieldCount(); iField++ ) { OGRFieldDefn *poField = poFeatureDefn_->GetFieldDefn( iField ); if( poFeature->IsFieldSet( iField )) { if (NULL != poDS_->GetNameField() && EQUAL(poField->GetNameRef(), poDS_->GetNameField()) ) continue; if (NULL != poDS_->GetDescriptionField() && EQUAL(poField->GetNameRef(), poDS_->GetDescriptionField()) ) continue; if (!bHasFoundOtherField) { VSIFPrintfL( fp, "\t<ExtendedData><SchemaData schemaUrl=\"#%s\">\n", pszName_ ); bHasFoundOtherField = TRUE; } const char *pszRaw = poFeature->GetFieldAsString( iField ); while( *pszRaw == ' ' ) pszRaw++; char *pszEscaped; if (poFeatureDefn_->GetFieldDefn(iField)->GetType() == OFTReal) { pszEscaped = CPLStrdup( pszRaw ); } else { pszEscaped = OGRGetXML_UTF8_EscapedString( pszRaw ); } VSIFPrintfL( fp, "\t\t<SimpleData name=\"%s\">%s</SimpleData>\n", poField->GetNameRef(), pszEscaped); CPLFree( pszEscaped ); } } if (bHasFoundOtherField) { VSIFPrintfL( fp, "\t</SchemaData></ExtendedData>\n" ); } // Write out Geometry - for now it isn't indented properly. if( poFeature->GetGeometryRef() != NULL ) { char* pszGeometry = NULL; OGREnvelope sGeomBounds; OGRGeometry* poWGS84Geom; if (NULL != poCT_) { poWGS84Geom = poFeature->GetGeometryRef()->clone(); poWGS84Geom->transform( poCT_ ); } else { poWGS84Geom = poFeature->GetGeometryRef(); } // TODO - porting // pszGeometry = poFeature->GetGeometryRef()->exportToKML(); pszGeometry = OGR_G_ExportToKML( (OGRGeometryH)poWGS84Geom, poDS_->GetAltitudeMode()); VSIFPrintfL( fp, " %s\n", pszGeometry ); CPLFree( pszGeometry ); poWGS84Geom->getEnvelope( &sGeomBounds ); poDS_->GrowExtents( &sGeomBounds ); if (NULL != poCT_) { delete poWGS84Geom; } } VSIFPrintfL( fp, " </Placemark>\n" ); nWroteFeatureCount_++; return OGRERR_NONE; }