QGIS API Documentation  3.25.0-Master (6b426f5f8a)
qgsmaptoolcapturerubberband.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmaptoolcapturerubberband.cpp - map tool for capturing points, lines, polygons
3  ---------------------
4  begin : January 2022
5  copyright : (C) Denis Rouzaud
6  email : [email protected]
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 "qgsgeometryrubberband.h"
18 
19 
21 
22 
23 QgsMapToolCaptureRubberBand::QgsMapToolCaptureRubberBand( QgsMapCanvas *mapCanvas, QgsWkbTypes::GeometryType geomType ):
24  QgsGeometryRubberBand( mapCanvas, geomType )
25 {
26  setVertexDrawingEnabled( false );
27 }
28 
29 QgsCurve *QgsMapToolCaptureRubberBand::curve()
30 {
31  if ( mPoints.empty() )
32  return nullptr;
33 
34  switch ( mStringType )
35  {
37  return new QgsLineString( mPoints ) ;
38  break;
40  if ( mPoints.count() != 3 )
41  return nullptr;
42  return new QgsCircularString(
43  mPoints[0],
44  mPoints[1],
45  mPoints[2] ) ;
46  break;
47  default:
48  return nullptr;
49  }
50 }
51 
52 bool QgsMapToolCaptureRubberBand::curveIsComplete() const
53 {
54  return ( mStringType == QgsWkbTypes::LineString && mPoints.count() > 1 ) ||
55  ( mStringType == QgsWkbTypes::CircularString && mPoints.count() > 2 );
56 }
57 
58 void QgsMapToolCaptureRubberBand::reset( QgsWkbTypes::GeometryType geomType, QgsWkbTypes::Type stringType, const QgsPoint &firstPolygonPoint )
59 {
60  if ( !( geomType == QgsWkbTypes::LineGeometry || geomType == QgsWkbTypes::PolygonGeometry ) )
61  return;
62 
63  mPoints.clear();
64  mFirstPolygonPoint = firstPolygonPoint;
65  setStringType( stringType );
66  setRubberBandGeometryType( geomType );
67 }
68 
69 void QgsMapToolCaptureRubberBand::setRubberBandGeometryType( QgsWkbTypes::GeometryType geomType )
70 {
72  updateCurve();
73 }
74 
75 void QgsMapToolCaptureRubberBand::addPoint( const QgsPoint &point, bool doUpdate )
76 {
77  if ( mPoints.count() == 0 )
78  mPoints.append( point );
79 
80  mPoints.append( point );
81 
82  if ( doUpdate )
83  updateCurve();
84 }
85 
86 void QgsMapToolCaptureRubberBand::movePoint( const QgsPoint &point )
87 {
88  if ( mPoints.count() > 0 )
89  mPoints.last() = point ;
90 
91  updateCurve();
92 }
93 
94 void QgsMapToolCaptureRubberBand::movePoint( int index, const QgsPoint &point )
95 {
96  if ( mPoints.count() > 0 && mPoints.size() > index )
97  mPoints[index] = point;
98 
99  updateCurve();
100 }
101 
102 int QgsMapToolCaptureRubberBand::pointsCount()
103 {
104  return mPoints.size();
105 }
106 
107 QgsWkbTypes::Type QgsMapToolCaptureRubberBand::stringType() const
108 {
109  return mStringType;
110 }
111 
112 void QgsMapToolCaptureRubberBand::setStringType( const QgsWkbTypes::Type &type )
113 {
114  if ( ( type != QgsWkbTypes::CircularString && type != QgsWkbTypes::LineString ) || type == mStringType )
115  return;
116 
117  mStringType = type;
118  if ( type == QgsWkbTypes::LineString && mPoints.count() == 3 )
119  {
120  mPoints.removeAt( 1 );
121  }
122 
123  setVertexDrawingEnabled( type == QgsWkbTypes::CircularString );
124  updateCurve();
125 }
126 
127 QgsPoint QgsMapToolCaptureRubberBand::lastPoint() const
128 {
129  if ( mPoints.empty() )
130  return QgsPoint();
131 
132  return mPoints.last();
133 }
134 
135 QgsPoint QgsMapToolCaptureRubberBand::pointFromEnd( int posFromEnd ) const
136 {
137  if ( posFromEnd < mPoints.size() )
138  return mPoints.at( mPoints.size() - 1 - posFromEnd );
139  else
140  return QgsPoint();
141 }
142 
143 void QgsMapToolCaptureRubberBand::removeLastPoint()
144 {
145  if ( mPoints.count() > 1 )
146  mPoints.removeLast();
147 
148  updateCurve();
149 }
150 
151 void QgsMapToolCaptureRubberBand::setGeometry( QgsAbstractGeometry *geom )
152 {
154 }
155 
156 void QgsMapToolCaptureRubberBand::updateCurve()
157 {
158  std::unique_ptr<QgsCurve> curve;
159  switch ( mStringType )
160  {
162  curve.reset( createLinearString() );
163  break;
165  curve.reset( createCircularString() );
166  break;
167  default:
168  return;
169  break;
170  }
171 
172  if ( geometryType() == QgsWkbTypes::PolygonGeometry )
173  {
174  std::unique_ptr<QgsCurvePolygon> geom( new QgsCurvePolygon );
175  geom->setExteriorRing( curve.release() );
176  setGeometry( geom.release() );
177  }
178  else
179  {
180  setGeometry( curve.release() );
181  }
182 }
183 
184 QgsCurve *QgsMapToolCaptureRubberBand::createLinearString()
185 {
186  std::unique_ptr<QgsLineString> curve( new QgsLineString );
187  if ( geometryType() == QgsWkbTypes::PolygonGeometry )
188  {
189  QgsPointSequence points = mPoints;
190  points.prepend( mFirstPolygonPoint );
191  curve->setPoints( points );
192  }
193  else
194  curve->setPoints( mPoints );
195 
196  return curve.release();
197 }
198 
199 QgsCurve *QgsMapToolCaptureRubberBand::createCircularString()
200 {
201  std::unique_ptr<QgsCircularString> curve( new QgsCircularString );
202  curve->setPoints( mPoints );
203  if ( geometryType() == QgsWkbTypes::PolygonGeometry )
204  {
205  // add a linear string to close the polygon
206  std::unique_ptr<QgsCompoundCurve> polygonCurve( new QgsCompoundCurve );
207  polygonCurve->addVertex( mFirstPolygonPoint );
208  if ( !mPoints.empty() )
209  polygonCurve->addVertex( mPoints.first() );
210  polygonCurve->addCurve( curve.release() );
211  return polygonCurve.release();
212  }
213  else
214  return curve.release();
215 }
216 
Abstract base class for all geometries.
Circular string geometry type.
Compound curve geometry type.
Curve polygon geometry type.
Abstract base class for curved geometry type.
Definition: qgscurve.h:36
A rubberband class for QgsAbstractGeometry (considering curved geometries).
void setGeometryType(const QgsWkbTypes::GeometryType &geometryType)
Sets which geometry is handled by the rubber band, polygon or line.
virtual void setGeometry(QgsAbstractGeometry *geom)
Sets geometry (takes ownership). Geometry is expected to be in map coordinates.
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:44
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:90
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:141
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:70
QVector< QgsPoint > QgsPointSequence