QGIS API Documentation 4.1.0-Master (64029b4150b)
Loading...
Searching...
No Matches
qgssfcgalgeometry.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgssfcgalGeometry.cpp
3 ----------------
4 begin : May 2025
5 copyright : (C) 2025 by Oslandia
6 email : benoit dot de dot mezzo at oslandia dot com
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#ifdef WITH_SFCGAL
19
20#include "qgssfcgalgeometry.h"
21
22#include "qgsvector3d.h"
23#include "qgswkbptr.h"
24
25#include <QByteArray>
26#include <QString>
27
28using namespace Qt::StringLiterals;
29
30QgsSfcgalGeometry::QgsSfcgalGeometry()
31 : mIsPrimitive( false )
32{}
33
34QgsSfcgalGeometry::QgsSfcgalGeometry( const QgsAbstractGeometry *qgsGeom )
35 : mIsPrimitive( false )
36{
37 if ( qgsGeom )
38 {
39 QString errorMsg;
40 sfcgal::errorHandler()->clearText( &errorMsg );
41 mSfcgalGeom = QgsSfcgalEngine::fromAbstractGeometry( qgsGeom, &errorMsg );
42 THROW_ON_ERROR( &errorMsg );
43 }
44}
45
46QgsSfcgalGeometry::QgsSfcgalGeometry( const QgsAbstractGeometry &qgsGeom )
47 : mIsPrimitive( false )
48{
49 QString errorMsg;
50 sfcgal::errorHandler()->clearText( &errorMsg );
51 mSfcgalGeom = QgsSfcgalEngine::fromAbstractGeometry( &qgsGeom, &errorMsg );
52 THROW_ON_ERROR( &errorMsg );
53}
54
55QgsSfcgalGeometry::QgsSfcgalGeometry( sfcgal::shared_geom sfcgalGeom )
56 : mSfcgalGeom( sfcgalGeom )
57 , mIsPrimitive( false )
58{}
59
60QgsSfcgalGeometry::QgsSfcgalGeometry( sfcgal::shared_prim sfcgalPrim, sfcgal::primitiveType type )
61 : mIsPrimitive( true )
62{
63#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
64 mSfcgalPrim = sfcgalPrim;
65 mPrimType = type;
66#else
67 ( void ) sfcgalPrim;
68 ( void ) type;
69 throw QgsNotSupportedException( QObject::tr( "This operation requires a QGIS build based on SFCGAL 2.3 or later" ) );
70#endif
71}
72
73QgsSfcgalGeometry::QgsSfcgalGeometry( const QgsGeometry &qgsGeom )
74{
75 QString errorMsg;
76 sfcgal::errorHandler()->clearText( &errorMsg );
77 mSfcgalGeom = QgsSfcgalEngine::fromAbstractGeometry( qgsGeom.constGet(), &errorMsg );
78 THROW_ON_ERROR( &errorMsg );
79}
80
81QgsSfcgalGeometry::QgsSfcgalGeometry( const QgsSfcgalGeometry &otherGeom )
82{
83 QString errorMsg;
84 sfcgal::errorHandler()->clearText( &errorMsg );
85 mIsPrimitive = otherGeom.mIsPrimitive;
86#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
87 mPrimType = otherGeom.mPrimType;
88 mPrimTransform = otherGeom.mPrimTransform;
89 if ( mIsPrimitive )
90 mSfcgalPrim = QgsSfcgalEngine::primitiveClone( otherGeom.mSfcgalPrim.get(), &errorMsg );
91 else
92#endif
93 mSfcgalGeom = QgsSfcgalEngine::cloneGeometry( otherGeom.mSfcgalGeom.get(), &errorMsg );
94 THROW_ON_ERROR( &errorMsg );
95}
96
97QgsSfcgalGeometry::QgsSfcgalGeometry( const QString &wkt )
98{
99 QString errorMsg;
100 sfcgal::errorHandler()->clearText( &errorMsg );
101 mSfcgalGeom = QgsSfcgalEngine::fromWkt( wkt, &errorMsg );
102 THROW_ON_ERROR( &errorMsg );
103}
104
105sfcgal::shared_geom QgsSfcgalGeometry::workingGeom() const
106{
107 sfcgal::shared_geom geom;
108
109#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
110 if ( mIsPrimitive )
111 {
112 QString errorMsg;
113 geom = QgsSfcgalEngine::primitiveAsPolyhedral( mSfcgalPrim.get(), mPrimTransform, &errorMsg );
114 THROW_ON_ERROR( &errorMsg );
115 }
116 else
117#endif
118 geom = mSfcgalGeom;
119
120 return geom;
121}
122
123
124Qgis::WkbType QgsSfcgalGeometry::wkbType() const
125{
126 QString errorMsg;
127 sfcgal::errorHandler()->clearText( &errorMsg );
128
129#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
130 if ( mIsPrimitive )
132#endif
133
134 Qgis::WkbType out = QgsSfcgalEngine::wkbType( mSfcgalGeom.get(), &errorMsg );
135 THROW_ON_ERROR( &errorMsg );
136 return out;
137}
138
139QString QgsSfcgalGeometry::geometryType() const
140{
141 QString errorMsg;
142 sfcgal::errorHandler()->clearText( &errorMsg );
143
144 QString out;
145#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
146 if ( mIsPrimitive )
147 {
148 switch ( mPrimType )
149 {
150 case sfcgal::primitiveType::SFCGAL_TYPE_CYLINDER:
151 out = "cylinder";
152 break;
153 case sfcgal::primitiveType::SFCGAL_TYPE_SPHERE:
154 out = "sphere";
155 break;
156 case sfcgal::primitiveType::SFCGAL_TYPE_TORUS:
157 out = "torus";
158 break;
159 case sfcgal::primitiveType::SFCGAL_TYPE_BOX:
160 out = "box";
161 break;
162 case sfcgal::primitiveType::SFCGAL_TYPE_CUBE:
163 out = "cube";
164 break;
165 case sfcgal::primitiveType::SFCGAL_TYPE_CONE:
166 out = "cone";
167 break;
168 default:
169 sfcgal::errorHandler()->addText( u"Type '%1' is unknown."_s.arg( mPrimType ) );
170 }
171 }
172 else
173#endif
174 {
175 out = QgsSfcgalEngine::geometryType( mSfcgalGeom.get(), &errorMsg );
176 THROW_ON_ERROR( &errorMsg );
177 }
178 return out;
179}
180
181std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::clone() const
182{
183 return std::make_unique<QgsSfcgalGeometry>( *this );
184}
185
186std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::fromWkb( const QgsConstWkbPtr &wkbPtr )
187{
188 if ( !wkbPtr )
189 {
190 return nullptr;
191 }
192
193 QString errorMsg;
194 sfcgal::shared_geom sfcgalGeom = QgsSfcgalEngine::fromWkb( wkbPtr, &errorMsg );
195 THROW_ON_ERROR( &errorMsg );
196
197 return std::make_unique<QgsSfcgalGeometry>( sfcgalGeom );
198}
199
200
201QByteArray QgsSfcgalGeometry::asWkb( QgsAbstractGeometry::WkbFlags ) const
202{
203 QString errorMsg;
204 sfcgal::errorHandler()->clearText( &errorMsg );
205
206 sfcgal::shared_geom geom = workingGeom();
207 QByteArray wkbArray = QgsSfcgalEngine::toWkb( geom.get(), &errorMsg );
208 THROW_ON_ERROR( &errorMsg );
209
210 return wkbArray;
211}
212
213QString QgsSfcgalGeometry::asWkt( int precision ) const
214{
215 QString errorMsg;
216 sfcgal::errorHandler()->clearText( &errorMsg );
217
218 sfcgal::shared_geom geom = workingGeom();
219 QString out = QgsSfcgalEngine::toWkt( geom.get(), precision, &errorMsg );
220 THROW_ON_ERROR( &errorMsg );
221
222 return out;
223}
224
225std::unique_ptr<QgsAbstractGeometry> QgsSfcgalGeometry::asQgisGeometry() const
226{
227 QString errorMsg;
228 sfcgal::errorHandler()->clearText( &errorMsg );
229
230 sfcgal::shared_geom geom = workingGeom();
231 std::unique_ptr<QgsAbstractGeometry> out = QgsSfcgalEngine::toAbstractGeometry( geom.get(), &errorMsg );
232 THROW_ON_ERROR( &errorMsg );
233 return out;
234}
235
236std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::boundary() const
237{
238 QString errorMsg;
239 sfcgal::errorHandler()->clearText( &errorMsg );
240
241 sfcgal::shared_geom geom = workingGeom();
242 sfcgal::shared_geom boundary = QgsSfcgalEngine::boundary( geom.get(), &errorMsg );
243 THROW_ON_ERROR( &errorMsg );
244
245 std::unique_ptr<QgsSfcgalGeometry> resultGeom = QgsSfcgalEngine::toSfcgalGeometry( boundary, &errorMsg );
246 THROW_ON_ERROR( &errorMsg );
247 return resultGeom;
248}
249
250bool QgsSfcgalGeometry::operator==( const QgsSfcgalGeometry &other ) const
251{
252#if SFCGAL_VERSION_NUM < SFCGAL_MAKE_VERSION( 2, 1, 0 )
253 ( void ) other;
254 throw QgsNotSupportedException( QObject::tr( "This operation requires a QGIS build based on SFCGAL 2.1 or later" ) );
255#else
256 QString errorMsg;
257 sfcgal::errorHandler()->clearText( &errorMsg );
258 bool out;
259
260#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
261 if ( mIsPrimitive != other.mIsPrimitive )
262 return false;
263
264 if ( mIsPrimitive )
265 {
266 if ( mPrimTransform != other.mPrimTransform )
267 {
268 return false;
269 }
270 out = QgsSfcgalEngine::primitiveIsEqual( mSfcgalPrim.get(), other.mSfcgalPrim.get(), -1.0, &errorMsg );
271 }
272 else
273#endif
274 {
275 out = QgsSfcgalEngine::isEqual( mSfcgalGeom.get(), other.mSfcgalGeom.get(), -1.0, &errorMsg );
276 }
277 THROW_ON_ERROR( &errorMsg );
278 return out;
279#endif
280}
281
282bool QgsSfcgalGeometry::operator!=( const QgsSfcgalGeometry &other ) const
283{
284 return !( *this == other );
285}
286
287bool QgsSfcgalGeometry::fuzzyEqual( const QgsSfcgalGeometry &other, double epsilon ) const
288{
289 QString errorMsg;
290 sfcgal::errorHandler()->clearText( &errorMsg );
291
292 bool out;
293
294#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
295 if ( mIsPrimitive != other.mIsPrimitive )
296 return false;
297
298 if ( mIsPrimitive )
299 {
300 if ( !mPrimTransform.fuzzyEqual( other.mPrimTransform, epsilon ) )
301 {
302 return false;
303 }
304 out = QgsSfcgalEngine::primitiveIsEqual( mSfcgalPrim.get(), other.mSfcgalPrim.get(), epsilon, &errorMsg );
305 }
306 else
307#endif
308 {
309 out = QgsSfcgalEngine::isEqual( mSfcgalGeom.get(), other.mSfcgalGeom.get(), epsilon, &errorMsg );
310 }
311
312 THROW_ON_ERROR( &errorMsg );
313 return out;
314}
315
316int QgsSfcgalGeometry::dimension() const
317{
318 QString errorMsg;
319 sfcgal::errorHandler()->clearText( &errorMsg );
320
321 if ( mIsPrimitive )
322 return 3;
323
324 int result = QgsSfcgalEngine::dimension( mSfcgalGeom.get(), &errorMsg );
325 THROW_ON_ERROR( &errorMsg );
326
327 return result;
328}
329
330std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::fromWkt( const QString &wkt )
331{
332 QString errorMsg;
333
334 sfcgal::shared_geom sfcgalGeom = QgsSfcgalEngine::fromWkt( wkt, &errorMsg );
335 THROW_ON_ERROR( &errorMsg );
336
337 return std::make_unique<QgsSfcgalGeometry>( sfcgalGeom );
338}
339
340int QgsSfcgalGeometry::partCount() const
341{
342 QString errorMsg;
343 sfcgal::errorHandler()->clearText( &errorMsg );
344
345 if ( mIsPrimitive )
346 return 1;
347
348 int out = QgsSfcgalEngine::partCount( mSfcgalGeom.get(), &errorMsg );
349 THROW_ON_ERROR( &errorMsg );
350
351 return out;
352}
353
354bool QgsSfcgalGeometry::addZValue( double zValue )
355{
356 QString errorMsg;
357 sfcgal::errorHandler()->clearText( &errorMsg );
358
359 if ( mIsPrimitive )
360 throw QgsNotSupportedException( QObject::tr( "Operation '%1' does not apply to primitive." ).arg( "addZValue" ) );
361
362 const bool added = QgsSfcgalEngine::addZValue( mSfcgalGeom.get(), zValue, &errorMsg );
363 THROW_ON_ERROR( &errorMsg );
364
365 clearCache();
366
367 return added;
368}
369
370bool QgsSfcgalGeometry::addMValue( double mValue )
371{
372 QString errorMsg;
373 sfcgal::errorHandler()->clearText( &errorMsg );
374
375 if ( mIsPrimitive )
376 throw QgsNotSupportedException( QObject::tr( "Operation '%1' does not apply to primitive." ).arg( "addMValue" ) );
377
378 const bool added = QgsSfcgalEngine::addMValue( mSfcgalGeom.get(), mValue, &errorMsg );
379 THROW_ON_ERROR( &errorMsg );
380
381 clearCache();
382
383 return added;
384}
385
386bool QgsSfcgalGeometry::dropZValue()
387{
388 QString errorMsg;
389 sfcgal::errorHandler()->clearText( &errorMsg );
390
391 if ( mIsPrimitive )
392 throw QgsNotSupportedException( QObject::tr( "Operation '%1' does not apply to primitive." ).arg( "dropZValue" ) );
393
394 const bool dropped = QgsSfcgalEngine::dropZValue( mSfcgalGeom.get(), &errorMsg );
395 THROW_ON_ERROR( &errorMsg );
396
397 clearCache();
398
399 return dropped;
400}
401
402bool QgsSfcgalGeometry::dropMValue()
403{
404 QString errorMsg;
405 sfcgal::errorHandler()->clearText( &errorMsg );
406
407 if ( mIsPrimitive )
408 throw QgsNotSupportedException( QObject::tr( "Operation '%1' does not apply to primitive." ).arg( "dropMValue" ) );
409
410 const bool dropped = QgsSfcgalEngine::dropMValue( mSfcgalGeom.get(), &errorMsg );
411 THROW_ON_ERROR( &errorMsg );
412
413 clearCache();
414
415 return dropped;
416}
417
418void QgsSfcgalGeometry::swapXy()
419{
420 QString errorMsg;
421 sfcgal::errorHandler()->clearText( &errorMsg );
422
423 if ( mIsPrimitive )
424 throw QgsNotSupportedException( QObject::tr( "Operation '%1' does not apply to primitive." ).arg( "swapXy" ) );
425
426 QgsSfcgalEngine::swapXy( mSfcgalGeom.get(), &errorMsg );
427 THROW_ON_ERROR( &errorMsg );
428
429 clearCache();
430}
431
432bool QgsSfcgalGeometry::isValid() const
433{
434 QString errorMsg;
435 sfcgal::errorHandler()->clearText( &errorMsg );
436
437 if ( mIsPrimitive )
438 return true;
439
440 const bool valid = QgsSfcgalEngine::isValid( mSfcgalGeom.get(), &errorMsg, nullptr );
441 THROW_ON_ERROR( &errorMsg );
442 return valid;
443}
444
445void QgsSfcgalGeometry::clearCache() const
446{}
447
448bool QgsSfcgalGeometry::isSimple() const
449{
450 QString errorMsg;
451 sfcgal::errorHandler()->clearText( &errorMsg );
452
453 if ( mIsPrimitive )
454 return true;
455
456 bool result = QgsSfcgalEngine::isSimple( mSfcgalGeom.get(), &errorMsg );
457 THROW_ON_ERROR( &errorMsg );
458 return result;
459}
460
461std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::geometryN( unsigned int index ) const
462{
463 QString errorMsg;
464 sfcgal::errorHandler()->clearText( &errorMsg );
465
466 sfcgal::shared_geom geom = workingGeom();
467 sfcgal::shared_geom result = QgsSfcgalEngine::geometryN( geom.get(), index );
468 THROW_ON_ERROR( &errorMsg );
469
470 std::unique_ptr<QgsSfcgalGeometry> resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, &errorMsg );
471 THROW_ON_ERROR( &errorMsg );
472 return resultGeom;
473}
474
475QgsPoint QgsSfcgalGeometry::centroid() const
476{
477 QString errorMsg;
478 sfcgal::errorHandler()->clearText( &errorMsg );
479
480 sfcgal::shared_geom geom = workingGeom();
481 return QgsSfcgalEngine::centroid( geom.get(), &errorMsg );
482}
483
484bool QgsSfcgalGeometry::isEmpty() const
485{
486 QString errorMsg;
487 sfcgal::errorHandler()->clearText( &errorMsg );
488
489 if ( mIsPrimitive )
490 return false;
491
492 bool result = QgsSfcgalEngine::isEmpty( mSfcgalGeom.get(), &errorMsg );
493 THROW_ON_ERROR( &errorMsg );
494
495 return result;
496}
497
498std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::translate( const QgsVector3D &translation ) const
499{
500 QString errorMsg;
501 sfcgal::errorHandler()->clearText( &errorMsg );
502
503 std::unique_ptr<QgsSfcgalGeometry> resultGeom;
504#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
505 if ( mIsPrimitive )
506 {
507 resultGeom = clone();
508 resultGeom->setPrimitiveTranslate( translation );
509 }
510 else
511#endif
512 {
513 sfcgal::shared_geom result = QgsSfcgalEngine::translate( mSfcgalGeom.get(), translation, &errorMsg );
514 THROW_ON_ERROR( &errorMsg );
515 resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, &errorMsg );
516 }
517
518 THROW_ON_ERROR( &errorMsg );
519 return resultGeom;
520}
521
522std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::scale( const QgsVector3D &scaleFactor, const QgsPoint &center ) const
523{
524 QString errorMsg;
525 sfcgal::errorHandler()->clearText( &errorMsg );
526
527 std::unique_ptr<QgsSfcgalGeometry> resultGeom;
528#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
529 if ( mIsPrimitive )
530 {
531 resultGeom = clone();
532 resultGeom->setPrimitiveScale( scaleFactor, center );
533 }
534 else
535#endif
536 {
537 sfcgal::shared_geom result = QgsSfcgalEngine::scale( mSfcgalGeom.get(), scaleFactor, center, &errorMsg );
538 THROW_ON_ERROR( &errorMsg );
539 resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, &errorMsg );
540 }
541
542 THROW_ON_ERROR( &errorMsg );
543 return resultGeom;
544}
545
546std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::rotate2D( double angle, const QgsPoint &center ) const
547{
548 QString errorMsg;
549 sfcgal::errorHandler()->clearText( &errorMsg );
550
551 std::unique_ptr<QgsSfcgalGeometry> resultGeom;
552#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
553 if ( mIsPrimitive )
554 {
555 resultGeom = clone();
556 resultGeom->setPrimitiveRotation( angle, { 0.0, 0.0, 1.0 }, center );
557 }
558 else
559#endif
560 {
561 sfcgal::shared_geom result = QgsSfcgalEngine::rotate2D( mSfcgalGeom.get(), angle, center, &errorMsg );
562 THROW_ON_ERROR( &errorMsg );
563
564 resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, &errorMsg );
565 }
566
567 THROW_ON_ERROR( &errorMsg );
568 return resultGeom;
569}
570
571std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::transform( const QgsMatrix4x4 &mat ) const
572{
573 QString errorMsg;
574 sfcgal::errorHandler()->clearText( &errorMsg );
575
576#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
577 sfcgal::shared_geom geom = workingGeom();
578
579 sfcgal::shared_geom result = QgsSfcgalEngine::transform( geom.get(), mat );
580 THROW_ON_ERROR( &errorMsg );
581
582 std::unique_ptr<QgsSfcgalGeometry> resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, &errorMsg );
583 THROW_ON_ERROR( &errorMsg );
584 return resultGeom;
585#else
586 ( void ) mat;
587 throw QgsNotSupportedException( QObject::tr( "This operation requires a QGIS build based on SFCGAL 2.3 or later" ) );
588#endif
589}
590
591std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::rotate3D( double angle, const QgsVector3D &axisVector, const QgsPoint &center ) const
592{
593 QString errorMsg;
594 sfcgal::errorHandler()->clearText( &errorMsg );
595
596 std::unique_ptr<QgsSfcgalGeometry> resultGeom;
597#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
598 if ( mIsPrimitive )
599 {
600 resultGeom = clone();
601 resultGeom->setPrimitiveRotation( angle, axisVector, center );
602 }
603 else
604#endif
605 {
606 sfcgal::shared_geom result = QgsSfcgalEngine::rotate3D( mSfcgalGeom.get(), angle, axisVector, center, &errorMsg );
607 THROW_ON_ERROR( &errorMsg );
608
609 resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, &errorMsg );
610 }
611
612 THROW_ON_ERROR( &errorMsg );
613 return resultGeom;
614}
615
616double QgsSfcgalGeometry::area( bool withDiscretization ) const
617{
618 QString errorMsg;
619 sfcgal::errorHandler()->clearText( &errorMsg );
620
621 double result;
622#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
623 if ( mIsPrimitive )
624 {
625 result = QgsSfcgalEngine::primitiveArea( mSfcgalPrim.get(), mPrimTransform, withDiscretization, &errorMsg );
626 }
627 else
628#endif
629 {
630 ( void ) withDiscretization;
631 result = QgsSfcgalEngine::area( mSfcgalGeom.get(), &errorMsg );
632 }
633
634 THROW_ON_ERROR( &errorMsg );
635 return result;
636}
637
638double QgsSfcgalGeometry::length() const
639{
640 QString errorMsg;
641 sfcgal::errorHandler()->clearText( &errorMsg );
642
643 if ( mIsPrimitive )
644 throw QgsNotSupportedException( QObject::tr( "Operation '%1' does not apply to primitive." ).arg( "length" ) );
645
646 double result = QgsSfcgalEngine::length( mSfcgalGeom.get(), &errorMsg );
647 THROW_ON_ERROR( &errorMsg );
648
649 return result;
650}
651
652double QgsSfcgalGeometry::volume( bool withDiscretization ) const
653{
654 QString errorMsg;
655 sfcgal::errorHandler()->clearText( &errorMsg );
656
657 if ( !mIsPrimitive )
658 throw QgsNotSupportedException( QObject::tr( "Operation '%1' does not apply to geometry." ).arg( "volume" ) );
659
660 double result;
661#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
662 result = QgsSfcgalEngine::primitiveVolume( mSfcgalPrim.get(), mPrimTransform, withDiscretization, &errorMsg );
663#else
664 ( void ) withDiscretization;
665 throw QgsNotSupportedException( QObject::tr( "This operation requires a QGIS build based on SFCGAL 2.3 or later" ) );
666#endif
667
668 THROW_ON_ERROR( &errorMsg );
669 return result;
670}
671
672bool QgsSfcgalGeometry::intersects( const QgsAbstractGeometry *otherGeom ) const
673{
674 QString errorMsg;
675 sfcgal::errorHandler()->clearText( &errorMsg );
676 sfcgal::shared_geom otherShared = QgsSfcgalEngine::fromAbstractGeometry( otherGeom, &errorMsg );
677 THROW_ON_ERROR( &errorMsg );
678
679 sfcgal::shared_geom geom = workingGeom();
680 bool out = QgsSfcgalEngine::intersects( geom.get(), otherShared.get(), &errorMsg );
681 THROW_ON_ERROR( &errorMsg );
682 return out;
683}
684
685bool QgsSfcgalGeometry::intersects( const QgsSfcgalGeometry &otherGeom ) const
686{
687 QString errorMsg;
688 sfcgal::errorHandler()->clearText( &errorMsg );
689
690 sfcgal::shared_geom geom = workingGeom();
691 bool out = QgsSfcgalEngine::intersects( geom.get(), otherGeom.workingGeom().get(), &errorMsg );
692 THROW_ON_ERROR( &errorMsg );
693 return out;
694}
695
696std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::intersection( const QgsAbstractGeometry *otherGeom ) const
697{
698 QString errorMsg;
699 sfcgal::errorHandler()->clearText( &errorMsg );
700 sfcgal::shared_geom otherShared = QgsSfcgalEngine::fromAbstractGeometry( otherGeom, &errorMsg );
701 THROW_ON_ERROR( &errorMsg );
702
703 sfcgal::shared_geom geom = workingGeom();
704 sfcgal::shared_geom result = QgsSfcgalEngine::intersection( geom.get(), otherShared.get(), &errorMsg );
705 THROW_ON_ERROR( &errorMsg );
706
707 std::unique_ptr<QgsSfcgalGeometry> resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, &errorMsg );
708 THROW_ON_ERROR( &errorMsg );
709 return resultGeom;
710}
711
712std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::intersection( const QgsSfcgalGeometry &otherGeom ) const
713{
714 QString errorMsg;
715 sfcgal::errorHandler()->clearText( &errorMsg );
716
717 sfcgal::shared_geom geom = workingGeom();
718 sfcgal::shared_geom result = QgsSfcgalEngine::intersection( geom.get(), otherGeom.workingGeom().get(), &errorMsg );
719 THROW_ON_ERROR( &errorMsg );
720
721 std::unique_ptr<QgsSfcgalGeometry> resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, &errorMsg );
722 THROW_ON_ERROR( &errorMsg );
723 return resultGeom;
724}
725
726std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::combine( const QVector<QgsAbstractGeometry *> &geomList ) const
727{
728 QString errorMsg;
729 sfcgal::errorHandler()->clearText( &errorMsg );
730 QVector<sfcgal::shared_geom> sfcgalGeomList;
731
732 sfcgal::shared_geom geom = workingGeom();
733 sfcgalGeomList.append( geom );
734 for ( QVector<QgsAbstractGeometry *>::const_iterator ite = geomList.constBegin(); ite != geomList.constEnd(); ++ite )
735 {
736 sfcgal::shared_geom otherShared = QgsSfcgalEngine::fromAbstractGeometry( *ite, &errorMsg );
737 THROW_ON_ERROR( &errorMsg );
738 sfcgalGeomList.append( otherShared );
739 }
740
741 sfcgal::shared_geom result = QgsSfcgalEngine::combine( sfcgalGeomList, &errorMsg );
742 THROW_ON_ERROR( &errorMsg );
743
744 std::unique_ptr<QgsSfcgalGeometry> resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, &errorMsg );
745 THROW_ON_ERROR( &errorMsg );
746 return resultGeom;
747}
748
749std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::difference( const QgsAbstractGeometry *otherGeom ) const
750{
751 QString errorMsg;
752 sfcgal::errorHandler()->clearText( &errorMsg );
753 sfcgal::shared_geom otherSharedr = QgsSfcgalEngine::fromAbstractGeometry( otherGeom, &errorMsg );
754 THROW_ON_ERROR( &errorMsg );
755
756 sfcgal::shared_geom geom = workingGeom();
757 sfcgal::shared_geom result = QgsSfcgalEngine::difference( geom.get(), otherSharedr.get(), &errorMsg );
758 THROW_ON_ERROR( &errorMsg );
759
760 std::unique_ptr<QgsSfcgalGeometry> resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, &errorMsg );
761 THROW_ON_ERROR( &errorMsg );
762 return resultGeom;
763}
764
765std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::difference( const QgsSfcgalGeometry &otherGeom ) const
766{
767 QString errorMsg;
768 sfcgal::errorHandler()->clearText( &errorMsg );
769
770 sfcgal::shared_geom geom = workingGeom();
771 sfcgal::shared_geom result = QgsSfcgalEngine::difference( geom.get(), otherGeom.workingGeom().get(), &errorMsg );
772 THROW_ON_ERROR( &errorMsg );
773
774 std::unique_ptr<QgsSfcgalGeometry> resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, &errorMsg );
775 THROW_ON_ERROR( &errorMsg );
776 return resultGeom;
777}
778
779std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::triangulate() const
780{
781 QString errorMsg;
782 sfcgal::errorHandler()->clearText( &errorMsg );
783
784 sfcgal::shared_geom geom = workingGeom();
785 sfcgal::shared_geom result = QgsSfcgalEngine::triangulate( geom.get(), &errorMsg );
786 THROW_ON_ERROR( &errorMsg );
787
788 std::unique_ptr<QgsSfcgalGeometry> resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, &errorMsg );
789 THROW_ON_ERROR( &errorMsg );
790 return resultGeom;
791}
792
793std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::convexHull() const
794{
795 QString errorMsg;
796 sfcgal::errorHandler()->clearText( &errorMsg );
797
798 sfcgal::shared_geom geom = workingGeom();
799 sfcgal::shared_geom result = QgsSfcgalEngine::convexHull( geom.get(), &errorMsg );
800 THROW_ON_ERROR( &errorMsg );
801
802 std::unique_ptr<QgsSfcgalGeometry> resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, &errorMsg );
803 THROW_ON_ERROR( &errorMsg );
804 return resultGeom;
805}
806
807std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::envelope() const
808{
809 QString errorMsg;
810 sfcgal::errorHandler()->clearText( &errorMsg );
811
812 sfcgal::shared_geom geom = workingGeom();
813 sfcgal::shared_geom result = QgsSfcgalEngine::envelope( geom.get(), &errorMsg );
814 THROW_ON_ERROR( &errorMsg );
815
816 std::unique_ptr<QgsSfcgalGeometry> resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, &errorMsg );
817 THROW_ON_ERROR( &errorMsg );
818 return resultGeom;
819}
820
821bool QgsSfcgalGeometry::covers( const QgsSfcgalGeometry &otherGeom ) const
822{
823 QString errorMsg;
824 sfcgal::errorHandler()->clearText( &errorMsg );
825
826 sfcgal::shared_geom geom = workingGeom();
827 bool out = QgsSfcgalEngine::covers( geom.get(), otherGeom.workingGeom().get(), &errorMsg );
828 THROW_ON_ERROR( &errorMsg );
829 return out;
830}
831
832std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::buffer3D( double radius, int segments, Qgis::JoinStyle3D joinStyle3D ) const
833{
834 QString errorMsg;
835 sfcgal::errorHandler()->clearText( &errorMsg );
836
837 sfcgal::shared_geom geom = workingGeom();
838 sfcgal::shared_geom result = QgsSfcgalEngine::buffer3D( geom.get(), radius, segments, joinStyle3D, &errorMsg );
839 THROW_ON_ERROR( &errorMsg );
840
841 std::unique_ptr<QgsSfcgalGeometry> resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, &errorMsg );
842 THROW_ON_ERROR( &errorMsg );
843 return resultGeom;
844}
845
846std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::buffer2D( double radius, int segments, Qgis::JoinStyle joinStyle ) const
847{
848 QString errorMsg;
849 sfcgal::errorHandler()->clearText( &errorMsg );
850
851 sfcgal::shared_geom geom = workingGeom();
852 sfcgal::shared_geom result = QgsSfcgalEngine::buffer2D( geom.get(), radius, segments, joinStyle, &errorMsg );
853 THROW_ON_ERROR( &errorMsg );
854
855 std::unique_ptr<QgsSfcgalGeometry> resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, &errorMsg );
856 THROW_ON_ERROR( &errorMsg );
857 return resultGeom;
858}
859
860std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::simplify( double tolerance, bool preserveTopology ) const
861{
862 QString errorMsg;
863 sfcgal::errorHandler()->clearText( &errorMsg );
864
865 sfcgal::shared_geom geom = workingGeom();
866 sfcgal::shared_geom result = QgsSfcgalEngine::simplify( geom.get(), tolerance, preserveTopology, &errorMsg );
867 THROW_ON_ERROR( &errorMsg );
868
869 std::unique_ptr<QgsSfcgalGeometry> resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, &errorMsg );
870 THROW_ON_ERROR( &errorMsg );
871 return resultGeom;
872}
873
874std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::extrude( const QgsVector3D &extrusion ) const
875{
876 QString errorMsg;
877 sfcgal::errorHandler()->clearText( &errorMsg );
878
879 sfcgal::shared_geom geom = workingGeom();
880 sfcgal::shared_geom result = QgsSfcgalEngine::extrude( geom.get(), extrusion, &errorMsg );
881 THROW_ON_ERROR( &errorMsg );
882
883 std::unique_ptr<QgsSfcgalGeometry> resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, &errorMsg );
884 THROW_ON_ERROR( &errorMsg );
885 return resultGeom;
886}
887
888std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::approximateMedialAxis( bool extendToEdges ) const
889{
890 QString errorMsg;
891 sfcgal::errorHandler()->clearText( &errorMsg );
892
893 sfcgal::shared_geom geom = workingGeom();
894 sfcgal::shared_geom result = QgsSfcgalEngine::approximateMedialAxis( geom.get(), extendToEdges, &errorMsg );
895 THROW_ON_ERROR( &errorMsg );
896
897 std::unique_ptr<QgsSfcgalGeometry> resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, &errorMsg );
898 THROW_ON_ERROR( &errorMsg );
899 return resultGeom;
900}
901
902std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::toSolid() const
903{
904 QString errorMsg;
905 sfcgal::errorHandler()->clearText( &errorMsg );
906
907 sfcgal::shared_geom geom = workingGeom();
908 sfcgal::shared_geom solid = QgsSfcgalEngine::toSolid( geom.get(), &errorMsg );
909 THROW_ON_ERROR( &errorMsg );
910
911 std::unique_ptr<QgsSfcgalGeometry> solidGeom = QgsSfcgalEngine::toSfcgalGeometry( solid, &errorMsg );
912 THROW_ON_ERROR( &errorMsg );
913 return solidGeom;
914}
915
916std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::split3D( const QgsPoint &planePoint, const QgsVector3D &planeNormal, bool closeGeometries ) const
917{
918 QString errorMsg;
919 sfcgal::errorHandler()->clearText( &errorMsg );
920
921#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
922 sfcgal::shared_geom geom = workingGeom();
923
924 sfcgal::shared_geom result = QgsSfcgalEngine::split3D( geom.get(), planePoint, planeNormal, closeGeometries );
925 THROW_ON_ERROR( &errorMsg );
926
927 std::unique_ptr<QgsSfcgalGeometry> resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, &errorMsg );
928 THROW_ON_ERROR( &errorMsg );
929 return resultGeom;
930#else
931 Q_UNUSED( planePoint )
932 Q_UNUSED( planeNormal )
933 Q_UNUSED( closeGeometries )
934 throw QgsNotSupportedException( QObject::tr( "This operation requires a QGIS build based on SFCGAL 2.3 or later" ) );
935#endif
936}
937
938std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::toPolyhedralSurface() const
939{
940 QString errorMsg;
941 sfcgal::errorHandler()->clearText( &errorMsg );
942
943 sfcgal::shared_geom geom = workingGeom();
944 sfcgal::shared_geom phs = QgsSfcgalEngine::toPolyhedralSurface( geom.get(), &errorMsg );
945 THROW_ON_ERROR( &errorMsg );
946
947 std::unique_ptr<QgsSfcgalGeometry> phsGeom = QgsSfcgalEngine::toSfcgalGeometry( phs, &errorMsg );
948 THROW_ON_ERROR( &errorMsg );
949 return phsGeom;
950}
951
952std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::createBox( double sizeX, double sizeY, double sizeZ )
953{
954#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
955 QString errorMsg;
956 sfcgal::errorHandler()->clearText( &errorMsg );
957 sfcgal::shared_prim result = QgsSfcgalEngine::createBox( sizeX, sizeY, sizeZ, &errorMsg );
958 THROW_ON_ERROR( &errorMsg );
959
960 auto resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, sfcgal::primitiveType::SFCGAL_TYPE_BOX, &errorMsg );
961 THROW_ON_ERROR( &errorMsg );
962 return resultGeom;
963#else
964 ( void ) sizeX;
965 ( void ) sizeY;
966 ( void ) sizeZ;
967 throw QgsNotSupportedException( QObject::tr( "This operation requires a QGIS build based on SFCGAL 2.3 or later" ) );
968#endif
969}
970
971std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::createCone( double bottomRadius, double height, double topRadius, unsigned int radial )
972{
973#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
974 QString errorMsg;
975 sfcgal::errorHandler()->clearText( &errorMsg );
976 sfcgal::shared_prim result = QgsSfcgalEngine::createCone( bottomRadius, height, topRadius, radial, &errorMsg );
977 THROW_ON_ERROR( &errorMsg );
978
979 auto resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, sfcgal::primitiveType::SFCGAL_TYPE_CONE, &errorMsg );
980 THROW_ON_ERROR( &errorMsg );
981 return resultGeom;
982#else
983 ( void ) bottomRadius;
984 ( void ) height;
985 ( void ) topRadius;
986 ( void ) radial;
987 throw QgsNotSupportedException( QObject::tr( "This operation requires a QGIS build based on SFCGAL 2.3 or later" ) );
988#endif
989}
990
991std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::createCube( double size )
992{
993#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
994 QString errorMsg;
995 sfcgal::errorHandler()->clearText( &errorMsg );
996 sfcgal::shared_prim result = QgsSfcgalEngine::createCube( size, &errorMsg );
997 THROW_ON_ERROR( &errorMsg );
998
999 std::unique_ptr<QgsSfcgalGeometry> resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, sfcgal::primitiveType::SFCGAL_TYPE_CUBE, &errorMsg );
1000 THROW_ON_ERROR( &errorMsg );
1001 return resultGeom;
1002#else
1003 ( void ) size;
1004 throw QgsNotSupportedException( QObject::tr( "This operation requires a QGIS build based on SFCGAL 2.3 or later" ) );
1005#endif
1006}
1007
1008std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::createCylinder( double radius, double height, unsigned int radial )
1009{
1010#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
1011 QString errorMsg;
1012 sfcgal::errorHandler()->clearText( &errorMsg );
1013 sfcgal::shared_prim result = QgsSfcgalEngine::createCylinder( radius, height, radial, &errorMsg );
1014 THROW_ON_ERROR( &errorMsg );
1015
1016 auto resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, sfcgal::primitiveType::SFCGAL_TYPE_CYLINDER, &errorMsg );
1017 THROW_ON_ERROR( &errorMsg );
1018 return resultGeom;
1019#else
1020 ( void ) radius;
1021 ( void ) height;
1022 ( void ) radial;
1023 throw QgsNotSupportedException( QObject::tr( "This operation requires a QGIS build based on SFCGAL 2.3 or later" ) );
1024#endif
1025}
1026
1027std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::createSphere( double radius, unsigned int subdivisions )
1028{
1029#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
1030 QString errorMsg;
1031 sfcgal::errorHandler()->clearText( &errorMsg );
1032 sfcgal::shared_prim result = QgsSfcgalEngine::createSphere( radius, subdivisions, &errorMsg );
1033 THROW_ON_ERROR( &errorMsg );
1034
1035 auto resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, sfcgal::primitiveType::SFCGAL_TYPE_SPHERE, &errorMsg );
1036 THROW_ON_ERROR( &errorMsg );
1037 return resultGeom;
1038#else
1039 ( void ) radius;
1040 ( void ) subdivisions;
1041 throw QgsNotSupportedException( QObject::tr( "This operation requires a QGIS build based on SFCGAL 2.3 or later" ) );
1042#endif
1043}
1044
1045std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::createTorus( double mainRadius, double tubeRadius, unsigned int mainRadial, unsigned int tubeRadial )
1046{
1047#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
1048 QString errorMsg;
1049 sfcgal::errorHandler()->clearText( &errorMsg );
1050 sfcgal::shared_prim result = QgsSfcgalEngine::createTorus( mainRadius, tubeRadius, mainRadial, tubeRadial, &errorMsg );
1051 THROW_ON_ERROR( &errorMsg );
1052
1053 auto resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, sfcgal::primitiveType::SFCGAL_TYPE_TORUS, &errorMsg );
1054 THROW_ON_ERROR( &errorMsg );
1055 return resultGeom;
1056#else
1057 ( void ) mainRadius;
1058 ( void ) tubeRadius;
1059 ( void ) mainRadial;
1060 ( void ) tubeRadial;
1061 throw QgsNotSupportedException( QObject::tr( "This operation requires a QGIS build based on SFCGAL 2.3 or later" ) );
1062#endif
1063}
1064
1065std::unique_ptr<QgsSfcgalGeometry> QgsSfcgalGeometry::primitiveAsPolyhedralSurface() const
1066{
1067#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
1068 if ( !mIsPrimitive )
1069 throw QgsSfcgalException( "Need primitive geometry to operate." );
1070
1071 QString errorMsg;
1072 sfcgal::errorHandler()->clearText( &errorMsg );
1073 sfcgal::shared_prim result = QgsSfcgalEngine::primitiveAsPolyhedral( mSfcgalPrim.get(), mPrimTransform, &errorMsg );
1074 THROW_ON_ERROR( &errorMsg );
1075
1076 std::unique_ptr<QgsSfcgalGeometry> resultGeom = QgsSfcgalEngine::toSfcgalGeometry( result, &errorMsg );
1077 THROW_ON_ERROR( &errorMsg );
1078 return resultGeom;
1079#else
1080 throw QgsNotSupportedException( QObject::tr( "This operation requires a QGIS build based on SFCGAL 2.3 or later" ) );
1081#endif
1082}
1083
1084QgsMatrix4x4 QgsSfcgalGeometry::primitiveTransform() const
1085{
1086#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
1087 if ( !mIsPrimitive )
1088 throw QgsSfcgalException( "Need primitive geometry to operate." );
1089
1090 return mPrimTransform;
1091#else
1092 throw QgsNotSupportedException( QObject::tr( "This operation requires a QGIS build based on SFCGAL 2.3 or later" ) );
1093#endif
1094}
1095
1096QList<std::pair<QString, QString>> QgsSfcgalGeometry::primitiveParameters() const
1097{
1098#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
1099 if ( !mIsPrimitive )
1100 throw QgsSfcgalException( "Need primitive geometry to operate." );
1101
1102 QString errorMsg;
1103 sfcgal::errorHandler()->clearText( &errorMsg );
1104 QVector<sfcgal::PrimitiveParameterDesc> result = QgsSfcgalEngine::primitiveParameters( mSfcgalPrim.get(), &errorMsg );
1105 THROW_ON_ERROR( &errorMsg );
1106
1107 QList<QPair<QString, QString>> out;
1108 for ( const auto &param : result )
1109 {
1110 out.append( std::pair<QString, QString>( QString::fromStdString( param.name ), QString::fromStdString( param.type ) ) );
1111 }
1112
1113 return out;
1114#else
1115 throw QgsNotSupportedException( QObject::tr( "This operation requires a QGIS build based on SFCGAL 2.3 or later" ) );
1116#endif
1117}
1118
1119QVariant QgsSfcgalGeometry::primitiveParameter( const QString &name ) const
1120{
1121#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
1122 if ( !mIsPrimitive )
1123 throw QgsSfcgalException( "Need primitive geometry to operate." );
1124
1125 QString errorMsg;
1126 sfcgal::errorHandler()->clearText( &errorMsg );
1127 QVariant result = QgsSfcgalEngine::primitiveParameter( mSfcgalPrim.get(), name, &errorMsg );
1128 THROW_ON_ERROR( &errorMsg );
1129
1130 return result;
1131#else
1132 ( void ) name;
1133 throw QgsNotSupportedException( QObject::tr( "This operation requires a QGIS build based on SFCGAL 2.3 or later" ) );
1134#endif
1135}
1136
1137void QgsSfcgalGeometry::primitiveSetParameter( const QString &name, const QVariant &value )
1138{
1139#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
1140 if ( !mIsPrimitive )
1141 throw QgsSfcgalException( "Need primitive geometry to operate." );
1142
1143 QString errorMsg;
1144 sfcgal::errorHandler()->clearText( &errorMsg );
1145 QgsSfcgalEngine::primitiveSetParameter( mSfcgalPrim.get(), name, value, &errorMsg );
1146 THROW_ON_ERROR( &errorMsg );
1147
1148#else
1149 ( void ) name;
1150 ( void ) value;
1151 throw QgsNotSupportedException( QObject::tr( "This operation requires a QGIS build based on SFCGAL 2.3 or later" ) );
1152#endif
1153}
1154
1155
1156#if SFCGAL_VERSION_NUM >= SFCGAL_MAKE_VERSION( 2, 3, 0 )
1157void QgsSfcgalGeometry::setPrimitiveTranslate( const QgsVector3D &translation )
1158{
1159 QgsMatrix4x4 mat;
1160 mat.translate( translation );
1161 mPrimTransform = mat * mPrimTransform;
1162}
1163
1164void QgsSfcgalGeometry::setPrimitiveScale( const QgsVector3D &scaleFactor, const QgsPoint &center )
1165{
1166 QgsVector3D qCenter;
1167 if ( center.isEmpty() )
1168 {
1169 qCenter = QgsVector3D( 0.0, 0.0, 0.0 );
1170 }
1171 else
1172 {
1173 qCenter = QgsVector3D( center.x(), center.y(), center.z() );
1174 }
1175
1176 QgsMatrix4x4 mat;
1177 mat.translate( qCenter );
1178 mat.scale( scaleFactor );
1179 mat.translate( -qCenter );
1180
1181 mPrimTransform = mat * mPrimTransform;
1182}
1183
1184void QgsSfcgalGeometry::setPrimitiveRotation( double angle, const QgsVector3D &axisVector, const QgsPoint &center )
1185{
1186 QgsVector3D qCenter;
1187 if ( center.isEmpty() )
1188 {
1189 qCenter = QgsVector3D( 0.0, 0.0, 0.0 );
1190 }
1191 else
1192 {
1193 qCenter = QgsVector3D( center.x(), center.y(), center.z() );
1194 }
1195
1196 QgsMatrix4x4 mat;
1197 mat.translate( qCenter );
1198 mat.rotate( angle * 180.0 / M_PI, axisVector );
1199 mat.translate( -qCenter );
1200
1201 mPrimTransform = mat * mPrimTransform;
1202}
1203
1204#endif
1205
1206#endif
JoinStyle3D
Join styles for 3D buffers.
Definition qgis.h:2255
JoinStyle
Join styles for buffers.
Definition qgis.h:2242
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:294
@ PolyhedralSurfaceZ
PolyhedralSurfaceZ.
Definition qgis.h:326
Abstract base class for all geometries.
QFlags< WkbFlag > WkbFlags
A const WKB pointer.
Definition qgswkbptr.h:211
A geometry is the spatial representation of a feature.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
A simple 4x4 matrix implementation useful for transformation in 3D space.
void scale(const QgsVector3D &vector)
Multiplies this matrix by another that scales coordinates by the components of a vector.
void translate(const QgsVector3D &vector)
Multiplies this matrix by another that translates coordinates by the components of a vector.
void rotate(double angle, double x, double y, double z)
Multiples this matrix by another that rotates coordinates through angle degrees about the vector (x,...
Custom exception class which is raised when an operation is not supported.
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:53
double z
Definition qgspoint.h:58
double x
Definition qgspoint.h:56
bool isEmpty() const override
Returns true if the geometry is empty.
Definition qgspoint.cpp:766
double y
Definition qgspoint.h:57
Custom exception class for SfCGAL related operations.
A 3D vector (similar to QVector3D) with the difference that it uses double precision instead of singl...
Definition qgsvector3d.h:33