/** * @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 ogr2altitudemode_rec ( GeometryPtr poKmlGeometry, int iAltitudeMode, int isGX ) { PointPtr poKmlPoint; LineStringPtr poKmlLineString; PolygonPtr poKmlPolygon; MultiGeometryPtr poKmlMultiGeometry; size_t nGeom; size_t i; switch ( poKmlGeometry->Type ( ) ) { case kmldom::Type_Point: poKmlPoint = AsPoint ( poKmlGeometry ); if ( !isGX ) poKmlPoint->set_altitudemode ( iAltitudeMode ); else poKmlPoint->set_gx_altitudemode ( iAltitudeMode ); break; case kmldom::Type_LineString: poKmlLineString = AsLineString ( poKmlGeometry ); if ( !isGX ) poKmlLineString->set_altitudemode ( iAltitudeMode ); else poKmlLineString->set_gx_altitudemode ( iAltitudeMode ); break; case kmldom::Type_LinearRing: break; case kmldom::Type_Polygon: poKmlPolygon = AsPolygon ( poKmlGeometry ); if ( !isGX ) poKmlPolygon->set_altitudemode ( iAltitudeMode ); else poKmlPolygon->set_gx_altitudemode ( iAltitudeMode ); break; case kmldom::Type_MultiGeometry: poKmlMultiGeometry = AsMultiGeometry ( poKmlGeometry ); nGeom = poKmlMultiGeometry->get_geometry_array_size ( ); for ( i = 0; i < nGeom; i++ ) { ogr2altitudemode_rec ( poKmlMultiGeometry-> get_geometry_array_at ( i ), iAltitudeMode, isGX ); } break; default: break; } }