Skip to content

Commit

Permalink
Added duplicate button to actions dialogue
Browse files Browse the repository at this point in the history
  • Loading branch information
Speedrace4 committed Jun 4, 2024
1 parent 7c69f92 commit 7204efb
Show file tree
Hide file tree
Showing 49 changed files with 667 additions and 216 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ E.g. :py:class:`QgsLineString` -> :py:class:`QgsCompoundCurve`, :py:class:`QgsPo
:return: the converted geometry. Caller takes ownership
%End

virtual QgsAbstractGeometry *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const = 0 /Factory/;
virtual QgsAbstractGeometry *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0, bool removeRedundantPoints = false ) const = 0 /Factory/;
%Docstring
Makes a new geometry with all the points or vertices snapped to the closest point of the grid.
Ownership is transferred to the caller.
Expand All @@ -626,6 +626,7 @@ In this case, it can be thought like rounding the x and y of all the points/vert
:param vSpacing: Vertical spacing of the grid (y axis). 0 to disable.
:param dSpacing: Depth spacing of the grid (z axis). 0 (default) to disable.
:param mSpacing: Custom dimension spacing of the grid (m axis). 0 (default) to disable.
:param removeRedundantPoints: if ``True``, then points which are redundant (e.g. they represent mid points on a straight line segment) will be skipped (since QGIS 3.38)
%End

virtual bool removeDuplicateNodes( double epsilon = 4 * DBL_EPSILON, bool useZValues = false ) = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ Appends the contents of another circular ``string`` to the end of this circular

virtual QgsLineString *curveToLine( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const /Factory/;

virtual QgsCircularString *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const /Factory/;
virtual QgsCircularString *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0, bool removeRedundantPoints = false ) const /Factory/;

virtual bool removeDuplicateNodes( double epsilon = 4 * DBL_EPSILON, bool useZValues = false );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ of the curve.
:param toleranceType: maximum segmentation angle or maximum difference between approximation and curve
%End

virtual QgsCompoundCurve *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const /Factory/;
virtual QgsCompoundCurve *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0, bool removeRedundantPoints = false ) const /Factory/;

virtual bool removeDuplicateNodes( double epsilon = 4 * DBL_EPSILON, bool useZValues = false );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Curve polygon geometry type

virtual QgsAbstractGeometry *boundary() const /Factory/;

virtual QgsCurvePolygon *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const /Factory/;
virtual QgsCurvePolygon *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0, bool removeRedundantPoints = false ) const /Factory/;

virtual bool removeDuplicateNodes( double epsilon = 4 * DBL_EPSILON, bool useZValues = false );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ Returns a geometry from within the collection.

virtual void clear();

virtual QgsGeometryCollection *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const /Factory/;
virtual QgsGeometryCollection *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0, bool removeRedundantPoints = false ) const /Factory/;

virtual bool removeDuplicateNodes( double epsilon = 4 * DBL_EPSILON, bool useZValues = false );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ segment in the line.
int indexOf( const QgsPoint &point ) const final;
virtual bool isValid( QString &error /Out/, Qgis::GeometryValidityFlags flags = Qgis::GeometryValidityFlags() ) const;

virtual QgsLineString *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const /Factory/;
virtual QgsLineString *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0, bool removeRedundantPoints = false ) const /Factory/;

virtual bool removeDuplicateNodes( double epsilon = 4 * DBL_EPSILON, bool useZValues = false );

Expand Down
2 changes: 1 addition & 1 deletion python/PyQt6/core/auto_generated/geometry/qgspoint.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ Example

virtual QgsPoint *clone() const /Factory/;

virtual QgsPoint *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const /Factory/;
virtual QgsPoint *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0, bool removeRedundantPoints = false ) const /Factory/;

virtual bool removeDuplicateNodes( double epsilon = 4 * DBL_EPSILON, bool useZValues = false );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ E.g. :py:class:`QgsLineString` -> :py:class:`QgsCompoundCurve`, :py:class:`QgsPo
:return: the converted geometry. Caller takes ownership
%End

