Skip to content
Permalink
Browse files

[feature] Add streaming digitizing mode

When active, points are automatically added following the mouse
cursor movement.

Refs Natural resources Canada Contract: 3000720707
  • Loading branch information
nyalldawson committed Mar 11, 2021
1 parent ffbedde commit 7234d89303cdfea2df3f7db0a8f2e01cfdbc3586
@@ -33,6 +33,7 @@ class QgsMapToolCapture : QgsMapToolAdvancedDigitizing
{
StraightSegments,
CircularString,
Streaming,
};

enum Capability
@@ -135,6 +136,13 @@ transfers ownership to the caller.
void setCircularDigitizingEnabled( bool enable );
%Docstring
Enable the digitizing with curve
%End

void setStreamDigitizingEnabled( bool enable );
%Docstring
Toggles the stream digitizing mode.

.. versionadded:: 3.20
%End

protected:
@@ -2562,6 +2562,9 @@ void QgisApp::createActions()
connect( mActionRegularPolygonCenterPoint, &QAction::triggered, this, [ = ] { setMapTool( mMapTools->mapTool( QgsAppMapTools::RegularPolygonCenterPoint ), true ); } );
connect( mActionRegularPolygonCenterCorner, &QAction::triggered, this, [ = ] { setMapTool( mMapTools->mapTool( QgsAppMapTools::RegularPolygonCenterCorner ), true ); } );
connect( mActionDigitizeWithCurve, &QAction::triggered, this, &QgisApp::enableDigitizeWithCurve );
connect( mActionStreamDigitize, &QAction::triggered, this, &QgisApp::enableStreamDigitizing );
mActionStreamDigitize->setShortcut( tr( "R", "Keyboard shortcut: toggle stream digitizing" ) );

connect( mActionMoveFeature, &QAction::triggered, this, &QgisApp::moveFeature );
connect( mActionMoveFeatureCopy, &QAction::triggered, this, &QgisApp::moveFeatureCopy );
connect( mActionRotateFeature, &QAction::triggered, this, &QgisApp::rotateFeature );
@@ -10121,6 +10124,18 @@ void QgisApp::enableDigitizeWithCurve( bool enable )
settings.setValue( QStringLiteral( "UI/digitizeWithCurve" ), enable ? 1 : 0 );
}

void QgisApp::enableStreamDigitizing( bool enable )
{
const QList< QgsMapToolCapture * > captureTools = mMapTools->captureTools();
for ( QgsMapToolCapture *tool : captureTools )
{
if ( tool->supportsTechnique( QgsMapToolCapture::Streaming ) )
tool->setStreamDigitizingEnabled( enable );
}
QgsSettings settings;
settings.setValue( QStringLiteral( "UI/digitizeWithStream" ), enable ? 1 : 0 );
}

void QgisApp::enableDigitizeTechniqueActions( bool enable, QAction *triggeredFromToolAction )
{
QgsSettings settings;
@@ -10132,8 +10147,11 @@ void QgisApp::enableDigitizeTechniqueActions( bool enable, QAction *triggeredFro
{
if ( triggeredFromToolAction == tool->action() || ( !triggeredFromToolAction && mMapCanvas->mapTool() == tool ) )
{
if ( tool->supportsTechnique( QgsMapToolCapture::CircularString ) )
supportedTechniques.insert( QgsMapToolCapture::CircularString );
for ( QgsMapToolCapture::CaptureTechnique technique : { QgsMapToolCapture::CircularString, QgsMapToolCapture::Streaming } )
{
if ( tool->supportsTechnique( technique ) )
supportedTechniques.insert( technique );
}
break;
}
}
@@ -10142,10 +10160,16 @@ void QgisApp::enableDigitizeTechniqueActions( bool enable, QAction *triggeredFro
const bool curveIsChecked = settings.value( QStringLiteral( "UI/digitizeWithCurve" ) ).toInt();
mActionDigitizeWithCurve->setChecked( curveIsChecked && mActionDigitizeWithCurve->isEnabled() );

mActionStreamDigitize->setEnabled( enable && supportedTechniques.contains( QgsMapToolCapture::Streaming ) );
const bool streamIsChecked = settings.value( QStringLiteral( "UI/digitizeWithStream" ) ).toInt();
mActionStreamDigitize->setChecked( streamIsChecked && mActionStreamDigitize->isEnabled() );

for ( QgsMapToolCapture *tool : captureTools )
{
if ( tool->supportsTechnique( QgsMapToolCapture::CircularString ) )
tool->setCircularDigitizingEnabled( mActionDigitizeWithCurve->isChecked() );
if ( tool->supportsTechnique( QgsMapToolCapture::Streaming ) )
tool->setStreamDigitizingEnabled( mActionStreamDigitize->isChecked() );
}
}

@@ -1962,6 +1962,12 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
*/
void enableDigitizeWithCurve( bool enable );

/**
* Enables or disables stream digitizing
* \since QGIS 3.20
*/
void enableStreamDigitizing( bool enable );

/**
* Enables the action that toggles digitizing with curve
*/
@@ -364,6 +364,11 @@ void QgsMapToolCapture::setCircularDigitizingEnabled( bool enable )
mTempRubberBand->setStringType( mDigitizingType );
}

void QgsMapToolCapture::setStreamDigitizingEnabled( bool enable )
{
mStreamingEnabled = enable;
mStartNewCurve = true;
}

void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent *e )
{
@@ -378,8 +383,13 @@ void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent *e )
{
bool hasTrace = false;


if ( tracingEnabled() && mCaptureCurve.numPoints() != 0 )
if ( mStreamingEnabled )
{
mAllowAddingStreamingPoints = true;
addVertex( mapPoint );
mAllowAddingStreamingPoints = false;
}
else if ( tracingEnabled() && mCaptureCurve.numPoints() != 0 )
{
// Store the intermediate point for circular string to retrieve after tracing mouse move if
// the digitizing type is circular and the temp rubber band is effectivly circular and if this point is existing
@@ -407,7 +417,7 @@ void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent *e )
}
}

