/** * @brief KmlExport::createTimespanPlacemark Creates a timespan placemark, which allows the * trajectory to be played forward in time. The placemark also contains pertinent data about * the vehicle's state at that timespan * @param timestampPoint * @param lastPlacemarkTime * @param newPlacemarkTime * @return Returns the placemark containing the timespan */ PlacemarkPtr KmlExport::createTimespanPlacemark(const LLAVCoordinates ×tampPoint, quint32 lastPlacemarkTime, quint32 newPlacemarkTime) { // Create coordinates CoordinatesPtr coordinates = factory->CreateCoordinates(); coordinates->add_latlngalt(timestampPoint.latitude, timestampPoint.longitude, timestampPoint.altitude); // Create point, using previous coordinates PointPtr point = factory->CreatePoint(); point->set_extrude(true); // Extrude to ground point->set_altitudemode(kmldom::ALTITUDEMODE_ABSOLUTE); point->set_coordinates(coordinates); // Create the timespan TimeSpanPtr timeSpan = factory->CreateTimeSpan(); QDateTime startTime = QDateTime::currentDateTimeUtc().addMSecs(lastPlacemarkTime); // FIXME: Make it a function of the realtime preferably gotten from the GPS QDateTime endTime = QDateTime::currentDateTimeUtc().addMSecs(newPlacemarkTime); timeSpan->set_begin(startTime.toString(dateTimeFormat).toStdString()); timeSpan->set_end(endTime.toString(dateTimeFormat).toStdString()); // Create an icon style. This arrow icon will be rotated and colored to represent velocity AttitudeActual::DataFields attitudeActualData = attitudeActual->getData(); AirspeedActual::DataFields airspeedActualData = airspeedActual->getData(); IconStylePtr iconStyle = factory->CreateIconStyle(); iconStyle->set_color(mapVelocity2Color(airspeedActualData.CalibratedAirspeed)); iconStyle->set_heading(attitudeActualData.Yaw + 180); //Adding 180 degrees because the arrow art points down, i.e. south. // Create a line style. This defines the style for the "legs" connecting the points to the ground. LineStylePtr lineStyle = factory->CreateLineStyle(); lineStyle->set_color(mapVelocity2Color(timestampPoint.groundspeed)); // Link the style to the icon StylePtr style = factory->CreateStyle(); style->set_linestyle(lineStyle); style->set_iconstyle(iconStyle); // Generate the placemark with all above attributes PlacemarkPtr placemark = factory->CreatePlacemark(); placemark->set_geometry(point); placemark->set_timeprimitive(timeSpan); placemark->set_name(QString("%1").arg(timeStamp / 1000.0).toStdString()); placemark->set_visibility(true); // Set the placemark to use the custom rotated arrow style placemark->set_styleurl("#directiveArrowStyle"); placemark->set_styleselector(style); // Add a nice description to the placemark placemark->set_description(informationString.toStdString()); return placemark; }
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; }
/** * @brief KmlExport::exportToKML Triggers logfile export to KML. */ bool KmlExport::exportToKML() { bool ret = open(); if (!ret) { qDebug () << "Logfile failed to open during KML export"; return false; } // Parses logfile and generates KML document ret = preparseLogFile(); if (!ret) { qDebug () << "Logfile preparsing failed"; return false; } // Call parser. parseLogFile(); // Add track to <Document> document->add_feature(trackFolder); // Add timespans to <Document> document->add_feature(timestampFolder); // Add ground track to <Document> { LineStringPtr linestring = factory->CreateLineString(); linestring->set_extrude(false); // Do not extrude to ground linestring->set_altitudemode(kmldom::ALTITUDEMODE_CLAMPTOGROUND); linestring->set_coordinates(wallAxes[0]); MultiGeometryPtr multiGeometry = factory->CreateMultiGeometry(); multiGeometry->add_geometry(linestring); PlacemarkPtr placemark = factory->CreatePlacemark(); placemark->set_geometry(multiGeometry); placemark->set_styleurl("#ts_2_tb"); placemark->set_name("Ground track"); document->add_feature(placemark); } // Add wall axes to <Document> FolderPtr folder = factory->CreateFolder(); for (int i=0; i<numberOfWallAxes; i++) { LineStringPtr linestring = factory->CreateLineString(); linestring->set_extrude(false); // Do not extrude to ground linestring->set_altitudemode(kmldom::ALTITUDEMODE_ABSOLUTE); linestring->set_coordinates(wallAxes[i]); MultiGeometryPtr multiGeometry = factory->CreateMultiGeometry(); multiGeometry->add_geometry(linestring); PlacemarkPtr placemark = factory->CreatePlacemark(); placemark->set_geometry(multiGeometry); placemark->set_styleurl("#ts_1_tb"); folder->add_feature(placemark); folder->set_name("Wall axes"); } document->add_feature(folder); // Create <kml> and give it <Document>. KmlPtr kml = factory->CreateKml(); kml->set_feature(document); // kml takes ownership. // Serialize to XML std::string kml_data = kmldom::SerializePretty(kml); // Save to file if (QFileInfo(outputFileName).suffix().toLower() == "kmz") { if (!kmlengine::KmzFile::WriteKmz(outputFileName.toStdString().c_str(), kml_data)) { qDebug() << "KMZ write failed: " << outputFileName; QMessageBox::critical(new QWidget(),"KMZ write failed", "Failed to write KMZ file."); return false; } } else if (QFileInfo(outputFileName).suffix().toLower() == "kml") { if (!kmlbase::File::WriteStringToFile(kml_data, outputFileName.toStdString())) { qDebug() << "KML write failed: " << outputFileName; QMessageBox::critical(new QWidget(),"KML write failed", "Failed to write KML file."); return false; } } else { qDebug() << "Write failed. Invalid file name:" << outputFileName; QMessageBox::critical(new QWidget(),"Write failed", "Failed to write file. Invalid filename"); return false; } return true; }
/** * @brief KmlExport::CreateLineStringPlacemark Adds a line segment which is colored according to the * vehicle's speed. * @param startPoint Beginning point along line * @param endPoint End point point along line * @return Returns the placemark containing the line segment */ PlacemarkPtr KmlExport::CreateLineStringPlacemark(const LLAVCoordinates &startPoint, const LLAVCoordinates &endPoint, quint32 newPlacemarkTime) { CoordinatesPtr coordinates = factory->CreateCoordinates(); coordinates->add_latlngalt(startPoint.latitude, startPoint.longitude, startPoint.altitude); coordinates->add_latlngalt(endPoint.latitude, endPoint.longitude, endPoint.altitude); LineStringPtr linestring = factory->CreateLineString(); linestring->set_extrude(true); // Extrude to ground linestring->set_altitudemode(kmldom::ALTITUDEMODE_ABSOLUTE); linestring->set_coordinates(coordinates); StyleMapPtr styleMap = factory->CreateStyleMap(); // Add custom balloon style (gets rid of "Directions to here...") // https://groups.google.com/forum/?fromgroups#!topic/kml-support-getting-started/2CqF9oiynRY BalloonStylePtr balloonStyle = factory->CreateBalloonStyle(); balloonStyle->set_text("$[description]"); { double currentVelocity = (startPoint.groundspeed + endPoint.groundspeed)/2; // Set the linestyle. The color is a function of speed. LineStylePtr lineStyle = factory->CreateLineStyle(); lineStyle->set_color(mapVelocity2Color(currentVelocity)); PolyStylePtr polyStyle = factory->CreatePolyStyle(); polyStyle->set_color(mapVelocity2Color(currentVelocity, 100)); // Link the style to the icon StylePtr style = factory->CreateStyle(); style->set_balloonstyle(balloonStyle); style->set_linestyle(lineStyle); style->set_polystyle(polyStyle); PairPtr pair = factory->CreatePair(); pair->set_styleselector(style); pair->set_key(kmldom::STYLESTATE_NORMAL); styleMap->add_pair(pair); } { double currentVelocity = (startPoint.groundspeed + endPoint.groundspeed)/2; // Set the linestyle. The color is a function of speed. LineStylePtr lineStyle = factory->CreateLineStyle(); lineStyle->set_color(mapVelocity2Color(currentVelocity)); PolyStylePtr polyStyle = factory->CreatePolyStyle(); polyStyle->set_color(mapVelocity2Color(currentVelocity, 100)); polyStyle->set_fill(false); // Link the style to the icon StylePtr style = factory->CreateStyle(); style->set_balloonstyle(balloonStyle); style->set_linestyle(lineStyle); style->set_polystyle(polyStyle); PairPtr pair = factory->CreatePair(); pair->set_styleselector(style); pair->set_key(kmldom::STYLESTATE_HIGHLIGHT); styleMap->add_pair(pair); } PlacemarkPtr placemark = factory->CreatePlacemark(); placemark->set_geometry(linestring); placemark->set_styleselector(styleMap); placemark->set_visibility(true); // Create the timespan TimeSpanPtr timeSpan = factory->CreateTimeSpan(); QDateTime startTime = QDateTime::currentDateTimeUtc().addMSecs(newPlacemarkTime); // FIXME: Make this a function of the true time, preferably gotten from the GPS QDateTime endTime = QDateTime::currentDateTimeUtc().addMSecs(newPlacemarkTime); timeSpan->set_begin(startTime.toString(dateTimeFormat).toStdString()); timeSpan->set_end(endTime.toString(dateTimeFormat).toStdString()); // Set the name QDateTime trackTime = QDateTime::currentDateTimeUtc().addMSecs(newPlacemarkTime); // FIXME: Make it a function of the realtime preferably gotten from the GPS placemark->set_name(trackTime.toString(dateTimeFormat).toStdString()); // Add a nice description to the track placemark placemark->set_description(informationString.toStdString()); // Set the timespan placemark->set_timeprimitive(timeSpan); return placemark; }
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; }