Skip to content

Commit

Permalink
split vector feature with QgsCurve
Browse files Browse the repository at this point in the history
  • Loading branch information
vcloarec committed Jul 29, 2020
1 parent c4722b4 commit 24b1b3b
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 14 deletions.
15 changes: 15 additions & 0 deletions python/core/auto_generated/geometry/qgsgeometry.sip.in
Expand Up @@ -884,6 +884,21 @@ Example:
> LineStringZ (2749549.12 1262908.38 125.14, 2749557.82 1262920.06 200)
%End

OperationResult splitGeometry( const QgsCurve *curve, QVector<QgsGeometry> &newGeometries /Out/, bool preserveCircular, bool topological, QgsPointSequence &topologyTestPoints /Out/, bool splitFeature = true );
%Docstring
Splits this geometry according to a given curve.

:param curve: the curve that splits the geometry
\param[out] newGeometries list of new geometries that have been created with the ``splitLine``. If the geometry is 3D, a linear interpolation of the z value is performed on the geometry at split points, see example.
:param preserveCircular: whether if circular strings are preserved after splitting
:param topological: ``True`` if topological editing is enabled
\param[out] topologyTestPoints points that need to be tested for topological completeness in the dataset
:param splitFeature: Set to True if you want to split a feature, otherwise set to False to split parts
fix this bug?

:return: OperationResult a result code: success or reason of failure
%End

OperationResult reshapeGeometry( const QgsLineString &reshapeLineString );
%Docstring
Replaces a part of this geometry with another line
Expand Down
26 changes: 26 additions & 0 deletions python/core/auto_generated/qgsvectorlayer.sip.in
Expand Up @@ -1585,6 +1585,32 @@ Splits features cut by the given line
:param splitLine: line that splits the layer features
:param topologicalEditing: ``True`` if topological editing is enabled

:return: QgsGeometry.OperationResult

- Success
- NothingHappened
- LayerNotEditable
- InvalidInputGeometryType
- InvalidBaseGeometry
- GeometryEngineError
- SplitCannotSplitPoint

.. note::

Calls to :py:func:`~QgsVectorLayer.splitFeatures` are only valid for layers in which edits have been enabled
by a call to :py:func:`~QgsVectorLayer.startEditing`. Changes made to features using this method are not committed
to the underlying data provider until a :py:func:`~QgsVectorLayer.commitChanges` call is made. Any uncommitted
changes can be discarded by calling :py:func:`~QgsVectorLayer.rollBack`.
%End

QgsGeometry::OperationResult splitFeatures( const QgsCurve *curve, bool preserveCircular = false, bool topologicalEditing = false );
%Docstring
Splits features cut by the given curve

:param curve: curve that splits the layer features
:param preserveCircular: whether if circular strings are preserved after splitting
:param topologicalEditing: ``True`` if topological editing is enabled

:return: QgsGeometry.OperationResult

- Success
Expand Down
12 changes: 12 additions & 0 deletions python/core/auto_generated/qgsvectorlayereditutils.sip.in
Expand Up @@ -219,6 +219,18 @@ Splits features cut by the given line
:param splitLine: line that splits the layer features
:param topologicalEditing: ``True`` if topological editing is enabled

:return: 0 in case of success,
4 if there is a selection but no feature split
%End

QgsGeometry::OperationResult splitFeatures( const QgsCurve *curve, bool preserveCircular = false, bool topologicalEditing = false );
%Docstring
Splits features cut by the given curve

:param curve: line that splits the layer features
:param preserveCircular: whether if circular strings are preserved after splitting
:param topologicalEditing: ``True`` if topological editing is enabled

:return: 0 in case of success,
4 if there is a selection but no feature split
%End
Expand Down
20 changes: 20 additions & 0 deletions src/core/geometry/qgsgeometry.cpp
Expand Up @@ -881,6 +881,26 @@ QgsGeometry::OperationResult QgsGeometry::splitGeometry( const QgsPointSequence
return QgsGeometry::NothingHappened;
}

