Skip to content
Permalink
Browse files
On demand hierarchy loading in remote EPT
  • Loading branch information
NEDJIMAbelgacem authored and wonder-sk committed Apr 8, 2021
1 parent e9f8cab commit dcd621d0787de96303de96908583691d674ef973
@@ -41,6 +41,11 @@ IndexedPointCloudNode::IndexedPointCloudNode( int _d, int _x, int _y, int _z ):
mZ( _z )
{}

IndexedPointCloudNode IndexedPointCloudNode::parentNode() const
{
return IndexedPointCloudNode( mD - 1, mX / 2, mY / 2, mZ / 2 );
}

IndexedPointCloudNode IndexedPointCloudNode::fromString( const QString &str )
{
QStringList lst = str.split( '-' );
@@ -67,6 +67,12 @@ class CORE_EXPORT IndexedPointCloudNode
return mD == other.d() && mX == other.x() && mY == other.y() && mZ == other.z();
}

/**
* Returns the parent of the node
* \since QGIS 3.20
*/
IndexedPointCloudNode parentNode() const;

//! Creates node from string
static IndexedPointCloudNode fromString( const QString &str );

@@ -197,7 +203,7 @@ class CORE_EXPORT QgsPointCloudIndex: public QObject
bool hasNode( const IndexedPointCloudNode &n ) const { return mHierarchy.contains( n ); }

//! Returns all children of node
QList<IndexedPointCloudNode> nodeChildren( const IndexedPointCloudNode &n ) const;
virtual QList<IndexedPointCloudNode> nodeChildren( const IndexedPointCloudNode &n ) const;

//! Returns all attributes that are stored in the file
QgsPointCloudAttributeCollection attributes() const;
@@ -277,7 +283,7 @@ class CORE_EXPORT QgsPointCloudIndex: public QObject
QgsRectangle mExtent; //!< 2D extent of data
double mZMin = 0, mZMax = 0; //!< Vertical extent of data