virtual QgsAbstractGeometry *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const = 0 /Factory/;
virtual QgsAbstractGeometry *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0, bool removeRedundantPoints = false ) const = 0 /Factory/;
%Docstring
Makes a new geometry with all the points or vertices snapped to the closest point of the grid.
Ownership is transferred to the caller.
Expand All @@ -626,6 +626,7 @@ In this case, it can be thought like rounding the x and y of all the points/vert
:param vSpacing: Vertical spacing of the grid (y axis). 0 to disable.
:param dSpacing: Depth spacing of the grid (z axis). 0 (default) to disable.
:param mSpacing: Custom dimension spacing of the grid (m axis). 0 (default) to disable.
:param removeRedundantPoints: if ``True``, then points which are redundant (e.g. they represent mid points on a straight line segment) will be skipped (since QGIS 3.38)
%End

virtual bool removeDuplicateNodes( double epsilon = 4 * DBL_EPSILON, bool useZValues = false ) = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ Appends the contents of another circular ``string`` to the end of this circular

virtual QgsLineString *curveToLine( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const /Factory/;

virtual QgsCircularString *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const /Factory/;
virtual QgsCircularString *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0, bool removeRedundantPoints = false ) const /Factory/;

virtual bool removeDuplicateNodes( double epsilon = 4 * DBL_EPSILON, bool useZValues = false );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ of the curve.
:param toleranceType: maximum segmentation angle or maximum difference between approximation and curve
%End

virtual QgsCompoundCurve *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const /Factory/;
virtual QgsCompoundCurve *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0, bool removeRedundantPoints = false ) const /Factory/;

virtual bool removeDuplicateNodes( double epsilon = 4 * DBL_EPSILON, bool useZValues = false );

Expand Down
2 changes: 1 addition & 1 deletion python/core/auto_generated/geometry/qgscurvepolygon.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Curve polygon geometry type

virtual QgsAbstractGeometry *boundary() const /Factory/;

virtual QgsCurvePolygon *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const /Factory/;
virtual QgsCurvePolygon *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0, bool removeRedundantPoints = false ) const /Factory/;

virtual bool removeDuplicateNodes( double epsilon = 4 * DBL_EPSILON, bool useZValues = false );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ Returns a geometry from within the collection.

virtual void clear();

virtual QgsGeometryCollection *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const /Factory/;
virtual QgsGeometryCollection *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0, bool removeRedundantPoints = false ) const /Factory/;

virtual bool removeDuplicateNodes( double epsilon = 4 * DBL_EPSILON, bool useZValues = false );

Expand Down
2 changes: 1 addition & 1 deletion python/core/auto_generated/geometry/qgslinestring.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ segment in the line.
int indexOf( const QgsPoint &point ) const final;
virtual bool isValid( QString &error /Out/, Qgis::GeometryValidityFlags flags = Qgis::GeometryValidityFlags() ) const;

virtual QgsLineString *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const /Factory/;
virtual QgsLineString *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0, bool removeRedundantPoints = false ) const /Factory/;

virtual bool removeDuplicateNodes( double epsilon = 4 * DBL_EPSILON, bool useZValues = false );

Expand Down
2 changes: 1 addition & 1 deletion python/core/auto_generated/geometry/qgspoint.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ Example

virtual QgsPoint *clone() const /Factory/;

virtual QgsPoint *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const /Factory/;
virtual QgsPoint *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0, bool removeRedundantPoints = false ) const /Factory/;

virtual bool removeDuplicateNodes( double epsilon = 4 * DBL_EPSILON, bool useZValues = false );

Expand Down
6 changes: 4 additions & 2 deletions src/app/qgsattributetabledialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,16 +217,18 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *layer, QgsAttr
{
request.setFilterExpression( filterExpression );
}

// If sort expression requires geometry, we'll need to fetch it
needsGeom |= mLayer && QgsExpression( mLayer->attributeTableConfig().sortExpression() ).needsGeometry();
if ( !needsGeom )
request.setFlags( Qgis::FeatureRequestFlag::NoGeometry );


