Skip to content

Commit

Permalink
Add map tools for creating line/polygon annotation items
Browse files Browse the repository at this point in the history
These use the same base class as the vector feature capture tools,
so support the same interaction (snapping, tracing, cad dock, backspace
to remove vertices, etc) as drawing vector line/polygon features
  • Loading branch information
nyalldawson committed Sep 8, 2021
1 parent da9b9b0 commit 0464eec
Show file tree
Hide file tree
Showing 3 changed files with 225 additions and 5 deletions.
12 changes: 10 additions & 2 deletions src/gui/annotations/qgsannotationitemguiregistry.cpp
Expand Up @@ -186,7 +186,11 @@ void QgsAnnotationItemGuiRegistry::addDefaultItems()
QgsAnnotationPolygonItemWidget *widget = new QgsAnnotationPolygonItemWidget( nullptr );
widget->setItem( item );
return widget;
}, QString(), Qgis::AnnotationItemGuiFlag::FlagNoCreationTools ) );
}, QString(), Qgis::AnnotationItemGuiFlags(), nullptr,
[ = ]( QgsMapCanvas * canvas, QgsAdvancedDigitizingDockWidget * cadDockWidget )->QgsCreateAnnotationItemMapToolInterface *
{
return new QgsCreatePolygonItemMapTool( canvas, cadDockWidget );
} ) );

addAnnotationItemGuiMetadata( new QgsAnnotationItemGuiMetadata( QStringLiteral( "linestring" ),
QObject::tr( "Line" ),
Expand All @@ -196,7 +200,11 @@ void QgsAnnotationItemGuiRegistry::addDefaultItems()
QgsAnnotationLineItemWidget *widget = new QgsAnnotationLineItemWidget( nullptr );
widget->setItem( item );
return widget;
}, QString(), Qgis::AnnotationItemGuiFlag::FlagNoCreationTools ) );
}, QString(), Qgis::AnnotationItemGuiFlags(), nullptr,
[ = ]( QgsMapCanvas * canvas, QgsAdvancedDigitizingDockWidget * cadDockWidget )->QgsCreateAnnotationItemMapToolInterface *
{
return new QgsCreateLineItemMapTool( canvas, cadDockWidget );
} ) );

addAnnotationItemGuiMetadata( new QgsAnnotationItemGuiMetadata( QStringLiteral( "marker" ),
QObject::tr( "Marker" ),
Expand Down
164 changes: 164 additions & 0 deletions src/gui/annotations/qgscreateannotationitemmaptool_impl.cpp
Expand Up @@ -17,10 +17,14 @@
#include "qgsmapmouseevent.h"
#include "qgsannotationpointtextitem.h"
#include "qgsannotationmarkeritem.h"
#include "qgsannotationlineitem.h"
#include "qgsannotationpolygonitem.h"
#include "qgsannotationlayer.h"
#include "qgsstyle.h"
#include "qgsmapcanvas.h"
#include "qgsmarkersymbol.h"
#include "qgslinesymbol.h"
#include "qgsfillsymbol.h"

///@cond PRIVATE

Expand Down Expand Up @@ -103,4 +107,164 @@ QgsMapTool *QgsCreateMarkerItemMapTool::mapTool()
return this;
}

//
// QgsMapToolCaptureAnnotationItem
//

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

}

QgsMapToolCapture::Capabilities QgsMapToolCaptureAnnotationItem::capabilities() const
{
// no geometry validation!
return SupportsCurves;
}


//
// QgsCreateLineMapTool
//

QgsCreateLineItemMapTool::QgsCreateLineItemMapTool( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget )
: QgsMapToolCaptureAnnotationItem( canvas, cadDockWidget, CaptureLine )
, mHandler( new QgsCreateAnnotationItemMapToolHandler( canvas, cadDockWidget ) )
{

}

void QgsCreateLineItemMapTool::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
{
//add point to list and to rubber band
if ( e->button() == Qt::LeftButton )
{
const int error = addVertex( e->mapPoint(), e->mapPointMatch() );
if ( error == 2 )
{
//problem with coordinate transformation
emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), Qgis::MessageLevel::Warning );
return;
}

startCapturing();
}
else if ( e->button() == Qt::RightButton )
{
deleteTempRubberBand();

//find out bounding box of mCaptureList
if ( size() < 1 )
{
stopCapturing();
return;
}

// do it!
std::unique_ptr< QgsAbstractGeometry > geometry( captureCurve()->simplifiedTypeRef()->clone() );
if ( qgsgeometry_cast< QgsCurve * >( geometry.get() ) )
{
std::unique_ptr< QgsAnnotationLineItem > createdItem = std::make_unique< QgsAnnotationLineItem >( qgsgeometry_cast< QgsCurve * >( geometry.release() ) );
createdItem->setSymbol( qgis::down_cast< QgsLineSymbol * >( QgsSymbol::defaultSymbol( QgsWkbTypes::LineGeometry ) ) );
// set reference scale to match canvas scale, but don't enable it by default for marker items
createdItem->setSymbologyReferenceScale( canvas()->scale() );

mHandler->pushCreatedItem( createdItem.release() );
}
stopCapturing();
}
}

