mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-15 00:07:25 -05:00
Add method to add a linestring to compound curves where we extend
the existing final part if it's a linestring and the newly added curve is also a linestring, instead of adding a whole new curve
This commit is contained in:
parent
0908a0990e
commit
afccd31720
@ -93,9 +93,15 @@ Returns the number of curves in the geometry.
|
||||
Returns the curve at the specified index.
|
||||
%End
|
||||
|
||||
void addCurve( QgsCurve *c /Transfer/ );
|
||||
void addCurve( QgsCurve *c /Transfer/, bool extendPrevious = false );
|
||||
%Docstring
|
||||
Adds a curve to the geometry (takes ownership)
|
||||
Adds a curve to the geometry (takes ownership).
|
||||
|
||||
Since QGIS 3.20, if ``extendPrevious`` is ``True``, then adding a LineString when the last existing curve
|
||||
in the compound curve is also a LineString will cause the existing linestring to be
|
||||
extended with the newly added LineString vertices instead of appending a whole new
|
||||
LineString curve to the compound curve. This can result in simplified compound curves with lesser number
|
||||
of component curves while still being topologically identical to the desired result.
|
||||
%End
|
||||
|
||||
void removeCurve( int i );
|
||||
|
||||
@ -474,35 +474,49 @@ const QgsCurve *QgsCompoundCurve::curveAt( int i ) const
|
||||
return mCurves.at( i );
|
||||
}
|
||||
|
||||
void QgsCompoundCurve::addCurve( QgsCurve *c )
|
||||
void QgsCompoundCurve::addCurve( QgsCurve *c, const bool extendPrevious )
|
||||
{
|
||||
if ( c )
|
||||
if ( !c )
|
||||
return;
|
||||
|
||||
if ( mCurves.empty() )
|
||||
{
|
||||
if ( mCurves.empty() )
|
||||
{
|
||||
setZMTypeFromSubGeometry( c, QgsWkbTypes::CompoundCurve );
|
||||
}
|
||||
|
||||
mCurves.append( c );
|
||||
|
||||
if ( QgsWkbTypes::hasZ( mWkbType ) && !QgsWkbTypes::hasZ( c->wkbType() ) )
|
||||
{
|
||||
c->addZValue();
|
||||
}
|
||||
else if ( !QgsWkbTypes::hasZ( mWkbType ) && QgsWkbTypes::hasZ( c->wkbType() ) )
|
||||
{
|
||||
c->dropZValue();
|
||||
}
|
||||
if ( QgsWkbTypes::hasM( mWkbType ) && !QgsWkbTypes::hasM( c->wkbType() ) )
|
||||
{
|
||||
c->addMValue();
|
||||
}
|
||||
else if ( !QgsWkbTypes::hasM( mWkbType ) && QgsWkbTypes::hasM( c->wkbType() ) )
|
||||
{
|
||||
c->dropMValue();
|
||||
}
|
||||
clearCache();
|
||||
setZMTypeFromSubGeometry( c, QgsWkbTypes::CompoundCurve );
|
||||
}
|
||||
|
||||
if ( QgsWkbTypes::hasZ( mWkbType ) && !QgsWkbTypes::hasZ( c->wkbType() ) )
|
||||
{
|
||||
c->addZValue();
|
||||
}
|
||||
else if ( !QgsWkbTypes::hasZ( mWkbType ) && QgsWkbTypes::hasZ( c->wkbType() ) )
|
||||
{
|
||||
c->dropZValue();
|
||||
}
|
||||
if ( QgsWkbTypes::hasM( mWkbType ) && !QgsWkbTypes::hasM( c->wkbType() ) )
|
||||
{
|
||||
c->addMValue();
|
||||
}
|
||||
else if ( !QgsWkbTypes::hasM( mWkbType ) && QgsWkbTypes::hasM( c->wkbType() ) )
|
||||
{
|
||||
c->dropMValue();
|
||||
}
|
||||
|
||||
QgsLineString *previousLineString = !mCurves.empty() ? qgsgeometry_cast< QgsLineString * >( mCurves.constLast() ) : nullptr;
|
||||
const QgsLineString *newLineString = qgsgeometry_cast< const QgsLineString * >( c );
|
||||
const bool canExtendPrevious = extendPrevious && previousLineString && newLineString;
|
||||
if ( canExtendPrevious )
|
||||
{
|
||||
previousLineString->append( newLineString );
|
||||
// we are taking ownership, so delete the input curve
|
||||
delete c;
|
||||
c = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCurves.append( c );
|
||||
}
|
||||
|
||||
clearCache();
|
||||
}
|
||||
|
||||
void QgsCompoundCurve::removeCurve( int i )
|
||||
|
||||
@ -84,9 +84,15 @@ class CORE_EXPORT QgsCompoundCurve: public QgsCurve
|
||||
const QgsCurve *curveAt( int i ) const SIP_HOLDGIL;
|
||||
|
||||
/**
|
||||
* Adds a curve to the geometry (takes ownership)
|
||||
* Adds a curve to the geometry (takes ownership).
|
||||
*
|
||||
* Since QGIS 3.20, if \a extendPrevious is TRUE, then adding a LineString when the last existing curve
|
||||
* in the compound curve is also a LineString will cause the existing linestring to be
|
||||
* extended with the newly added LineString vertices instead of appending a whole new
|
||||
* LineString curve to the compound curve. This can result in simplified compound curves with lesser number
|
||||
* of component curves while still being topologically identical to the desired result.
|
||||
*/
|
||||
void addCurve( QgsCurve *c SIP_TRANSFER );
|
||||
void addCurve( QgsCurve *c SIP_TRANSFER, bool extendPrevious = false );
|
||||
|
||||
/**
|
||||
* Removes a curve from the geometry.
|
||||
|
||||
@ -914,7 +914,7 @@ void QgsLineString::append( const QgsLineString *line )
|
||||
setZMTypeFromSubGeometry( line, QgsWkbTypes::LineString );
|
||||
}
|
||||
|
||||
// do not store duplicit points
|
||||
// do not store duplicate points
|
||||
if ( numPoints() > 0 &&
|
||||
line->numPoints() > 0 &&
|
||||
endPoint() == line->startPoint() )
|
||||
|
||||
@ -10319,6 +10319,38 @@ void TestQgsGeometry::compoundCurve()
|
||||
<< QgsPoint( QgsWkbTypes::PointM, 3, 4, 0, 9 ) );
|
||||
c8.removeCurve( 1 );
|
||||
|
||||
// add curve and extend existing
|
||||
QgsCompoundCurve c8j;
|
||||
// try to extend empty compound curve
|
||||
l8.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 2, 3 ) << QgsPoint( 3, 4 ) );
|
||||
c8j.addCurve( l8.clone(), true );
|
||||
QCOMPARE( c8j.asWkt(), QStringLiteral( "CompoundCurve (CircularString (1 2, 2 3, 3 4))" ) );
|
||||
// try to add another curve with extend existing as true - should be ignored.
|
||||
l8.setPoints( QgsPointSequence() << QgsPoint( 6, 6 ) << QgsPoint( 7, 8 ) );
|
||||
c8j.addCurve( l8.clone(), true );
|
||||
QCOMPARE( c8j.asWkt(), QStringLiteral( "CompoundCurve (CircularString (1 2, 2 3, 3 4),CircularString (6 6, 7 8))" ) );
|
||||
// try to add a linestring with extend existing as true - should be ignored because the last curve isn't a linestring
|
||||
QgsLineString l8j;
|
||||
l8j.setPoints( QgsPointSequence() << QgsPoint( 10, 8 ) << QgsPoint( 10, 12 ) );
|
||||
c8j.addCurve( l8j.clone(), true );
|
||||
QCOMPARE( c8j.asWkt(), QStringLiteral( "CompoundCurve (CircularString (1 2, 2 3, 3 4),CircularString (6 6, 7 8),(10 8, 10 12))" ) );
|
||||
// try to extend with another linestring -- should add to final part
|
||||
l8j.setPoints( QgsPointSequence() << QgsPoint( 11, 13 ) << QgsPoint( 12, 12 ) );
|
||||
c8j.addCurve( l8j.clone(), true );
|
||||
QCOMPARE( c8j.asWkt(), QStringLiteral( "CompoundCurve (CircularString (1 2, 2 3, 3 4),CircularString (6 6, 7 8),(10 8, 10 12, 11 13, 12 12))" ) );
|
||||
// try to extend with another linestring -- should add to final part, with no duplicate points
|
||||
l8j.setPoints( QgsPointSequence() << QgsPoint( 12, 12 ) << QgsPoint( 13, 12 ) << QgsPoint( 14, 15 ) );
|
||||
c8j.addCurve( l8j.clone(), true );
|
||||
QCOMPARE( c8j.asWkt(), QStringLiteral( "CompoundCurve (CircularString (1 2, 2 3, 3 4),CircularString (6 6, 7 8),(10 8, 10 12, 11 13, 12 12, 13 12, 14 15))" ) );
|
||||
// not extending, should be added as new curve
|
||||
l8j.setPoints( QgsPointSequence() << QgsPoint( 15, 16 ) << QgsPoint( 17, 12 ) );
|
||||
c8j.addCurve( l8j.clone(), false );
|
||||
QCOMPARE( c8j.asWkt(), QStringLiteral( "CompoundCurve (CircularString (1 2, 2 3, 3 4),CircularString (6 6, 7 8),(10 8, 10 12, 11 13, 12 12, 13 12, 14 15),(15 16, 17 12))" ) );
|
||||
c8j.clear();
|
||||
// adding a linestring as first part, with extend as true
|
||||
c8j.addCurve( l8j.clone(), true );
|
||||
QCOMPARE( c8j.asWkt(), QStringLiteral( "CompoundCurve ((15 16, 17 12))" ) );
|
||||
|
||||
//test getters/setters
|
||||
QgsCompoundCurve c9;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user