// Initialize dual view
if ( mLayer )
{
request.setSubsetOfAttributes( mMainView->requiredAttributes( mLayer ) );
mMainView->init( mLayer, QgisApp::instance()->mapCanvas(), request, editorContext, false );
QgsAttributeTableConfig config = mLayer->attributeTableConfig();
const QgsAttributeTableConfig config = mLayer->attributeTableConfig();
mMainView->setAttributeTableConfig( config );
mFeatureFilterWidget->init( mLayer, editorContext, mMainView, QgisApp::instance()->messageBar(), QgsMessageBar::defaultMessageTimeout() );
}
Expand Down
3 changes: 2 additions & 1 deletion src/core/geometry/qgsabstractgeometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -644,8 +644,9 @@ class CORE_EXPORT QgsAbstractGeometry
* \param vSpacing Vertical spacing of the grid (y axis). 0 to disable.
* \param dSpacing Depth spacing of the grid (z axis). 0 (default) to disable.
* \param mSpacing Custom dimension spacing of the grid (m axis). 0 (default) to disable.
* \param removeRedundantPoints if TRUE, then points which are redundant (e.g. they represent mid points on a straight line segment) will be skipped (since QGIS 3.38)
*/
virtual QgsAbstractGeometry *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const = 0 SIP_FACTORY;
virtual QgsAbstractGeometry *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0, bool removeRedundantPoints = false ) const = 0 SIP_FACTORY;

