Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
1 change: 1 addition & 0 deletions images/images.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -171,5 +171,6 @@
<file>themes/qfield/nodpi/ic_shutdown_24dp.svg</file>
<file>themes/qfield/nodpi/ic_egeniouss_receiver_black_24dp.svg</file>
<file>themes/qfield/nodpi/ic_location_tracking_white_24dp.svg</file>
<file>themes/qfield/nodpi/ic_line_curve_24dp.svg</file>
</qresource>
</RCC>
5 changes: 5 additions & 0 deletions images/themes/qfield/nodpi/ic_line_curve_24dp.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
178 changes: 136 additions & 42 deletions src/core/rubberbandmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,28 +24,39 @@ RubberbandModel::RubberbandModel( QObject *parent )
: QObject( parent )
, mLayer( nullptr )
{
mPointList.insert( 0, QgsPoint() );
mCompoundCurve.addVertex( QgsPoint() );
}

int RubberbandModel::vertexCount() const
{
return mPointList.size();
return mCompoundCurve.vertexCount( 0, 0 );
}

bool RubberbandModel::isEmpty() const
{
return mPointList.isEmpty();
return mCompoundCurve.isEmpty();
}

QVector<QgsPoint> RubberbandModel::vertices() const
{
return mPointList;
QgsVertexIterator vertexIterator = mCompoundCurve.curveToLine( QSettings().value( "/QField/Digitizing/CurveTolerance", true ).toDouble(), QgsAbstractGeometry::SegmentationToleranceType::MaximumDifference )->vertices();


// Create an empty QVector<QgsPoint>
QVector<QgsPoint> points;

// Iterate over the vertices and add them to the vector
while ( vertexIterator.hasNext() )
{
points.append( vertexIterator.next() );
}
return points;
}

