Skip to content

Commit

Permalink
add new class QgsMapToolCaptureLayerGeometry to handle layer specific…
Browse files Browse the repository at this point in the history
… operation in capture map tool

such as avoiding intersections
  • Loading branch information
3nids committed Jan 28, 2022
1 parent f577cf9 commit 83c5e6f
Show file tree
Hide file tree
Showing 11 changed files with 235 additions and 54 deletions.
@@ -0,0 +1,67 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/maptools/qgsmaptoolcapturelayergeometry.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/




class QgsMapToolCaptureLayerGeometry : QgsMapToolCapture
{
%Docstring(signature="appended")
:py:class:`QgsMapToolCaptureLayerGeometry` is a base class for map tools digitizing layer geometries
It will implement avoid intersections

.. versionadded:: 3.24
%End

%TypeHeaderCode
#include "qgsmaptoolcapturelayergeometry.h"
%End
public:
QgsMapToolCaptureLayerGeometry( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget, CaptureMode mode );
%Docstring
Constructor
%End

private:
virtual void layerGeometryCaptured( const QgsGeometry &geometry );
%Docstring
Called when the geometry is captured
A more specific handler is also called afterwards (pointCaptured, lineCaptured or polygonCaptured)

.. versionadded:: 3.24
%End
virtual void layerPointCaptured( const QgsPoint &point );
%Docstring
Called when a point is captured
geometryCaptured is called just before

.. versionadded:: 3.24
%End
virtual void layerLineCaptured( const QgsCurve *line );
%Docstring
Called when a line is captured
geometryCaptured is called just before

.. versionadded:: 3.24
%End
virtual void layerPolygonCaptured( const QgsCurvePolygon *polygon );
%Docstring
Called when a polygon is captured
geometryCaptured is called just before

.. versionadded:: 3.24
%End
};

/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/maptools/qgsmaptoolcapturelayergeometry.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
2 changes: 1 addition & 1 deletion python/gui/auto_generated/qgsmaptooldigitizefeature.sip.in
Expand Up @@ -8,7 +8,7 @@



