15static void writeByte(uint8_t b, 
QIODevice *io)
 
   17    io->
write(
reinterpret_cast<const char*
>(&b), 1);
 
   20static void writeUnsigned(uint64_t n, 
QIODevice *io)
 
   23        uint8_t b = ((n >> 7) > 0 ? O5M_NUMBER_CONTINUATION : 0) | (n & O5M_NUMBER_MASK);
 
   29static void writeSigned(int64_t n, 
QIODevice *io)
 
   31    uint64_t u = n < 0 ? (-n - 1) : n;
 
   33    u |= n < 0 ? O5M_NUMBER_SIGNED_BIT : 0;
 
   39    writeByte(O5M_BLOCK_RESET, io);
 
   40    writeByte(O5M_BLOCK_HEADER, io);
 
   42    io->
write(O5M_HEADER, 4);
 
   47    writeByte(O5M_TRAILER, io);
 
   53    writeNodes(dataSet, io);
 
   54    writeWays(dataSet, io);
 
   55    writeRelations(dataSet, io);
 
   58    m_stringTable.clear();
 
   61void O5mWriter::writeNodes(
const OSM::DataSet &dataSet, QIODevice *io)
 
   63    if (dataSet.nodes.empty()) {
 
   67    writeByte(O5M_BLOCK_RESET, io);
 
   68    m_stringTable.clear();
 
   71    int64_t prevLat = 900'000'000ll;
 
   72    int64_t prevLon = 1'800'000'000ll;
 
   74    QByteArray bufferData;
 
   75    QBuffer buffer(&bufferData);
 
   76    for(
auto const &node: dataSet.nodes) {
 
   79        writeByte(O5M_BLOCK_NODE, io);
 
   81        writeSigned((int64_t)node.id - (int64_t)prevId, &buffer);
 
   84        writeByte(0x0, &buffer);
 
   85        writeSigned((int64_t)node.coordinate.longitude - prevLon, &buffer);
 
   86        prevLon = node.coordinate.longitude;
 
   87        writeSigned((int64_t)node.coordinate.latitude - prevLat, &buffer);
 
   88        prevLat = node.coordinate.latitude;
 
   90        writeTags(node, &buffer);
 
   93        writeUnsigned(bufferData.
size(), io);
 
   98void O5mWriter::writeWays(
const OSM::DataSet &dataSet, QIODevice *io)
 
  100    if (dataSet.ways.empty()) {
 
  104    writeByte(O5M_BLOCK_RESET, io);
 
  105    m_stringTable.clear();
 
  109    QByteArray bufferData;
 
  110    QBuffer buffer(&bufferData);
 
  111    QByteArray referencesBufferData;
 
  112    QBuffer referencesBuffer(&referencesBufferData);
 
  114    for (
auto const &way: dataSet.ways) {
 
  115        writeByte(O5M_BLOCK_WAY, io);
 
  119        writeSigned((int64_t)way.id - (int64_t)prevId, &buffer);
 
  121        writeByte(0x0, &buffer);
 
  123        referencesBufferData.
clear();
 
  125        for (
const auto &node : way.nodes) {
 
  126            writeSigned((int64_t)node - (int64_t)prevNodeId, &referencesBuffer);
 
  129        referencesBuffer.close();
 
  130        writeUnsigned(referencesBufferData.
size(), &buffer);
 
  131        buffer.write(referencesBufferData.
constData(), referencesBufferData.
size());
 
  132        writeTags(way, &buffer);
 
  134        writeUnsigned(bufferData.
size(), io);
 
  139void O5mWriter::writeRelations(
const OSM::DataSet &dataSet, QIODevice *io)
 
  141    if (dataSet.relations.empty()) {
 
  145    writeByte(O5M_BLOCK_RESET, io);
 
  146    m_stringTable.clear();
 
  148    OSM::Id prevMemberId[3] = { 0, 0, 0 };
 
  150    QByteArray bufferData;
 
  151    QBuffer buffer(&bufferData);
 
  152    QByteArray referencesBufferData;
 
  153    QBuffer referencesBuffer(&referencesBufferData);
 
  156    for (
auto const &relation: dataSet.relations) {
 
  157        writeByte(O5M_BLOCK_RELATION, io);
 
  162        writeSigned((int64_t)relation.id - (int64_t)prevId, &buffer);
 
  163        prevId = relation.id;
 
  164        writeByte(0x0, &buffer);
 
  166        referencesBufferData.
clear();
 
  169        for (
const auto &member : relation.members) {
 
  171            switch (member.type()) {
 
  172                case OSM::Type::Node:
 
  173                    writeSigned((int64_t)member.id - (int64_t)prevMemberId[0], &referencesBuffer);
 
  174                    prevMemberId[0] = member.id;
 
  175                    role += (
const char)O5M_MEMTYPE_NODE;
 
  176                    role += member.role().name();
 
  177                    writeStringPair(role.
constData(), 
nullptr, &referencesBuffer);
 
  180                    writeSigned((int64_t)member.id - (int64_t)prevMemberId[1], &referencesBuffer);
 
  181                    prevMemberId[1] = member.id;
 
  182                    role += (
const char)O5M_MEMTYPE_WAY;
 
  183                    role += member.role().name();
 
  184                    writeStringPair(role.
constData(), 
nullptr, &referencesBuffer);
 
  186                case OSM::Type::Relation:
 
  187                    writeSigned((int64_t)member.id - (int64_t)prevMemberId[2], &referencesBuffer);
 
  188                    prevMemberId[2] = member.id;
 
  189                    role += (
const char)O5M_MEMTYPE_RELATION;
 
  190                    role += member.role().name();
 
  191                    writeStringPair(role.
constData(), 
nullptr, &referencesBuffer);
 
  193                case OSM::Type::Null:
 
  199        referencesBuffer.close();
 
  200        writeUnsigned(referencesBufferData.
size(), &buffer);
 
  201        buffer.write(referencesBufferData.
constData(), referencesBufferData.
size());
 
  202        writeTags(relation, &buffer);
 
  204        writeUnsigned(bufferData.
size(), io);
 
  210void O5mWriter::writeTags(
const T &elem, QIODevice *io)
 
  212    for (
auto &tag : elem.tags) {
 
  213        writeStringPair(tag.key.name(), tag.value.constData(), io);
 
  217void O5mWriter::writeStringPair(
const char *s1, 
const char *s2, QIODevice *io)
 
  225    const auto it = m_stringTable.find(p);
 
  226    if (it != m_stringTable.end()) {
 
  227        writeUnsigned(m_stringTable.size() - it->second, io);
 
  236        if ((std::strlen(s1) + (s2 ? std::strlen(s2) : 0) <= O5M_STRING_TABLE_MAXLEN) && (m_stringTable.size() <= O5M_STRING_TABLE_SIZE)) {
 
  237            m_stringTable[p] = m_stringTable.size();
 
A set of nodes, ways and relations.
 
Low-level types and functions to work with raw OSM data as efficiently as possible.
 
int64_t Id
OSM element identifier.
 
Common declarations for O5M file format I/O.
 
const char * constData() const const
 
qsizetype size() const const
 
qint64 write(const QByteArray &data)