void field2kml ( OGRFeature * poOgrFeat, OGRLIBKMLLayer * poOgrLayer, KmlFactory * poKmlFactory, PlacemarkPtr poKmlPlacemark ) { int i; SchemaDataPtr poKmlSchemaData = poKmlFactory->CreateSchemaData ( ); SchemaPtr poKmlSchema = poOgrLayer->GetKmlSchema ( ); /***** set the url to the schema *****/ if ( poKmlSchema && poKmlSchema->has_id ( ) ) { std::string oKmlSchemaID = poKmlSchema->get_id ( ); std::string oKmlSchemaURL = "#"; oKmlSchemaURL.append ( oKmlSchemaID ); poKmlSchemaData->set_schemaurl ( oKmlSchemaURL ); } const char *namefield = CPLGetConfigOption ( "LIBKML_NAME_FIELD", "Name" ); const char *descfield = CPLGetConfigOption ( "LIBKML_DESCRIPTION_FIELD", "description" ); const char *tsfield = CPLGetConfigOption ( "LIBKML_TIMESTAMP_FIELD", "timestamp" ); const char *beginfield = CPLGetConfigOption ( "LIBKML_BEGIN_FIELD", "begin" ); const char *endfield = CPLGetConfigOption ( "LIBKML_END_FIELD", "end" ); const char *altitudeModefield = CPLGetConfigOption ( "LIBKML_ALTITUDEMODE_FIELD", "altitudeMode" ); const char *tessellatefield = CPLGetConfigOption ( "LIBKML_TESSELLATE_FIELD", "tessellate" ); const char *extrudefield = CPLGetConfigOption ( "LIBKML_EXTRUDE_FIELD", "extrude" ); const char *visibilityfield = CPLGetConfigOption ( "LIBKML_VISIBILITY_FIELD", "visibility" ); TimeSpanPtr poKmlTimeSpan = NULL; int nFields = poOgrFeat->GetFieldCount ( ); int iSkip1 = -1; int iSkip2 = -1; for ( i = 0; i < nFields; i++ ) { /***** if the field is set to skip, do so *****/ if ( i == iSkip1 || i == iSkip2 ) continue; /***** if the field isn't set just bail now *****/ if ( !poOgrFeat->IsFieldSet ( i ) ) continue; OGRFieldDefn *poOgrFieldDef = poOgrFeat->GetFieldDefnRef ( i ); OGRFieldType type = poOgrFieldDef->GetType ( ); const char *name = poOgrFieldDef->GetNameRef ( ); SimpleDataPtr poKmlSimpleData = NULL; int year, month, day, hour, min, sec, tz; switch ( type ) { case OFTString: // String of ASCII chars { char* pszUTF8String = OGRLIBKMLSanitizeUTF8String( poOgrFeat->GetFieldAsString ( i )); /***** name *****/ if ( EQUAL ( name, namefield ) ) { poKmlPlacemark->set_name ( pszUTF8String ); CPLFree( pszUTF8String ); continue; } /***** description *****/ else if ( EQUAL ( name, descfield ) ) { poKmlPlacemark->set_description ( pszUTF8String ); CPLFree( pszUTF8String ); continue; } /***** altitudemode *****/ else if ( EQUAL ( name, altitudeModefield ) ) { const char *pszAltitudeMode = pszUTF8String ; int isGX = FALSE; int iAltitudeMode = kmldom::ALTITUDEMODE_CLAMPTOGROUND; if ( EQUAL ( pszAltitudeMode, "clampToGround" ) ) iAltitudeMode = kmldom::ALTITUDEMODE_CLAMPTOGROUND; else if ( EQUAL ( pszAltitudeMode, "relativeToGround" ) ) iAltitudeMode = kmldom::ALTITUDEMODE_RELATIVETOGROUND; else if ( EQUAL ( pszAltitudeMode, "absolute" ) ) iAltitudeMode = kmldom::ALTITUDEMODE_ABSOLUTE; else if ( EQUAL ( pszAltitudeMode, "relativeToSeaFloor" ) ) { iAltitudeMode = kmldom::GX_ALTITUDEMODE_RELATIVETOSEAFLOOR; isGX = TRUE; } else if ( EQUAL ( pszAltitudeMode, "clampToSeaFloor" ) ) { iAltitudeMode = kmldom::GX_ALTITUDEMODE_CLAMPTOSEAFLOOR; isGX = TRUE; } if ( poKmlPlacemark->has_geometry ( ) ) { GeometryPtr poKmlGeometry = poKmlPlacemark->get_geometry ( ); ogr2altitudemode_rec ( poKmlGeometry, iAltitudeMode, isGX ); } CPLFree( pszUTF8String ); continue; } /***** timestamp *****/ else if ( EQUAL ( name, tsfield ) ) { TimeStampPtr poKmlTimeStamp = poKmlFactory->CreateTimeStamp ( ); poKmlTimeStamp->set_when ( pszUTF8String ); poKmlPlacemark->set_timeprimitive ( poKmlTimeStamp ); CPLFree( pszUTF8String ); continue; } /***** begin *****/ if ( EQUAL ( name, beginfield ) ) { if ( !poKmlTimeSpan ) { poKmlTimeSpan = poKmlFactory->CreateTimeSpan ( ); poKmlPlacemark->set_timeprimitive ( poKmlTimeSpan ); } poKmlTimeSpan->set_begin ( pszUTF8String ); CPLFree( pszUTF8String ); continue; } /***** end *****/ else if ( EQUAL ( name, endfield ) ) { if ( !poKmlTimeSpan ) { poKmlTimeSpan = poKmlFactory->CreateTimeSpan ( ); poKmlPlacemark->set_timeprimitive ( poKmlTimeSpan ); } poKmlTimeSpan->set_end ( pszUTF8String ); CPLFree( pszUTF8String ); continue; } /***** other *****/ poKmlSimpleData = poKmlFactory->CreateSimpleData ( ); poKmlSimpleData->set_name ( name ); poKmlSimpleData->set_text ( pszUTF8String ); CPLFree( pszUTF8String ); break; } case OFTDate: // Date { poOgrFeat->GetFieldAsDateTime ( i, &year, &month, &day, &hour, &min, &sec, &tz ); int iTimeField; for ( iTimeField = i + 1; iTimeField < nFields; iTimeField++ ) { if ( iTimeField == iSkip1 || iTimeField == iSkip2 ) continue; OGRFieldDefn *poOgrFieldDef2 = poOgrFeat->GetFieldDefnRef ( i ); OGRFieldType type2 = poOgrFieldDef2->GetType ( ); const char *name2 = poOgrFieldDef2->GetNameRef ( ); if ( EQUAL ( name2, name ) && type2 == OFTTime && ( EQUAL ( name, tsfield ) || EQUAL ( name, beginfield ) || EQUAL ( name, endfield ) ) ) { int year2, month2, day2, hour2, min2, sec2, tz2; poOgrFeat->GetFieldAsDateTime ( iTimeField, &year2, &month2, &day2, &hour2, &min2, &sec2, &tz2 ); hour = hour2; min = min2; sec = sec2; tz = tz2; if ( 0 > iSkip1 ) iSkip1 = iTimeField; else iSkip2 = iTimeField; } } goto Do_DateTime; } case OFTTime: // Time { poOgrFeat->GetFieldAsDateTime ( i, &year, &month, &day, &hour, &min, &sec, &tz ); int iTimeField; for ( iTimeField = i + 1; iTimeField < nFields; iTimeField++ ) { if ( iTimeField == iSkip1 || iTimeField == iSkip2 ) continue; OGRFieldDefn *poOgrFieldDef2 = poOgrFeat->GetFieldDefnRef ( i ); OGRFieldType type2 = poOgrFieldDef2->GetType ( ); const char *name2 = poOgrFieldDef2->GetNameRef ( ); if ( EQUAL ( name2, name ) && type2 == OFTTime && ( EQUAL ( name, tsfield ) || EQUAL ( name, beginfield ) || EQUAL ( name, endfield ) ) ) { int year2, month2, day2, hour2, min2, sec2, tz2; poOgrFeat->GetFieldAsDateTime ( iTimeField, &year2, &month2, &day2, &hour2, &min2, &sec2, &tz2 ); year = year2; month = month2; day = day2; if ( 0 > iSkip1 ) iSkip1 = iTimeField; else iSkip2 = iTimeField; } } goto Do_DateTime; } case OFTDateTime: // Date and Time { poOgrFeat->GetFieldAsDateTime ( i, &year, &month, &day, &hour, &min, &sec, &tz ); Do_DateTime: /***** timestamp *****/ if ( EQUAL ( name, tsfield ) ) { char *timebuf = OGRGetXMLDateTime ( year, month, day, hour, min, sec, tz ); TimeStampPtr poKmlTimeStamp = poKmlFactory->CreateTimeStamp ( ); poKmlTimeStamp->set_when ( timebuf ); poKmlPlacemark->set_timeprimitive ( poKmlTimeStamp ); CPLFree( timebuf ); continue; } /***** begin *****/ if ( EQUAL ( name, beginfield ) ) { char *timebuf = OGRGetXMLDateTime ( year, month, day, hour, min, sec, tz ); if ( !poKmlTimeSpan ) { poKmlTimeSpan = poKmlFactory->CreateTimeSpan ( ); poKmlPlacemark->set_timeprimitive ( poKmlTimeSpan ); } poKmlTimeSpan->set_begin ( timebuf ); CPLFree( timebuf ); continue; } /***** end *****/ else if ( EQUAL ( name, endfield ) ) { char *timebuf = OGRGetXMLDateTime ( year, month, day, hour, min, sec, tz ); if ( !poKmlTimeSpan ) { poKmlTimeSpan = poKmlFactory->CreateTimeSpan ( ); poKmlPlacemark->set_timeprimitive ( poKmlTimeSpan ); } poKmlTimeSpan->set_end ( timebuf ); CPLFree( timebuf ); continue; } /***** other *****/ poKmlSimpleData = poKmlFactory->CreateSimpleData ( ); poKmlSimpleData->set_name ( name ); poKmlSimpleData->set_text ( poOgrFeat-> GetFieldAsString ( i ) ); break; } case OFTInteger: // Simple 32bit integer /***** extrude *****/ if ( EQUAL ( name, extrudefield ) ) { if ( poKmlPlacemark->has_geometry ( ) && -1 < poOgrFeat->GetFieldAsInteger ( i ) ) { GeometryPtr poKmlGeometry = poKmlPlacemark->get_geometry ( ); ogr2extrude_rec ( poOgrFeat->GetFieldAsInteger ( i ), poKmlGeometry ); } continue; } /***** tessellate *****/ if ( EQUAL ( name, tessellatefield ) ) { if ( poKmlPlacemark->has_geometry ( ) && -1 < poOgrFeat->GetFieldAsInteger ( i ) ) { GeometryPtr poKmlGeometry = poKmlPlacemark->get_geometry ( ); ogr2tessellate_rec ( poOgrFeat->GetFieldAsInteger ( i ), poKmlGeometry ); } continue; } /***** visibility *****/ if ( EQUAL ( name, visibilityfield ) ) { if ( -1 < poOgrFeat->GetFieldAsInteger ( i ) ) poKmlPlacemark->set_visibility ( poOgrFeat-> GetFieldAsInteger ( i ) ); continue; } /***** other *****/ poKmlSimpleData = poKmlFactory->CreateSimpleData ( ); poKmlSimpleData->set_name ( name ); poKmlSimpleData->set_text ( poOgrFeat->GetFieldAsString ( i ) ); break; case OFTReal: // Double Precision floating point { poKmlSimpleData = poKmlFactory->CreateSimpleData ( ); poKmlSimpleData->set_name ( name ); char* pszStr = CPLStrdup( poOgrFeat->GetFieldAsString ( i ) ); /* Use point as decimal separator */ char* pszComma = strchr(pszStr, ','); if (pszComma) *pszComma = '.'; poKmlSimpleData->set_text ( pszStr ); CPLFree(pszStr); break; } case OFTStringList: // Array of strings case OFTIntegerList: // List of 32bit integers case OFTRealList: // List of doubles case OFTBinary: // Raw Binary data case OFTWideStringList: // deprecated default: /***** other *****/ poKmlSimpleData = poKmlFactory->CreateSimpleData ( ); poKmlSimpleData->set_name ( name ); poKmlSimpleData->set_text ( poOgrFeat->GetFieldAsString ( i ) ); break; } poKmlSchemaData->add_simpledata ( poKmlSimpleData ); } /***** dont add it to the placemark unless there is data *****/ if ( poKmlSchemaData->get_simpledata_array_size ( ) > 0 ) { ExtendedDataPtr poKmlExtendedData = poKmlFactory->CreateExtendedData ( ); poKmlExtendedData->add_schemadata ( poKmlSchemaData ); poKmlPlacemark->set_extendeddata ( poKmlExtendedData ); } return; }