QHash<IndexedPointCloudNode, int> mHierarchy; //!< Data hierarchy
mutable QHash<IndexedPointCloudNode, int> mHierarchy; //!< Data hierarchy
QgsVector3D mScale; //!< Scale of our int32 coordinates compared to CRS coords
QgsVector3D mOffset; //!< Offset of our int32 coordinates compared to CRS coords
QgsPointCloudDataBounds mRootBounds; //!< Bounds of the root node's cube (in int32 coordinates)
@@ -53,6 +53,27 @@ QgsRemoteEptPointCloudIndex::QgsRemoteEptPointCloudIndex() : QgsPointCloudIndex(

QgsRemoteEptPointCloudIndex::~QgsRemoteEptPointCloudIndex() = default;

QList<IndexedPointCloudNode> QgsRemoteEptPointCloudIndex::nodeChildren( const IndexedPointCloudNode &n ) const
{
// Potential bug: what if loadNodeHierarchy fails and returns false
Q_ASSERT( loadNodeHierarchy( n ) );

QList<IndexedPointCloudNode> lst;
int d = n.d() + 1;
int x = n.x() * 2;
int y = n.y() * 2;
int z = n.z() * 2;

for ( int i = 0; i < 8; ++i )
{
int dx = i & 1, dy = !!( i & 2 ), dz = !!( i & 4 );
IndexedPointCloudNode n2( d, x + dx, y + dy, z + dz );
if ( mHierarchy.contains( n2 ) )
lst.append( n2 );
}
return lst;
}

void QgsRemoteEptPointCloudIndex::load( const QString &url )
{
mUrl = QUrl( url );
@@ -76,10 +97,10 @@ void QgsRemoteEptPointCloudIndex::load( const QString &url )

QgsNetworkReplyContent reply = req.reply();
bool success = loadSchema( reply.content() );
if ( success )
{
success = loadHierarchy();
}
// if ( success )
// {
// success = loadHierarchy();
// }

mIsValid = success;
}
@@ -288,9 +309,9 @@ bool QgsRemoteEptPointCloudIndex::loadSchema( const QByteArray &data )

QgsPointCloudBlock *QgsRemoteEptPointCloudIndex::nodeData( const IndexedPointCloudNode &n, const QgsPointCloudRequest &request )
{
qDebug() << __PRETTY_FUNCTION__;
if ( !mHierarchy.contains( n ) )
if ( !loadNodeHierarchy( n ) )
return nullptr;

QString fileUrl;
QString fileName;
if ( mDataType == QLatin1String( "binary" ) )
@@ -364,8 +385,9 @@ QgsPointCloudBlock *QgsRemoteEptPointCloudIndex::nodeData( const IndexedPointClo

QgsPointCloudBlockHandle *QgsRemoteEptPointCloudIndex::asyncNodeData( const IndexedPointCloudNode &n, const QgsPointCloudRequest &request )
{
if ( !mHierarchy.contains( n ) )
if ( !loadNodeHierarchy( n ) )
return nullptr;

QgsPointCloudBlockHandle *handle = nullptr;

QString fileUrl;
@@ -463,14 +485,29 @@ QVariant QgsRemoteEptPointCloudIndex::metadataClassStatistic( const QString &att
return values.value( value.toInt() );
}

bool QgsRemoteEptPointCloudIndex::loadHierarchy()
bool QgsRemoteEptPointCloudIndex::loadNodeHierarchy( const IndexedPointCloudNode &nodeId ) const
{
QQueue<QString> queue;
queue.enqueue( QStringLiteral( "0-0-0-0" ) );
while ( !queue.isEmpty() )
if ( mHierarchy.contains( nodeId ) )
return true;
QVector<IndexedPointCloudNode> nodePathToRoot;
{
//const QString filename = QStringLiteral( "%1/ept-hierarchy/%2.json" ).arg( mDirectory, queue.dequeue() );
const QString fileUrl = QStringLiteral( "%1/ept-hierarchy/%2.json" ).arg( mUrlDirectoryPart, queue.dequeue() );
nodePathToRoot.push_back( nodeId );
IndexedPointCloudNode currentNode = nodeId;
while ( currentNode.d() != 0 )
{
currentNode = currentNode.parentNode();
nodePathToRoot.push_back( currentNode );
}
}

for ( int i = nodePathToRoot.size() - 1; i >= 0 && mHierarchy.find( nodeId ) == mHierarchy.end(); --i )
{
IndexedPointCloudNode node = nodePathToRoot[i];
//! The hierarchy of the node is found => No need to load its file
if ( mHierarchy.find( node ) != mHierarchy.end() )
continue;

const QString fileUrl = QStringLiteral( "%1/ept-hierarchy/%2.json" ).arg( mUrlDirectoryPart, node.toString() );
QNetworkRequest nr( fileUrl );

QgsBlockingNetworkRequest req;
@@ -497,18 +534,15 @@ bool QgsRemoteEptPointCloudIndex::loadHierarchy()
{
QString nodeIdStr = it.key();
int nodePointCount = it.value().toInt();
if ( nodePointCount < 0 )
{
queue.enqueue( nodeIdStr );
}
else
if ( nodePointCount > 0 )
{
IndexedPointCloudNode nodeId = IndexedPointCloudNode::fromString( nodeIdStr );
mHierarchy[nodeId] = nodePointCount;
}
}
}
return true;

return mHierarchy.contains( nodeId );
}

bool QgsRemoteEptPointCloudIndex::isValid() const
@@ -46,6 +46,8 @@ class CORE_EXPORT QgsRemoteEptPointCloudIndex: public QgsPointCloudIndex
explicit QgsRemoteEptPointCloudIndex();
~QgsRemoteEptPointCloudIndex();

QList<IndexedPointCloudNode> nodeChildren( const IndexedPointCloudNode &n ) const override;

void load( const QString &fileName ) override;

QgsPointCloudBlock *nodeData( const IndexedPointCloudNode &n, const QgsPointCloudRequest &request ) override;
@@ -64,7 +66,8 @@ class CORE_EXPORT QgsRemoteEptPointCloudIndex: public QgsPointCloudIndex

private:
bool loadSchema( const QByteArray &data );
bool loadHierarchy();

bool loadNodeHierarchy( const IndexedPointCloudNode &nodeId ) const;

bool mIsValid = false;
QString mDataType;

0 comments on commit dcd621d

Please sign in to comment.