QgsGeometry::OperationResult QgsGeometry::splitGeometry( const QgsCurve *curve, QVector<QgsGeometry> &newGeometries, bool preserveCircular, bool topological, QgsPointSequence &topologyTestPoints, bool splitFeature )
{
std::unique_ptr<QgsLineString> segmentizedLine( curve->curveToLine() );
QgsPointSequence points;
segmentizedLine->points( points );
QgsGeometry::OperationResult result = splitGeometry( points, newGeometries, topological, topologyTestPoints, splitFeature );

if ( result == QgsGeometry::Success )
{
if ( preserveCircular )
{
for ( int i = 0; i < newGeometries.count(); ++i )
newGeometries[i] = newGeometries[i].convertToCurves();
*this = convertToCurves();
}
}

return result;
}

QgsGeometry::OperationResult QgsGeometry::reshapeGeometry( const QgsLineString &reshapeLineString )
{
if ( !d->geometry )
Expand Down
14 changes: 14 additions & 0 deletions src/core/geometry/qgsgeometry.h
Expand Up @@ -47,6 +47,7 @@ class QgsMapToPixel;
class QPainter;
class QgsPolygon;
class QgsLineString;
class QgsCurve;
class QgsFeedback;

/**
Expand Down Expand Up @@ -911,6 +912,19 @@ class CORE_EXPORT QgsGeometry
*/
OperationResult splitGeometry( const QgsPointSequence &splitLine, QVector<QgsGeometry> &newGeometries SIP_OUT, bool topological, QgsPointSequence &topologyTestPoints SIP_OUT, bool splitFeature = true );

/**
* Splits this geometry according to a given curve.
* \param curve the curve that splits the geometry
* \param[out] newGeometries list of new geometries that have been created with the ``splitLine``. If the geometry is 3D, a linear interpolation of the z value is performed on the geometry at split points, see example.
* \param preserveCircular whether if circular strings are preserved after splitting
* \param topological TRUE if topological editing is enabled
* \param[out] topologyTestPoints points that need to be tested for topological completeness in the dataset
* \param splitFeature Set to True if you want to split a feature, otherwise set to False to split parts
* fix this bug?
* \returns OperationResult a result code: success or reason of failure
*/
OperationResult splitGeometry( const QgsCurve *curve, QVector<QgsGeometry> &newGeometries SIP_OUT, bool preserveCircular, bool topological, QgsPointSequence &topologyTestPoints SIP_OUT, bool splitFeature = true );

/**
* Replaces a part of this geometry with another line
* \returns OperationResult a result code: success or reason of failure
Expand Down
8 changes: 7 additions & 1 deletion src/core/qgsvectorlayer.cpp
Expand Up @@ -1369,12 +1369,18 @@ QgsGeometry::OperationResult QgsVectorLayer::splitFeatures( const QVector<QgsPoi
}

QgsGeometry::OperationResult QgsVectorLayer::splitFeatures( const QgsPointSequence &splitLine, bool topologicalEditing )
{
QgsLineString splitLineString( splitLine );
return splitFeatures( &splitLineString, topologicalEditing );
}

QgsGeometry::OperationResult QgsVectorLayer::splitFeatures( const QgsCurve *curve, bool preserveCircular, bool topologicalEditing )
{
if ( !mValid || !mEditBuffer || !mDataProvider )
return QgsGeometry::OperationResult::LayerNotEditable;

QgsVectorLayerEditUtils utils( this );
return utils.splitFeatures( splitLine, topologicalEditing );
return utils.splitFeatures( curve, preserveCircular, topologicalEditing );
}

int QgsVectorLayer::addTopologicalPoints( const QgsGeometry &geom )
Expand Down
22 changes: 22 additions & 0 deletions src/core/qgsvectorlayer.h
Expand Up @@ -1547,6 +1547,28 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
*/
Q_INVOKABLE QgsGeometry::OperationResult splitFeatures( const QgsPointSequence &splitLine, bool topologicalEditing = false );

/**
* Splits features cut by the given curve
* \param curve curve that splits the layer features
* \param preserveCircular whether if circular strings are preserved after splitting
* \param topologicalEditing TRUE if topological editing is enabled
* \returns QgsGeometry::OperationResult
*
* - Success
* - NothingHappened
* - LayerNotEditable
* - InvalidInputGeometryType
* - InvalidBaseGeometry
* - GeometryEngineError
* - SplitCannotSplitPoint
*
* \note Calls to splitFeatures() are only valid for layers in which edits have been enabled
* by a call to startEditing(). Changes made to features using this method are not committed
* to the underlying data provider until a commitChanges() call is made. Any uncommitted
* changes can be discarded by calling rollBack().
*/
Q_INVOKABLE QgsGeometry::OperationResult splitFeatures( const QgsCurve *curve, bool preserveCircular = false, bool topologicalEditing = false );

/**
* Adds topological points for every vertex of the geometry.
* \param geom the geometry where each vertex is added to segments of other features
Expand Down
22 changes: 9 additions & 13 deletions src/core/qgsvectorlayereditutils.cpp
Expand Up @@ -295,11 +295,16 @@ QgsGeometry::OperationResult QgsVectorLayerEditUtils::splitFeatures( const QVect
}

QgsGeometry::OperationResult QgsVectorLayerEditUtils::splitFeatures( const QgsPointSequence &splitLine, bool topologicalEditing )
{
QgsLineString lineString( splitLine );
return splitFeatures( &lineString, false, topologicalEditing );
}

QgsGeometry::OperationResult QgsVectorLayerEditUtils::splitFeatures( const QgsCurve *curve, bool preserveCircular, bool topologicalEditing )
{
if ( !mLayer->isSpatial() )
return QgsGeometry::InvalidBaseGeometry;

double xMin, yMin, xMax, yMax;
QgsRectangle bBox; //bounding box of the split line
QgsGeometry::OperationResult returnCode = QgsGeometry::OperationResult::Success;
QgsGeometry::OperationResult splitFunctionReturn; //return code of QgsGeometry::splitGeometry
Expand All @@ -314,17 +319,8 @@ QgsGeometry::OperationResult QgsVectorLayerEditUtils::splitFeatures( const QgsPo
}
else //else consider all the feature that intersect the bounding box of the split line
{
if ( boundingBoxFromPointList( splitLine, xMin, yMin, xMax, yMax ) )
{
bBox.setXMinimum( xMin );
bBox.setYMinimum( yMin );
bBox.setXMaximum( xMax );
bBox.setYMaximum( yMax );
}
else
{
return QgsGeometry::OperationResult::InvalidInputGeometryType;
}

bBox = curve->boundingBox();

if ( bBox.isEmpty() )
{
Expand Down Expand Up @@ -365,7 +361,7 @@ QgsGeometry::OperationResult QgsVectorLayerEditUtils::splitFeatures( const QgsPo
QVector<QgsGeometry> newGeometries;
QgsPointSequence topologyTestPoints;
QgsGeometry featureGeom = feat.geometry();
splitFunctionReturn = featureGeom.splitGeometry( splitLine, newGeometries, topologicalEditing, topologyTestPoints );
splitFunctionReturn = featureGeom.splitGeometry( curve, newGeometries, preserveCircular, topologicalEditing, topologyTestPoints );
if ( splitFunctionReturn == QgsGeometry::OperationResult::Success )
{
//change this geometry
Expand Down
10 changes: 10 additions & 0 deletions src/core/qgsvectorlayereditutils.h
Expand Up @@ -203,6 +203,16 @@ class CORE_EXPORT QgsVectorLayerEditUtils
*/
QgsGeometry::OperationResult splitFeatures( const QgsPointSequence &splitLine, bool topologicalEditing = false );

/**
* Splits features cut by the given curve
* \param curve line that splits the layer features
* \param preserveCircular whether if circular strings are preserved after splitting
* \param topologicalEditing TRUE if topological editing is enabled
* \returns 0 in case of success,
* 4 if there is a selection but no feature split
*/
QgsGeometry::OperationResult splitFeatures( const QgsCurve *curve, bool preserveCircular = false, bool topologicalEditing = false );

/**
* Adds topological points for every vertex of the geometry.
* \param geom the geometry where each vertex is added to segments of other features
Expand Down

0 comments on commit 24b1b3b

Please sign in to comment.