Commit 5bd4ba44 authored by Volker Krause's avatar Volker Krause
Browse files

Add GPX writer class

This implements the subset of what Itinerary can provide and Nextcloud
Maps can consume, and will be used for exporting trips to Nextcloud Maps.
parent 87a41b24
......@@ -8,6 +8,8 @@ ecm_add_test(jnipropertytest.cpp LINK_LIBRARIES Qt5::Test KAndroidExtras)
ecm_add_test(jniarraytest.cpp LINK_LIBRARIES Qt5::Test KAndroidExtras)
ecm_add_test(androidwrappertest.cpp LINK_LIBRARIES Qt5::Test KAndroidExtras)
ecm_add_test(gpxwritertest.cpp LINK_LIBRARIES Qt5::Test GpxIo)
ecm_add_test(pkpassmanagertest.cpp LINK_LIBRARIES Qt5::Test itinerary)
ecm_add_test(reservationmanagertest.cpp LINK_LIBRARIES Qt5::Test itinerary)
ecm_add_test(applicationcontrollertest.cpp LINK_LIBRARIES Qt5::Test itinerary)
......
/*
SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include <gpx/gpxwriter.h>
#include <QBuffer>
#include <QDateTime>
#include <QTimeZone>
#include <QtTest/qtest.h>
class GpxWriterTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void testWrite()
{
QByteArray gpxOut;
QBuffer buffer(&gpxOut);
buffer.open(QIODevice::WriteOnly);
{
Gpx::Writer writer(&buffer);
writer.writeStartMetadata();
writer.writeLink(QStringLiteral("https://apps.kde.org/itinerary"), QStringLiteral("KDE Itinerary"));
writer.writeEndMetadata();
writer.writeStartRoute();
writer.writeName(QStringLiteral("ICE 123 from A to B"));
writer.writeStartRoutePoint(46.1, 7.8);
writer.writeTime(QDateTime({1996, 10, 14}, {12, 23}, QTimeZone("Europe/Brussels")));
writer.writeEndRoutePoint();
writer.writeEndRoute();
}
const char expected[] =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<gpx xmlns=\"http://www.topografix.com/GPX/1/1\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1\">\n"
" <metadata>\n"
" <link href=\"https://apps.kde.org/itinerary\">\n"
" <text>KDE Itinerary</text>\n"
" </link>\n"
" </metadata>\n"
" <rte>\n"
" <name>ICE 123 from A to B</name>\n"
" <rtept lat=\"46.1\" lon=\"7.8\">\n"
" <time>1996-10-14T12:23:00+02:00</time>\n"
" </rtept>\n"
" </rte>\n"
"</gpx>\n";
if (gpxOut != expected) {
qDebug().noquote() << gpxOut;
}
QCOMPARE(gpxOut, expected);
}
};
QTEST_GUILESS_MAIN(GpxWriterTest)
#include "gpxwritertest.moc"
......@@ -6,4 +6,5 @@ add_definitions(-DTRANSLATION_DOMAIN=\"kde-itinerary\")
add_subdirectory(solidextras)
add_subdirectory(weather)
add_subdirectory(kandroidextras)
add_subdirectory(gpx)
add_subdirectory(app)
# SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
# SPDX-License-Identifier: BSD-3-Clause
add_library(GpxIo STATIC
gpxwriter.cpp
)
target_include_directories(GpxIo PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>")
target_link_libraries(GpxIo PUBLIC Qt5::Core)
/*
SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "gpxwriter.h"
#include <QDateTime>
Gpx::Writer::Writer(QIODevice* device)
: m_writer(device)
{
m_writer.setAutoFormatting(true);
m_writer.writeStartDocument(QStringLiteral("1.0"));
m_writer.writeStartElement(QStringLiteral("gpx"));
m_writer.writeAttribute(QStringLiteral("xmlns"), QStringLiteral("http://www.topografix.com/GPX/1/1"));
m_writer.writeNamespace(QStringLiteral("http://www.w3.org/2001/XMLSchema-instance"), QStringLiteral("xsi"));
m_writer.writeAttribute(QStringLiteral("xsi:schemaLocation"), QStringLiteral("http://www.topografix.com/GPX/1/1"));
}
Gpx::Writer::~Writer()
{
m_writer.writeEndElement();
m_writer.writeEndDocument();
}
void Gpx::Writer::writeStartMetadata()
{
m_writer.writeStartElement(QStringLiteral("metadata"));
}
void Gpx::Writer::writeEndMetadata()
{
m_writer.writeEndElement();
}
void Gpx::Writer::writeStartRoute()
{
m_writer.writeStartElement(QStringLiteral("rte"));
}
void Gpx::Writer::writeEndRoute()
{
m_writer.writeEndElement();
}
void Gpx::Writer::writeStartRoutePoint(float latitude, float longitude)
{
m_writer.writeStartElement(QStringLiteral("rtept"));
m_writer.writeAttribute(QStringLiteral("lat"), QString::number(latitude));
m_writer.writeAttribute(QStringLiteral("lon"), QString::number(longitude));
}
void Gpx::Writer::writeEndRoutePoint()
{
m_writer.writeEndElement();
}
void Gpx::Writer::writeName(const QString& name)
{
m_writer.writeTextElement(QStringLiteral("name"), name);
}
void Gpx::Writer::writeLink(const QString &href, const QString &text)
{
m_writer.writeStartElement(QStringLiteral("link"));
m_writer.writeAttribute(QStringLiteral("href"), href);
if (!text.isEmpty()) {
m_writer.writeTextElement(QStringLiteral("text"), text);
}
m_writer.writeEndElement();
}
void Gpx::Writer::writeTime(const QDateTime &time)
{
m_writer.writeTextElement(QStringLiteral("time"), time.toString(Qt::ISODate));
}
/*
SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#ifndef GPX_WRITER_H
#define GPX_WRITER_H
#include <QXmlStreamWriter>
class QDateTime;
class QIODevice;
namespace Gpx {
/** GPX file writer.
* @see https://www.topografix.com/GPX/1/1/
*/
class Writer
{
public:
explicit Writer(QIODevice *device);
~Writer();
void writeStartMetadata();
void writeEndMetadata();
void writeStartRoute();
void writeEndRoute();
void writeStartRoutePoint(float latitude, float longitude);
void writeEndRoutePoint();
void writeName(const QString &name);
void writeLink(const QString &href, const QString &text);
void writeTime(const QDateTime &time);
private:
QXmlStreamWriter m_writer;
};
}
#endif // GPX_WRITER_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment