Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Point cloud editing part 1 #59973

Merged
merged 5 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
QgsPointCloudDataProvider.WriteLayerMetadata = QgsPointCloudDataProvider.Capability.WriteLayerMetadata
QgsPointCloudDataProvider.CreateRenderer = QgsPointCloudDataProvider.Capability.CreateRenderer
QgsPointCloudDataProvider.ContainSubIndexes = QgsPointCloudDataProvider.Capability.ContainSubIndexes
QgsPointCloudDataProvider.ChangeAttributeValues = QgsPointCloudDataProvider.Capability.ChangeAttributeValues
QgsPointCloudDataProvider.Capabilities = lambda flags=0: QgsPointCloudDataProvider.Capability(flags)
QgsPointCloudDataProvider.NotIndexed = QgsPointCloudDataProvider.PointCloudIndexGenerationState.NotIndexed
QgsPointCloudDataProvider.Indexing = QgsPointCloudDataProvider.PointCloudIndexGenerationState.Indexing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Responsible for reading native point cloud data and returning the indexed data.
WriteLayerMetadata,
CreateRenderer,
ContainSubIndexes,
ChangeAttributeValues,
};

typedef QFlags<QgsPointCloudDataProvider::Capability> Capabilities;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,13 @@ Returns all attributes that are stored in the file



bool updateNodeData( const QHash<QgsPointCloudNodeId, QByteArray> &data );
%Docstring
Tries to update the data for the specified nodes.

:return: ``True`` on success, otherwise ``False``
%End

QgsRectangle extent() const;
%Docstring
Returns extent of the data
Expand Down Expand Up @@ -346,6 +353,18 @@ Returns extra metadata that's not accessible through the other methods
in an implementation-specific dynamic structure.

.. seealso:: :py:func:`QgsAbstractPointCloudIndex.extraMetadata`
%End

bool commitChanges();
%Docstring
Tries to store pending changes to the data provider.

:return: ``True`` on success, otherwise ``False``
%End

bool isModified() const;
%Docstring
Returns ``True`` if there are uncommitted changes, ``False`` otherwise
%End

};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@ Constructor - creates a point cloud layer
virtual QgsPointCloudDataProvider *dataProvider();


virtual bool supportsEditing() const;

virtual bool isEditable() const;

virtual bool isModified() const;


virtual bool readXml( const QDomNode &layerNode, QgsReadWriteContext &context );


Expand Down Expand Up @@ -201,6 +208,82 @@ Returns the status of point cloud statistics calculation

.. versionadded:: 3.26
%End

bool startEditing();
%Docstring
Makes the layer editable.

This starts an edit session on this layer. Changes made in this edit session will not
be made persistent until :py:func:`~QgsPointCloudLayer.commitChanges` is called, and can be reverted by calling
:py:func:`~QgsPointCloudLayer.rollBack`.

:return: ``True`` if the layer was successfully made editable, or ``False`` if the operation
failed (e.g. due to an underlying read-only data source, or lack of edit support
by the backend data provider).

.. seealso:: :py:func:`commitChanges`

.. seealso:: :py:func:`rollBack`

.. versionadded:: 3.42
%End

bool commitChanges( bool stopEditing = true );
%Docstring
Attempts to commit to the underlying data provider any buffered changes made since the
last to call to :py:func:`~QgsPointCloudLayer.startEditing`.

Returns the result of the attempt. If a commit fails (i.e. ``False`` is returned), the
in-memory changes are left untouched and are not discarded. This allows editing to
continue if the commit failed on e.g. a disallowed value for an attribute - the user
can re-edit and try again.

If the commit failed, an error message may returned by :py:func:`~QgsPointCloudLayer.commitError`.

By setting ``stopEditing`` to ``False``, the layer will stay in editing mode.
Otherwise the layer editing mode will be disabled if the commit is successful.

.. seealso:: :py:func:`startEditing`

.. seealso:: :py:func:`commitError`

.. seealso:: :py:func:`rollBack`

.. versionadded:: 3.42
%End

QString commitError() const;
%Docstring
Returns the last error message generated when attempting
to commit changes to the layer.

.. seealso:: :py:func:`commitChanges`

.. versionadded:: 3.42
%End

bool rollBack();
%Docstring
Stops a current editing operation and discards any uncommitted edits.

.. seealso:: :py:func:`startEditing`

.. seealso:: :py:func:`commitChanges`

.. versionadded:: 3.42
%End


QgsPointCloudIndex index() const;
%Docstring
Returns the point cloud index associated with the layer.
If the layer is editable, its :py:class:`QgsPointCloudEditingIndex` is returned,
otherwise the index is fetched from the data provider.

.. versionadded:: 3.42
%End


signals:

void subsetStringChanged();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Responsible for reading native point cloud data and returning the indexed data.
WriteLayerMetadata,
CreateRenderer,
ContainSubIndexes,
ChangeAttributeValues,
};

typedef QFlags<QgsPointCloudDataProvider::Capability> Capabilities;
Expand Down
19 changes: 19 additions & 0 deletions python/core/auto_generated/pointcloud/qgspointcloudindex.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,13 @@ Returns all attributes that are stored in the file



bool updateNodeData( const QHash<QgsPointCloudNodeId, QByteArray> &data );
%Docstring
Tries to update the data for the specified nodes.

:return: ``True`` on success, otherwise ``False``
%End

QgsRectangle extent() const;
%Docstring
Returns extent of the data
Expand Down Expand Up @@ -346,6 +353,18 @@ Returns extra metadata that's not accessible through the other methods
in an implementation-specific dynamic structure.

.. seealso:: :py:func:`QgsAbstractPointCloudIndex.extraMetadata`
%End

bool commitChanges();
%Docstring
Tries to store pending changes to the data provider.

:return: ``True`` on success, otherwise ``False``
%End

bool isModified() const;
%Docstring
Returns ``True`` if there are uncommitted changes, ``False`` otherwise
%End

};
Expand Down
83 changes: 83 additions & 0 deletions python/core/auto_generated/pointcloud/qgspointcloudlayer.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@ Constructor - creates a point cloud layer
virtual QgsPointCloudDataProvider *dataProvider();


virtual bool supportsEditing() const;

virtual bool isEditable() const;

virtual bool isModified() const;


virtual bool readXml( const QDomNode &layerNode, QgsReadWriteContext &context );


Expand Down Expand Up @@ -201,6 +208,82 @@ Returns the status of point cloud statistics calculation

.. versionadded:: 3.26
%End

bool startEditing();
%Docstring
Makes the layer editable.

This starts an edit session on this layer. Changes made in this edit session will not
be made persistent until :py:func:`~QgsPointCloudLayer.commitChanges` is called, and can be reverted by calling
:py:func:`~QgsPointCloudLayer.rollBack`.

:return: ``True`` if the layer was successfully made editable, or ``False`` if the operation
failed (e.g. due to an underlying read-only data source, or lack of edit support
by the backend data provider).

.. seealso:: :py:func:`commitChanges`

.. seealso:: :py:func:`rollBack`

.. versionadded:: 3.42
%End

bool commitChanges( bool stopEditing = true );
%Docstring
Attempts to commit to the underlying data provider any buffered changes made since the
last to call to :py:func:`~QgsPointCloudLayer.startEditing`.

Returns the result of the attempt. If a commit fails (i.e. ``False`` is returned), the
in-memory changes are left untouched and are not discarded. This allows editing to
continue if the commit failed on e.g. a disallowed value for an attribute - the user
can re-edit and try again.

If the commit failed, an error message may returned by :py:func:`~QgsPointCloudLayer.commitError`.

By setting ``stopEditing`` to ``False``, the layer will stay in editing mode.
Otherwise the layer editing mode will be disabled if the commit is successful.

.. seealso:: :py:func:`startEditing`

.. seealso:: :py:func:`commitError`

.. seealso:: :py:func:`rollBack`

.. versionadded:: 3.42
%End

QString commitError() const;
%Docstring
Returns the last error message generated when attempting
to commit changes to the layer.

.. seealso:: :py:func:`commitChanges`

.. versionadded:: 3.42
%End

bool rollBack();
%Docstring
Stops a current editing operation and discards any uncommitted edits.

.. seealso:: :py:func:`startEditing`

.. seealso:: :py:func:`commitChanges`

.. versionadded:: 3.42
%End


QgsPointCloudIndex index() const;
%Docstring
Returns the point cloud index associated with the layer.
If the layer is editable, its :py:class:`QgsPointCloudEditingIndex` is returned,
otherwise the index is fetched from the data provider.

.. versionadded:: 3.42
%End


signals:

void subsetStringChanged();
Expand Down
4 changes: 2 additions & 2 deletions src/3d/qgspointcloudlayer3drenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,9 @@ Qt3DCore::QEntity *QgsPointCloudLayer3DRenderer::createEntity( Qgs3DMapSettings
const QgsCoordinateTransform coordinateTransform( pcl->crs3D(), map->crs(), map->transformContext() );

Qt3DCore::QEntity *entity = nullptr;
if ( pcl->dataProvider()->index() )
if ( pcl->index() )
{
entity = new QgsPointCloudLayerChunkedEntity( map, pcl->dataProvider()->index(), coordinateTransform, dynamic_cast<QgsPointCloud3DSymbol *>( mSymbol->clone() ), static_cast<float>( maximumScreenError() ), showBoundingBoxes(), static_cast<const QgsPointCloudLayerElevationProperties *>( pcl->elevationProperties() )->zScale(), static_cast<const QgsPointCloudLayerElevationProperties *>( pcl->elevationProperties() )->zOffset(), mPointBudget );
entity = new QgsPointCloudLayerChunkedEntity( map, pcl->index(), coordinateTransform, dynamic_cast<QgsPointCloud3DSymbol *>( mSymbol->clone() ), static_cast<float>( maximumScreenError() ), showBoundingBoxes(), static_cast<const QgsPointCloudLayerElevationProperties *>( pcl->elevationProperties() )->zScale(), static_cast<const QgsPointCloudLayerElevationProperties *>( pcl->elevationProperties() )->zOffset(), mPointBudget );
}
else if ( !pcl->dataProvider()->subIndexes().isEmpty() )
{
Expand Down
4 changes: 4 additions & 0 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -859,11 +859,13 @@ set(QGIS_CORE_SRCS
pointcloud/qgspointcloudattributebyramprenderer.cpp
pointcloud/qgspointcloudattributemodel.cpp
pointcloud/qgspointcloudclassifiedrenderer.cpp
pointcloud/qgspointcloudeditingindex.cpp
pointcloud/qgspointcloudextentrenderer.cpp
pointcloud/qgspointcloudrequest.cpp
pointcloud/qgspointcloudblock.cpp
pointcloud/qgspointcloudblockrequest.cpp
pointcloud/qgspointcloudlayer.cpp
pointcloud/qgspointcloudlayereditutils.cpp
pointcloud/qgspointcloudlayerelevationproperties.cpp
pointcloud/qgspointcloudlayerprofilegenerator.cpp
pointcloud/qgspointcloudlayerrenderer.cpp
Expand Down Expand Up @@ -1723,11 +1725,13 @@ set(QGIS_CORE_HDRS
pointcloud/qgspointcloudattributebyramprenderer.h
pointcloud/qgspointcloudattributemodel.h
pointcloud/qgspointcloudclassifiedrenderer.h
pointcloud/qgspointcloudeditingindex.h
pointcloud/qgspointcloudextentrenderer.h
pointcloud/qgspointcloudrequest.h
pointcloud/qgspointcloudblock.h
pointcloud/qgspointcloudblockrequest.h
pointcloud/qgspointcloudlayer.h
pointcloud/qgspointcloudlayereditutils.h
pointcloud/qgspointcloudlayerelevationproperties.h
pointcloud/qgspointcloudlayerprofilegenerator.h
pointcloud/qgspointcloudlayerrenderer.h
Expand Down
5 changes: 5 additions & 0 deletions src/core/pointcloud/qgslazdecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,11 @@ bool lazSerialize_( char *data, size_t outputPosition, QgsPointCloudAttribute::D
return true;
}

bool lazStoreDoubleToStream( char *s, size_t position, QgsPointCloudAttribute::DataType type, double value )
{
return lazStoreToStream_<double>( s, position, type, value );
}

// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

std::vector< QgsLazDecoder::RequestedAttributeDetails > prepareRequestedAttributeDetails_( const QgsPointCloudAttributeCollection &requestedAttributes, QVector<QgsLazInfo::ExtraBytesAttributeDetails> &extrabytesAttr )
Expand Down
1 change: 1 addition & 0 deletions src/core/pointcloud/qgslazdecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ template <typename T>
bool lazStoreToStream_( char *s, size_t position, QgsPointCloudAttribute::DataType type, T value );
bool lazSerialize_( char *data, size_t outputPosition, QgsPointCloudAttribute::DataType outputType,
const char *input, QgsPointCloudAttribute::DataType inputType, int inputSize, size_t inputPosition );
bool lazStoreDoubleToStream( char *s, size_t position, QgsPointCloudAttribute::DataType type, double value );

class QgsLazDecoder
{
Expand Down
1 change: 1 addition & 0 deletions src/core/pointcloud/qgspointclouddataprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class CORE_EXPORT QgsPointCloudDataProvider: public QgsDataProvider
WriteLayerMetadata = 1 << 1, //!< Provider can write layer metadata to the data store. See QgsDataProvider::writeLayerMetadata()
CreateRenderer = 1 << 2, //!< Provider can create 2D renderers using backend-specific formatting information. See QgsPointCloudDataProvider::createRenderer().
ContainSubIndexes = 1 << 3, //!< Provider can contain multiple indexes. Virtual point cloud files for example \since QGIS 3.32
ChangeAttributeValues = 1 << 4, //!< Provider can modify the values of point attributes. \since QGIS 3.42
};

Q_DECLARE_FLAGS( Capabilities, Capability )
Expand Down
Loading
Loading