Skip to content

Commit

Permalink
[feature] Add streaming digitizing mode
Browse files Browse the repository at this point in the history
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 7234d89
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 6 deletions.
8 changes: 8 additions & 0 deletions python/gui/auto_generated/qgsmaptoolcapture.sip.in
Expand Up @@ -33,6 +33,7 @@ class QgsMapToolCapture : QgsMapToolAdvancedDigitizing
{
StraightSegments,
CircularString,
Streaming,
};

enum Capability
Expand Down Expand Up @@ -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:
Expand Down
28 changes: 26 additions & 2 deletions src/app/qgisapp.cpp
Expand Up @@ -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 );
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}
}
Expand All @@ -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() );
}
}

Expand Down
6 changes: 6 additions & 0 deletions src/app/qgisapp.h
Expand Up @@ -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
*/
Expand Down
22 changes: 18 additions & 4 deletions src/gui/qgsmaptoolcapture.cpp
Expand Up @@ -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 )
{
Expand All @@ -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
Expand Down Expand Up @@ -407,7 +417,7 @@ void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent *e )
}
}

if ( !hasTrace )
if ( !mStreamingEnabled && !hasTrace )
{
if ( mCaptureCurve.numPoints() > 0 )
{
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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;
Expand Down
13 changes: 13 additions & 0 deletions src/gui/qgsmaptoolcapture.h
Expand Up @@ -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
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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 )
Expand Down
19 changes: 19 additions & 0 deletions src/ui/qgisapp.ui
Expand Up @@ -521,6 +521,7 @@
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="mActionStreamDigitize"/>
<addaction name="mActionDigitizeWithCurve"/>
<addaction name="mActionRotateFeature"/>
<addaction name="mActionScaleFeature"/>
Expand Down Expand Up @@ -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"/>
Expand Down

0 comments on commit 7234d89

Please sign in to comment.