KOSMIndoorMap

levelparser.cpp
1/*
2 SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "levelparser_p.h"
8#include "logging.h"
9
10#include <osm/element.h>
11
12// ### ugly workaround for locale-ignoring string to float conversion
13// std::from_chars offers that with C++17, but isn't actually implemented yet for floats/doubles...
14#include <private/qlocale_tools_p.h>
15
16#include <cstdlib>
17#include <limits>
18
19using namespace KOSMIndoorMap;
20
21// NOTE string to float conversion in here must be done ignoring the locale!
22void LevelParser::parse(QByteArray &&level, OSM::Element e, const std::function<void(int, OSM::Element)> &callback)
23{
24 int rangeBegin = std::numeric_limits<int>::max();
25 int numStartIdx = -1;
26
27 for (int i = 0; i < level.size(); ++i) {
28 auto &c = level[i];
29
30 if (c == ',') { // fix decimal separator errors
31 qCDebug(Log) << "syntax error in level tag:" << level << e.url();
32 c = '.';
33 }
34
35 if (std::isdigit(static_cast<unsigned char>(c)) || c == '.') {
36 if (numStartIdx < 0) {
37 numStartIdx = i;
38 }
39 continue;
40 }
41
42 if (c == ';') {
43 const int l = std::round(qstrtod(level.constData() + numStartIdx, nullptr, nullptr) * 10.0); // ### waiting for std::from_chars
44 if (rangeBegin <= l) {
45 for (int j = rangeBegin; j <= l; j += 10) {
46 callback(j, e);
47 }
48 rangeBegin = std::numeric_limits<int>::max();
49 } else {
50 callback(l, e);
51 }
52 numStartIdx = -1;
53 continue;
54 }
55
56 if (c == '-') {
57 if (numStartIdx < 0) {
58 numStartIdx = i;
59 } else {
60 rangeBegin = std::round(qstrtod(level.constData() + numStartIdx, nullptr, nullptr) * 10.0); // ### waiting for std::from_chars
61 numStartIdx = -1;
62 }
63 }
64 }
65
66 if (numStartIdx >= level.size() || numStartIdx < 0) {
67 return;
68 }
69 const int l = std::round(qstrtod(level.constData() + numStartIdx, nullptr, nullptr) * 10.0); // ### waiting for std::from_chars
70 if (rangeBegin <= l) {
71 for (int j = rangeBegin; j <= l; j += 10) {
72 callback(j, e);
73 }
74 } else {
75 callback(l, e);
76 }
77}
A reference to any of OSM::Node/OSM::Way/OSM::Relation.
Definition element.h:24
OSM-based multi-floor indoor maps for buildings.
QStringView level(QStringView ifopt)
const_pointer constData() const const
qsizetype size() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:17:55 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.