QgsCreateLineItemMapTool::~QgsCreateLineItemMapTool() = default;

QgsCreateAnnotationItemMapToolHandler *QgsCreateLineItemMapTool::handler()
{
return mHandler;
}

QgsMapTool *QgsCreateLineItemMapTool::mapTool()
{
return this;
}

QgsMapLayer *QgsCreateLineItemMapTool::layer() const
{
return mHandler->targetLayer();
}



//
// QgsCreatePolygonItemMapTool
//

QgsCreatePolygonItemMapTool::QgsCreatePolygonItemMapTool( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget )
: QgsMapToolCaptureAnnotationItem( canvas, cadDockWidget, CapturePolygon )
, mHandler( new QgsCreateAnnotationItemMapToolHandler( canvas, cadDockWidget ) )
{

}

void QgsCreatePolygonItemMapTool::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
{
//add point to list and to rubber band
if ( e->button() == Qt::LeftButton )
{
const int error = addVertex( e->mapPoint(), e->mapPointMatch() );
if ( error == 2 )
{
//problem with coordinate transformation
emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), Qgis::MessageLevel::Warning );
return;
}

startCapturing();
}
else if ( e->button() == Qt::RightButton )
{
deleteTempRubberBand();

//find out bounding box of mCaptureList
if ( size() < 1 )
{
stopCapturing();
return;
}

closePolygon();

std::unique_ptr< QgsAbstractGeometry > geometry( captureCurve()->simplifiedTypeRef()->clone() );
if ( qgsgeometry_cast< QgsCurve * >( geometry.get() ) )
{
std::unique_ptr< QgsCurvePolygon > newPolygon = std::make_unique< QgsCurvePolygon >();
newPolygon->setExteriorRing( qgsgeometry_cast< QgsCurve * >( geometry.release() ) );
std::unique_ptr< QgsAnnotationPolygonItem > createdItem = std::make_unique< QgsAnnotationPolygonItem >( newPolygon.release() );
createdItem->setSymbol( qgis::down_cast< QgsFillSymbol * >( QgsSymbol::defaultSymbol( QgsWkbTypes::PolygonGeometry ) ) );
// set reference scale to match canvas scale, but don't enable it by default for marker items
createdItem->setSymbologyReferenceScale( canvas()->scale() );

mHandler->pushCreatedItem( createdItem.release() );
}
stopCapturing();
}
}

QgsCreatePolygonItemMapTool::~QgsCreatePolygonItemMapTool() = default;

QgsCreateAnnotationItemMapToolHandler *QgsCreatePolygonItemMapTool::handler()
{
return mHandler;
}

QgsMapTool *QgsCreatePolygonItemMapTool::mapTool()
{
return this;
}

QgsMapLayer *QgsCreatePolygonItemMapTool::layer() const
{
return mHandler->targetLayer();
}

///@endcond PRIVATE
54 changes: 51 additions & 3 deletions src/gui/annotations/qgscreateannotationitemmaptool_impl.h
Expand Up @@ -18,9 +18,7 @@
#include "qgis_gui.h"
#include "qgis_sip.h"
#include "qgscreateannotationitemmaptool.h"

class QgsAnnotationPointTextItem;
class QgsAnnotationMarkerItem;
#include "qgsmaptoolcapture.h"

#define SIP_NO_FILE

Expand Down Expand Up @@ -64,6 +62,56 @@ class QgsCreateMarkerItemMapTool: public QgsMapToolAdvancedDigitizing, public Qg

};

class QgsMapToolCaptureAnnotationItem : public QgsMapToolCapture
{
Q_OBJECT
public:
QgsMapToolCaptureAnnotationItem( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget, CaptureMode mode );

QgsMapToolCapture::Capabilities capabilities() const override;


};

class QgsCreateLineItemMapTool: public QgsMapToolCaptureAnnotationItem, public QgsCreateAnnotationItemMapToolInterface
{
Q_OBJECT

public:

QgsCreateLineItemMapTool( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget );
~QgsCreateLineItemMapTool() override;

void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
QgsCreateAnnotationItemMapToolHandler *handler() override;
QgsMapTool *mapTool() override;
QgsMapLayer *layer() const override;

private:

QgsCreateAnnotationItemMapToolHandler *mHandler = nullptr;

};

class QgsCreatePolygonItemMapTool: public QgsMapToolCaptureAnnotationItem, public QgsCreateAnnotationItemMapToolInterface
{
Q_OBJECT

public:

QgsCreatePolygonItemMapTool( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget );
~QgsCreatePolygonItemMapTool() override;

void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
QgsCreateAnnotationItemMapToolHandler *handler() override;
QgsMapTool *mapTool() override;
QgsMapLayer *layer() const override;

private:

QgsCreateAnnotationItemMapToolHandler *mHandler = nullptr;

};

///@endcond PRIVATE

Expand Down

0 comments on commit 0464eec

Please sign in to comment.