Commit 7d1931c4 authored by Volker Krause's avatar Volker Krause
Browse files

Add GeoJson I/O methods for unmerged multi-polygons

parent 14fd9ac7
......@@ -44,6 +44,14 @@ static QPolygonF readPolygonCoordinates(const QJsonArray &coords)
return poly;
}
static QPolygonF readOuterPolygonCoordinates(const QJsonArray &coordinates)
{
if (coordinates.empty()) {
return {};
}
return readPolygonCoordinates(coordinates.at(0).toArray());
}
QPolygonF GeoJson::readLineString(const QJsonObject &obj)
{
const auto type = obj.value(QLatin1String("type")).toString();
......@@ -59,20 +67,12 @@ QPolygonF GeoJson::readOuterPolygon(const QJsonObject &obj)
{
const auto type = obj.value(QLatin1String("type")).toString();
if (type == QLatin1String("Polygon")) {
const auto coordinates = obj.value(QLatin1String("coordinates")).toArray();
if (coordinates.empty()) {
return {};
}
return readPolygonCoordinates(coordinates.at(0).toArray());
return readOuterPolygonCoordinates(obj.value(QLatin1String("coordinates")).toArray());
} else if (type == QLatin1String("MultiPolygon")) {
const auto coordinates = obj.value(QLatin1String("coordinates")).toArray();
QPolygonF poly;
for (const auto &polyV : coordinates) {
const auto polyElements = polyV.toArray();
if (polyElements.empty()) {
return {};
}
auto subPoly = readPolygonCoordinates(polyElements.at(0).toArray());
auto subPoly = readOuterPolygonCoordinates(polyV.toArray());
poly = poly.empty() ? std::move(subPoly) : poly.united(subPoly);
}
return poly;
......@@ -81,6 +81,24 @@ QPolygonF GeoJson::readOuterPolygon(const QJsonObject &obj)
return {};
}
std::vector<QPolygonF> GeoJson::readOuterPolygons(const QJsonObject &obj)
{
const auto type = obj.value(QLatin1String("type")).toString();
if (type == QLatin1String("Polygon")) {
return {readOuterPolygonCoordinates(obj.value(QLatin1String("coordinates")).toArray())};
} else if (type == QLatin1String("MultiPolygon")) {
const auto coordinates = obj.value(QLatin1String("coordinates")).toArray();
std::vector<QPolygonF> polys;
polys.reserve(coordinates.size());
for (const auto &polyV : coordinates) {
polys.push_back(readOuterPolygonCoordinates(polyV.toArray()));
}
return polys;
}
return {};
}
static QJsonArray writePoint(const QPointF &p)
{
return QJsonArray({ p.x(), p.y() });
......@@ -113,3 +131,29 @@ QJsonObject GeoJson::writePolygon(const QPolygonF &polygon)
obj.insert(QLatin1String("coordinates"), polyArray);
return obj;
}
QJsonObject GeoJson::writePolygons(const std::vector<QPolygonF> &polygons)
{
if (polygons.empty()) {
return {};
}
if (polygons.size() == 1) {
return writePolygon(polygons[0]);
}
QJsonObject obj;
obj.insert(QLatin1String("type"), QLatin1String("MultiPolygon"));
QJsonArray multiPolys;
for (const auto &polygon : polygons) {
QJsonArray coords;
for (const auto &p : polygon) {
coords.push_back(writePoint(p));
}
QJsonArray polyArray;
polyArray.push_back(coords);
multiPolys.push_back(polyArray);
}
obj.insert(QLatin1String("coordinates"), multiPolys);
return obj;
}
......@@ -7,6 +7,8 @@
#ifndef KPUBLICTRANSPORT_GEOJSON_P_H
#define KPUBLICTRANSPORT_GEOJSON_P_H
#include <vector>
class QJsonObject;
class QPointF;
class QPolygonF;
......@@ -22,14 +24,20 @@ namespace GeoJson
/** Reads a line string object. */
QPolygonF readLineString(const QJsonObject &obj);
/** Outer path of a polygon or multi-polygon geometry object. */
/** Outer path of a polygon or multi-polygon geometry object.
* Multiple outer polygons are united.
*/
QPolygonF readOuterPolygon(const QJsonObject &obj);
/** Outer paths of a polygon or multi-polygon geometry object. */
std::vector<QPolygonF> readOuterPolygons(const QJsonObject &obj);
/** Creates a line string object. */
QJsonObject writeLineString(const QPolygonF &lineString);
/** Create a polygon object. */
QJsonObject writePolygon(const QPolygonF &polygon);
/** Create a multi-polygon object. */
QJsonObject writePolygons(const std::vector<QPolygonF> &polygons);
}
}
......
Markdown is supported
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