Skip to content

Commit

Permalink
Use nlohmann for json instead of QVariant
Browse files Browse the repository at this point in the history
But leave QVariant version of util function for use in Python scripts
  • Loading branch information
nyalldawson committed Jul 12, 2023
1 parent 30e50ae commit 5ae547a
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 57 deletions.
2 changes: 2 additions & 0 deletions python/core/auto_generated/tiledmesh/qgscesiumutils.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@




class QgsCesiumUtils
{
%Docstring(signature="appended")
Expand All @@ -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.
Expand Down
54 changes: 23 additions & 31 deletions src/core/tiledmesh/qgscesiumtilesdataprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() );
Expand Down Expand Up @@ -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
{
Expand All @@ -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
{
Expand Down Expand Up @@ -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() )
Expand Down
6 changes: 4 additions & 2 deletions src/core/tiledmesh/qgscesiumtilesdataprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include "qgis.h"
#include "qgsprovidermetadata.h"
#include "qgsrange.h"
#include "nlohmann/json.hpp"

#define SIP_NO_FILE

///@cond PRIVATE
Expand All @@ -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;
Expand Down
44 changes: 21 additions & 23 deletions src/core/tiledmesh/qgscesiumutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,31 @@
***************************************************************************/

#include "qgscesiumutils.h"
#include "nlohmann/json.hpp"
#include "qgsjsonutils.h"

QgsBox3d QgsCesiumUtils::parseRegion( const QVariantList &region )
QgsBox3d QgsCesiumUtils::parseRegion( const json &region )
{
if ( region.size() != 6 )
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();
}
}

// 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 )
QgsBox3d QgsCesiumUtils::parseRegion( const QVariantList &region )
{
if ( region.size() != 6 )
return QgsBox3d();

return QgsBox3d( west, south, minHeight, east, north, maxHeight );
return parseRegion( QgsJsonUtils::jsonFromVariant( region ) );
}
15 changes: 15 additions & 0 deletions src/core/tiledmesh/qgscesiumutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
*/
Expand Down
2 changes: 1 addition & 1 deletion tests/src/python/test_qgscesiumutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def test_parse_region(self):
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)
Expand Down

0 comments on commit 5ae547a

Please sign in to comment.