Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jul 21, 2023
1 parent 8c69bdc commit f1fcd85
Show file tree
Hide file tree
Showing 11 changed files with 370 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,13 @@ Abstract base class for bounding volumes for tiled mesh nodes.
Returns the type of the volume;
%End

virtual QgsBox3D bounds( const QgsCoordinateTransform &transform = QgsCoordinateTransform(), Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const = 0;
virtual QgsBox3D bounds( const QgsMatrix4x4 *transform = 0, const QgsCoordinateTransform &coordinateTransform = QgsCoordinateTransform(), Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const = 0;
%Docstring
Returns the axis aligned bounding box of the volume.

The optional ``transform`` and ``direction`` arguments should be used whenever the volume needs
An optional ``transform`` matrix can be specified to transform the raw coordinates.

The optional ``coordinateTransform`` and ``direction`` arguments should be used whenever the volume needs
to be transformed into a specific destination CRS, in order to correctly handle 3D coordinate transforms.
%End

Expand Down Expand Up @@ -95,7 +97,7 @@ Constructor for QgsTiledMeshNodeBoundingVolumeRegion, with the specified ``regio

virtual Qgis::TiledMeshBoundingVolumeType type() const ${SIP_FINAL};

virtual QgsBox3D bounds( const QgsCoordinateTransform &transform = QgsCoordinateTransform(), Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const ${SIP_FINAL} throw( QgsCsException );
virtual QgsBox3D bounds( const QgsMatrix4x4 *transform = 0, const QgsCoordinateTransform &coordinateTransform = QgsCoordinateTransform(), Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const ${SIP_FINAL} throw( QgsCsException );

virtual QgsTiledMeshNodeBoundingVolumeRegion *clone() const ${SIP_FINAL} /Factory/;

Expand Down Expand Up @@ -129,7 +131,7 @@ Constructor for QgsTiledMeshNodeBoundingVolumeBox, with the specified oriented `

virtual Qgis::TiledMeshBoundingVolumeType type() const ${SIP_FINAL};

virtual QgsBox3D bounds( const QgsCoordinateTransform &transform = QgsCoordinateTransform(), Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const ${SIP_FINAL} throw( QgsCsException );
virtual QgsBox3D bounds( const QgsMatrix4x4 *transform = 0, const QgsCoordinateTransform &coordinateTransform = QgsCoordinateTransform(), Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const ${SIP_FINAL} throw( QgsCsException );

virtual QgsTiledMeshNodeBoundingVolumeBox *clone() const ${SIP_FINAL} /Factory/;

Expand Down Expand Up @@ -163,7 +165,7 @@ Constructor for :py:class:`QgsTiledMeshNodeBoundingVolumeBox`, with the specifie

virtual Qgis::TiledMeshBoundingVolumeType type() const ${SIP_FINAL};

virtual QgsBox3D bounds( const QgsCoordinateTransform &transform = QgsCoordinateTransform(), Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const ${SIP_FINAL} throw( QgsCsException );
virtual QgsBox3D bounds( const QgsMatrix4x4 *transform = 0, const QgsCoordinateTransform &coordinateTransform = QgsCoordinateTransform(), Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const ${SIP_FINAL} throw( QgsCsException );

virtual QgsTiledMeshNodeBoundingVolumeSphere *clone() const ${SIP_FINAL} /Factory/;

Expand Down
84 changes: 84 additions & 0 deletions python/core/auto_generated/tiledmesh/qgstiledmeshindex.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,81 @@



class QgsTiledMeshRequest
{
%Docstring(signature="appended")

Tiled mesh data request.

.. versionadded:: 3.34
%End

%TypeHeaderCode
#include "qgstiledmeshindex.h"
%End
public:

QgsTiledMeshRequest();

QgsBox3D filterBox() const;
%Docstring
Returns the box from which data will be taken, in the layer's crs.

If the returned box is null, then no filter box is set.

.. seealso:: :py:func:`setFilterBox`
%End

void setFilterBox( const QgsBox3D &box );
%Docstring
Sets the ``box`` from which data will be taken, in the layer's crs.

An null ``box`` removes the filter.

.. seealso:: :py:func:`filterBox`
%End

double requiredGeometricError() const;
%Docstring
Returns the required geometric error treshold for the returned nodes, in
mesh CRS units.

If the error is 0 then no geometric error filtering will be applied.

.. seealso:: :py:func:`setRequiredGeometricError`
%End

void setRequiredGeometricError( double error );
%Docstring
Sets the required geometric ``error`` treshold for the returned nodes, in
mesh CRS units.

If the ``error`` is 0 then no geometric error filtering will be applied.

.. seealso:: :py:func:`requiredGeometricError`
%End

void setFeedback( QgsFeedback *feedback );
%Docstring
Attach a ``feedback`` object that can be queried regularly by the request to check
if it should be canceled.

Ownership of ``feedback`` is NOT transferred, and the caller must take care that it exists
for the lifetime of the request.

.. seealso:: :py:func:`feedback`
%End

QgsFeedback *feedback() const;
%Docstring
Returns the feedback object that can be queried regularly by the request to check
if it should be canceled, if set.

.. seealso:: :py:func:`setFeedback`
%End

};

class QgsTiledMeshIndex
{
%Docstring(signature="appended")
Expand Down Expand Up @@ -47,6 +122,15 @@ Returns ``True`` if the index is valid.
QgsTiledMeshNode rootNode() const;
%Docstring
Returns the root node for the index.
%End

QgsTiledMeshNode *getNodes( const QgsTiledMeshRequest &request ) /Factory/;
%Docstring
Returns a node tree containing all nodes matching the given ``request``.

Caller takes ownership of the returned node.

May return ``None`` if no data satisfies the request.
%End

QByteArray retrieveContent( const QString &uri, QgsFeedback *feedback = 0 );
Expand Down
18 changes: 18 additions & 0 deletions python/core/auto_generated/tiledmesh/qgstiledmeshnode.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ Copy constructor
Returns ``True`` if the node is a valid node (i.e. not default constructed).
%End

QgsTiledMeshNode *zeroDepthCopy() const;

void addChild( QgsTiledMeshNode *child /Transfer/ );
%Docstring
Adds a ``child`` to this node.
Expand Down Expand Up @@ -110,6 +112,22 @@ Returns the content URI for the node.
Sets the content ``uri`` for the node.

.. seealso:: :py:func:`contentUri`
%End

double geometricError() const;
%Docstring
Returns the node's geometric error, which is the error, in mesh CRS units, of the tile's
simplified representation of its source geometry.

.. seealso:: :py:func:`setGeometricError`
%End

void setGeometricError( double error );
%Docstring
Sets the node's geometric ``error``, which is the error, in mesh CRS units, of the tile's
simplified representation of its source geometry.

.. seealso:: :py:func:`geometricError`
%End

};
Expand Down
8 changes: 5 additions & 3 deletions src/core/tiledmesh/qgscesiumtilesdataprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ QgsCesiumTiledMeshIndex::QgsCesiumTiledMeshIndex( const json &tileset, const QSt
const auto &boundingVolume = json[ "boundingVolume" ];
if ( boundingVolume.contains( "region" ) )
{
const QgsBox3d rootRegion = QgsCesiumUtils::parseRegion( boundingVolume[ "region" ] );
const QgsBox3D rootRegion = QgsCesiumUtils::parseRegion( boundingVolume[ "region" ] );
if ( !rootRegion.isNull() )
{
node->setBoundingVolume( new QgsTiledMeshNodeBoundingVolumeRegion( rootRegion ) );
Expand All @@ -137,6 +137,8 @@ QgsCesiumTiledMeshIndex::QgsCesiumTiledMeshIndex( const json &tileset, const QSt
QgsDebugError( QStringLiteral( "unsupported boundingVolume format" ) );
}

node->setGeometricError( json["geometricError"].get< double >() );

if ( json.contains( "content" ) && !json["content"].is_null() )
{
const auto &contentJson = json["content"];
Expand Down Expand Up @@ -286,7 +288,7 @@ void QgsCesiumTilesDataProviderSharedData::initialize( const QString &tileset, c
mBoundingVolume = std::make_unique< QgsTiledMeshNodeBoundingVolumeBox >( bbox );
try
{
const QgsBox3D rootRegion = mBoundingVolume->bounds( transform );
const QgsBox3D rootRegion = mBoundingVolume->bounds( rootTransform.isIdentity() ? nullptr : &rootTransform, transform );
mZRange = QgsDoubleRange( rootRegion.zMinimum(), rootRegion.zMaximum() );

std::unique_ptr< QgsAbstractGeometry > extent2D( mBoundingVolume->as2DGeometry( rootTransform.isIdentity() ? nullptr : &rootTransform, transform ) );
Expand Down Expand Up @@ -315,7 +317,7 @@ void QgsCesiumTilesDataProviderSharedData::initialize( const QString &tileset, c
mBoundingVolume = std::make_unique< QgsTiledMeshNodeBoundingVolumeSphere >( sphere );
try
{
const QgsBox3D rootRegion = mBoundingVolume->bounds( transform );
const QgsBox3D rootRegion = mBoundingVolume->bounds( rootTransform.isIdentity() ? nullptr : &rootTransform, transform );
mZRange = QgsDoubleRange( rootRegion.zMinimum(), rootRegion.zMaximum() );

std::unique_ptr< QgsAbstractGeometry > extent2D( mBoundingVolume->as2DGeometry( rootTransform.isIdentity() ? nullptr : &rootTransform, transform ) );
Expand Down
30 changes: 17 additions & 13 deletions src/core/tiledmesh/qgstiledmeshboundingvolume.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ Qgis::TiledMeshBoundingVolumeType QgsTiledMeshNodeBoundingVolumeRegion::type() c
return Qgis::TiledMeshBoundingVolumeType::Region;
}

QgsBox3D QgsTiledMeshNodeBoundingVolumeRegion::bounds( const QgsCoordinateTransform &transform, Qgis::TransformDirection direction ) const
QgsBox3D QgsTiledMeshNodeBoundingVolumeRegion::bounds( const QgsMatrix4x4 *transform, const QgsCoordinateTransform &coordinateTransform, Qgis::TransformDirection direction ) const
{
if ( !transform.isValid() || transform.isShortCircuited() )
if ( !coordinateTransform.isValid() || coordinateTransform.isShortCircuited() )
{
return mRegion;
}
Expand All @@ -52,7 +52,7 @@ QgsBox3D QgsTiledMeshNodeBoundingVolumeRegion::bounds( const QgsCoordinateTransf
QVector< double > x{ mRegion.xMinimum(), mRegion.xMinimum(), mRegion.xMaximum(), mRegion.xMaximum(), mRegion.xMinimum(), mRegion.xMinimum(), mRegion.xMaximum(), mRegion.xMaximum() };
QVector< double > y{ mRegion.yMinimum(), mRegion.yMaximum(), mRegion.yMinimum(), mRegion.yMaximum(), mRegion.yMinimum(), mRegion.yMaximum(), mRegion.yMinimum(), mRegion.yMaximum() };
QVector< double > z{ mRegion.zMinimum(), mRegion.zMinimum(), mRegion.zMinimum(), mRegion.zMinimum(), mRegion.zMaximum(), mRegion.zMaximum(), mRegion.zMaximum(), mRegion.zMaximum() };
transform.transformInPlace( x, y, z, direction );
coordinateTransform.transformInPlace( x, y, z, direction );

const auto minMaxX = std::minmax_element( x.constBegin(), x.constEnd() );
const auto minMaxY = std::minmax_element( y.constBegin(), y.constEnd() );
Expand Down Expand Up @@ -114,9 +114,9 @@ Qgis::TiledMeshBoundingVolumeType QgsTiledMeshNodeBoundingVolumeBox::type() cons
return Qgis::TiledMeshBoundingVolumeType::OrientedBox;
}

QgsBox3D QgsTiledMeshNodeBoundingVolumeBox::bounds( const QgsCoordinateTransform &transform, Qgis::TransformDirection direction ) const
QgsBox3D QgsTiledMeshNodeBoundingVolumeBox::bounds( const QgsMatrix4x4 *transform, const QgsCoordinateTransform &coordinateTransform, Qgis::TransformDirection direction ) const
{
if ( transform.isValid() && !transform.isShortCircuited() )
if ( transform || ( coordinateTransform.isValid() && !coordinateTransform.isShortCircuited() ) )
{
const QVector< QgsVector3D > corners = mBox.corners();
QVector< double > x;
Expand All @@ -127,11 +127,15 @@ QgsBox3D QgsTiledMeshNodeBoundingVolumeBox::bounds( const QgsCoordinateTransform
z.reserve( 8 );
for ( int i = 0; i < 8; ++i )
{
x.append( corners[i].x() );
y.append( corners[i].y() );
z.append( corners[i].z() );
QgsVector3D corner = corners[i];
if ( transform )
corner = transform->map( corner );

x.append( corner.x() );
y.append( corner.y() );
z.append( corner.z() );
}
transform.transformInPlace( x, y, z, direction );
coordinateTransform.transformInPlace( x, y, z, direction );

const auto minMaxX = std::minmax_element( x.constBegin(), x.constEnd() );
const auto minMaxY = std::minmax_element( y.constBegin(), y.constEnd() );
Expand Down Expand Up @@ -205,17 +209,17 @@ Qgis::TiledMeshBoundingVolumeType QgsTiledMeshNodeBoundingVolumeSphere::type() c
return Qgis::TiledMeshBoundingVolumeType::Sphere;
}

QgsBox3D QgsTiledMeshNodeBoundingVolumeSphere::bounds( const QgsCoordinateTransform &transform, Qgis::TransformDirection direction ) const
QgsBox3D QgsTiledMeshNodeBoundingVolumeSphere::bounds( const QgsMatrix4x4 *transform, const QgsCoordinateTransform &coordinateTransform, Qgis::TransformDirection direction ) const
{
if ( transform.isValid() && !transform.isShortCircuited() )
if ( transform || ( coordinateTransform.isValid() && !coordinateTransform.isShortCircuited() ) )
{
std::unique_ptr< QgsAbstractGeometry > centerSlice( as2DGeometry( nullptr, transform, direction ) );
std::unique_ptr< QgsAbstractGeometry > centerSlice( as2DGeometry( transform, coordinateTransform, direction ) );

// a line through the z range of sphere, passing through center
QVector< double > x { mSphere.centerX(), mSphere.centerX() };
QVector< double > y { mSphere.centerY(), mSphere.centerY() };
QVector< double > z { mSphere.centerZ() - mSphere.radius(), mSphere.centerZ() + mSphere.radius() };
transform.transformInPlace( x, y, z, direction );
coordinateTransform.transformInPlace( x, y, z, direction );

const QgsRectangle bounds2d( centerSlice->boundingBox() );
return QgsBox3D( bounds2d.xMinimum(), bounds2d.yMinimum(), std::min( z[0], z[1] ), bounds2d.xMaximum(), bounds2d.yMaximum(), std::max( z[0], z[1] ) );
Expand Down
12 changes: 7 additions & 5 deletions src/core/tiledmesh/qgstiledmeshboundingvolume.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,12 @@ class CORE_EXPORT QgsAbstractTiledMeshNodeBoundingVolume
/**
* Returns the axis aligned bounding box of the volume.
*
* The optional \a transform and \a direction arguments should be used whenever the volume needs
* An optional \a transform matrix can be specified to transform the raw coordinates.
*
* The optional \a coordinateTransform and \a direction arguments should be used whenever the volume needs
* to be transformed into a specific destination CRS, in order to correctly handle 3D coordinate transforms.
*/
virtual QgsBox3D bounds( const QgsCoordinateTransform &transform = QgsCoordinateTransform(), Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const = 0;
virtual QgsBox3D bounds( const QgsMatrix4x4 *transform = nullptr, const QgsCoordinateTransform &coordinateTransform = QgsCoordinateTransform(), Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const = 0;

/**
* Returns a clone of the volume.
Expand Down Expand Up @@ -109,7 +111,7 @@ class CORE_EXPORT QgsTiledMeshNodeBoundingVolumeRegion : public QgsAbstractTiled
QgsTiledMeshNodeBoundingVolumeRegion( const QgsBox3D &region );

Qgis::TiledMeshBoundingVolumeType type() const FINAL;
QgsBox3D bounds( const QgsCoordinateTransform &transform = QgsCoordinateTransform(), Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const FINAL SIP_THROW( QgsCsException );
QgsBox3D bounds( const QgsMatrix4x4 *transform = nullptr, const QgsCoordinateTransform &coordinateTransform = QgsCoordinateTransform(), Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const FINAL SIP_THROW( QgsCsException );
QgsTiledMeshNodeBoundingVolumeRegion *clone() const FINAL SIP_FACTORY;
QgsAbstractGeometry *as2DGeometry( const QgsMatrix4x4 *transform = nullptr, const QgsCoordinateTransform &coordinateTransform = QgsCoordinateTransform(), Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const FINAL SIP_THROW( QgsCsException ) SIP_FACTORY;

Expand Down Expand Up @@ -138,7 +140,7 @@ class CORE_EXPORT QgsTiledMeshNodeBoundingVolumeBox : public QgsAbstractTiledMes
QgsTiledMeshNodeBoundingVolumeBox( const QgsOrientedBox3D &box );

Qgis::TiledMeshBoundingVolumeType type() const FINAL;
QgsBox3D bounds( const QgsCoordinateTransform &transform = QgsCoordinateTransform(), Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const FINAL SIP_THROW( QgsCsException );
QgsBox3D bounds( const QgsMatrix4x4 *transform = nullptr, const QgsCoordinateTransform &coordinateTransform = QgsCoordinateTransform(), Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const FINAL SIP_THROW( QgsCsException );
QgsTiledMeshNodeBoundingVolumeBox *clone() const FINAL SIP_FACTORY;
QgsAbstractGeometry *as2DGeometry( const QgsMatrix4x4 *transform = nullptr, const QgsCoordinateTransform &coordinateTransform = QgsCoordinateTransform(), Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const FINAL SIP_THROW( QgsCsException ) SIP_FACTORY;

Expand Down Expand Up @@ -169,7 +171,7 @@ class CORE_EXPORT QgsTiledMeshNodeBoundingVolumeSphere: public QgsAbstractTiledM
QgsTiledMeshNodeBoundingVolumeSphere( const QgsSphere &sphere );

Qgis::TiledMeshBoundingVolumeType type() const FINAL;
QgsBox3D bounds( const QgsCoordinateTransform &transform = QgsCoordinateTransform(), Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const FINAL SIP_THROW( QgsCsException );
QgsBox3D bounds( const QgsMatrix4x4 *transform = nullptr, const QgsCoordinateTransform &coordinateTransform = QgsCoordinateTransform(), Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const FINAL SIP_THROW( QgsCsException );
QgsTiledMeshNodeBoundingVolumeSphere *clone() const FINAL SIP_FACTORY;
QgsAbstractGeometry *as2DGeometry( const QgsMatrix4x4 *transform = nullptr, const QgsCoordinateTransform &coordinateTransform = QgsCoordinateTransform(), Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const FINAL SIP_THROW( QgsCsException ) SIP_FACTORY;

Expand Down
Loading

0 comments on commit f1fcd85

Please sign in to comment.