Example #1
0
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");
    }
}