/**
* Removes duplicate nodes from the geometry, wherever removing the nodes does not result in a
Expand Down
5 changes: 3 additions & 2 deletions src/core/geometry/qgscircularstring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -624,13 +624,14 @@ QgsLineString *QgsCircularString::curveToLine( double tolerance, SegmentationTol
return line;
}

QgsCircularString *QgsCircularString::snappedToGrid( double hSpacing, double vSpacing, double dSpacing, double mSpacing ) const
QgsCircularString *QgsCircularString::snappedToGrid( double hSpacing, double vSpacing, double dSpacing, double mSpacing, bool ) const
{
// prepare result
std::unique_ptr<QgsCircularString> result { createEmptyWithSameType() };

// remove redundant not supported for circular strings
bool res = snapToGridPrivate( hSpacing, vSpacing, dSpacing, mSpacing, mX, mY, mZ, mM,
result->mX, result->mY, result->mZ, result->mM );
result->mX, result->mY, result->mZ, result->mM, false );
if ( res )
return result.release();
else
Expand Down
2 changes: 1 addition & 1 deletion src/core/geometry/qgscircularstring.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ class CORE_EXPORT QgsCircularString: public QgsCurve
QgsPoint startPoint() const override SIP_HOLDGIL;
QgsPoint endPoint() const override SIP_HOLDGIL;
QgsLineString *curveToLine( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const override SIP_FACTORY;
QgsCircularString *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const override SIP_FACTORY;
QgsCircularString *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0, bool removeRedundantPoints = false ) const override SIP_FACTORY;
bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false ) override;

void draw( QPainter &p ) const override;
Expand Down
57 changes: 33 additions & 24 deletions src/core/geometry/qgscompoundcurve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -465,13 +465,13 @@ QgsLineString *QgsCompoundCurve::curveToLine( double tolerance, SegmentationTole
return line;
}

QgsCompoundCurve *QgsCompoundCurve::snappedToGrid( double hSpacing, double vSpacing, double dSpacing, double mSpacing ) const
QgsCompoundCurve *QgsCompoundCurve::snappedToGrid( double hSpacing, double vSpacing, double dSpacing, double mSpacing, bool removeRedundantPoints ) const
{
std::unique_ptr<QgsCompoundCurve> result( createEmptyWithSameType() );

for ( QgsCurve *curve : mCurves )
{
std::unique_ptr<QgsCurve> gridified( static_cast< QgsCurve * >( curve->snappedToGrid( hSpacing, vSpacing, dSpacing, mSpacing ) ) );
std::unique_ptr<QgsCurve> gridified( static_cast< QgsCurve * >( curve->snappedToGrid( hSpacing, vSpacing, dSpacing, mSpacing, removeRedundantPoints ) ) );
if ( gridified )
{
result->mCurves.append( gridified.release() );
Expand Down Expand Up @@ -825,6 +825,7 @@ bool QgsCompoundCurve::deleteVertex( QgsVertexId position )
removeCurve( curveId );
}
}
// We are on a vertex that belongs to two curves
else if ( curveIds.size() == 2 )
{
const int nextCurveId = curveIds.at( 1 ).first;
Expand All @@ -835,46 +836,51 @@ bool QgsCompoundCurve::deleteVertex( QgsVertexId position )
Q_ASSERT( subVertexId.vertex == curve->numPoints() - 1 );
Q_ASSERT( nextSubVertexId.vertex == 0 );

// globals start and end points
const QgsPoint startPoint = curve->startPoint();
const QgsPoint endPoint = nextCurve->endPoint();

if ( QgsWkbTypes::flatType( curve->wkbType() ) == Qgis::WkbType::LineString &&
QgsWkbTypes::flatType( nextCurve->wkbType() ) == Qgis::WkbType::CircularString &&
nextCurve->numPoints() > 3 )
{
QgsPoint intermediatePoint;
Qgis::VertexType type;
nextCurve->pointAt( 2, intermediatePoint, type );
curve->moveVertex( QgsVertexId( 0, 0, curve->numPoints() - 1 ), intermediatePoint );
}
else if ( !curve->deleteVertex( subVertexId ) )
// delete the vertex on first curve
if ( !curve->deleteVertex( subVertexId ) )
{
clearCache(); //bbox may have changed
return false;
}
if ( QgsWkbTypes::flatType( curve->wkbType() ) == Qgis::WkbType::CircularString &&
curve->numPoints() > 0 &&
QgsWkbTypes::flatType( nextCurve->wkbType() ) == Qgis::WkbType::LineString )
{
QgsPoint intermediatePoint = curve->endPoint();
nextCurve->moveVertex( QgsVertexId( 0, 0, 0 ), intermediatePoint );
}
else if ( !nextCurve->deleteVertex( nextSubVertexId ) )

// delete the vertex on second curve
if ( !nextCurve->deleteVertex( nextSubVertexId ) )
{
clearCache(); //bbox may have changed
return false;
}
if ( curve->numPoints() == 0 &&
nextCurve->numPoints() != 0 )

// if first curve is now empty and second is not then
// create a LineString to link from the global start point to the
// new start of the second curve and delete the first curve
if ( curve->numPoints() == 0 && nextCurve->numPoints() != 0 )
{
nextCurve->moveVertex( QgsVertexId( 0, 0, 0 ), startPoint );
QgsPoint startPointOfSecond = nextCurve->startPoint();
removeCurve( curveId );
QgsLineString *line = new QgsLineString();
line->insertVertex( QgsVertexId( 0, 0, 0 ), startPoint );
line->insertVertex( QgsVertexId( 0, 0, 1 ), startPointOfSecond );
mCurves.insert( curveId, line );
}
// else, if the first curve is not empty and the second is
// then create a LineString to link from the new end of the first curve to the
// global end point and delete the first curve
else if ( curve->numPoints() != 0 && nextCurve->numPoints() == 0 )
{
curve->moveVertex( QgsVertexId( 0, 0, curve->numPoints() - 1 ), endPoint );
QgsPoint endPointOfFirst = curve->endPoint();
removeCurve( nextCurveId );
QgsLineString *line = new QgsLineString();
line->insertVertex( QgsVertexId( 0, 0, 0 ), endPointOfFirst );
line->insertVertex( QgsVertexId( 0, 0, 1 ), endPoint );
mCurves.insert( nextCurveId, line );
}
// else, if both curves are empty then
// remove both curves and create a LineString to link
// the curves before and the curves after the whole geometry
else if ( curve->numPoints() == 0 &&
nextCurve->numPoints() == 0 )
{
Expand All @@ -885,6 +891,8 @@ bool QgsCompoundCurve::deleteVertex( QgsVertexId position )
line->insertVertex( QgsVertexId( 0, 0, 1 ), endPoint );
mCurves.insert( curveId, line );
}
// else, both curves still have vertices, create a LineString to link
// the curves if needed
else
{
QgsPoint endPointOfFirst = curve->endPoint();
Expand All @@ -897,6 +905,7 @@ bool QgsCompoundCurve::deleteVertex( QgsVertexId position )
mCurves.insert( nextCurveId, line );
}
}
condenseCurves(); // We merge consecutive LineStrings and CircularStrings
}

bool success = !curveIds.isEmpty();
Expand Down
2 changes: 1 addition & 1 deletion src/core/geometry/qgscompoundcurve.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class CORE_EXPORT QgsCompoundCurve: public QgsCurve
*/
QgsLineString *curveToLine( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const override SIP_FACTORY;

QgsCompoundCurve *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const override SIP_FACTORY;
QgsCompoundCurve *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0, bool removeRedundantPoints = false ) const override SIP_FACTORY;
bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false ) override;
bool boundingBoxIntersects( const QgsBox3D &box3d ) const override SIP_HOLDGIL;
const QgsAbstractGeometry *simplifiedTypeRef() const override SIP_HOLDGIL;
Expand Down
Loading

0 comments on commit 7204efb

Please sign in to comment.