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