KPublicTransport

geojson.cpp
1 /*
2  SPDX-FileCopyrightText: 2021 Volker Krause <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "geojson_p.h"
8 
9 #include <QJsonArray>
10 #include <QJsonObject>
11 #include <QPointF>
12 #include <QPolygonF>
13 
14 using namespace KPublicTransport;
15 
16 static QPointF readPointCoordinates(const QJsonArray &coords)
17 {
18  if (coords.size() != 2) {
19  return {};
20  }
21 
22  return {coords.at(0).toDouble(), coords.at(1).toDouble()};
23 }
24 
25 QPointF GeoJson::readPoint(const QJsonObject &obj)
26 {
27  const auto type = obj.value(QLatin1String("type")).toString();
28  if (type != QLatin1String("Point")) {
29  return {};
30  }
31 
32  const auto coordinates = obj.value(QLatin1String("coordinates")).toArray();
33  return readPointCoordinates(coordinates);
34 }
35 
36 static QPolygonF readPolygonCoordinates(const QJsonArray &coords)
37 {
38  QPolygonF poly;
39  poly.reserve(coords.size());
40  for (const auto &pointV : coords) {
41  const auto point = pointV.toArray();
42  poly.push_back(readPointCoordinates(point));
43  }
44  return poly;
45 }
46 
47 static QPolygonF readOuterPolygonCoordinates(const QJsonArray &coordinates)
48 {
49  if (coordinates.empty()) {
50  return {};
51  }
52  return readPolygonCoordinates(coordinates.at(0).toArray());
53 }
54 
55 QPolygonF GeoJson::readLineString(const QJsonObject &obj)
56 {
57  const auto type = obj.value(QLatin1String("type")).toString();
58  if (type != QLatin1String("LineString")) {
59  return {};
60  }
61 
62  const auto coordinates = obj.value(QLatin1String("coordinates")).toArray();
63  return readPolygonCoordinates(coordinates);
64 }
65 
66 QPolygonF GeoJson::readOuterPolygon(const QJsonObject &obj)
67 {
68  const auto type = obj.value(QLatin1String("type")).toString();
69  if (type == QLatin1String("Polygon")) {
70  return readOuterPolygonCoordinates(obj.value(QLatin1String("coordinates")).toArray());
71  } else if (type == QLatin1String("MultiPolygon")) {
72  const auto coordinates = obj.value(QLatin1String("coordinates")).toArray();
73  QPolygonF poly;
74  for (const auto &polyV : coordinates) {
75  auto subPoly = readOuterPolygonCoordinates(polyV.toArray());
76  poly = poly.empty() ? std::move(subPoly) : poly.united(subPoly);
77  }
78  return poly;
79  }
80 
81  return {};
82 }
83 
84 std::vector<QPolygonF> GeoJson::readOuterPolygons(const QJsonObject &obj)
85 {
86  const auto type = obj.value(QLatin1String("type")).toString();
87  if (type == QLatin1String("Polygon")) {
88  return {readOuterPolygonCoordinates(obj.value(QLatin1String("coordinates")).toArray())};
89  } else if (type == QLatin1String("MultiPolygon")) {
90  const auto coordinates = obj.value(QLatin1String("coordinates")).toArray();
91  std::vector<QPolygonF> polys;
92  polys.reserve(coordinates.size());
93  for (const auto &polyV : coordinates) {
94  polys.push_back(readOuterPolygonCoordinates(polyV.toArray()));
95  }
96  return polys;
97  }
98 
99  return {};
100 }
101 
102 static QJsonArray writePoint(const QPointF &p)
103 {
104  return QJsonArray({ p.x(), p.y() });
105 }
106 
107 QJsonObject GeoJson::writeLineString(const QPolygonF &lineString)
108 {
109  QJsonObject obj;
110  obj.insert(QLatin1String("type"), QLatin1String("LineString"));
111 
112  QJsonArray coords;
113  for (const auto &p : lineString) {
114  coords.push_back(writePoint(p));
115  }
116  obj.insert(QLatin1String("coordinates"), coords);
117  return obj;
118 }
119 
120 QJsonObject GeoJson::writePolygon(const QPolygonF &polygon)
121 {
122  QJsonObject obj;
123  obj.insert(QLatin1String("type"), QLatin1String("Polygon"));
124 
125  QJsonArray coords;
126  for (const auto &p : polygon) {
127  coords.push_back(writePoint(p));
128  }
129  QJsonArray polyArray;
130  polyArray.push_back(coords);
131  obj.insert(QLatin1String("coordinates"), polyArray);
132  return obj;
133 }
134 
135 QJsonObject GeoJson::writePolygons(const std::vector<QPolygonF> &polygons)
136 {
137  if (polygons.empty()) {
138  return {};
139  }
140  if (polygons.size() == 1) {
141  return writePolygon(polygons[0]);
142  }
143 
144  QJsonObject obj;
145  obj.insert(QLatin1String("type"), QLatin1String("MultiPolygon"));
146 
147  QJsonArray multiPolys;
148  for (const auto &polygon : polygons) {
149  QJsonArray coords;
150  for (const auto &p : polygon) {
151  coords.push_back(writePoint(p));
152  }
153  QJsonArray polyArray;
154  polyArray.push_back(coords);
155  multiPolys.push_back(polyArray);
156  }
157  obj.insert(QLatin1String("coordinates"), multiPolys);
158  return obj;
159 }
Query operations and data types for accessing realtime public transport information from online servi...
Definition: attribution.cpp:16
int size() const const
qreal x() const const
qreal y() const const
QString toString() const const
QJsonValue at(int i) const const
QJsonArray toArray() const const
bool empty() const const
void reserve(int size)
void push_back(const QJsonValue &value)
void push_back(const T &value)
QJsonValue value(const QString &key) const const
bool empty() const const
QJsonObject::iterator insert(const QString &key, const QJsonValue &value)
double toDouble(double defaultValue) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Oct 23 2021 23:05:21 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.