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();
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;
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);
100 if (dataSet.ways.empty()) {
104 writeByte(O5M_BLOCK_RESET, io);
105 m_stringTable.clear();
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);
141 if (dataSet.relations.empty()) {
145 writeByte(O5M_BLOCK_RESET, io);
146 m_stringTable.clear();
148 OSM::Id prevMemberId[3] = { 0, 0, 0 };
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)