Use nlohmann for json instead of QVariant

But leave QVariant version of util function for use in Python scripts
This commit is contained in:
Nyall Dawson 2023-07-12 11:50:29 +10:00
parent b50a6c64d6
commit a739ad7097
6 changed files with 66 additions and 57 deletions

View File

@ -9,6 +9,7 @@
class QgsCesiumUtils
{
%Docstring(signature="appended")
@ -22,6 +23,7 @@ Contains utilities for working with Cesium data.
%End
public:
static QgsBox3d parseRegion( const QVariantList &region );
%Docstring
Parses a ``region`` object from a Cesium JSON document to a 3D box.

View File

@ -42,20 +42,21 @@
QgsCesiumTilesDataProviderSharedData::QgsCesiumTilesDataProviderSharedData() = default;
void QgsCesiumTilesDataProviderSharedData::setTilesetContent( const QVariantMap &tileset )
void QgsCesiumTilesDataProviderSharedData::setTilesetContent( const QString &tileset )
{
mTileset = tileset;
mTileset = json::parse( tileset.toStdString() );
mCrs = QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:4979" ) );
// parse root
{
const QVariantMap root = tileset.value( QStringLiteral( "root" ) ).toMap();
const auto &root = mTileset[ "root" ];
// parse root bounding volume
{
const QVariantMap rootBoundingVolume = root.value( QStringLiteral( "boundingVolume" ) ).toMap();
if ( rootBoundingVolume.contains( QStringLiteral( "region" ) ) )
const auto &rootBoundingVolume = root[ "boundingVolume" ];
if ( rootBoundingVolume.contains( "region" ) )
{
const QgsBox3d rootRegion = QgsCesiumUtils::parseRegion( rootBoundingVolume.value( QStringLiteral( "region" ) ).toList() );
const QgsBox3d rootRegion = QgsCesiumUtils::parseRegion( rootBoundingVolume[ "region" ] );
if ( !rootRegion.isNull() )
{
mZRange = QgsDoubleRange( rootRegion.zMinimum(), rootRegion.zMaximum() );
@ -142,16 +143,7 @@ bool QgsCesiumTilesDataProvider::init()
}
const QgsNetworkReplyContent content = networkRequest.reply();
const QByteArray raw = content.content();
// Parse data
QJsonParseError err;
const QJsonDocument doc = QJsonDocument::fromJson( raw, &err );
if ( doc.isNull() )
{
return false;
}
mShared->setTilesetContent( doc.object().toVariantMap() );
mShared->setTilesetContent( content.content() );
}
else
{
@ -162,14 +154,7 @@ bool QgsCesiumTilesDataProvider::init()
if ( file.open( QIODevice::ReadOnly | QIODevice::Text ) )
{
const QByteArray raw = file.readAll();
// Parse data
QJsonParseError err;
const QJsonDocument doc = QJsonDocument::fromJson( raw, &err );
if ( doc.isNull() )
{
return false;
}
mShared->setTilesetContent( doc.object().toVariantMap() );
mShared->setTilesetContent( raw );
}
else
{
@ -226,19 +211,26 @@ QString QgsCesiumTilesDataProvider::htmlMetadata() const
QString metadata;
if ( mShared->mTileset.contains( "asset" ) )
{
const QVariantMap asset = mShared->mTileset.value( QStringLiteral( "asset" ) ).toMap();
const QString version = asset.value( QStringLiteral( "version" ) ).toString();
if ( !version.isEmpty() )
const auto &asset = mShared->mTileset[ "asset" ];
if ( asset.contains( "version" ) )
{
const QString version = QString::fromStdString( asset["version"].get<std::string>() );
metadata += QStringLiteral( "<tr><td class=\"highlight\">" ) % tr( "3D Tiles Version" ) % QStringLiteral( "</td><td>%1</a>" ).arg( version ) % QStringLiteral( "</td></tr>\n" );
}
const QString tilesetVersion = asset.value( QStringLiteral( "tilesetVersion" ) ).toString();
if ( !tilesetVersion.isEmpty() )
if ( asset.contains( "tilesetVersion" ) )
{
const QString tilesetVersion = QString::fromStdString( asset["tilesetVersion"].get<std::string>() );
metadata += QStringLiteral( "<tr><td class=\"highlight\">" ) % tr( "Tileset Version" ) % QStringLiteral( "</td><td>%1</a>" ).arg( tilesetVersion ) % QStringLiteral( "</td></tr>\n" );
}
const QString generator = asset.value( QStringLiteral( "generator" ) ).toString();
if ( !generator.isEmpty() )
if ( asset.contains( "generator" ) )
{
const QString generator = QString::fromStdString( asset["generator"].get<std::string>() );
metadata += QStringLiteral( "<tr><td class=\"highlight\">" ) % tr( "Tileset Generator" ) % QStringLiteral( "</td><td>%1</a>" ).arg( generator ) % QStringLiteral( "</td></tr>\n" );
}
}
if ( !mShared->mZRange.isInfinite() )

View File

@ -24,6 +24,8 @@
#include "qgis.h"
#include "qgsprovidermetadata.h"
#include "qgsrange.h"
#include "nlohmann/json.hpp"
#define SIP_NO_FILE
///@cond PRIVATE
@ -32,11 +34,11 @@ class QgsCesiumTilesDataProviderSharedData
{
public:
QgsCesiumTilesDataProviderSharedData();
void setTilesetContent( const QVariantMap &tileset );
void setTilesetContent( const QString &tileset );
QgsCoordinateReferenceSystem mCrs;
QgsRectangle mExtent;
QVariantMap mTileset;
nlohmann::json mTileset;
QgsDoubleRange mZRange;
QReadWriteLock mMutex;

View File

@ -17,33 +17,31 @@
***************************************************************************/
#include "qgscesiumutils.h"
#include "nlohmann/json.hpp"
#include "qgsjsonutils.h"
QgsBox3d QgsCesiumUtils::parseRegion( const json &region )
{
try
{
const double west = region[0].get<double>();
const double south = region[1].get<double>();
const double east = region[2].get<double>();
const double north = region[3].get<double>();
double minHeight = region[4].get<double>();
double maxHeight = region[5].get<double>();
return QgsBox3d( west, south, minHeight, east, north, maxHeight );
}
catch ( nlohmann::json::exception & )
{
return QgsBox3d();
}
}
QgsBox3d QgsCesiumUtils::parseRegion( const QVariantList &region )
{
if ( region.size() != 6 )
return QgsBox3d();
// The region property is an array of six numbers that define the bounding geographic region with
// latitude, longitude, and height coordinates with the order [west, south, east, north, minimum height, maximum height].
bool ok = false;
const double west = region.at( 0 ).toDouble( &ok );
if ( !ok )
return QgsBox3d();
const double south = region.at( 1 ).toDouble( &ok );
if ( !ok )
return QgsBox3d();
const double east = region.at( 2 ).toDouble( &ok );
if ( !ok )
return QgsBox3d();
const double north = region.at( 3 ).toDouble( &ok );
if ( !ok )
return QgsBox3d();
const double minHeight = region.at( 4 ).toDouble( &ok );
if ( !ok )
return QgsBox3d();
const double maxHeight = region.at( 5 ).toDouble( &ok );
if ( !ok )
return QgsBox3d();
return QgsBox3d( west, south, minHeight, east, north, maxHeight );
return parseRegion( QgsJsonUtils::jsonFromVariant( region ) );
}

View File

@ -21,6 +21,11 @@
#include "qgis_core.h"
#include "qgsbox3d.h"
#include "nlohmann/json_fwd.hpp"
#ifndef SIP_RUN
using namespace nlohmann;
#endif
/**
* \brief Contains utilities for working with Cesium data.
@ -33,6 +38,16 @@ class CORE_EXPORT QgsCesiumUtils
{
public:
#ifndef SIP_RUN
/**
* Parses a \a region object from a Cesium JSON object to a 3D box.
*
* \note Not available in Python bindings.
*/
static QgsBox3d parseRegion( const json &region );
#endif
/**
* Parses a \a region object from a Cesium JSON document to a 3D box.
*/

View File

@ -37,7 +37,7 @@ class TestQgsCesiumUtils(QgisTestCase):
QgsCesiumUtils.parseRegion([1, 'a', 3, 4, 5, 6]).isNull())
# valid
box = QgsCesiumUtils.parseRegion(['1.2', '2', 3, '4.6', 5.5, 6])
box = QgsCesiumUtils.parseRegion([1.2, 2, 3, 4.6, 5.5, 6])
self.assertEqual(box.xMinimum(), 1.2)
self.assertEqual(box.xMaximum(), 3.0)
self.assertEqual(box.yMinimum(), 2.0)