QGIS API Documentation 3.99.0-Master (8e76e220402)
Loading...
Searching...
No Matches
qgsgeometryfactory.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsgeometryfactory.cpp
3 ------------------------
4 begin : September 2014
5 copyright : (C) 2014 by Marco Hugentobler
6 email : marco at sourcepole dot ch
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18#include "qgsgeometryfactory.h"
19
20#include "qgscircularstring.h"
21#include "qgscompoundcurve.h"
22#include "qgscurvepolygon.h"
23#include "qgslinestring.h"
24#include "qgslogger.h"
25#include "qgsmulticurve.h"
26#include "qgsmultilinestring.h"
27#include "qgsmultipoint.h"
28#include "qgsmultipolygon.h"
29#include "qgsmultisurface.h"
30#include "qgsnurbscurve.h"
31#include "qgspoint.h"
32#include "qgspolygon.h"
34#include "qgstriangle.h"
36#include "qgswkbtypes.h"
37
38#include <QString>
39
40using namespace Qt::StringLiterals;
41
42std::unique_ptr<QgsAbstractGeometry> QgsGeometryFactory::geomFromWkb( QgsConstWkbPtr &wkbPtr )
43{
44 if ( !wkbPtr )
45 return nullptr;
46
47 //find out type (bytes 2-5)
49 try
50 {
51 type = wkbPtr.readHeader();
52 }
53 catch ( const QgsWkbException &e )
54 {
55 Q_UNUSED( e )
56 QgsDebugError( "WKB exception while reading header: " + e.what() );
57 return nullptr;
58 }
59 wkbPtr -= 1 + sizeof( int );
60
61 std::unique_ptr< QgsAbstractGeometry > geom = geomFromWkbType( type );
62
63 if ( geom )
64 {
65 try
66 {
67 geom->fromWkb( wkbPtr ); // also updates wkbPtr
68 }
69 catch ( const QgsWkbException &e )
70 {
71 Q_UNUSED( e )
72 QgsDebugError( "WKB exception: " + e.what() );
73 geom.reset();
74 }
75 }
76
77 return geom;
78}
79
80std::unique_ptr<QgsAbstractGeometry> QgsGeometryFactory::geomFromWkt( const QString &text )
81{
82 const QString trimmed = text.trimmed();
83 std::unique_ptr< QgsAbstractGeometry> geom;
84 if ( trimmed.startsWith( "Point"_L1, Qt::CaseInsensitive ) )
85 {
86 geom = std::make_unique< QgsPoint >();
87 }
88 else if ( trimmed.startsWith( "LineString"_L1, Qt::CaseInsensitive ) )
89 {
90 geom = std::make_unique< QgsLineString >();
91 }
92 else if ( trimmed.startsWith( "CircularString"_L1, Qt::CaseInsensitive ) )
93 {
94 geom = std::make_unique< QgsCircularString >();
95 }
96 else if ( trimmed.startsWith( "CompoundCurve"_L1, Qt::CaseInsensitive ) )
97 {
98 geom = std::make_unique< QgsCompoundCurve>();
99 }
100 else if ( trimmed.startsWith( "Polygon"_L1, Qt::CaseInsensitive ) )
101 {
102 geom = std::make_unique< QgsPolygon >();
103 }
104 else if ( trimmed.startsWith( "Triangle"_L1, Qt::CaseInsensitive ) )
105 {
106 geom = std::make_unique< QgsTriangle >();
107 }
108 else if ( trimmed.startsWith( "CurvePolygon"_L1, Qt::CaseInsensitive ) )
109 {
110 geom = std::make_unique< QgsCurvePolygon >();
111 }
112 else if ( trimmed.startsWith( "MultiPoint"_L1, Qt::CaseInsensitive ) )
113 {
114 geom = std::make_unique< QgsMultiPoint >();
115 }
116 else if ( trimmed.startsWith( "MultiCurve"_L1, Qt::CaseInsensitive ) )
117 {
118 geom = std::make_unique< QgsMultiCurve >();
119 }
120 else if ( trimmed.startsWith( "MultiLineString"_L1, Qt::CaseInsensitive ) )
121 {
122 geom = std::make_unique< QgsMultiLineString >();
123 }
124 else if ( trimmed.startsWith( "MultiSurface"_L1, Qt::CaseInsensitive ) )
125 {
126 geom = std::make_unique< QgsMultiSurface >();
127 }
128 else if ( trimmed.startsWith( "MultiPolygon"_L1, Qt::CaseInsensitive ) )
129 {
130 geom = std::make_unique< QgsMultiPolygon >();
131 }
132 else if ( trimmed.startsWith( "GeometryCollection"_L1, Qt::CaseInsensitive ) )
133 {
134 geom = std::make_unique< QgsGeometryCollection >();
135 }
136 else if ( trimmed.startsWith( "PolyhedralSurface"_L1, Qt::CaseInsensitive ) )
137 {
138 geom = std::make_unique< QgsPolyhedralSurface >();
139 }
140 else if ( trimmed.startsWith( "TIN"_L1, Qt::CaseInsensitive ) )
141 {
142 geom = std::make_unique< QgsTriangulatedSurface >();
143 }
144 else if ( trimmed.startsWith( "NurbsCurve"_L1, Qt::CaseInsensitive ) )
145 {
146 geom = std::make_unique< QgsNurbsCurve >();
147 }
148
149 if ( geom )
150 {
151 if ( !geom->fromWkt( text ) )
152 {
153 return nullptr;
154 }
155 }
156 return geom;
157}
158
159std::unique_ptr< QgsAbstractGeometry > QgsGeometryFactory::fromPointXY( const QgsPointXY &point )
160{
161 return std::make_unique< QgsPoint >( point.x(), point.y() );
162}
163
164std::unique_ptr<QgsMultiPoint> QgsGeometryFactory::fromMultiPointXY( const QgsMultiPointXY &multipoint )
165{
166 auto mp = std::make_unique< QgsMultiPoint >();
167 QgsMultiPointXY::const_iterator ptIt = multipoint.constBegin();
168 mp->reserve( multipoint.size() );
169 for ( ; ptIt != multipoint.constEnd(); ++ptIt )
170 {
171 QgsPoint *pt = new QgsPoint( ptIt->x(), ptIt->y() );
172 mp->addGeometry( pt );
173 }
174 return mp;
175}
176
177std::unique_ptr<QgsAbstractGeometry> QgsGeometryFactory::fromPolylineXY( const QgsPolylineXY &polyline )
178{
179 return linestringFromPolyline( polyline );
180}
181
182std::unique_ptr<QgsMultiLineString> QgsGeometryFactory::fromMultiPolylineXY( const QgsMultiPolylineXY &multiline )
183{
184 auto mLine = std::make_unique< QgsMultiLineString >();
185 mLine->reserve( multiline.size() );
186 for ( int i = 0; i < multiline.size(); ++i )
187 {
188 mLine->addGeometry( fromPolylineXY( multiline.at( i ) ).release() );
189 }
190 return mLine;
191}
192
193std::unique_ptr<QgsPolygon> QgsGeometryFactory::fromPolygonXY( const QgsPolygonXY &polygon )
194{
195 auto poly = std::make_unique< QgsPolygon >();
196
197 QVector<QgsCurve *> holes;
198 holes.reserve( polygon.size() );
199 for ( int i = 0; i < polygon.size(); ++i )
200 {
201 std::unique_ptr< QgsLineString > l = linestringFromPolyline( polygon.at( i ) );
202 l->close();
203
204 if ( i == 0 )
205 {
206 poly->setExteriorRing( l.release() );
207 }
208 else
209 {
210 holes.push_back( l.release() );
211 }
212 }
213 poly->setInteriorRings( holes );
214 return poly;
215}
216
217std::unique_ptr< QgsMultiPolygon > QgsGeometryFactory::fromMultiPolygonXY( const QgsMultiPolygonXY &multipoly )
218{
219 auto mp = std::make_unique< QgsMultiPolygon >();
220 mp->reserve( multipoly.size() );
221 for ( int i = 0; i < multipoly.size(); ++i )
222 {
223 mp->addGeometry( fromPolygonXY( multipoly.at( i ) ).release() );
224 }
225 return mp;
226}
227
228std::unique_ptr<QgsLineString> QgsGeometryFactory::linestringFromPolyline( const QgsPolylineXY &polyline )
229{
230 const int size = polyline.size();
231 QVector< double > x;
232 x.resize( size );
233 QVector< double > y;
234 y.resize( size );
235 double *destX = x.data();
236 double *destY = y.data();
237 const QgsPointXY *src = polyline.data();
238 for ( int i = 0; i < size; ++i )
239 {
240 *destX++ = src->x();
241 *destY++ = src->y();
242 src++;
243 }
244 auto line = std::make_unique< QgsLineString >( x, y );
245 return line;
246}
247
248std::unique_ptr<QgsAbstractGeometry> QgsGeometryFactory::geomFromWkbType( Qgis::WkbType t )
249{
250 const Qgis::WkbType type = QgsWkbTypes::flatType( t );
251 switch ( type )
252 {
254 return std::make_unique< QgsPoint >();
256 return std::make_unique< QgsLineString >();
258 return std::make_unique< QgsCircularString >();
260 return std::make_unique< QgsCompoundCurve >();
262 return std::make_unique< QgsPolygon >();
264 return std::make_unique< QgsCurvePolygon >();
266 return std::make_unique< QgsMultiLineString >();
268 return std::make_unique< QgsMultiPolygon >();
270 return std::make_unique< QgsMultiPoint >();
272 return std::make_unique< QgsMultiCurve >();
274 return std::make_unique< QgsMultiSurface >();
276 return std::make_unique< QgsGeometryCollection >();
278 return std::make_unique< QgsTriangle >();
280 return std::make_unique< QgsPolyhedralSurface >();
282 return std::make_unique< QgsTriangulatedSurface >();
284 return std::make_unique< QgsNurbsCurve >();
285 default:
286 return nullptr;
287 }
288}
289
290std::unique_ptr<QgsGeometryCollection> QgsGeometryFactory::createCollectionOfType( Qgis::WkbType t )
291{
293 std::unique_ptr< QgsGeometryCollection > collect;
294 switch ( type )
295 {
297 collect = std::make_unique< QgsMultiPoint >();
298 break;
300 collect = std::make_unique< QgsMultiLineString >();
301 break;
303 collect = std::make_unique< QgsMultiCurve >();
304 break;
306 collect = std::make_unique< QgsMultiPolygon >();
307 break;
309 collect = std::make_unique< QgsMultiSurface >();
310 break;
312 collect = std::make_unique< QgsGeometryCollection >();
313 break;
314 default:
315 // should not be possible
316 return nullptr;
317 }
318 if ( QgsWkbTypes::hasM( t ) )
319 collect->addMValue();
320 if ( QgsWkbTypes::hasZ( t ) )
321 collect->addZValue();
322
323 return collect;
324}
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:280
@ CompoundCurve
CompoundCurve.
Definition qgis.h:291
@ Point
Point.
Definition qgis.h:282
@ LineString
LineString.
Definition qgis.h:283
@ TIN
TIN.
Definition qgis.h:296
@ MultiPoint
MultiPoint.
Definition qgis.h:286
@ Polygon
Polygon.
Definition qgis.h:284
@ MultiPolygon
MultiPolygon.
Definition qgis.h:288
@ Triangle
Triangle.
Definition qgis.h:285
@ NurbsCurve
NurbsCurve.
Definition qgis.h:297
@ MultiLineString
MultiLineString.
Definition qgis.h:287
@ Unknown
Unknown.
Definition qgis.h:281
@ CircularString
CircularString.
Definition qgis.h:290
@ GeometryCollection
GeometryCollection.
Definition qgis.h:289
@ MultiCurve
MultiCurve.
Definition qgis.h:293
@ CurvePolygon
CurvePolygon.
Definition qgis.h:292
@ PolyhedralSurface
PolyhedralSurface.
Definition qgis.h:295
@ MultiSurface
MultiSurface.
Definition qgis.h:294
A const WKB pointer.
Definition qgswkbptr.h:139
Qgis::WkbType readHeader() const
readHeader
Definition qgswkbptr.cpp:60
QString what() const
static std::unique_ptr< QgsMultiPolygon > fromMultiPolygonXY(const QgsMultiPolygonXY &multipoly)
Construct geometry from a multipolygon.
static std::unique_ptr< QgsAbstractGeometry > geomFromWkb(QgsConstWkbPtr &wkb)
Construct geometry from a WKB string.
static std::unique_ptr< QgsGeometryCollection > createCollectionOfType(Qgis::WkbType type)
Returns a new geometry collection matching a specified WKB type.
static std::unique_ptr< QgsAbstractGeometry > fromPolylineXY(const QgsPolylineXY &polyline)
Construct geometry from a polyline.
static std::unique_ptr< QgsMultiPoint > fromMultiPointXY(const QgsMultiPointXY &multipoint)
Construct geometry from a multipoint.
static std::unique_ptr< QgsAbstractGeometry > geomFromWkt(const QString &text)
Construct geometry from a WKT string.
static std::unique_ptr< QgsMultiLineString > fromMultiPolylineXY(const QgsMultiPolylineXY &multiline)
Construct geometry from a multipolyline.
static std::unique_ptr< QgsAbstractGeometry > fromPointXY(const QgsPointXY &point)
Construct geometry from a point.
static std::unique_ptr< QgsPolygon > fromPolygonXY(const QgsPolygonXY &polygon)
Construct geometry from a polygon.
static std::unique_ptr< QgsAbstractGeometry > geomFromWkbType(Qgis::WkbType t)
Returns empty geometry from wkb type.
Represents a 2D point.
Definition qgspointxy.h:62
double y
Definition qgspointxy.h:66
double x
Definition qgspointxy.h:65
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:53
Custom exception class for Wkb related exceptions.
Definition qgswkbptr.h:32
static Q_INVOKABLE bool hasZ(Qgis::WkbType type)
Tests whether a WKB type contains the z-dimension.
static Q_INVOKABLE bool hasM(Qgis::WkbType type)
Tests whether a WKB type contains m values.
static Qgis::WkbType multiType(Qgis::WkbType type)
Returns the multi type for a WKB type.
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
Definition qgsgeometry.h:63
QVector< QgsPolylineXY > QgsPolygonXY
QVector< QgsPolylineXY > QgsMultiPolylineXY
QVector< QgsPointXY > QgsMultiPointXY
QVector< QgsPointXY > QgsPolylineXY
QVector< QgsPolygonXY > QgsMultiPolygonXY
#define QgsDebugError(str)
Definition qgslogger.h:59