void TrackRecorder::exportGpx(QString name, QString desc, QString type) { qDebug()<<"Exporting track to gpx"; if(m_points.size() < 1) { qDebug()<<"Nothing to save"; return; // Nothing to save } QString homeDir = QStandardPaths::writableLocation(QStandardPaths::HomeLocation); QString subDir = "Rena"; QString filename; if(!name.isEmpty()) { filename = m_points.at(0).timestamp().toUTC().toString(Qt::ISODate) + " - " + name + ".gpx"; } else { filename = m_points.at(0).timestamp().toUTC().toString(Qt::ISODate) + ".gpx"; } qDebug()<<"File:"<<homeDir<<"/"<<subDir<<"/"<<filename; QDir home = QDir(homeDir); if(!home.exists(subDir)) { qDebug()<<"Directory does not exist, creating"; if(home.mkdir(subDir)) { qDebug()<<"Directory created"; } else { qDebug()<<"Directory creation failed, aborting"; return; } } QSaveFile file; file.setFileName(homeDir + "/" + subDir + "/" + filename); if(!file.open(QIODevice::WriteOnly | QIODevice::Text)) { qDebug()<<"File opening failed, aborting"; return; } QXmlStreamWriter xml; xml.setDevice(&file); xml.setAutoFormatting(true); // Human readable output xml.writeStartDocument(); xml.writeDefaultNamespace("http://www.topografix.com/GPX/1/1"); xml.writeStartElement("gpx"); xml.writeAttribute("version", "1.1"); xml.writeAttribute("Creator", "Rena for Sailfish"); // Now this is a bit redundant, but to be able to write the totals in the metadata section we do need to loop // through the whole pointset here... qreal duration = 0; qreal distance = 0; qreal avg_speed = 0; qreal max_speed = 0; QDateTime start_time(m_points.at(0).timestamp()); QDateTime stop_time(m_points.at(m_points.size()-1).timestamp()); duration = start_time.secsTo(stop_time); for(int i=1 ; i < m_points.size(); i++) { if(m_points.at(i-1).coordinate().type() != QGeoCoordinate::Coordinate3D) { break; // No position info, skip this point } QGeoCoordinate first(m_points.at(i-1).coordinate().latitude(), m_points.at(i-1).coordinate().longitude()); QGeoCoordinate second(m_points.at(i).coordinate().latitude(), m_points.at(i).coordinate().longitude()); distance += first.distanceTo(second); if(m_points.at(i).attribute(QGeoPositionInfo::GroundSpeed) > max_speed) { max_speed = m_points.at(i).attribute(QGeoPositionInfo::GroundSpeed); } } if(distance == 0 || duration == 0) { avg_speed = 0; } else { avg_speed = distance / duration; } xml.writeStartElement("metadata"); if(!name.isEmpty()) { xml.writeTextElement("name", name); } if(!desc.isEmpty()) { xml.writeTextElement("desc", desc); } if(!type.isEmpty()) { xml.writeTextElement("type", type); } xml.writeTextElement("duration", QString::number(duration)); xml.writeTextElement("distance", QString::number(distance)); xml.writeTextElement("avg_speed", QString::number(avg_speed)); xml.writeTextElement("max_speed", QString::number(max_speed)); xml.writeEndElement(); // metadata xml.writeStartElement("trk"); xml.writeStartElement("trkseg"); for(int i=0 ; i < m_points.size(); i++) { if(m_points.at(i).coordinate().type() == QGeoCoordinate::InvalidCoordinate) { break; // No position info, skip this point } xml.writeStartElement("trkpt"); xml.writeAttribute("lat", QString::number(m_points.at(i).coordinate().latitude(), 'g', 15)); xml.writeAttribute("lon", QString::number(m_points.at(i).coordinate().longitude(), 'g', 15)); xml.writeTextElement("time", m_points.at(i).timestamp().toUTC().toString(Qt::ISODate)); if(m_points.at(i).coordinate().type() == QGeoCoordinate::Coordinate3D) { xml.writeTextElement("ele", QString::number(m_points.at(i).coordinate().altitude(), 'g', 15)); } xml.writeStartElement("extensions"); if(m_points.at(i).hasAttribute(QGeoPositionInfo::Direction)) { xml.writeTextElement("dir", QString::number(m_points.at(i).attribute(QGeoPositionInfo::Direction), 'g', 15)); } if(m_points.at(i).hasAttribute(QGeoPositionInfo::GroundSpeed)) { xml.writeTextElement("g_spd", QString::number(m_points.at(i).attribute(QGeoPositionInfo::GroundSpeed), 'g', 15)); } if(m_points.at(i).hasAttribute(QGeoPositionInfo::VerticalSpeed)) { xml.writeTextElement("v_spd", QString::number(m_points.at(i).attribute(QGeoPositionInfo::VerticalSpeed), 'g', 15)); } if(m_points.at(i).hasAttribute(QGeoPositionInfo::MagneticVariation)) { xml.writeTextElement("m_var", QString::number(m_points.at(i).attribute(QGeoPositionInfo::MagneticVariation), 'g', 15)); } if(m_points.at(i).hasAttribute(QGeoPositionInfo::HorizontalAccuracy)) { xml.writeTextElement("h_acc", QString::number(m_points.at(i).attribute(QGeoPositionInfo::HorizontalAccuracy), 'g', 15)); } if(m_points.at(i).hasAttribute(QGeoPositionInfo::VerticalAccuracy)) { xml.writeTextElement("v_acc", QString::number(m_points.at(i).attribute(QGeoPositionInfo::VerticalAccuracy), 'g', 15)); } xml.writeEndElement(); // extensions xml.writeEndElement(); // trkpt } xml.writeEndElement(); // trkseg xml.writeEndElement(); // trk xml.writeEndElement(); // gpx xml.writeEndDocument(); file.commit(); if(file.error()) { qDebug()<<"Error in writing to a file"; qDebug()<<file.errorString(); } else { QDir renaDir = QDir(homeDir + "/" + subDir); renaDir.remove("Autosave"); } }