class QgsMapToolDigitizeFeature : QgsMapToolCapture
class QgsMapToolDigitizeFeature : QgsMapToolCaptureLayerGeometry
{
%Docstring(signature="appended")
This tool digitizes geometry of new point/line/polygon features on already existing vector layers
Expand Down
1 change: 1 addition & 0 deletions python/gui/gui_auto.sip
Expand Up @@ -354,6 +354,7 @@
%Include auto_generated/layout/qgslayoutviewtooltemporarymousepan.sip
%Include auto_generated/layout/qgslayoutviewtoolzoom.sip
%Include auto_generated/locator/qgslocatorwidget.sip
%Include auto_generated/maptools/qgsmaptoolcapturelayergeometry.sip
%Include auto_generated/mesh/qgsmeshlayerproperties.sip
%Include auto_generated/numericformats/qgsnumericformatselectorwidget.sip
%Include auto_generated/numericformats/qgsnumericformatwidget.sip
Expand Down
8 changes: 4 additions & 4 deletions src/app/qgsmaptooladdpart.cpp
Expand Up @@ -28,7 +28,7 @@


QgsMapToolAddPart::QgsMapToolAddPart( QgsMapCanvas *canvas )
: QgsMapToolCapture( canvas, QgisApp::instance()->cadDockWidget(), CaptureNone )
: QgsMapToolCaptureLayerGeometry( canvas, QgisApp::instance()->cadDockWidget(), CaptureNone )
{
mToolName = tr( "Add part" );
connect( QgisApp::instance(), &QgisApp::newProject, this, &QgsMapToolAddPart::stopCapturing );
Expand Down Expand Up @@ -76,7 +76,7 @@ void QgsMapToolAddPart::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
QgsMapToolCapture::cadCanvasReleaseEvent( e );
}

void QgsMapToolAddPart::pointCaptured( const QgsPoint &point )
void QgsMapToolAddPart::layerPointCaptured( const QgsPoint &point )
{
QgsVectorLayer *layer = getLayerAndCheckSelection();
if ( !layer )
Expand All @@ -86,7 +86,7 @@ void QgsMapToolAddPart::pointCaptured( const QgsPoint &point )
finalizeEditCommand( layer, errorCode );
}

void QgsMapToolAddPart::lineCaptured( const QgsCurve *line )
void QgsMapToolAddPart::layerLineCaptured( const QgsCurve *line )
{
QgsVectorLayer *layer = getLayerAndCheckSelection();
if ( !layer )
Expand All @@ -96,7 +96,7 @@ void QgsMapToolAddPart::lineCaptured( const QgsCurve *line )
finalizeEditCommand( layer, errorCode );
}

void QgsMapToolAddPart::polygonCaptured( const QgsCurvePolygon *polygon )
void QgsMapToolAddPart::layerPolygonCaptured( const QgsCurvePolygon *polygon )
{
QgsVectorLayer *layer = getLayerAndCheckSelection();
if ( !layer )
Expand Down
10 changes: 5 additions & 5 deletions src/app/qgsmaptooladdpart.h
Expand Up @@ -13,13 +13,13 @@
* *
***************************************************************************/

#include "qgsmaptoolcapture.h"
#include "qgsmaptoolcapturelayergeometry.h"
#include "qgis_app.h"

class QgsCurvePolygon;

//! A map tool that adds new parts to multipart features
class APP_EXPORT QgsMapToolAddPart : public QgsMapToolCapture
class APP_EXPORT QgsMapToolAddPart : public QgsMapToolCaptureLayerGeometry
{
Q_OBJECT
public:
Expand All @@ -41,9 +41,9 @@ class APP_EXPORT QgsMapToolAddPart : public QgsMapToolCapture
*/
QgsVectorLayer *getLayerAndCheckSelection();

void pointCaptured( const QgsPoint &point ) override;
void lineCaptured( const QgsCurve *line ) override;
void polygonCaptured( const QgsCurvePolygon *polygon ) override;
void layerPointCaptured( const QgsPoint &point ) override;
void layerLineCaptured( const QgsCurve *line ) override;
void layerPolygonCaptured( const QgsCurvePolygon *polygon ) override;

void finalizeEditCommand( QgsVectorLayer *layer, Qgis::GeometryOperationResult errorCode );
};
5 changes: 5 additions & 0 deletions src/gui/CMakeLists.txt
Expand Up @@ -288,6 +288,8 @@ set(QGIS_GUI_SRCS

locator/qgslocatorwidget.cpp

maptools/qgsmaptoolcapturelayergeometry.cpp

mesh/qgsmeshlayerproperties.cpp
mesh/qgsrenderermeshpropertieswidget.cpp
mesh/qgsmeshdatasetgrouptreewidget.cpp
Expand Down Expand Up @@ -1117,6 +1119,8 @@ set(QGIS_GUI_HDRS

locator/qgslocatorwidget.h

maptools/qgsmaptoolcapturelayergeometry.h

mesh/qgsmeshlayerproperties.h
mesh/qgsrenderermeshpropertieswidget.h
mesh/qgsmeshdatasetgrouptreeview.h
Expand Down Expand Up @@ -1467,6 +1471,7 @@ target_include_directories(qgis_gui PUBLIC
${CMAKE_SOURCE_DIR}/src/gui/layertree
${CMAKE_SOURCE_DIR}/src/gui/layout
${CMAKE_SOURCE_DIR}/src/gui/locator
${CMAKE_SOURCE_DIR}/src/gui/maptools
${CMAKE_SOURCE_DIR}/src/gui/mesh
${CMAKE_SOURCE_DIR}/src/gui/numericformats
${CMAKE_SOURCE_DIR}/src/gui/ogr
Expand Down
74 changes: 74 additions & 0 deletions src/gui/maptools/qgsmaptoolcapturelayergeometry.cpp
@@ -0,0 +1,74 @@
/***************************************************************************
qgsmaptoolcapturelayergeometry.cpp - base class for map tools digitizing layer geometries
---------------------
begin : January 2022
copyright : (C) Denis Rouzaud
email : denis@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/


#include "qgsmaptoolcapturelayergeometry.h"
#include "qgsproject.h"
#include "qgscurvepolygon.h"
#include "qgscurve.h"


QgsMapToolCaptureLayerGeometry::QgsMapToolCaptureLayerGeometry( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget, CaptureMode mode )
: QgsMapToolCapture( canvas, cadDockWidget, mode )
{

}


void QgsMapToolCaptureLayerGeometry::geometryCaptured( const QgsGeometry &geometry )
{
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer() );
if ( !vlayer )
return;

QgsGeometry g( geometry );
QList<QgsVectorLayer *> avoidIntersectionsLayers;
switch ( QgsProject::instance()->avoidIntersectionsMode() )
{
case QgsProject::AvoidIntersectionsMode::AvoidIntersectionsCurrentLayer:
if ( vlayer )
avoidIntersectionsLayers.append( vlayer );
break;
case QgsProject::AvoidIntersectionsMode::AvoidIntersectionsLayers:
avoidIntersectionsLayers = QgsProject::instance()->avoidIntersectionsLayers();
break;
case QgsProject::AvoidIntersectionsMode::AllowIntersections:
break;
}
if ( avoidIntersectionsLayers.size() > 0 )
{
const int avoidIntersectionsReturn = g.avoidIntersections( avoidIntersectionsLayers );
if ( avoidIntersectionsReturn == 3 )
{
emit messageEmitted( tr( "The feature has been added, but at least one geometry intersected is invalid. These geometries must be manually repaired." ), Qgis::MessageLevel::Warning );
}
if ( g.isEmpty() ) //avoid intersection might have removed the whole geometry
{
emit messageEmitted( tr( "The feature cannot be added because its geometry collapsed due to intersection avoidance" ), Qgis::MessageLevel::Critical );
stopCapturing();
return;
}
}

layerGeometryCaptured( g );
if ( mode() == CaptureLine )
{
layerLineCaptured( qgsgeometry_cast<const QgsCurve *>( g.constGet() ) );
}
else
{
layerPolygonCaptured( qgsgeometry_cast<const QgsCurvePolygon *>( g.constGet() ) );
}
}
68 changes: 68 additions & 0 deletions src/gui/maptools/qgsmaptoolcapturelayergeometry.h
@@ -0,0 +1,68 @@
/***************************************************************************
qgsmaptoolcapturelayergeometry.h - base class for map tools digitizing layer geometries
---------------------
begin : January 2022
copyright : (C) Denis Rouzaud
email : denis@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSMAPTOOLCAPTURELAYERGEOMETRY_H
#define QGSMAPTOOLCAPTURELAYERGEOMETRY_H

#include "qgsmaptoolcapture.h"

class QgsAdvancedDigitizingDockWidget;
class QgsMapCanvas;

/**
* \ingroup gui
* QgsMapToolCaptureLayerGeometry is a base class for map tools digitizing layer geometries
* It will implement avoid intersections
* \since QGIS 3.24
*/
class GUI_EXPORT QgsMapToolCaptureLayerGeometry : public QgsMapToolCapture
{
public:
//! Constructor
QgsMapToolCaptureLayerGeometry( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget, CaptureMode mode );

private:
void geometryCaptured( const QgsGeometry &geometry ) override;

/**
* Called when the geometry is captured
* A more specific handler is also called afterwards (pointCaptured, lineCaptured or polygonCaptured)
* \since QGIS 3.24
*/
virtual void layerGeometryCaptured( const QgsGeometry &geometry ) {Q_UNUSED( geometry )} SIP_FORCE

/**
* Called when a point is captured
* geometryCaptured is called just before
* \since QGIS 3.24
*/
virtual void layerPointCaptured( const QgsPoint &point ) {Q_UNUSED( point )} SIP_FORCE

/**
* Called when a line is captured
* geometryCaptured is called just before
* \since QGIS 3.24
*/
virtual void layerLineCaptured( const QgsCurve *line ) {Q_UNUSED( line )} SIP_FORCE

/**
* Called when a polygon is captured
* geometryCaptured is called just before
* \since QGIS 3.24
*/
virtual void layerPolygonCaptured( const QgsCurvePolygon *polygon ) {Q_UNUSED( polygon )} SIP_FORCE
};

#endif // QGSMAPTOOLCAPTURELAYERGEOMETRY_H
40 changes: 3 additions & 37 deletions src/gui/qgsmaptoolcapture.cpp
Expand Up @@ -1239,6 +1239,8 @@ void QgsMapToolCapture::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
if ( mode() == CaptureLine )
{
g = QgsGeometry( curveToAdd );
geometryCaptured( g );
lineCaptured( curveToAdd );
}
else
{
Expand All @@ -1252,43 +1254,7 @@ void QgsMapToolCapture::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
}
poly->setExteriorRing( curveToAdd );
g = QgsGeometry( poly );

QList<QgsVectorLayer *> avoidIntersectionsLayers;
switch ( QgsProject::instance()->avoidIntersectionsMode() )
{
case QgsProject::AvoidIntersectionsMode::AvoidIntersectionsCurrentLayer:
if ( vlayer )
avoidIntersectionsLayers.append( vlayer );
break;
case QgsProject::AvoidIntersectionsMode::AvoidIntersectionsLayers:
avoidIntersectionsLayers = QgsProject::instance()->avoidIntersectionsLayers();
break;
case QgsProject::AvoidIntersectionsMode::AllowIntersections:
break;
}
if ( avoidIntersectionsLayers.size() > 0 )
{
const int avoidIntersectionsReturn = g.avoidIntersections( avoidIntersectionsLayers );
if ( avoidIntersectionsReturn == 3 )
{
emit messageEmitted( tr( "The feature has been added, but at least one geometry intersected is invalid. These geometries must be manually repaired." ), Qgis::MessageLevel::Warning );
}
if ( g.isEmpty() ) //avoid intersection might have removed the whole geometry
{
emit messageEmitted( tr( "The feature cannot be added because its geometry collapsed due to intersection avoidance" ), Qgis::MessageLevel::Critical );
stopCapturing();
return;
}
}
}

geometryCaptured( g );
if ( mode() == CaptureLine )
{
lineCaptured( curveToAdd );
}
else
{
geometryCaptured( g );
polygonCaptured( poly );
}

Expand Down

0 comments on commit 83c5e6f

Please sign in to comment.