QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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
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
18
19
21
22
23QgsMapToolCaptureRubberBand::QgsMapToolCaptureRubberBand( QgsMapCanvas *mapCanvas, Qgis::GeometryType geomType ):
24 QgsGeometryRubberBand( mapCanvas, geomType )
25{
26 setVertexDrawingEnabled( false );
27}
28
29QgsCurve *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
52bool QgsMapToolCaptureRubberBand::curveIsComplete() const
53{
54 return ( mStringType == Qgis::WkbType::LineString && mPoints.count() > 1 ) ||
55 ( mStringType == Qgis::WkbType::CircularString && mPoints.count() > 2 );
56}
57
58void QgsMapToolCaptureRubberBand::reset( Qgis::GeometryType geomType, Qgis::WkbType stringType, const QgsPoint &firstPolygonPoint )
59{
60 if ( !( geomType == Qgis::GeometryType::Line || geomType == Qgis::GeometryType::Polygon ) )
61 return;
62
63 mPoints.clear();
64 mFirstPolygonPoint = firstPolygonPoint;
65 setStringType( stringType );
66 setRubberBandGeometryType( geomType );
67}
68
69void QgsMapToolCaptureRubberBand::setRubberBandGeometryType( Qgis::GeometryType geomType )
70{
72 updateCurve();
73}
74
75void 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
86void QgsMapToolCaptureRubberBand::movePoint( const QgsPoint &point )
87{
88 if ( mPoints.count() > 0 )
89 mPoints.last() = point ;
90
91 updateCurve();
92}
93
94void 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
102int QgsMapToolCaptureRubberBand::pointsCount()
103{
104 return mPoints.size();
105}
106
107Qgis::WkbType QgsMapToolCaptureRubberBand::stringType() const
108{
109 return mStringType;
110}
111
112void QgsMapToolCaptureRubberBand::setStringType( Qgis::WkbType type )
113{
114 if ( ( type != Qgis::WkbType::CircularString && type != Qgis::WkbType::LineString ) || type == mStringType )
115 return;
116
117 mStringType = type;
118 if ( type == Qgis::WkbType::LineString && mPoints.count() == 3 )
119 {
120 mPoints.removeAt( 1 );
121 }
122
123 setVertexDrawingEnabled( type == Qgis::WkbType::CircularString );
124 updateCurve();
125}
126
127QgsPoint QgsMapToolCaptureRubberBand::lastPoint() const
128{
129 if ( mPoints.empty() )
130 return QgsPoint();
131
132 return mPoints.last();
133}
134
135QgsPoint 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
143void QgsMapToolCaptureRubberBand::removeLastPoint()
144{
145 if ( mPoints.count() > 1 )
146 mPoints.removeLast();
147
148 updateCurve();
149}
150
151void QgsMapToolCaptureRubberBand::setGeometry( QgsAbstractGeometry *geom )
152{
154}
155
156void 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() == Qgis::GeometryType::Polygon )
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
184QgsCurve *QgsMapToolCaptureRubberBand::createLinearString()
185{
186 std::unique_ptr<QgsLineString> curve( new QgsLineString );
187 if ( geometryType() == Qgis::GeometryType::Polygon )
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
199QgsCurve *QgsMapToolCaptureRubberBand::createCircularString()
200{
201 std::unique_ptr<QgsCircularString> curve( new QgsCircularString );
202 curve->setPoints( mPoints );
203 if ( geometryType() == Qgis::GeometryType::Polygon )
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
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
Definition: qgis.h:255
@ Polygon
Polygons.
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition: qgis.h:182
@ LineString
LineString.
@ CircularString
CircularString.
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:35
A rubberband class for QgsAbstractGeometry (considering curved geometries).
void setGeometryType(Qgis::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:45
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:93
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
QVector< QgsPoint > QgsPointSequence