QGIS API Documentation  3.22.4-Białowieża (ce8e65e95e)
qgscreateannotationitemmaptool_impl.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscreateannotationitemmaptool_impl.cpp
3  ------------------------
4  Date : September 2021
5  Copyright : (C) 2021 Nyall Dawson
6  Email : nyall dot dawson at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 #include "qgsmapmouseevent.h"
20 #include "qgsannotationlineitem.h"
22 #include "qgsannotationlayer.h"
23 #include "qgsstyle.h"
24 #include "qgsmapcanvas.h"
25 #include "qgsmarkersymbol.h"
26 #include "qgslinesymbol.h"
27 #include "qgsfillsymbol.h"
29 #include "qgsapplication.h"
30 #include "qgsrecentstylehandler.h"
31 
33 
34 //
35 // QgsMapToolCaptureAnnotationItem
36 //
37 
38 QgsMapToolCaptureAnnotationItem::QgsMapToolCaptureAnnotationItem( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget, CaptureMode mode )
39  : QgsMapToolCapture( canvas, cadDockWidget, mode )
40 {
41 
42 }
43 
44 QgsCreateAnnotationItemMapToolHandler *QgsMapToolCaptureAnnotationItem::handler()
45 {
46  return mHandler;
47 }
48 
49 QgsMapTool *QgsMapToolCaptureAnnotationItem::mapTool()
50 {
51  return this;
52 }
53 
54 QgsMapLayer *QgsMapToolCaptureAnnotationItem::layer() const
55 {
56  return mHandler->targetLayer();
57 }
58 
59 
60 QgsMapToolCapture::Capabilities QgsMapToolCaptureAnnotationItem::capabilities() const
61 {
62  // no geometry validation!
63  return SupportsCurves;
64 }
65 
66 bool QgsMapToolCaptureAnnotationItem::supportsTechnique( CaptureTechnique ) const
67 {
68  return true;
69 }
70 
71 
72 
73 
74 //
75 // QgsCreatePointTextItemMapTool
76 //
77 
78 QgsCreatePointTextItemMapTool::QgsCreatePointTextItemMapTool( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget )
79  : QgsMapToolAdvancedDigitizing( canvas, cadDockWidget )
80  , mHandler( new QgsCreateAnnotationItemMapToolHandler( canvas, cadDockWidget ) )
81 {
82 
83 }
84 
85 QgsCreatePointTextItemMapTool::~QgsCreatePointTextItemMapTool() = default;
86 
87 void QgsCreatePointTextItemMapTool::cadCanvasPressEvent( QgsMapMouseEvent *event )
88 {
89  if ( event->button() != Qt::LeftButton )
90  return;
91 
92  const QgsPointXY layerPoint = toLayerCoordinates( mHandler->targetLayer(), event->mapPoint() );
93 
94  std::unique_ptr< QgsAnnotationPointTextItem > createdItem = std::make_unique< QgsAnnotationPointTextItem >( tr( "Text" ), layerPoint );
95  createdItem->setAlignment( Qt::AlignLeft );
96  createdItem->setFormat( QgsStyle::defaultStyle()->defaultTextFormat( QgsStyle::TextFormatContext::Labeling ) );
97  // newly created point text items default to using symbology reference scale at the current map scale
98  createdItem->setUseSymbologyReferenceScale( true );
99  createdItem->setSymbologyReferenceScale( canvas()->scale() );
100  mHandler->pushCreatedItem( createdItem.release() );
101 }
102 
103 QgsCreateAnnotationItemMapToolHandler *QgsCreatePointTextItemMapTool::handler()
104 {
105  return mHandler;
106 }
107 
108 QgsMapTool *QgsCreatePointTextItemMapTool::mapTool()
109 {
110  return this;
111 }
112 
113 
114 
115 //
116 // QgsCreateMarkerMapTool
117 //
118 
119 QgsCreateMarkerItemMapTool::QgsCreateMarkerItemMapTool( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget )
120  : QgsMapToolCaptureAnnotationItem( canvas, cadDockWidget, CapturePoint )
121 {
122  mHandler = new QgsCreateAnnotationItemMapToolHandler( canvas, cadDockWidget, this );
123 }
124 
125 void QgsCreateMarkerItemMapTool::cadCanvasReleaseEvent( QgsMapMouseEvent *event )
126 {
127  if ( event->button() != Qt::LeftButton )
128  return;
129 
130  const QgsPointXY layerPoint = toLayerCoordinates( mHandler->targetLayer(), event->mapPoint() );
131  std::unique_ptr< QgsAnnotationMarkerItem > createdItem = std::make_unique< QgsAnnotationMarkerItem >( QgsPoint( layerPoint ) );
132 
133  std::unique_ptr< QgsMarkerSymbol > markerSymbol = QgsApplication::recentStyleHandler()->recentSymbol< QgsMarkerSymbol >( QStringLiteral( "marker_annotation_item" ) );
134  if ( !markerSymbol )
135  markerSymbol.reset( qgis::down_cast< QgsMarkerSymbol * >( QgsSymbol::defaultSymbol( QgsWkbTypes::PointGeometry ) ) );
136  createdItem->setSymbol( markerSymbol.release() );
137 
138  // set reference scale to match canvas scale, but don't enable it by default for marker items
139  createdItem->setSymbologyReferenceScale( canvas()->scale() );
140 
141  mHandler->pushCreatedItem( createdItem.release() );
142 
143  stopCapturing();
144 
145  cadDockWidget()->clearPoints();
146 }
147 
148 //
149 // QgsCreateLineMapTool
150 //
151 
152 QgsCreateLineItemMapTool::QgsCreateLineItemMapTool( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget )
153  : QgsMapToolCaptureAnnotationItem( canvas, cadDockWidget, CaptureLine )
154 {
155  mHandler = new QgsCreateAnnotationItemMapToolHandler( canvas, cadDockWidget, this );
156 }
157 
158 void QgsCreateLineItemMapTool::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
159 {
160  //add point to list and to rubber band
161  if ( e->button() == Qt::LeftButton )
162  {
163  const int error = addVertex( e->mapPoint(), e->mapPointMatch() );
164  if ( error == 2 )
165  {
166  //problem with coordinate transformation
167  emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), Qgis::MessageLevel::Warning );
168  return;
169  }
170 
171  startCapturing();
172  }
173  else if ( e->button() == Qt::RightButton )
174  {
175  deleteTempRubberBand();
176 
177  //find out bounding box of mCaptureList
178  if ( size() < 1 )
179  {
180  stopCapturing();
181  return;
182  }
183 
184  // do it!
185  std::unique_ptr< QgsAbstractGeometry > geometry( captureCurve()->simplifiedTypeRef()->clone() );
186  if ( qgsgeometry_cast< QgsCurve * >( geometry.get() ) )
187  {
188  std::unique_ptr< QgsAnnotationLineItem > createdItem = std::make_unique< QgsAnnotationLineItem >( qgsgeometry_cast< QgsCurve * >( geometry.release() ) );
189 
190  std::unique_ptr< QgsLineSymbol > lineSymbol = QgsApplication::recentStyleHandler()->recentSymbol< QgsLineSymbol >( QStringLiteral( "line_annotation_item" ) );
191  if ( !lineSymbol )
192  lineSymbol.reset( qgis::down_cast< QgsLineSymbol * >( QgsSymbol::defaultSymbol( QgsWkbTypes::LineGeometry ) ) );
193  createdItem->setSymbol( lineSymbol.release() );
194 
195  // set reference scale to match canvas scale, but don't enable it by default for marker items
196  createdItem->setSymbologyReferenceScale( canvas()->scale() );
197 
198  mHandler->pushCreatedItem( createdItem.release() );
199  }
200  stopCapturing();
201  }
202 }
203 
204 //
205 // QgsCreatePolygonItemMapTool
206 //
207 
208 QgsCreatePolygonItemMapTool::QgsCreatePolygonItemMapTool( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget )
209  : QgsMapToolCaptureAnnotationItem( canvas, cadDockWidget, CapturePolygon )
210 {
211  mHandler = new QgsCreateAnnotationItemMapToolHandler( canvas, cadDockWidget, this );
212 }
213 
214 void QgsCreatePolygonItemMapTool::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
215 {
216  //add point to list and to rubber band
217  if ( e->button() == Qt::LeftButton )
218  {
219  const int error = addVertex( e->mapPoint(), e->mapPointMatch() );
220  if ( error == 2 )
221  {
222  //problem with coordinate transformation
223  emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), Qgis::MessageLevel::Warning );
224  return;
225  }
226 
227  startCapturing();
228  }
229  else if ( e->button() == Qt::RightButton )
230  {
231  deleteTempRubberBand();
232 
233  //find out bounding box of mCaptureList
234  if ( size() < 1 )
235  {
236  stopCapturing();
237  return;
238  }
239 
240  closePolygon();
241 
242  std::unique_ptr< QgsAbstractGeometry > geometry( captureCurve()->simplifiedTypeRef()->clone() );
243  if ( qgsgeometry_cast< QgsCurve * >( geometry.get() ) )
244  {
245  std::unique_ptr< QgsCurvePolygon > newPolygon = std::make_unique< QgsCurvePolygon >();
246  newPolygon->setExteriorRing( qgsgeometry_cast< QgsCurve * >( geometry.release() ) );
247  std::unique_ptr< QgsAnnotationPolygonItem > createdItem = std::make_unique< QgsAnnotationPolygonItem >( newPolygon.release() );
248 
249  std::unique_ptr< QgsFillSymbol > fillSymbol = QgsApplication::recentStyleHandler()->recentSymbol< QgsFillSymbol >( QStringLiteral( "polygon_annotation_item" ) );
250  if ( !fillSymbol )
251  fillSymbol.reset( qgis::down_cast< QgsFillSymbol * >( QgsSymbol::defaultSymbol( QgsWkbTypes::PolygonGeometry ) ) );
252  createdItem->setSymbol( fillSymbol.release() );
253 
254  // set reference scale to match canvas scale, but don't enable it by default for marker items
255  createdItem->setSymbologyReferenceScale( canvas()->scale() );
256 
257  mHandler->pushCreatedItem( createdItem.release() );
258  }
259  stopCapturing();
260  }
261 }
262 
264 
The QgsAdvancedDigitizingDockWidget class is a dockable widget used to handle the CAD tools on top of...
static QgsRecentStyleHandler * recentStyleHandler()
Returns the handler for recently used style items.
A handler object for map tools which create annotation items.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
Definition: qgsfillsymbol.h:30
A line symbol type, for rendering LineString and MultiLineString geometries.
Definition: qgslinesymbol.h:30
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:89
Base class for all map layer types.
Definition: qgsmaplayer.h:73
A QgsMapMouseEvent is the result of a user interaction with the mouse on a QgsMapCanvas.
QgsPointXY mapPoint() const
mapPoint returns the point in coordinates
QgsPointLocator::Match mapPointMatch() const
Returns the matching data from the most recently snapped point.
The QgsMapToolAdvancedDigitizing class is a QgsMapTool which gives event directly in map coordinates ...
Abstract base class for all map tools.
Definition: qgsmaptool.h:71
A marker symbol type, for rendering Point and MultiPoint geometries.
A class to represent a 2D point.
Definition: qgspointxy.h:59
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
QgsSymbol * recentSymbol(const QString &identifier) const
Returns a copy of the recently used symbol with the specified identifier, or nullptr if no symbol wit...
static QgsStyle * defaultStyle()
Returns default application-wide style.
Definition: qgsstyle.cpp:131
@ Labeling
Text format used in labeling.
static QgsSymbol * defaultSymbol(QgsWkbTypes::GeometryType geomType)
Returns a new default symbol for the specified geometry type.
Definition: qgssymbol.cpp:355