// Copyright (C) 2020 The Qt Company Ltd. // Copyright (C) 2018 Julian Sherollari // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qgeojson_p.h" #include #include #include #include #include #include #include #include #include #include QT_BEGIN_NAMESPACE /*! \namespace QGeoJson \inmodule QtLocation \internal From Qt 6.7, QGeoJson is a private API. The replacement API is the GeoJsonData QML type. */ static QGeoCoordinate importPosition(const QVariant &position) { QGeoCoordinate returnedCoordinates; const QVariantList positionList = position.value(); for (qsizetype i = 0; i < positionList.size(); ++i) { // Iterating Point coordinates arrays switch (i) { case 0: returnedCoordinates.setLongitude(positionList.at(i).toDouble()); break; case 1: returnedCoordinates.setLatitude(positionList.at(i).toDouble()); break; case 2: returnedCoordinates.setAltitude(positionList.at(i).toDouble()); break; default: break; } } return returnedCoordinates; } static QList importArrayOfPositions(const QVariant &arrayOfPositions) { QList returnedCoordinates; const QVariantList positionsList = arrayOfPositions.value(); for (const auto &position : positionsList) // Iterating the LineString coordinates nested arrays returnedCoordinates.append(importPosition(position)); // Populating the QList of coordinates return returnedCoordinates; } static QList> importArrayOfArrayOfPositions(const QVariant &arrayOfArrayofPositions) { QList> returnedCoordinates; const QVariantList positionsList = arrayOfArrayofPositions.value(); for (const auto &position : positionsList) // Iterating the Polygon coordinates nested arrays returnedCoordinates << importArrayOfPositions(position); return returnedCoordinates; } static QGeoCircle importPoint(const QVariantMap &inputMap) { QGeoCircle returnedObject; QGeoCoordinate center; QVariant valueCoords = inputMap.value(QStringLiteral("coordinates")); center = importPosition(valueCoords); returnedObject.setCenter(center); return returnedObject; } static QGeoPath importLineString(const QVariantMap &inputMap) { QGeoPath returnedObject; QList coordinatesList; const QVariant valueCoordinates = inputMap.value(QStringLiteral("coordinates")); coordinatesList = importArrayOfPositions(valueCoordinates); returnedObject.setPath(coordinatesList); return returnedObject; } static QGeoPolygon importPolygon(const QVariantMap &inputMap) { QGeoPolygon returnedObject; const QVariant valueCoordinates = inputMap.value(QStringLiteral("coordinates")); const QList> perimeters = importArrayOfArrayOfPositions(valueCoordinates); for (qsizetype i = 0; i < perimeters.size(); ++i) { // Import an array of QList if (i == 0) returnedObject.setPerimeter(perimeters.at(i)); // External perimeter else returnedObject.addHole(perimeters.at(i)); // Inner perimeters } return returnedObject; } static QVariantList importMultiPoint(const QVariantMap &inputMap) { QVariantList returnedObject; const QVariantList coordinatesList = inputMap.value(QStringLiteral("coordinates")).value(); QVariantMap singlePointMap; QGeoCircle parsedPoint; for (const auto &coordinate : coordinatesList) { // Iterating MultiPoint coordinates nasted arrays parsedPoint.setCenter(importPosition(coordinate)); singlePointMap.insert(QStringLiteral("type"), QStringLiteral("Point")); singlePointMap.insert(QStringLiteral("data"), QVariant::fromValue(parsedPoint)); returnedObject.append(QVariant::fromValue(singlePointMap)); } return returnedObject; } static QVariantList importMultiLineString(const QVariantMap &inputMap) { QVariantList returnedObject; QGeoPath parsedLineString; const QVariant listCoords = inputMap.value(QStringLiteral("coordinates")); const QVariantList list = listCoords.value(); QVariantMap singleLinestringMap; for (int i = 0; i < list.size(); ++i) { // Iterating the MultiLineString coordinates nasted arrays using importArrayOfPositions singleLinestringMap.clear(); const QList coordinatesList = importArrayOfPositions(list.at(i)); singleLinestringMap.insert(QStringLiteral("type"), QStringLiteral("LineString")); parsedLineString.setPath(coordinatesList); singleLinestringMap.insert(QStringLiteral("data"), QVariant::fromValue(parsedLineString)); returnedObject.append(QVariant::fromValue(singleLinestringMap)); } return returnedObject; } static QVariantList importMultiPolygon(const QVariantMap &inputMap) { QVariantList returnedObject; QGeoPolygon singlePoly; QVariantMap singlePolygonMap; const QVariant valueCoordinates = inputMap.value(QStringLiteral("coordinates")); const QVariantList list = valueCoordinates.value(); for (int i = 0; i < list.size(); ++i) { // Iterating the MultiPolygon coordinates nasted arrays singlePolygonMap.clear(); const QList> coordinatesList = importArrayOfArrayOfPositions(list.at(i)); for (int j = 0; j < coordinatesList.size(); ++j) { if (j == 0) singlePoly.setPerimeter(coordinatesList.at(j)); else singlePoly.addHole(coordinatesList.at(j)); } singlePolygonMap.insert(QStringLiteral("type"), QStringLiteral("Polygon")); singlePolygonMap.insert(QStringLiteral("data"), QVariant::fromValue(singlePoly)); returnedObject.append(QVariant::fromValue(singlePolygonMap)); } return returnedObject; } static QVariantMap importGeometry(const QVariantMap &inputMap); // Function prototype for a tail recursion static QVariantList importGeometryCollection(const QVariantMap &inputMap) { QVariantList returnedObject; const QVariant listGeometries = inputMap.value(QStringLiteral("geometries")); const QVariantList list = listGeometries.value(); // QVariantList of heterogeneous composition of the other geometry types for (int i = 0; i < list.size(); ++i) { QVariantMap geometryMap = list.at(i).value(); QVariantMap geoMap = importGeometry(geometryMap); returnedObject.append(geoMap); } return returnedObject; } static QVariantMap importGeometry(const QVariantMap &inputMap) { QVariantMap returnedObject; QString geometryTypes[] = { QStringLiteral("Point"), QStringLiteral("MultiPoint"), QStringLiteral("LineString"), QStringLiteral("MultiLineString"), QStringLiteral("Polygon"), QStringLiteral("MultiPolygon"), QStringLiteral("GeometryCollection") }; enum geoTypeSwitch { Point, MultiPoint, LineString, MultiLineString, Polygon, MultiPolygon, GeometryCollection }; for (int i = 0; i<7; ++i) { if (inputMap.value(QStringLiteral("type")).value() == geometryTypes[i]) { switch (i) { case Point: { returnedObject.insert(QStringLiteral("type"), QStringLiteral("Point")); returnedObject.insert(QStringLiteral("data"), QVariant::fromValue(importPoint(inputMap))); break; } case MultiPoint: { returnedObject.insert(QStringLiteral("type"), QStringLiteral("MultiPoint")); returnedObject.insert(QStringLiteral("data"), QVariant::fromValue(importMultiPoint(inputMap))); break; } case LineString: { returnedObject.insert(QStringLiteral("type"), QStringLiteral("LineString")); returnedObject.insert(QStringLiteral("data"), QVariant::fromValue(importLineString(inputMap))); break; } case MultiLineString: { returnedObject.insert(QStringLiteral("type"), QStringLiteral("MultiLineString")); returnedObject.insert(QStringLiteral("data"), QVariant::fromValue(importMultiLineString(inputMap))); break; } case Polygon: { returnedObject.insert(QStringLiteral("type"), QStringLiteral("Polygon")); returnedObject.insert(QStringLiteral("data"), QVariant::fromValue(importPolygon(inputMap))); break; } case MultiPolygon: { returnedObject.insert(QStringLiteral("type"), QStringLiteral("MultiPolygon")); returnedObject.insert(QStringLiteral("data"), QVariant::fromValue(importMultiPolygon(inputMap))); break; } case GeometryCollection: { returnedObject.insert(QStringLiteral("type"), QStringLiteral("GeometryCollection")); returnedObject.insert(QStringLiteral("data"), QVariant::fromValue(importGeometryCollection(inputMap))); break; } default: break; } } } return returnedObject; } static QVariantList importFeatureCollection(const QVariantMap &inputMap) { QVariantList returnedObject; const QVariantList featuresList = inputMap.value(QStringLiteral("features")).value(); for (int i = 0; i < featuresList.size(); ++i) { QVariantMap inputFeatureMap = featuresList.at(i).value(); QVariantMap singleFeatureMap = importGeometry(inputFeatureMap.value(QStringLiteral("geometry")).value()); const QVariantMap importedProperties = inputFeatureMap.value(QStringLiteral("properties")).value(); singleFeatureMap.insert(QStringLiteral("properties"), importedProperties); if (inputFeatureMap.contains(QStringLiteral("id"))) { QVariant importedId = inputFeatureMap.value(QStringLiteral("id")).value(); singleFeatureMap.insert(QStringLiteral("id"), importedId); } returnedObject.append(singleFeatureMap); } return returnedObject; } static QJsonValue exportPosition(const QGeoCoordinate &obtainedCoordinates) { QJsonValue geoLat = obtainedCoordinates.latitude(); QJsonValue geoLong = obtainedCoordinates.longitude(); QJsonArray array = {geoLong, geoLat}; QJsonValue geoAlt; if (!qIsNaN(obtainedCoordinates.altitude())) { geoAlt = obtainedCoordinates.altitude(); array.append(geoAlt); } QJsonValue geoArray = array; return geoArray; } static QJsonValue exportArrayOfPositions(const QList &obtainedCoordinatesList) { QJsonValue lineCoordinates; QJsonValue multiPosition; QJsonArray arrayPosition; for (int i = 0; i < obtainedCoordinatesList.size(); ++i) { multiPosition = exportPosition(obtainedCoordinatesList.at(i)); arrayPosition.append(multiPosition); } lineCoordinates = arrayPosition; return lineCoordinates; } static QJsonValue exportArrayOfArrayOfPositions(const QList> &obtainedCoordinates) { QJsonValue lineCoordinates; QJsonValue polyCoordinates; QJsonArray arrayPath; for (int i = 0; i < obtainedCoordinates.size(); ++i) { lineCoordinates = exportArrayOfPositions(obtainedCoordinates.at(i)); arrayPath.append(lineCoordinates); } polyCoordinates = arrayPath; return polyCoordinates; } static QJsonObject exportPoint(const QVariantMap &pointMap) { QJsonObject parsedPoint; QGeoCircle circle = pointMap.value(QStringLiteral("data")).value(); parsedPoint.insert(QStringLiteral("type"), QJsonValue(QStringLiteral("Point"))); parsedPoint.insert(QStringLiteral("coordinates"), exportPosition(circle.center())); return parsedPoint; } static QJsonObject exportLineString(const QVariantMap &lineStringMap) { QJsonObject parsedLineString; QList linestringPath = lineStringMap.value(QStringLiteral("data")).value().path(); parsedLineString.insert(QStringLiteral("type"), QJsonValue(QStringLiteral("LineString"))); parsedLineString.insert(QStringLiteral("coordinates"), exportArrayOfPositions(linestringPath)); return parsedLineString; } static QJsonObject exportPolygon(const QVariantMap &polygonMap) { QVariant polygonVariant = polygonMap.value(QStringLiteral("data")); QJsonObject parsedPolygon; QJsonValue polyCoordinates; QList> obtainedCoordinatesPoly; QGeoPolygon parsedPoly = polygonVariant.value(); obtainedCoordinatesPoly << parsedPoly.perimeter(); if (parsedPoly.holesCount()!=0) for (int i = 0; i < parsedPoly.holesCount(); ++i) { obtainedCoordinatesPoly << parsedPoly.holePath(i); } polyCoordinates = exportArrayOfArrayOfPositions(obtainedCoordinatesPoly); parsedPolygon.insert(QStringLiteral("type"), QJsonValue(QStringLiteral("Polygon"))); parsedPolygon.insert(QStringLiteral("coordinates"), polyCoordinates); return parsedPolygon; } static QJsonObject exportMultiPoint(const QVariantMap &multiPointMap) { QJsonObject parsedMultiPoint; QList obtainedCoordinatesMP; QVariantList multiCircleVariantList = multiPointMap.value(QStringLiteral("data")).value(); for (const QVariant &exCircleVariantMap: multiCircleVariantList) { obtainedCoordinatesMP << exCircleVariantMap.value().value(QStringLiteral("data")).value().center(); } QJsonValue multiPosition = exportArrayOfPositions(obtainedCoordinatesMP); parsedMultiPoint.insert(QStringLiteral("type"), QJsonValue(QStringLiteral("MultiPoint"))); parsedMultiPoint.insert(QStringLiteral("coordinates"), multiPosition); return parsedMultiPoint; } static QJsonObject exportMultiLineString(const QVariantMap &multiLineStringMap) { QJsonObject parsedMultiLineString; QList> extractedCoordinatesValue; QVariant multiPathVariant = multiLineStringMap.value(QStringLiteral("data")); QVariantList multiPathList = multiPathVariant.value(); for (int i = 0; i < multiPathList.size(); ++i) { extractedCoordinatesValue << multiPathList.at(i).value().value(QStringLiteral("data")).value().path(); } QJsonValue exportedCoordinatesValue = exportArrayOfArrayOfPositions(extractedCoordinatesValue); parsedMultiLineString.insert(QStringLiteral("type"), QJsonValue(QStringLiteral("MultiLineString"))); parsedMultiLineString.insert(QStringLiteral("coordinates"), exportedCoordinatesValue); return parsedMultiLineString; } static QJsonObject exportMultiPolygon(const QVariantMap &multiPolygonMap) { QJsonObject parsedMultiPolygon; QJsonValue polyCoordinates; QJsonArray parsedArrayPolygon; QList> extractedCoordinatesValue; QVariant multiPolygonVariant = multiPolygonMap.value(QStringLiteral("data")); QVariantList multiPolygonList = multiPolygonVariant.value(); int polyHoles = 0; int currentHole; for (int i = 0; i < multiPolygonList.size(); ++i) { // Start parsing Polygon list extractedCoordinatesValue << multiPolygonList.at(i).value().value(QStringLiteral("data")).value().perimeter(); // Extract external polygon path polyHoles = multiPolygonList.at(i).value().value(QStringLiteral("data")).value().holesCount(); if (polyHoles) // Check if the polygon has holes for (currentHole = 0 ; currentHole < polyHoles; currentHole++) extractedCoordinatesValue << multiPolygonList.at(i).value().value(QStringLiteral("data")).value().holePath(currentHole); polyCoordinates = exportArrayOfArrayOfPositions(extractedCoordinatesValue); // Generates QJsonDocument compatible value parsedArrayPolygon.append(polyCoordinates); // Adds one level of nesting in coordinates extractedCoordinatesValue.clear(); // Clears the temporary polygon linear ring storage } QJsonValue exportedCoordinatesNodeValue = parsedArrayPolygon; parsedMultiPolygon.insert(QStringLiteral("type"), QJsonValue(QStringLiteral("MultiPolygon"))); parsedMultiPolygon.insert(QStringLiteral("coordinates"), exportedCoordinatesNodeValue); return parsedMultiPolygon; } static QJsonObject exportGeometry(const QVariantMap &geometryMap); // Function prototype static QJsonObject exportGeometryCollection(const QVariantMap &geometryCollection) { QJsonObject parsed; QJsonObject parsedGeometry; QJsonValue valueGeometries; QJsonArray parsedGeometries; QVariantList geometriesList = geometryCollection.value(QStringLiteral("data")).value(); for (int i = 0; i < geometriesList.size(); ++i) { parsedGeometry = exportGeometry(geometriesList.at(i).value()); valueGeometries = parsedGeometry; parsedGeometries.append(valueGeometries); } QJsonValue exportedGeometriesValue = parsedGeometries; parsed.insert(QStringLiteral("type"), QJsonValue(QStringLiteral("GeometryCollection"))); parsed.insert(QStringLiteral("geometries"), exportedGeometriesValue); return parsed; } static QJsonObject exportGeometry(const QVariantMap &geometryMap) { QJsonObject exportedGeometry; if (geometryMap.value(QStringLiteral("type")) == QStringLiteral("Point")) exportedGeometry = exportPoint(geometryMap); if (geometryMap.value(QStringLiteral("type")) == QStringLiteral("MultiPoint")) exportedGeometry = exportMultiPoint(geometryMap); if (geometryMap.value(QStringLiteral("type")) == QStringLiteral("LineString")) exportedGeometry = exportLineString(geometryMap); if (geometryMap.value(QStringLiteral("type")) == QStringLiteral("MultiLineString")) exportedGeometry = exportMultiLineString(geometryMap); if (geometryMap.value(QStringLiteral("type")) == QStringLiteral("Polygon")) exportedGeometry = exportPolygon(geometryMap); if (geometryMap.value(QStringLiteral("type")) == QStringLiteral("MultiPolygon")) exportedGeometry = exportMultiPolygon(geometryMap); if (geometryMap.value(QStringLiteral("type")) == QStringLiteral("GeometryCollection")) exportedGeometry = exportGeometryCollection(geometryMap); return exportedGeometry; } static QJsonObject exportFeature(const QVariantMap &featureMap) { QJsonObject exportedFeature; QJsonValue geometryNodeValue = QJsonValue(exportGeometry(featureMap)); QJsonValue propertiesNodeValue = featureMap.value(QStringLiteral("properties")).value().toJsonValue(); QJsonValue idNodeValue = featureMap.value(QStringLiteral("id")).value().toJsonValue(); exportedFeature.insert(QStringLiteral("type"), QJsonValue(QStringLiteral("Feature"))); exportedFeature.insert(QStringLiteral("geometry"), geometryNodeValue); exportedFeature.insert(QStringLiteral("properties"), propertiesNodeValue); if (!idNodeValue.isNull()) // this value is optional exportedFeature.insert(QStringLiteral("id"), idNodeValue); return exportedFeature; } static QJsonObject exportFeatureCollection(const QVariantMap &featureCollection) { QJsonObject exportedFeatureCollection; QJsonArray featureArray; QVariantList featureList = featureCollection.value(QStringLiteral("data")).value(); for (int i = 0; i < featureList.size(); ++i) { featureArray.append(QJsonValue(exportFeature(featureList.at(i).value()))); } exportedFeatureCollection.insert(QStringLiteral("type"), QJsonValue(QStringLiteral("FeatureCollection"))); exportedFeatureCollection.insert(QStringLiteral("features"), QJsonValue(featureArray) ); return exportedFeatureCollection; } namespace QGeoJson { /*! This method imports the \a geoJson document, expected to contain valid GeoJSON data, into a QVariantList structured like described in the section \l {Importing GeoJSON}. \note This method performs no validation on the input. \sa exportGeoJson */ QVariantList importGeoJson(const QJsonDocument &geoJson) { QVariantList returnedList; QJsonObject object = geoJson.object(); // Read json object from imported doc QVariantMap rootGeoJsonObject = object.toVariantMap(); // Extraced map using Qt's API QString geoType[] = { QStringLiteral("Point"), QStringLiteral("MultiPoint"), QStringLiteral("LineString"), QStringLiteral("MultiLineString"), QStringLiteral("Polygon"), QStringLiteral("MultiPolygon"), QStringLiteral("GeometryCollection"), QStringLiteral("Feature"), QStringLiteral("FeatureCollection") }; enum geoTypeSwitch { Point, MultiPoint, LineString, MultiLineString, Polygon, MultiPolygon, GeometryCollection, Feature, FeatureCollection }; QVariantMap parsedGeoJsonMap; // Checking whether the JSON object has a "type" member const QVariant keyVariant = rootGeoJsonObject.value(QStringLiteral("type")); if (!keyVariant.isValid()) { // Type check failed } QString valueType = keyVariant.value(); // Checking whether the "type" member has a GeoJSON admitted value for (int i = 0; i < 9; ++i) { if (valueType == geoType[i]) { switch (i) { case Point: { QGeoCircle circle = importPoint(rootGeoJsonObject); QVariant dataNodeValue = QVariant::fromValue(circle); parsedGeoJsonMap.insert(QStringLiteral("type"), QStringLiteral("Point")); parsedGeoJsonMap.insert(QStringLiteral("data"), dataNodeValue); break; } case MultiPoint: { QVariantList multiCircle = importMultiPoint(rootGeoJsonObject); QVariant dataNodeValue = QVariant::fromValue(multiCircle); QList testlist; parsedGeoJsonMap.insert(QStringLiteral("type"), QStringLiteral("MultiPoint")); parsedGeoJsonMap.insert(QStringLiteral("data"), dataNodeValue); break; } case LineString: { QGeoPath lineString = importLineString(rootGeoJsonObject); QVariant dataNodeValue = QVariant::fromValue(lineString); parsedGeoJsonMap.insert(QStringLiteral("type"), QStringLiteral("LineString")); parsedGeoJsonMap.insert(QStringLiteral("data"), dataNodeValue); break; } case MultiLineString: { QVariantList multiLineString = importMultiLineString(rootGeoJsonObject); QVariant dataNodeValue = QVariant::fromValue(multiLineString); parsedGeoJsonMap.insert(QStringLiteral("type"), QStringLiteral("MultiLineString")); parsedGeoJsonMap.insert(QStringLiteral("data"), dataNodeValue); break; } case Polygon: { QGeoPolygon poly = importPolygon(rootGeoJsonObject); QVariant dataNodeValue = QVariant::fromValue(poly); parsedGeoJsonMap.insert(QStringLiteral("type"), QStringLiteral("Polygon")); parsedGeoJsonMap.insert(QStringLiteral("data"), dataNodeValue); break; } case MultiPolygon: { QVariantList multiPoly = importMultiPolygon(rootGeoJsonObject); QVariant dataNodeValue = QVariant::fromValue(multiPoly); parsedGeoJsonMap.insert(QStringLiteral("type"), QStringLiteral("MultiPolygon")); parsedGeoJsonMap.insert(QStringLiteral("data"), dataNodeValue); break; } // List of GeoJson geometry objects case GeometryCollection: { QVariantList multiGeo = importGeometryCollection(rootGeoJsonObject); QVariant dataNodeValue = QVariant::fromValue(multiGeo); parsedGeoJsonMap.insert(QStringLiteral("type"), QStringLiteral("GeometryCollection")); parsedGeoJsonMap.insert(QStringLiteral("data"), dataNodeValue); break; } // Single GeoJson geometry object with properties case Feature: { parsedGeoJsonMap = importGeometry(rootGeoJsonObject.value(QStringLiteral("geometry")).value()); QVariantMap importedProperties = rootGeoJsonObject.value(QStringLiteral("properties")).value(); parsedGeoJsonMap.insert(QStringLiteral("properties"), importedProperties); if (rootGeoJsonObject.contains(QStringLiteral("id"))){ QVariant importedId = rootGeoJsonObject.value(QStringLiteral("id")).value(); parsedGeoJsonMap.insert(QStringLiteral("id"), importedId); } break; } // Heterogeneous list of GeoJSON geometries with properties case FeatureCollection: { QVariantList featCollection = importFeatureCollection(rootGeoJsonObject); QVariant dataNodeValue = QVariant::fromValue(featCollection); parsedGeoJsonMap.insert(QStringLiteral("type"), QStringLiteral("FeatureCollection")); parsedGeoJsonMap.insert(QStringLiteral("data"), dataNodeValue); break; } default: break; } QVariant bboxNodeValue = rootGeoJsonObject.value(QStringLiteral("bbox")); if (bboxNodeValue.isValid()) { parsedGeoJsonMap.insert(QStringLiteral("bbox"), bboxNodeValue); } returnedList.append(parsedGeoJsonMap); } else if (i >= 9) { // Error break; } } return returnedList; } /*! This method exports the QVariantList \a geoData, expected to be structured like described in the section \l {Importing GeoJSON}, to a QJsonDocument containing the data converted to GeoJSON. \note This method performs no validation on the input. \sa importGeoJson */ QJsonDocument exportGeoJson(const QVariantList &geoData) { if (geoData.isEmpty()) return QJsonDocument(); QVariantMap exportMap = geoData.at(0).value(); // Extracting the QVMap QJsonObject newObject; QJsonDocument newDocument; if (exportMap.contains(QStringLiteral("properties"))) { newObject = exportFeature(exportMap); } else { if (exportMap.value(QStringLiteral("type")) == QStringLiteral("Point")) // Check the value corresponding to the key "Point" newObject = exportPoint(exportMap); if (exportMap.value(QStringLiteral("type")) == QStringLiteral("MultiPoint")) newObject = exportMultiPoint(exportMap); if (exportMap.value(QStringLiteral("type")) == QStringLiteral("LineString")) newObject = exportLineString(exportMap); if (exportMap.value(QStringLiteral("type")) == QStringLiteral("MultiLineString")) newObject = exportMultiLineString(exportMap); if (exportMap.value(QStringLiteral("type")) == QStringLiteral("Polygon")) newObject = exportPolygon(exportMap); if (exportMap.value(QStringLiteral("type")) == QStringLiteral("MultiPolygon")) newObject = exportMultiPolygon(exportMap); if (exportMap.value(QStringLiteral("type")) == QStringLiteral("GeometryCollection")) newObject = exportGeometryCollection(exportMap); if (exportMap.value(QStringLiteral("type")) == QStringLiteral("FeatureCollection")) newObject = exportFeatureCollection(exportMap); } if (exportMap.contains((QStringLiteral("bbox")))) { QJsonArray bboxArray; QVariantList bboxList = exportMap.value(QStringLiteral("bbox")).value(); for (int i = 0; i < bboxList.size(); ++i) { bboxArray.append(QJsonValue(bboxList.at(i).value())); } newObject.insert(QStringLiteral("bbox"), QJsonValue(bboxArray)); } newDocument.setObject(newObject); return newDocument; } // Functions for toString QTextStream &operator<<(QTextStream &stream, const QGeoCoordinate &crd) { stream << "{ " << QString::number(crd.latitude(), 'f', 3) << ", " << QString::number(crd.longitude(), 'f', 3) << ", " << QString::number(crd.altitude(), 'f', 3) << " }"; return stream; } QTextStream &operator<<(QTextStream &stream, const QGeoShape &shape) { switch (shape.type()) { case QGeoShape::CircleType: { QGeoCircle circle(shape); stream << "QGeoCircle(" <()) { workigGeometry = v.value(); if (workigGeometry.type() == QGeoShape::CircleType) { QGeoCircle circle = v.value(); stream << circle<< "\n"; } else if (workigGeometry.type() == QGeoShape::PathType) { QGeoPath path = v.value(); stream << path<< "\n"; } else if (workigGeometry.type() == QGeoShape::PolygonType) { QGeoPolygon polygon = v.value(); stream << polygon<< "\n"; } } else { if (v.isNull()) stream << "null\n"; else stream << v.toString() << "\n"; } } return res; } /*! This method accepts the QVariantList \a geoData, structured as described in \l {Importing GeoJSON}, and returns a string containing the same data in a readable form. */ QString toString(const QVariantList &geoData) { if (geoData.isEmpty()) return QString(); return printQvariant(geoData.first(), 0); } } // namespace QGeoJson QT_END_NAMESPACE