QVector<QgsPoint> RubberbandModel::verticesCopy( bool skipCurrentPoint ) const
{
QVector<QgsPoint> points;
for ( const QgsPoint &pt : mPointList )
for ( const QgsPoint &pt : vertices() )
{
points << QgsPoint( pt );
}
Expand All @@ -60,7 +71,7 @@ QgsPointSequence RubberbandModel::pointSequence( const QgsCoordinateReferenceSys
QgsPointSequence sequence;
QgsCoordinateTransform ct( mCrs, crs, QgsProject::instance()->transformContext() );

for ( const QgsPoint &pt : mPointList )
for ( const QgsPoint &pt : vertices() )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do that instead.

Suggested change
for ( const QgsPoint &pt : vertices() )
const QVector<QgsPoint> vertices = vertices();
for ( const QgsPoint &pt : vertices )

{
//crs transformation of XY
QgsPointXY p1 = ct.transform( pt.x(), pt.y() );
Expand Down Expand Up @@ -97,7 +108,7 @@ QVector<QgsPointXY> RubberbandModel::flatPointSequence( const QgsCoordinateRefer

QgsCoordinateTransform ct( mCrs, crs, QgsProject::instance()->transformContext() );

for ( const QgsPoint &pt : mPointList )
for ( const QgsPoint &pt : vertices() )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above.

{
sequence.append( ct.transform( pt.x(), pt.y() ) );
}
Expand All @@ -107,9 +118,10 @@ QVector<QgsPointXY> RubberbandModel::flatPointSequence( const QgsCoordinateRefer

void RubberbandModel::setVertex( int index, QgsPoint coordinate )
{
if ( mPointList.at( index ) != coordinate )
QgsVertexId id = QgsVertexId( 0, 0, index );
if ( mCompoundCurve.vertexAt( id ) != coordinate )
{
mPointList.replace( index, coordinate );
mCompoundCurve.moveVertex( id, coordinate );
emit vertexChanged( index );
}
}
Expand All @@ -118,7 +130,8 @@ void RubberbandModel::insertVertices( int index, int count )
{
for ( int i = 0; i < count; ++i )
{
mPointList.insert( index, currentCoordinate() );
QgsVertexId id = QgsVertexId( 0, 0, index );
mCompoundCurve.insertVertex( id, currentCoordinate() );
}

emit verticesInserted( index, count );
Expand All @@ -127,14 +140,23 @@ void RubberbandModel::insertVertices( int index, int count )

void RubberbandModel::removeVertices( int index, int count )
{
if ( mPointList.size() <= 1 )
if ( vertexCount() <= 1 )
return;

mPointList.remove( index, count );
for ( int i = 0; i < count; ++i )
{
QgsVertexId id = QgsVertexId( 0, 0, index );
mCompoundCurve.deleteVertex( id );
}

if ( vertexCount() == 0 )
{
mCompoundCurve.addVertex( QgsPoint() );
}

if ( mCurrentCoordinateIndex >= mPointList.size() )
if ( mCurrentCoordinateIndex >= vertexCount() )
{
setCurrentCoordinateIndex( mPointList.size() - 1 );
setCurrentCoordinateIndex( vertexCount() - 1 );
}

emit verticesRemoved( index, count );
Expand Down Expand Up @@ -162,8 +184,8 @@ void RubberbandModel::setCurrentCoordinateIndex( int currentCoordinateIndex )
QgsPoint RubberbandModel::currentPoint( const QgsCoordinateReferenceSystem &crs, Qgis::WkbType wkbType ) const
{
QgsCoordinateTransform ct( mCrs, crs, QgsProject::instance()->transformContext() );

QgsPoint currentPt = mPointList.at( mCurrentCoordinateIndex );
QgsVertexId id = QgsVertexId( 0, 0, mCurrentCoordinateIndex );
QgsPoint currentPt = mCompoundCurve.vertexAt( id );
double x = currentPt.x();
double y = currentPt.y();
double z = QgsWkbTypes::hasZ( currentPt.wkbType() ) ? currentPt.z() : 0;
Expand Down Expand Up @@ -195,67 +217,97 @@ QgsPoint RubberbandModel::currentPoint( const QgsCoordinateReferenceSystem &crs,

QgsPoint RubberbandModel::currentCoordinate() const
{
return mPointList.value( mCurrentCoordinateIndex );
QgsVertexId id = QgsVertexId( 0, 0, mCurrentCoordinateIndex );
return mCompoundCurve.vertexAt( id );
}

QgsPoint RubberbandModel::firstCoordinate() const
{
if ( mPointList.isEmpty() )
if ( mCompoundCurve.isEmpty() )
return QgsPoint();

return mPointList.at( 0 );
QgsVertexId id = QgsVertexId( 0, 0, 0 );
return mCompoundCurve.vertexAt( id );
}

QgsPoint RubberbandModel::lastCoordinate() const
{
if ( mPointList.isEmpty() )
if ( mCompoundCurve.isEmpty() )
return QgsPoint();

return mPointList.at( mCurrentCoordinateIndex > 0 ? mCurrentCoordinateIndex - 1 : 0 );
QgsVertexId id = QgsVertexId( 0, 0, mCurrentCoordinateIndex > 0 ? mCurrentCoordinateIndex - 1 : 0 );
return mCompoundCurve.vertexAt( id );
}

QgsPoint RubberbandModel::penultimateCoordinate() const
{
if ( mPointList.size() < 3 )
if ( mCompoundCurve.vertexCount( 0, 0 ) < 3 )
return QgsPoint();

return mPointList.at( mCurrentCoordinateIndex > 1 ? mCurrentCoordinateIndex - 2 : 0 );
QgsVertexId id = QgsVertexId( 0, 0, mCurrentCoordinateIndex > 1 ? mCurrentCoordinateIndex - 2 : 0 );
return mCompoundCurve.vertexAt( id );
}

void RubberbandModel::setCurrentCoordinate( const QgsPoint &currentCoordinate )
{
// play safe, but try to find out
// Q_ASSERT( mPointList.count() != 0 );
if ( mPointList.count() == 0 )
if ( mCompoundCurve.isEmpty() )
return;

if ( mPointList.at( mCurrentCoordinateIndex ) == currentCoordinate )
QgsVertexId id = QgsVertexId( 0, 0, mCurrentCoordinateIndex );
if ( mCompoundCurve.vertexAt( id ) == currentCoordinate )
return;

if ( mFrozen )
return;

mPointList.replace( mCurrentCoordinateIndex, currentCoordinate );
if ( mDuringCurveDrawing == false )
{
mCompoundCurve.moveVertex( id, currentCoordinate );
}
else
{
QgsCircularString *curve = new QgsCircularString( mLastStartCurvePoint, mLastMiddleCurvePoint, currentCoordinate );
if ( mCompoundCurve.nCurves() != 0 )
{
const QgsCurve *lastSegment = mCompoundCurve.curveAt( mCompoundCurve.nCurves() - 1 );
if ( lastSegment->hasCurvedSegments() == true )
{
mCompoundCurve.removeCurve( mCompoundCurve.nCurves() - 1 );
}
else
{
if ( lastSegment->vertexCount( 0, 0 ) > 2 )
{
removeVertices( mCurrentCoordinateIndex - 1, 1 );
setCurrentCoordinateIndex( mCurrentCoordinateIndex + 1 );
}
else
{
mCompoundCurve.removeCurve( mCompoundCurve.nCurves() - 1 );
}
}
}
mCompoundCurve.addCurve( curve, true );
}

if ( !mLayer || QgsWkbTypes::hasM( mLayer->wkbType() ) )
{
if ( !std::isnan( mMeasureValue ) )
{
if ( QgsWkbTypes::hasM( mPointList[mCurrentCoordinateIndex].wkbType() ) )
if ( QgsWkbTypes::hasM( mCompoundCurve.vertexAt( id ).wkbType() ) )
{
mPointList[mCurrentCoordinateIndex].setM( mMeasureValue );
mCompoundCurve.vertexAt( id ).setM( mMeasureValue );
}
else
{
mPointList[mCurrentCoordinateIndex].addMValue( mMeasureValue );
mCompoundCurve.vertexAt( id ).addMValue( mMeasureValue );
}
}
else
{
mPointList[mCurrentCoordinateIndex].dropMValue();
mCompoundCurve.vertexAt( id ).dropMValue();
}
}

mCurrentCoordinate = currentCoordinate;
emit currentCoordinateChanged();
emit vertexChanged( mCurrentCoordinateIndex );
}
Expand Down Expand Up @@ -295,7 +347,7 @@ void RubberbandModel::setMeasureValue( const double measureValue )
void RubberbandModel::addVertex()
{
// Avoid double vertices accidentally
if ( mPointList.size() > 1 && *( mPointList.end() - 1 ) == *( mPointList.end() - 2 ) )
if ( mCompoundCurve.vertexCount( 0, 0 ) > 1 && currentCoordinate() == penultimateCoordinate() )
{
return;
}
Expand All @@ -314,11 +366,53 @@ void RubberbandModel::removeVertex()
{
setCurrentCoordinateIndex( mCurrentCoordinateIndex - 1 );
removeVertices( mCurrentCoordinateIndex + 1, 1 );
if ( QSettings().value( "/QField/Digitizing/CurveEdition", true ).toBool() )
{
mDuringCurveDrawing = !mDuringCurveDrawing;
if ( mDuringCurveDrawing == false )
{
mCompoundCurve.addVertex( mCurrentCoordinate );
setCurrentCoordinateIndex( vertexCount() - 1 );
emit vertexCountChanged();
}
}
}

void RubberbandModel::addCurve()
{
mDuringCurveDrawing = false;
QgsCircularString *curve = new QgsCircularString( mLastStartCurvePoint, mLastMiddleCurvePoint, mCurrentCoordinate );
if ( mCompoundCurve.nCurves() != 0 )
{
mCompoundCurve.removeCurve( mCompoundCurve.nCurves() - 1 );
}

mCompoundCurve.addCurve( curve, true );
mCompoundCurve.addVertex( mCurrentCoordinate );
setCurrentCoordinateIndex( vertexCount() - 1 );
emit vertexCountChanged();
}

void RubberbandModel::addMiddlePointCurve()
{
mDuringCurveDrawing = true;
mLastMiddleCurvePoint = currentCoordinate();
mLastStartCurvePoint = lastCoordinate();
setCurrentCoordinateIndex( mCurrentCoordinateIndex + 1 );
}

void RubberbandModel::removeCurve()
{
}

void RubberbandModel::reset()
{
removeVertices( 0, mPointList.size() - 1 );
mCompoundCurve.clear();
mDuringCurveDrawing = false;
mCompoundCurve.addVertex( mCurrentCoordinate );
emit verticesRemoved( 0, vertexCount() - 1 );
setCurrentCoordinateIndex( 0 );
emit vertexCountChanged();
mFrozen = false;
emit frozenChanged();
}
Expand All @@ -331,7 +425,7 @@ void RubberbandModel::setDataFromGeometry( QgsGeometry geometry, const QgsCoordi
QgsCoordinateTransform ct( crs, mCrs, QgsProject::instance()->transformContext() );
geometry.transform( ct );

mPointList.clear();
mCompoundCurve.clear();
const QgsAbstractGeometry *abstractGeom = geometry.constGet();
if ( !abstractGeom )
return;
Expand All @@ -344,22 +438,22 @@ void RubberbandModel::setDataFromGeometry( QgsGeometry geometry, const QgsCoordi
{
break;
}
mPointList << pt;
mCompoundCurve.addVertex( pt );
}

// for polygons, remove the last vertex which is a duplicate of the first vertex
if ( geometry.type() == Qgis::GeometryType::Polygon )
{
mPointList.removeLast();
mCompoundCurve.removeDuplicateNodes();
}

// insert the last point twice so the resutling rubberband's current coordinate property being modified (by e.g.
// the GNSS position) will not replace the last vertex from the passed geometry
mPointList << mPointList.last();
mCompoundCurve.addVertex( mCompoundCurve.endPoint() );

mCurrentCoordinateIndex = mPointList.size() - 1;
mCurrentCoordinateIndex = mCompoundCurve.vertexCount( 0, 0 ) - 1;

emit verticesInserted( 0, mPointList.size() );
emit verticesInserted( 0, mCompoundCurve.vertexCount( 0, 0 ) );
emit vertexCountChanged();
}

Expand Down
Loading
Loading