QGIS API Documentation 3.99.0-Master (a8882ad4560)
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
38std::unique_ptr<QgsAbstractGeometry> QgsGeometryFactory::geomFromWkb( QgsConstWkbPtr &wkbPtr )
39{
40 if ( !wkbPtr )
41 return nullptr;
42
43 //find out type (bytes 2-5)
45 try
46 {
47 type = wkbPtr.readHeader();
48 }
49 catch ( const QgsWkbException &e )
50 {
51 Q_UNUSED( e )
52 QgsDebugError( "WKB exception while reading header: " + e.what() );
53 return nullptr;
54 }
55 wkbPtr -= 1 + sizeof( int );
56
57 std::unique_ptr< QgsAbstractGeometry > geom = geomFromWkbType( type );
58
59 if ( geom )
60 {
61 try
62 {
63 geom->fromWkb( wkbPtr ); // also updates wkbPtr
64 }
65 catch ( const QgsWkbException &e )
66 {
67 Q_UNUSED( e )
68 QgsDebugError( "WKB exception: " + e.what() );
69 geom.reset();
70 }
71 }
72
73 return geom;
74}
75
76std::unique_ptr<QgsAbstractGeometry> QgsGeometryFactory::geomFromWkt( const QString &text )
77{
78 const QString trimmed = text.trimmed();
79 std::unique_ptr< QgsAbstractGeometry> geom;
80 if ( trimmed.startsWith( "Point"_L1, Qt::CaseInsensitive ) )
81 {
82 geom = std::make_unique< QgsPoint >();
83 }
84 else if ( trimmed.startsWith( "LineString"_L1, Qt::CaseInsensitive ) )
85 {
86 geom = std::make_unique< QgsLineString >();
87 }
88 else if ( trimmed.startsWith( "CircularString"_L1, Qt::CaseInsensitive ) )
89 {
90 geom = std::make_unique< QgsCircularString >();
91 }
92 else if ( trimmed.startsWith( "CompoundCurve"_L1, Qt::CaseInsensitive ) )
93 {
94 geom = std::make_unique< QgsCompoundCurve>();
95 }
96 else if ( trimmed.startsWith( "Polygon"_L1, Qt::CaseInsensitive ) )
97 {
98 geom = std::make_unique< QgsPolygon >();
99 }
100 else if ( trimmed.startsWith( "Triangle"_L1, Qt::CaseInsensitive ) )
101 {
102 geom = std::make_unique< QgsTriangle >();
103 }
104 else if ( trimmed.startsWith( "CurvePolygon"_L1, Qt::CaseInsensitive ) )
105 {
106 geom = std::make_unique< QgsCurvePolygon >();
107 }
108 else if ( trimmed.startsWith( "MultiPoint"_L1, Qt::CaseInsensitive ) )
109 {
110 geom = std::make_unique< QgsMultiPoint >();
111 }
112 else if ( trimmed.startsWith( "MultiCurve"_L1, Qt::CaseInsensitive ) )
113 {
114 geom = std::make_unique< QgsMultiCurve >();
115 }
116 else if ( trimmed.startsWith( "MultiLineString"_L1, Qt::CaseInsensitive ) )
117 {
118 geom = std::make_unique< QgsMultiLineString >();
119 }
120 else if ( trimmed.startsWith( "MultiSurface"_L1, Qt::CaseInsensitive ) )
121 {
122 geom = std::make_unique< QgsMultiSurface >();
123 }
124 else if ( trimmed.startsWith( "MultiPolygon"_L1, Qt::CaseInsensitive ) )
125 {
126 geom = std::make_unique< QgsMultiPolygon >();
127 }
128 else if ( trimmed.startsWith( "GeometryCollection"_L1, Qt::CaseInsensitive ) )
129 {
130 geom = std::make_unique< QgsGeometryCollection >();
131 }
132 else if ( trimmed.startsWith( "PolyhedralSurface"_L1, Qt::CaseInsensitive ) )
133 {
134 geom = std::make_unique< QgsPolyhedralSurface >();
135 }
136 else if ( trimmed.startsWith( "TIN"_L1, Qt::CaseInsensitive ) )
137 {
138 geom = std::make_unique< QgsTriangulatedSurface >();
139 }
140 else if ( trimmed.startsWith( "NurbsCurve"_L1, Qt::CaseInsensitive ) )
141 {
142 geom = std::make_unique< QgsNurbsCurve >();
143 }
144
145 if ( geom )
146 {
147 if ( !geom->fromWkt( text ) )
148 {
149 return nullptr;
150 }
151 }
152 return geom;
153}
154
155std::unique_ptr< QgsAbstractGeometry > QgsGeometryFactory::fromPointXY( const QgsPointXY &point )
156{
157 return std::make_unique< QgsPoint >( point.x(), point.y() );
158}
159
160std::unique_ptr<QgsMultiPoint> QgsGeometryFactory::fromMultiPointXY( const QgsMultiPointXY &multipoint )
161{
162 auto mp = std::make_unique< QgsMultiPoint >();
163 QgsMultiPointXY::const_iterator ptIt = multipoint.constBegin();
164 mp->reserve( multipoint.size() );
165 for ( ; ptIt != multipoint.constEnd(); ++ptIt )
166 {
167 QgsPoint *pt = new QgsPoint( ptIt->x(), ptIt->y() );
168 mp->addGeometry( pt );
169 }
170 return mp;
171}
172
173std::unique_ptr<QgsAbstractGeometry> QgsGeometryFactory::fromPolylineXY( const QgsPolylineXY &polyline )
174{
175 return linestringFromPolyline( polyline );
176}
177
178std::unique_ptr<QgsMultiLineString> QgsGeometryFactory::fromMultiPolylineXY( const QgsMultiPolylineXY &multiline )
179{
180 auto mLine = std::make_unique< QgsMultiLineString >();
181 mLine->reserve( multiline.size() );
182 for ( int i = 0; i < multiline.size(); ++i )
183 {
184 mLine->addGeometry( fromPolylineXY( multiline.at( i ) ).release() );
185 }
186 return mLine;
187}
188
189std::unique_ptr<QgsPolygon> QgsGeometryFactory::fromPolygonXY( const QgsPolygonXY &polygon )
190{
191 auto poly = std::make_unique< QgsPolygon >();
192
193 QVector<QgsCurve *> holes;
194 holes.reserve( polygon.size() );
195 for ( int i = 0; i < polygon.size(); ++i )
196 {
197 std::unique_ptr< QgsLineString > l = linestringFromPolyline( polygon.at( i ) );
198 l->close();
199
200 if ( i == 0 )
201 {
202 poly->setExteriorRing( l.release() );
203 }
204 else
205 {
206 holes.push_back( l.release() );
207 }
208 }
209 poly->setInteriorRings( holes );
210 return poly;
211}
212
213std::unique_ptr< QgsMultiPolygon > QgsGeometryFactory::fromMultiPolygonXY( const QgsMultiPolygonXY &multipoly )
214{
215 auto mp = std::make_unique< QgsMultiPolygon >();
216 mp->reserve( multipoly.size() );
217 for ( int i = 0; i < multipoly.size(); ++i )
218 {
219 mp->addGeometry( fromPolygonXY( multipoly.at( i ) ).release() );
220 }
221 return mp;
222}
223
224std::unique_ptr<QgsLineString> QgsGeometryFactory::linestringFromPolyline( const QgsPolylineXY &polyline )
225{
226 const int size = polyline.size();
227 QVector< double > x;
228 x.resize( size );
229 QVector< double > y;
230 y.resize( size );
231 double *destX = x.data();
232 double *destY = y.data();
233 const QgsPointXY *src = polyline.data();
234 for ( int i = 0; i < size; ++i )
235 {
236 *destX++ = src->x();
237 *destY++ = src->y();
238 src++;
239 }
240 auto line = std::make_unique< QgsLineString >( x, y );
241 return line;
242}
243
244std::unique_ptr<QgsAbstractGeometry> QgsGeometryFactory::geomFromWkbType( Qgis::WkbType t )
245{
246 const Qgis::WkbType type = QgsWkbTypes::flatType( t );
247 switch ( type )
248 {
250 return std::make_unique< QgsPoint >();
252 return std::make_unique< QgsLineString >();
254 return std::make_unique< QgsCircularString >();
256 return std::make_unique< QgsCompoundCurve >();
258 return std::make_unique< QgsPolygon >();
260 return std::make_unique< QgsCurvePolygon >();
262 return std::make_unique< QgsMultiLineString >();
264 return std::make_unique< QgsMultiPolygon >();
266 return std::make_unique< QgsMultiPoint >();
268 return std::make_unique< QgsMultiCurve >();
270 return std::make_unique< QgsMultiSurface >();
272 return std::make_unique< QgsGeometryCollection >();
274 return std::make_unique< QgsTriangle >();
276 return std::make_unique< QgsPolyhedralSurface >();
278 return std::make_unique< QgsTriangulatedSurface >();
280 return std::make_unique< QgsNurbsCurve >();
281 default:
282 return nullptr;
283 }
284}
285
286std::unique_ptr<QgsGeometryCollection> QgsGeometryFactory::createCollectionOfType( Qgis::WkbType t )
287{
289 std::unique_ptr< QgsGeometryCollection > collect;
290 switch ( type )
291 {
293 collect = std::make_unique< QgsMultiPoint >();
294 break;
296 collect = std::make_unique< QgsMultiLineString >();
297 break;
299 collect = std::make_unique< QgsMultiCurve >();
300 break;
302 collect = std::make_unique< QgsMultiPolygon >();
303 break;
305 collect = std::make_unique< QgsMultiSurface >();
306 break;
308 collect = std::make_unique< QgsGeometryCollection >();
309 break;
310 default:
311 // should not be possible
312 return nullptr;
313 }
314 if ( QgsWkbTypes::hasM( t ) )
315 collect->addMValue();
316 if ( QgsWkbTypes::hasZ( t ) )
317 collect->addZValue();
318
319 return collect;
320}
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:56
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:60
double y
Definition qgspointxy.h:64
double x
Definition qgspointxy.h:63
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:49
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:61
QVector< QgsPolylineXY > QgsPolygonXY
QVector< QgsPolylineXY > QgsMultiPolylineXY
QVector< QgsPointXY > QgsMultiPointXY
QVector< QgsPointXY > QgsPolylineXY
QVector< QgsPolygonXY > QgsMultiPolygonXY
#define QgsDebugError(str)
Definition qgslogger.h:59