1 /***************************************************************************
2 qgis.h - QGIS namespace
3 -------------------
4 begin : Sat Jun 30 2002
5 copyright : (C) 2002 by Gary E.Sherman
6 email : sherman at mrcc.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 #ifndef QGIS_H
19 #define QGIS_H
20
21 #include <QMetaEnum>
22 #include <cfloat>
23 #include <memory>
24 #include <cmath>
25
26 #include "qgstolerance.h"
27 #include "qgis_core.h"
28 #include "qgis_sip.h"
29
30 #ifdef SIP_RUN
31 % ModuleHeaderCode
32 #include <qgis.h>
33 % End
34
35 % ModuleCode
36 int QgisEvent = QEvent::User + 1;
37 % End
38 #endif
39
40
41 /**
42 * \ingroup core
43 * \brief The Qgis class provides global constants for use throughout the application.
44 */
45 class CORE_EXPORT Qgis
46 {
47 Q_GADGET
48 public:
49
50 /**
51 * Version string.
52 *
53 * \since QGIS 3.12
54 */
55 static QString version();
56
57 /**
58 * Version number used for comparing versions using the "Check QGIS Version" function
59 *
60 * \since QGIS 3.12
61 */
62 static int versionInt();
63
64 /**
65 * Release name
66 *
67 * \since QGIS 3.12
68 */
69 static QString releaseName();
70
71 //! The development version
72 static const char *QGIS_DEV_VERSION;
73
74 /**
75 * The development version
76 *
77 * \since QGIS 3.12
78 */
79 static QString devVersion();
80
81 // Enumerations
82 //
83
84 /**
85 * \brief Level for messages
86 * This will be used both for message log and message bar in application.
87 */
88 enum MessageLevel
89 {
90 Info = 0,
91 Warning = 1,
92 Critical = 2,
93 Success = 3,
94 None = 4
95 };
96
97 /**
98 * Raster data types.
99 * This is modified and extended copy of GDALDataType.
100 */
101 enum DataType
102 {
103 UnknownDataType = 0, //!< Unknown or unspecified type
104 Byte = 1, //!< Eight bit unsigned integer (quint8)
105 UInt16 = 2, //!< Sixteen bit unsigned integer (quint16)
106 Int16 = 3, //!< Sixteen bit signed integer (qint16)
107 UInt32 = 4, //!< Thirty two bit unsigned integer (quint32)
108 Int32 = 5, //!< Thirty two bit signed integer (qint32)
109 Float32 = 6, //!< Thirty two bit floating point (float)
110 Float64 = 7, //!< Sixty four bit floating point (double)
111 CInt16 = 8, //!< Complex Int16
112 CInt32 = 9, //!< Complex Int32
113 CFloat32 = 10, //!< Complex Float32
114 CFloat64 = 11, //!< Complex Float64
115 ARGB32 = 12, //!< Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32
116 ARGB32_Premultiplied = 13 //!< Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied
117 };
118 Q_ENUM( DataType )
119
120 /**
121 * Authorisation to run Python Macros
122 * \since QGIS 3.10
123 */
124 enum PythonMacroMode
125 {
126 Never = 0, //!< Macros are never run
127 Ask = 1, //!< User is prompt before running
128 SessionOnly = 2, //!< Only during this session
129 Always = 3, //!< Macros are always run
130 NotForThisSession, //!< Macros will not be run for this session
131 };
132 Q_ENUM( PythonMacroMode )
133
134 /**
135 * Identify search radius in mm
136 * \since QGIS 2.3
137 */
138 static const double DEFAULT_SEARCH_RADIUS_MM;
139
140 //! Default threshold between map coordinates and device coordinates for map2pixel simplification
141 static const float DEFAULT_MAPTOPIXEL_THRESHOLD;
142
143 /**
144 * Default highlight color. The transparency is expected to only be applied to polygon
145 * fill. Lines and outlines are rendered opaque.
146 *
147 * \since QGIS 2.3
148 */
149 static const QColor DEFAULT_HIGHLIGHT_COLOR;
150
151 /**
152 * Default highlight buffer in mm.
153 * \since QGIS 2.3
154 */
155 static const double DEFAULT_HIGHLIGHT_BUFFER_MM;
156
157 /**
158 * Default highlight line/stroke minimum width in mm.
159 * \since QGIS 2.3
160 */
161 static const double DEFAULT_HIGHLIGHT_MIN_WIDTH_MM;
162
163 /**
164 * Fudge factor used to compare two scales. The code is often going from scale to scale
165 * denominator. So it looses precision and, when a limit is inclusive, can lead to errors.
166 * To avoid that, use this factor instead of using <= or >=.
167 * \since QGIS 2.15
168 */
169 static const double SCALE_PRECISION;
170
171 /**
172 * Default Z coordinate value for 2.5d geometry
173 * This value have to be assigned to the Z coordinate for the new 2.5d geometry vertex.
174 * \since QGIS 3.0
175 */
176 static const double DEFAULT_Z_COORDINATE;
177
178 /**
179 * UI scaling factor. This should be applied to all widget sizes obtained from font metrics,
180 * to account for differences in the default font sizes across different platforms.
181 * \since QGIS 3.0
182 */
183 static const double UI_SCALE_FACTOR;
184
185 /**
186 * Default snapping distance tolerance.
187 * \since QGIS 3.0
188 */
189 static const double DEFAULT_SNAP_TOLERANCE;
190
191 /**
192 * Default snapping distance units.
193 * \since QGIS 3.0
194 */
195 static const QgsTolerance::UnitType DEFAULT_SNAP_UNITS;
196
197 /**
198 * A string with default project scales.
199 *
200 * \since QGIS 3.12
201 */
202 static QString defaultProjectScales();
203 };
204
205 // hack to workaround warnings when casting void pointers
206 // retrieved from QLibrary::resolve to function pointers.
207 // It's assumed that this works on all systems supporting
208 // QLibrary
209 #define cast_to_fptr(f) f
210
211
212 /**
213 * \ingroup core
214 * \brief RAII signal blocking class. Used for temporarily blocking signals from a QObject
215 * for the lifetime of QgsSignalBlocker object.
216 * \see whileBlocking()
217 * \note not available in Python bindings
218 * \since QGIS 2.16
219 */
220 // based on Boojum's code from http://stackoverflow.com/questions/3556687/prevent-firing-signals-in-qt
221 template<class Object> class QgsSignalBlocker SIP_SKIP SIP_SKIP // clazy:exclude=rule-of-three
222 {
223 public:
224
225 /**
226 * Constructor for QgsSignalBlocker
227 * \param object QObject to block signals from
228 */
QgsSignalBlocker(Object * object)229 explicit QgsSignalBlocker( Object *object )
230 : mObject( object )
231 , mPreviousState( object->blockSignals( true ) )
232 {}
233
~QgsSignalBlocker()234 ~QgsSignalBlocker()
235 {
236 mObject->blockSignals( mPreviousState );
237 }
238
239 //! Returns pointer to blocked QObject
240 Object *operator->() { return mObject; }
241
242 private:
243
244 Object *mObject = nullptr;
245 bool mPreviousState;
246
247 };
248
249 /**
250 * Temporarily blocks signals from a QObject while calling a single method from the object.
251 *
252 * Usage:
253 * whileBlocking( checkBox )->setChecked( true );
254 * whileBlocking( spinBox )->setValue( 50 );
255 *
256 * No signals will be emitted when calling these methods.
257 *
258 * \see QgsSignalBlocker
259 * \note not available in Python bindings
260 * \since QGIS 2.16
261 */
262 // based on Boojum's code from http://stackoverflow.com/questions/3556687/prevent-firing-signals-in-qt
whileBlocking(Object * object)263 template<class Object> inline QgsSignalBlocker<Object> whileBlocking( Object *object ) SIP_SKIP SIP_SKIP
264 {
265 return QgsSignalBlocker<Object>( object );
266 }
267
268 //! Hash for QVariant
269 CORE_EXPORT uint qHash( const QVariant &variant );
270
271 /**
272 * Returns a string representation of a double
273 * \param a double value
274 * \param precision number of decimal places to retain
275 */
276 inline QString qgsDoubleToString( double a, int precision = 17 )
277 {
278 if ( precision )
279 {
280 QString str = QString::number( a, 'f', precision );
281 if ( str.contains( QLatin1Char( '.' ) ) )
282 {
283 // remove ending 0s
284 int idx = str.length() - 1;
285 while ( str.at( idx ) == '0' && idx > 1 )
286 {
287 idx--;
288 }
289 if ( idx < str.length() - 1 )
290 str.truncate( str.at( idx ) == '.' ? idx : idx + 1 );
291 }
292 return str;
293 }
294 else
295 {
296 // avoid printing -0
297 // see https://bugreports.qt.io/browse/QTBUG-71439
298 const QString str( QString::number( a, 'f', precision ) );
299 if ( str == QLatin1String( "-0" ) )
300 {
301 return QLatin1String( "0" );
302 }
303 else
304 {
305 return str;
306 }
307 }
308 }
309
310 /**
311 * Compare two doubles (but allow some difference)
312 * \param a first double
313 * \param b second double
314 * \param epsilon maximum difference allowable between doubles
315 */
316 inline bool qgsDoubleNear( double a, double b, double epsilon = 4 * std::numeric_limits<double>::epsilon() )
317 {
318 if ( std::isnan( a ) || std::isnan( b ) )
319 return std::isnan( a ) && std::isnan( b ) ;
320
321 const double diff = a - b;
322 return diff > -epsilon && diff <= epsilon;
323 }
324
325 /**
326 * Compare two floats (but allow some difference)
327 * \param a first float
328 * \param b second float
329 * \param epsilon maximum difference allowable between floats
330 */
331 inline bool qgsFloatNear( float a, float b, float epsilon = 4 * FLT_EPSILON )
332 {
333 if ( std::isnan( a ) || std::isnan( b ) )
334 return std::isnan( a ) && std::isnan( b ) ;
335
336 const float diff = a - b;
337 return diff > -epsilon && diff <= epsilon;
338 }
339
340 //! Compare two doubles using specified number of significant digits
341 inline bool qgsDoubleNearSig( double a, double b, int significantDigits = 10 )
342 {
343 if ( std::isnan( a ) || std::isnan( b ) )
344 return std::isnan( a ) && std::isnan( b ) ;
345
346 // The most simple would be to print numbers as %.xe and compare as strings
347 // but that is probably too costly
348 // Then the fastest would be to set some bits directly, but little/big endian
349 // has to be considered (maybe TODO)
350 // Is there a better way?
351 int aexp, bexp;
352 double ar = std::frexp( a, &aexp );
353 double br = std::frexp( b, &bexp );
354
355 return aexp == bexp &&
356 std::round( ar * std::pow( 10.0, significantDigits ) ) == std::round( br * std::pow( 10.0, significantDigits ) );
357 }
358
359 /**
360 * Returns a double \a number, rounded (as close as possible) to the specified number of \a places.
361 *
362 * \since QGIS 3.0
363 */
qgsRound(double number,int places)364 inline double qgsRound( double number, int places )
365 {
366 double m = ( number < 0.0 ) ? -1.0 : 1.0;
367 double scaleFactor = std::pow( 10.0, places );
368 return ( std::round( number * m * scaleFactor ) / scaleFactor ) * m;
369 }
370
371
372 #ifndef SIP_RUN
373
374 ///@cond PRIVATE
375
376 /**
377 * Contains "polyfills" for backporting c++ features from standards > c++11 and Qt global methods
378 * added later than our minimum version.
379 *
380 * To be removed when minimum c++ or Qt build requirement includes the std implementation
381 * for these features.
382 *
383 * \note not available in Python bindings.
384 */
385 namespace qgis
386 {
387 // as_const
388
389 /**
390 * Adds const to non-const objects.
391 *
392 * To be used as a proxy for std::as_const until we target c++17 minimum.
393 *
394 * \note not available in Python bindings
395 * \since QGIS 3.0
396 */
397 template <typename T> struct QgsAddConst { typedef const T Type; };
398
399 template <typename T>
as_const(T & t)400 constexpr typename QgsAddConst<T>::Type &as_const( T &t ) noexcept { return t; }
401
402 template <typename T>
403 void as_const( const T && ) = delete;
404
405 // make_unique - from https://stackoverflow.com/a/17902439/1861260
406
407 template<class T> struct _Unique_if
408 {
409 typedef std::unique_ptr<T> _Single_object;
410 };
411
412 template<class T> struct _Unique_if<T[]>
413 {
414 typedef std::unique_ptr<T[]> _Unknown_bound;
415 };
416
417 template<class T, size_t N> struct _Unique_if<T[N]>
418 {
419 typedef void _Known_bound;
420 };
421
422 template<class T, class... Args>
423 typename _Unique_if<T>::_Single_object
424 make_unique( Args &&... args )
425 {
426 return std::unique_ptr<T>( new T( std::forward<Args>( args )... ) );
427 }
428
429 template<class T>
430 typename _Unique_if<T>::_Unknown_bound
431 make_unique( size_t n )
432 {
433 typedef typename std::remove_extent<T>::type U;
434 return std::unique_ptr<T>( new U[n]() );
435 }
436
437 template<class T, class... Args>
438 typename _Unique_if<T>::_Known_bound
439 make_unique( Args &&... ) = delete;
440
441 /**
442 * Used for new-style Qt connects to overloaded signals, avoiding the usual horrible connect syntax required
443 * in these circumstances.
444 *
445 * Example usage:
446 *
447 * connect( mSpinBox, qgis::overload< int >::of( &QSpinBox::valueChanged ), this, &MyClass::mySlot );
448 *
449 * This is an alternative to qOverload, which was implemented in Qt 5.7.
450 *
451 * See https://stackoverflow.com/a/16795664/1861260
452 */
453 template<typename... Args> struct overload
454 {
455 template<typename C, typename R>
456 static constexpr auto of( R( C::*pmf )( Args... ) ) -> decltype( pmf )
457 {
458 return pmf;
459 }
460 };
461
462 template<class T>
463 QSet<T> listToSet( const QList<T> &list )
464 {
465 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
466 return list.toSet();
467 #else
468 return QSet<T>( list.begin(), list.end() );
469 #endif
470 }
471
472 template<class T>
473 QList<T> setToList( const QSet<T> &set )
474 {
475 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
476 return set.toList();
477 #else
478 return QList<T>( set.begin(), set.end() );
479 #endif
480 }
481 }
482 ///@endcond
483 #endif
484
485 /**
486 * Returns a map of all enum entries.
487 * The map has the enum values (int) as keys and the enum keys (QString) as values.
488 * The enum must have been declared using Q_ENUM or Q_FLAG.
489 */
490 template<class T> const QMap<T, QString> qgsEnumMap() SIP_SKIP
491 {
492 QMetaEnum metaEnum = QMetaEnum::fromType<T>();
493 Q_ASSERT( metaEnum.isValid() );
494 QMap<T, QString> enumMap;
495 for ( int idx = 0; idx < metaEnum.keyCount(); ++idx )
496 {
497 const char *enumKey = metaEnum.key( idx );
498 enumMap.insert( static_cast<T>( metaEnum.keyToValue( enumKey ) ), QString( enumKey ) );
499 }
500 return enumMap;
501 }
502
503 /**
504 * Returns the value for the given key of an enum.
505 * \since QGIS 3.6
506 */
507 template<class T> QString qgsEnumValueToKey( const T &value ) SIP_SKIP
508 {
509 QMetaEnum metaEnum = QMetaEnum::fromType<T>();
510 Q_ASSERT( metaEnum.isValid() );
511 return QString::fromUtf8( metaEnum.valueToKey( static_cast<int>( value ) ) );
512 }
513
514 /**
515 * Returns the value corresponding to the given \a key of an enum.
516 * If the key is invalid, it will return the \a defaultValue.
517 * If \a tryValueAsKey is TRUE, it will try to convert the string key to an enum value
518 * \since QGIS 3.6
519 */
520 template<class T> T qgsEnumKeyToValue( const QString &key, const T &defaultValue, bool tryValueAsKey = true ) SIP_SKIP
521 {
522 QMetaEnum metaEnum = QMetaEnum::fromType<T>();
523 Q_ASSERT( metaEnum.isValid() );
524 bool ok = false;
525 T v = static_cast<T>( metaEnum.keyToValue( key.toUtf8().data(), &ok ) );
526 if ( ok )
527 {
528 return v;
529 }
530 else
531 {
532 // if conversion has failed, try with conversion from int value
533 if ( tryValueAsKey )
534 {
535 bool canConvert = false;
536 int intValue = key.toInt( &canConvert );
537 if ( canConvert && metaEnum.valueToKey( intValue ) )
538 {
539 return static_cast<T>( intValue );
540 }
541 }
542 }
543 return defaultValue;
544 }
545
546 /**
547 * Returns the value for the given keys of a flag.
548 * \since QGIS 3.16
549 */
550 template<class T> QString qgsFlagValueToKeys( const T &value ) SIP_SKIP
551 {
552 QMetaEnum metaEnum = QMetaEnum::fromType<T>();
553 Q_ASSERT( metaEnum.isValid() );
554 return QString::fromUtf8( metaEnum.valueToKeys( static_cast<int>( value ) ) );
555 }
556
557 /**
558 * Returns the value corresponding to the given \a keys of a flag.
559 * If the keys are invalid, it will return the \a defaultValue.
560 * \since QGIS 3.16
561 */
562 template<class T> T qgsFlagKeysToValue( const QString &keys, const T &defaultValue ) SIP_SKIP
563 {
564 QMetaEnum metaEnum = QMetaEnum::fromType<T>();
565 Q_ASSERT( metaEnum.isValid() );
566 bool ok = false;
567 T v = static_cast<T>( metaEnum.keysToValue( keys.toUtf8().constData(), &ok ) );
568 if ( ok )
569 return v;
570 else
571 return defaultValue;
572 }
573
574
575 /**
576 * Converts a string to a double in a permissive way, e.g., allowing for incorrect
577 * numbers of digits between thousand separators
578 * \param string string to convert
579 * \param ok will be set to TRUE if conversion was successful
580 * \returns string converted to double if possible
581 * \see permissiveToInt
582 * \since QGIS 2.9
583 */
584 CORE_EXPORT double qgsPermissiveToDouble( QString string, bool &ok );
585
586 /**
587 * Converts a string to an integer in a permissive way, e.g., allowing for incorrect
588 * numbers of digits between thousand separators
589 * \param string string to convert
590 * \param ok will be set to TRUE if conversion was successful
591 * \returns string converted to int if possible
592 * \see permissiveToDouble
593 * \since QGIS 2.9
594 */
595 CORE_EXPORT int qgsPermissiveToInt( QString string, bool &ok );
596
597 /**
598 * Converts a string to an qlonglong in a permissive way, e.g., allowing for incorrect
599 * numbers of digits between thousand separators
600 * \param string string to convert
601 * \param ok will be set to TRUE if conversion was successful
602 * \returns string converted to int if possible
603 * \see permissiveToInt
604 * \since QGIS 3.4
605 */
606 CORE_EXPORT qlonglong qgsPermissiveToLongLong( QString string, bool &ok );
607
608 /**
609 * Compares two QVariant values and returns whether the first is less than the second.
610 * Useful for sorting lists of variants, correctly handling sorting of the various
611 * QVariant data types (such as strings, numeric values, dates and times)
612 *
613 * Invalid < NULL < Values
614 *
615 * \see qgsVariantGreaterThan()
616 */
617 CORE_EXPORT bool qgsVariantLessThan( const QVariant &lhs, const QVariant &rhs );
618
619 /**
620 * Compares two QVariant values and returns whether they are equal, two NULL values are
621 * always treated as equal and 0 is not treated as equal with NULL
622 *
623 * \param lhs first value
624 * \param rhs second value
625 * \return TRUE if values are equal
626 */
627 CORE_EXPORT bool qgsVariantEqual( const QVariant &lhs, const QVariant &rhs );
628
629
630 /**
631 * Compares two QVariant values and returns whether the first is greater than the second.
632 * Useful for sorting lists of variants, correctly handling sorting of the various
633 * QVariant data types (such as strings, numeric values, dates and times)
634 * \see qgsVariantLessThan()
635 */
636 CORE_EXPORT bool qgsVariantGreaterThan( const QVariant &lhs, const QVariant &rhs );
637
638 /**
639 * Compares two QVariantList values and returns whether the first is less than the second.
640 */
641 template<> CORE_EXPORT bool qMapLessThanKey<QVariantList>( const QVariantList &key1, const QVariantList &key2 ) SIP_SKIP;
642
643
644 CORE_EXPORT QString qgsVsiPrefix( const QString &path );
645
646 /**
647 * Allocates size bytes and returns a pointer to the allocated memory.
648 * Works like C malloc() but prints debug message by QgsLogger if allocation fails.
649 * \param size size in bytes
650 */
651 void CORE_EXPORT *qgsMalloc( size_t size ) SIP_SKIP;
652
653 /**
654 * Allocates memory for an array of nmemb elements of size bytes each and returns
655 * a pointer to the allocated memory. Works like C calloc() but prints debug message
656 * by QgsLogger if allocation fails.
657 * \param nmemb number of elements
658 * \param size size of element in bytes
659 */
660 void CORE_EXPORT *qgsCalloc( size_t nmemb, size_t size ) SIP_SKIP;
661
662 /**
663 * Frees the memory space pointed to by ptr. Works like C free().
664 * \param ptr pointer to memory space
665 */
666 void CORE_EXPORT qgsFree( void *ptr ) SIP_SKIP;
667
668 #ifndef SIP_RUN
669
670 #ifdef _MSC_VER
671 #define CONSTLATIN1STRING inline const QLatin1String
672 #else
673 #define CONSTLATIN1STRING constexpr QLatin1String
674 #endif
675
676 /**
677 * Wkt string that represents a geographic coord sys
678 * \since QGIS GEOWkt
679 */
680 CONSTLATIN1STRING geoWkt()
681 {
682 #if PROJ_VERSION_MAJOR>=6
683 return QLatin1String(
684 R"""(GEOGCRS["WGS 84",DATUM["World Geodetic System 1984",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["unknown"],AREA["World"],BBOX[-90,-180,90,180]],ID["EPSG",4326]] )"""
685 );
686 #else
687 return QLatin1String(
688 "GEOGCS[\"WGS 84\", "
689 " DATUM[\"WGS_1984\", "
690 " SPHEROID[\"WGS 84\",6378137,298.257223563, "
691 " AUTHORITY[\"EPSG\",\"7030\"]], "
692 " TOWGS84[0,0,0,0,0,0,0], "
693 " AUTHORITY[\"EPSG\",\"6326\"]], "
694 " PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]], "
695 " UNIT[\"DMSH\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9108\"]], "
696 " AXIS[\"Lat\",NORTH], "
697 " AXIS[\"Long\",EAST], "
698 " AUTHORITY[\"EPSG\",\"4326\"]]"
699 );
700 #endif
701 }
702
703 //! PROJ4 string that represents a geographic coord sys
704 CONSTLATIN1STRING geoProj4()
705 {
706 return QLatin1String( "+proj=longlat +datum=WGS84 +no_defs" );
707 }
708
709 //! Geographic coord sys from EPSG authority
710 CONSTLATIN1STRING geoEpsgCrsAuthId()
711 {
712 return QLatin1String( "EPSG:4326" );
713 }
714
715 //! Constant that holds the string representation for "No ellips/No CRS"
716 CONSTLATIN1STRING geoNone()
717 {
718 return QLatin1String( "NONE" );
719 }
720
721 ///@cond PRIVATE
722
723 //! Delay between the scheduling of 2 preview jobs
724 const int PREVIEW_JOB_DELAY_MS = 250;
725
726 //! Maximum rendering time for a layer of a preview job
727 const int MAXIMUM_LAYER_PREVIEW_TIME_MS = 250;
728
729 ///@endcond
730
731 #endif
732
733 //! Magic number for a geographic coord sys in POSTGIS SRID
734 const long GEOSRID = 4326;
735
736 //! Magic number for a geographic coord sys in QGIS srs.db tbl_srs.srs_id
737 const long GEOCRS_ID = 3452;
738
739 //! Magic number for a geographic coord sys in EpsgCrsId ID format
740 const long GEO_EPSG_CRS_ID = 4326;
741
742 /**
743 * Magick number that determines whether a projection crsid is a system (srs.db)
744 * or user (~/.qgis.qgis.db) defined projection.
745 */
746 const int USER_CRS_START_ID = 100000;
747
748 //
749 // Constants for point symbols
750 //
751
752 //! Magic number that determines the default point size for point symbols
753 const double DEFAULT_POINT_SIZE = 2.0;
754 const double DEFAULT_LINE_WIDTH = 0.26;
755
756 //! Default snapping tolerance for segments
757 const double DEFAULT_SEGMENT_EPSILON = 1e-8;
758
759 typedef QMap<QString, QString> QgsStringMap SIP_SKIP;
760
761 /**
762 * Qgssize is used instead of size_t, because size_t is stdlib type, unknown
763 * by SIP, and it would be hard to define size_t correctly in SIP.
764 * Currently used "unsigned long long" was introduced in C++11 (2011)
765 * but it was supported already before C++11 on common platforms.
766 * "unsigned long long int" gives syntax error in SIP.
767 * KEEP IN SYNC WITH qgssize defined in SIP!
768 */
769 typedef unsigned long long qgssize;
770
771 #ifndef SIP_RUN
772 #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) || defined(__clang__)
773
774 #define Q_NOWARN_DEPRECATED_PUSH \
775 _Pragma("GCC diagnostic push") \
776 _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"");
777 #define Q_NOWARN_DEPRECATED_POP \
778 _Pragma("GCC diagnostic pop");
779 #define Q_NOWARN_UNREACHABLE_PUSH
780 #define Q_NOWARN_UNREACHABLE_POP
781
782 #elif defined(_MSC_VER)
783
784 #define Q_NOWARN_DEPRECATED_PUSH \
785 __pragma(warning(push)) \
786 __pragma(warning(disable:4996))
787 #define Q_NOWARN_DEPRECATED_POP \
788 __pragma(warning(pop))
789 #define Q_NOWARN_UNREACHABLE_PUSH \
790 __pragma(warning(push)) \
791 __pragma(warning(disable:4702))
792 #define Q_NOWARN_UNREACHABLE_POP \
793 __pragma(warning(pop))
794
795 #else
796
797 #define Q_NOWARN_DEPRECATED_PUSH
798 #define Q_NOWARN_DEPRECATED_POP
799 #define Q_NOWARN_UNREACHABLE_PUSH
800 #define Q_NOWARN_UNREACHABLE_POP
801
802 #endif
803 #endif
804
805 #ifndef QGISEXTERN
806 #ifdef Q_OS_WIN
807 # define QGISEXTERN extern "C" __declspec( dllexport )
808 # ifdef _MSC_VER
809 // do not warn about C bindings returning QString
810 # pragma warning(disable:4190)
811 # endif
812 #else
813 # if defined(__GNUC__) || defined(__clang__)
814 # define QGISEXTERN extern "C" __attribute__ ((visibility ("default")))
815 # else
816 # define QGISEXTERN extern "C"
817 # endif
818 #endif
819 #endif
820 #endif
821
822 #if __cplusplus >= 201500
823 #define FALLTHROUGH [[fallthrough]];
824 #elif defined(__clang__)
825 #define FALLTHROUGH [[clang::fallthrough]];
826 #elif defined(__GNUC__) && __GNUC__ >= 7
827 #define FALLTHROUGH [[gnu::fallthrough]];
828 #else
829 #define FALLTHROUGH
830 #endif
831
832 // see https://infektor.net/posts/2017-01-19-using-cpp17-attributes-today.html#using-the-nodiscard-attribute
833 #if __cplusplus >= 201703L
834 #define NODISCARD [[nodiscard]]
835 #elif defined(__clang__)
836 #define NODISCARD [[nodiscard]]
837 #elif defined(_MSC_VER)
838 #define NODISCARD // no support
839 #elif defined(__has_cpp_attribute)
840 #if __has_cpp_attribute(nodiscard)
841 #define NODISCARD [[nodiscard]]
842 #elif __has_cpp_attribute(gnu::warn_unused_result)
843 #define NODISCARD [[gnu::warn_unused_result]]
844 #else
845 #define NODISCARD Q_REQUIRED_RESULT
846 #endif
847 #else
848 #define NODISCARD Q_REQUIRED_RESULT
849 #endif
850
851 #if __cplusplus >= 201703L
852 #define MAYBE_UNUSED [[maybe_unused]]
853 #elif defined(__clang__)
854 #define MAYBE_UNUSED [[maybe_unused]]
855 #elif defined(_MSC_VER)
856 #define MAYBE_UNUSED // no support
857 #elif defined(__has_cpp_attribute)
858 #if __has_cpp_attribute(gnu::unused)
859 #define MAYBE_UNUSED [[gnu::unused]]
860 #else
861 #define MAYBE_UNUSED
862 #endif
863 #else
864 #define MAYBE_UNUSED
865 #endif
866
867 #ifndef FINAL
868 #define FINAL final
869 #endif
870
871 #ifdef SIP_RUN
872
873 /**
874 * Wkt string that represents a geographic coord sys
875 * \since QGIS GEOWkt
876 */
877 QString CORE_EXPORT geoWkt();
878
879 //! PROJ4 string that represents a geographic coord sys
880 QString CORE_EXPORT geoProj4();
881
882 //! Geographic coord sys from EPSG authority
883 QString CORE_EXPORT geoEpsgCrsAuthId();
884
885 //! Constant that holds the string representation for "No ellips/No CRS"
886 QString CORE_EXPORT geoNone();
887
888 #endif
889