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