17 #ifndef QGSEXPRESSIONUTILS_H 
   18 #define QGSEXPRESSIONUTILS_H 
   33 #define ENSURE_NO_EVAL_ERROR   {  if ( parent->hasEvalError() ) return QVariant(); } 
   34 #define SET_EVAL_ERROR(x)   { parent->setEvalErrorString( x ); return QVariant(); } 
   36 #define FEAT_FROM_CONTEXT(c, f) if ( !(c) || !( c )->hasFeature() ) return QVariant(); \ 
   37   QgsFeature f = ( c )->feature(); 
   43 class QgsExpressionUtils
 
   60 #define TVL_True QVariant( 1 ) 
   61 #define TVL_False QVariant( 0 ) 
   62 #define TVL_Unknown QVariant() 
   64     static QVariant tvl2variant( TVL v )
 
   79     static TVL getTVLValue( 
const QVariant &value, 
QgsExpression *parent )
 
   90         return geom.
isNull() ? False : True;
 
   96         return feat.
isValid() ? True : False;
 
   99       if ( value.type() == QVariant::Int )
 
  100         return value.toInt() != 0 ? True : False;
 
  103       double x = value.toDouble( &ok );
 
  106         parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1' to boolean" ).arg( value.toString() ) );
 
  113     static inline bool isIntSafe( 
const QVariant &v )
 
  115       if ( v.type() == QVariant::Int )
 
  117       if ( v.type() == QVariant::UInt )
 
  119       if ( v.type() == QVariant::LongLong )
 
  121       if ( v.type() == QVariant::ULongLong )
 
  123       if ( v.type() == QVariant::Double )
 
  125       if ( v.type() == QVariant::String )
 
  128         v.toString().toInt( &ok );
 
  134     static inline bool isDoubleSafe( 
const QVariant &v )
 
  136       if ( v.type() == QVariant::Double )
 
  138       if ( v.type() == QVariant::Int )
 
  140       if ( v.type() == QVariant::UInt )
 
  142       if ( v.type() == QVariant::LongLong )
 
  144       if ( v.type() == QVariant::ULongLong )
 
  146       if ( v.type() == QVariant::String )
 
  149         double val = v.toString().toDouble( &ok );
 
  150         ok = ok && std::isfinite( val ) && !std::isnan( val );
 
  156     static inline bool isDateTimeSafe( 
const QVariant &v )
 
  158       return v.type() == QVariant::DateTime
 
  159              || v.type() == QVariant::Date
 
  160              || v.type() == QVariant::Time;
 
  163     static inline bool isIntervalSafe( 
const QVariant &v )
 
  170       if ( v.type() == QVariant::String )
 
  177     static inline bool isNull( 
const QVariant &v )
 
  182     static inline bool isList( 
const QVariant &v )
 
  184       return v.type() == QVariant::List;
 
  188     static QString getStringValue( 
const QVariant &value, 
QgsExpression * )
 
  190       return value.toString();
 
  200     static QByteArray getBinaryValue( 
const QVariant &value, 
QgsExpression *parent )
 
  202       if ( value.type() != QVariant::ByteArray )
 
  207       return value.toByteArray();
 
  210     static double getDoubleValue( 
const QVariant &value, 
QgsExpression *parent )
 
  213       double x = value.toDouble( &ok );
 
  214       if ( !ok || std::isnan( x ) || !std::isfinite( x ) )
 
  216         parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1' to double" ).arg( value.toString() ) );
 
  222     static qlonglong getIntValue( 
const QVariant &value, 
QgsExpression *parent )
 
  225       qlonglong x = value.toLongLong( &ok );
 
  232         parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1' to int" ).arg( value.toString() ) );
 
  237     static int getNativeIntValue( 
const QVariant &value, 
QgsExpression *parent )
 
  240       qlonglong x = value.toLongLong( &ok );
 
  241       if ( ok && x >= std::numeric_limits<int>::min() && x <= std::numeric_limits<int>::max() )
 
  243         return static_cast<int>( x );
 
  247         parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1' to native int" ).arg( value.toString() ) );
 
  252     static QDateTime getDateTimeValue( 
const QVariant &value, 
QgsExpression *parent )
 
  254       QDateTime d = value.toDateTime();
 
  261         QTime t = value.toTime();
 
  264           return QDateTime( QDate( 1, 1, 1 ), t );
 
  267         parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1' to DateTime" ).arg( value.toString() ) );
 
  272     static QDate getDateValue( 
const QVariant &value, 
QgsExpression *parent )
 
  274       QDate d = value.toDate();
 
  281         parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1' to Date" ).arg( value.toString() ) );
 
  286     static QTime getTimeValue( 
const QVariant &value, 
QgsExpression *parent )
 
  288       QTime t = value.toTime();
 
  295         parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1' to Time" ).arg( value.toString() ) );
 
  306       if ( inter.isValid() )
 
  312         parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1' to interval" ).arg( value.toString() ) );
 
  324         parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1' to gradient ramp" ).arg( value.toString() ) );
 
  364         ml = project->
mapLayer( value.toString() );
 
  373     static std::unique_ptr<QgsVectorLayerFeatureSource> getFeatureSource( 
const QVariant &value, 
QgsExpression *e )
 
  375       std::unique_ptr<QgsVectorLayerFeatureSource> featureSource;
 
  377       auto getFeatureSource = [ &value, e, &featureSource ]
 
  389       if ( QThread::currentThread() == qApp->thread() )
 
  392         QMetaObject::invokeMethod( qApp, getFeatureSource, Qt::BlockingQueuedConnection );
 
  394       return featureSource;
 
  399       return qobject_cast<QgsVectorLayer *>( getMapLayer( value, e ) );
 
  404       return qobject_cast<QgsRasterLayer *>( getMapLayer( value, e ) );
 
  407     static QVariantList getListValue( 
const QVariant &value, 
QgsExpression *parent )
 
  409       if ( value.type() == QVariant::List || value.type() == QVariant::StringList )
 
  411         return value.toList();
 
  415         parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1' to array" ).arg( value.toString() ) );
 
  416         return QVariantList();
 
  420     static QVariantMap getMapValue( 
const QVariant &value, 
QgsExpression *parent )
 
  422       if ( value.type() == QVariant::Map )
 
  424         return value.toMap();
 
  428         parent->
setEvalErrorString( QObject::tr( 
"Cannot convert '%1' to map" ).arg( value.toString() ) );
 
  429         return QVariantMap();
 
Abstract base class for all nodes that can appear in an expression.
Class for parsing and evaluation of expressions (formerly called "search strings").
void setEvalErrorString(const QString &str)
Sets evaluation error (used internally by evaluation functions)
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
bool isValid() const
Returns the validity of this feature.
A geometry is the spatial representation of a feature.
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
double value(int index) const override
Returns relative value between [0,1] of color at specified index.
A representation of the interval between two datetime values.
bool isValid() const
Returns true if the interval is valid.
static QgsInterval fromString(const QString &string)
Converts a string to an interval.
Base class for all map layer types.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
static QgsProject * instance()
Returns the QgsProject singleton instance.
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
QList< QgsMapLayer * > mapLayersByName(const QString &layerName) const
Retrieve a list of matching registered layers by layer name.
Represents a raster layer.
Partial snapshot of vector layer's state (only the members necessary for access to features)
Represents a vector layer which manages a vector based data sets.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.