if ( !hasTrace )
if ( !mStreamingEnabled && !hasTrace )
{
if ( mCaptureCurve.numPoints() > 0 )
{
@@ -536,6 +546,9 @@ int QgsMapToolCapture::addVertex( const QgsPointXY &point, const QgsPointLocator
return 2;
}

if ( mCapturing && mStreamingEnabled && !mAllowAddingStreamingPoints )
return 0;

int res;
QgsPoint layerPoint;
res = fetchLayerPoint( match, layerPoint );
@@ -670,7 +683,8 @@ int QgsMapToolCapture::addCurve( QgsCurve *c )

// we set the extendPrevious option to true to avoid creating compound curves with many 2 vertex linestrings -- instead we prefer
// to extend linestring curves so that they continue the previous linestring wherever possible...
mCaptureCurve.addCurve( c, true );
mCaptureCurve.addCurve( c, !mStartNewCurve );
mStartNewCurve = false;

int countAfter = mCaptureCurve.vertexCount();
int addedPoint = countAfter - countBefore;
@@ -143,6 +143,7 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing
{
StraightSegments, //!< Default capture mode - capture occurs with straight line segments
CircularString, //!< Capture in circular strings
Streaming, //!< Streaming points digitizing mode (points are automatically added as the mouse cursor moves)
};

//! Specific capabilities of the tool
@@ -233,6 +234,12 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing
//! Enable the digitizing with curve
void setCircularDigitizingEnabled( bool enable );

/**
* Toggles the stream digitizing mode.
* \since QGIS 3.20
*/
void setStreamDigitizingEnabled( bool enable );

private slots:
void addError( const QgsGeometry::Error &error );
void currentLayerChanged( QgsMapLayer *layer );
@@ -454,6 +461,12 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing

//! Used to store the state of digitizing type (linear or circular)
QgsWkbTypes::Type mDigitizingType = QgsWkbTypes::LineString;

bool mStreamingEnabled = false;
bool mAllowAddingStreamingPoints = false;
bool mStartNewCurve = false;


};

Q_DECLARE_OPERATORS_FOR_FLAGS( QgsMapToolCapture::Capabilities )
@@ -521,6 +521,7 @@
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="mActionStreamDigitize"/>
<addaction name="mActionDigitizeWithCurve"/>
<addaction name="mActionRotateFeature"/>
<addaction name="mActionScaleFeature"/>
@@ -3486,6 +3487,24 @@ Shows placeholders for labels which could not be placed, e.g. due to overlaps wi
<string>Add Point Cloud Layer...</string>
</property>
</action>
<action name="mActionStreamDigitize">
<property name="checkable">
<bool>true</bool>
</property>
<property name="enabled">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mIconSnappingSelf.svg</normaloff>:/images/themes/default/mIconSnappingSelf.svg</iconset>
</property>
<property name="text">
<string>Stream Digitizing</string>
</property>
<property name="toolTip">
<string>Toggles stream digitizing mode</string>
</property>
</action>
</widget>
<resources>
<include location="../../images/images.qrc"/>

0 comments on commit 7234d89

Please sign in to comment.