Commit 17280400 authored by Volker Krause's avatar Volker Krause
Browse files

Avoid floating point math when parsing coordinates from XML attributes

This can cause loss of precision even on 64 bit architectures, and
apparently even more so on 32 bit. Mainly matters for unit test as
we don't use the OSM XML format elsewhere anyway.
parent 6ed9e87b
......@@ -26,7 +26,7 @@
mode: Rail
lines: EC 173|EC 379|RE3|RE5
4
position: 1425248313 1933695421
position: 1425248314 1933695421
stop point: n3856100098
edge: n3856100098
area: w202719941
......@@ -106,7 +106,7 @@
level: 20
mode: Rail
15
position: 1425251819 1933700299
position: 1425251819 1933700300
stop point: n27412648
edge: n27412648
area: r930922
......@@ -124,7 +124,7 @@
mode: Rail
lines: S3|S5|S7|S9
1
position: 1425252588 1933702857
position: 1425252589 1933702857
stop point: n446289301
edge: n446289301
area: w86379623
......@@ -141,7 +141,7 @@
mode: Tram
lines: M5|M8|M10
5
position: 1425264968 1933694391
position: 1425264969 1933694391
stop point: n2085211643
edge: n2085211643
area: r6809883
......
......@@ -145,7 +145,7 @@
name: G
position: n1629931022
9
position: 1409429562 1869594995
position: 1409429562 1869594996
stop point: n1629836040
edge: n1629836040
area: r6838147
......@@ -167,7 +167,7 @@
name: G
position: n1629931028
10
position: 1409429759 1869595583
position: 1409429760 1869595583
stop point: n1629836001
edge: n1629836001
area: r6838156
......@@ -211,7 +211,7 @@
mode: Tram
lines: 16|18
2
position: 1409418150 1869572123
position: 1409418151 1869572123
stop point: n1341075078
edge: n1341075078
area: w119317753
......
......@@ -13,7 +13,7 @@
name: E
position: n4126318179
6
position: 1435530832 1899348982
position: 1435530832 1899348983
stop point: n1686600812
edge: w662834904
area: w42873615
......@@ -150,7 +150,7 @@ Hamburg-Altona
mode: Rail
lines: S11|S31
Hamburg-Altona
position: 1435518777 1899349360
position: 1435518777 1899349361
stop point: n300809530
edge: n300809530
area: w42838505
......@@ -159,7 +159,7 @@ Hamburg-Altona
mode: Rail
lines: S1|S2|S3
Hamburg-Altona
position: 1435518544 1899343955
position: 1435518544 1899343956
stop point: n535951138
edge: n535951138
area: w42838504
......
1
position: 1435522329 1900083177
position: 1435522329 1900083178
stop point: n1359198009
edge: n1359198009
area: r4869406
......@@ -35,7 +35,7 @@
mode: Rail
lines: A1|S2|S3|S21|S31
5
position: 1435534436 1900069801
position: 1435534436 1900069802
stop point: n3934362101
edge: n3934362101
area: w28679287
......@@ -49,7 +49,7 @@
name: E
position: n6002452933
6
position: 1435534104 1900068116
position: 1435534105 1900068116
stop point: n3934362100
edge: n3934362100
area: w28679287
......@@ -131,7 +131,7 @@
name: B
position: n5859780192
13
position: 1435511273 1900067919
position: 1435511274 1900067919
stop point: n3595451434
edge: n3595451434
area: w152813949
......@@ -163,7 +163,7 @@
level: -20
mode: Subway
1
position: 1435519032 1900096591
position: 1435519032 1900096592
stop point: n1145811379
edge: n1145811379
area: n1145811379
......@@ -195,7 +195,7 @@
level: -20
mode: Subway
Hauptbahnhof Nord
position: 1435541390 1900061804
position: 1435541391 1900061804
stop point: n1143048428
edge: n1143048428
area: w408855544
......
......@@ -51,7 +51,7 @@
level: 10
mode: Rail
9
position: 1413459477 1923816067
position: 1413459477 1923816068
stop point: n2299420233
edge: w585434420
area: r5299028
......@@ -78,7 +78,7 @@
mode: Rail
lines: ICE 11|ICE 28
12
position: 1413457989 1923819758
position: 1413457989 1923819759
stop point: n2299420217
edge: w367895064
area: r5299021
......@@ -111,7 +111,7 @@
mode: Rail
lines: IC 55
15
position: 1413456335 1923824249
position: 1413456336 1923824249
stop point: n2299420220
edge: w180179182
area: r5299022
......@@ -120,7 +120,7 @@
mode: Rail
lines: ICE 50
16
position: 1413455918 1923825296
position: 1413455919 1923825296
stop point: n2299420221
edge: w585434432
area: r5299023
......@@ -144,7 +144,7 @@
level: 10
mode: Rail
18a
position: 1413466213 1923841277
position: 1413466213 1923841278
stop point: n1834202015
edge: w585434437
area: r9615735
......
......@@ -24,7 +24,7 @@
level: -30
mode: Rail
4
position: 1388435246 1823740874
position: 1388435247 1823740874
stop point: <null>
edge: <null>
area: w406470900
......@@ -89,7 +89,7 @@
name: V
position: n3618878871
11
position: 1388430150 1823782409
position: 1388430151 1823782409
stop point: <null>
edge: <null>
area: w361731435
......@@ -108,7 +108,7 @@
name: W
position: n3618878868
13
position: 1388430150 1823782409
position: 1388430151 1823782409
stop point: <null>
edge: <null>
area: w361731435
......@@ -165,7 +165,7 @@
name: W
position: n3618878870
19
position: 1388430809 1823786283
position: 1388430809 1823786284
stop point: <null>
edge: <null>
area: w361731429
......@@ -186,7 +186,7 @@
name: W
position: n3618878872
21
position: 1388430809 1823786283
position: 1388430809 1823786284
stop point: <null>
edge: <null>
area: w361731429
......@@ -528,7 +528,7 @@ Voie 1
level: 0
mode: Subway
Voie 2
position: 1388458489 1823737851
position: 1388458490 1823737852
stop point: n7064892033
edge: n7064892033
area: w756383638
......
......@@ -11,6 +11,8 @@
#include <QIODevice>
#include <QXmlStreamReader>
#include <cmath>
using namespace OSM;
XmlParser::XmlParser(DataSet* dataSet)
......@@ -45,11 +47,29 @@ void XmlParser::parse(QIODevice *io)
}
}
// parse double coordinate value without actually doing floating point computations
// this avoids any loss in precision we can other get heret
uint32_t parseCoordinateValue(QStringView s, int offset)
{
const auto idx = s.indexOf(QLatin1Char('.'));
if (idx < 0) {
return s.toUInt() * 10'000'000;
}
uint32_t result = (uint32_t)(s.left(idx).toInt() + offset) * 10'000'000;
const auto decimals = s.mid(idx + 1);
if (decimals.size() >= 7) {
result += decimals.left(7).toUInt();
} else {
result += decimals.toUInt() * std::pow(10, 7 - decimals.size());
}
return result;
}
void XmlParser::parseNode(QXmlStreamReader &reader)
{
Node node;
node.id = reader.attributes().value(QLatin1String("id")).toLongLong();
node.coordinate = Coordinate(reader.attributes().value(QLatin1String("lat")).toDouble(), reader.attributes().value(QLatin1String("lon")).toDouble());
node.coordinate = Coordinate(parseCoordinateValue(reader.attributes().value(QLatin1String("lat")), 90), parseCoordinateValue(reader.attributes().value(QLatin1String("lon")), 180));
while (!reader.atEnd() && reader.readNext() != QXmlStreamReader::EndElement) {
if (reader.tokenType() != QXmlStreamReader::StartElement) {
......
Supports Markdown
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