19 #include <QDomDocument>
53 QRegExp rx(
"(\\d?\\.?\\d+\\s+[a-z]+)", Qt::CaseInsensitive );
57 while (( pos = rx.indexIn(
string, pos ) ) != -1 )
60 pos += rx.matchedLength();
63 foreach ( QString match, list )
65 QStringList split = match.split( QRegExp(
"\\s+" ) );
67 int value = split.at( 0 ).toInt( &ok );
73 if ( match.contains(
"day", Qt::CaseInsensitive ) ||
74 match.contains(
QObject::tr(
"day",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
75 match.contains(
QObject::tr(
"days",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
77 if ( match.contains(
"week", Qt::CaseInsensitive ) ||
78 match.contains(
QObject::tr(
"week",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
79 match.contains(
QObject::tr(
"weeks",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
81 if ( match.contains(
"month", Qt::CaseInsensitive ) ||
82 match.contains(
QObject::tr(
"month",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
83 match.contains(
QObject::tr(
"months",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
85 if ( match.contains(
"year", Qt::CaseInsensitive ) ||
86 match.contains(
QObject::tr(
"year",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
87 match.contains(
QObject::tr(
"years",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
89 if ( match.contains(
"second", Qt::CaseInsensitive ) ||
90 match.contains(
QObject::tr(
"second",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
91 match.contains(
QObject::tr(
"seconds",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
93 if ( match.contains(
"minute", Qt::CaseInsensitive ) ||
94 match.contains(
QObject::tr(
"minute",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
95 match.contains(
QObject::tr(
"minutes",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
97 if ( match.contains(
"hour", Qt::CaseInsensitive ) ||
98 match.contains(
QObject::tr(
"hour",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
99 match.contains(
QObject::tr(
"hours",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
112 return ( mSeconds == other.
mSeconds );
146 case False:
return 0;
154 #define TVL_True QVariant(1)
155 #define TVL_False QVariant(0)
156 #define TVL_Unknown QVariant()
163 if ( v.type() == QVariant::Int )
return true;
164 if ( v.type() == QVariant::Double )
return false;
165 if ( v.type() == QVariant::String ) {
bool ok; v.toString().toInt( &ok );
return ok; }
170 if ( v.type() == QVariant::Double || v.type() == QVariant::Int )
return true;
171 if ( v.type() == QVariant::String ) {
bool ok; v.toString().toDouble( &ok );
return ok; }
177 return v.type() == QVariant::DateTime || v.type() == QVariant::Date ||
178 v.type() == QVariant::Time;
188 if ( v.type() == QVariant::String )
195 inline bool isNull(
const QVariant& v ) {
return v.isNull(); }
200 #define ENSURE_NO_EVAL_ERROR { if (parent->hasEvalError()) return QVariant(); }
201 #define SET_EVAL_ERROR(x) { parent->setEvalErrorString(x); return QVariant(); }
209 "=",
"<>",
"<=",
">=",
"<",
">",
"~",
"LIKE",
"NOT LIKE",
"ILIKE",
"NOT ILIKE",
"IS",
"IS NOT",
210 "+",
"-",
"*",
"/",
"%",
"^",
225 return value.toString();
231 double x = value.toDouble( &ok );
243 qint64 x = value.toLongLong( &ok );
257 QDateTime d = value.toDateTime();
271 QDate d = value.toDate();
285 QTime t = value.toTime();
303 if ( inter.isValid() )
327 if ( value.isNull() )
330 if ( value.type() == QVariant::Int )
331 return value.toInt() != 0 ?
True :
False;
334 double x = value.toDouble( &ok );
348 return QVariant( sqrt( x ) );
354 return QVariant( fabs( val ) );
360 return QVariant( sin( x ) );
365 return QVariant( cos( x ) );
370 return QVariant( tan( x ) );
375 return QVariant( asin( x ) );
380 return QVariant( acos( x ) );
385 return QVariant( atan( x ) );
391 return QVariant( atan2( y, x ) );
396 return QVariant( exp( x ) );
403 return QVariant( log( x ) );
410 return QVariant( log10( x ) );
416 if ( x <= 0 || b <= 0 )
418 return QVariant( log( x ) / log( b ) );
428 double f = ( double )rand() / RAND_MAX;
429 return QVariant( min + f * ( max - min ) ) ;
439 return QVariant( min + ( rand() % (
int )( max - min + 1 ) ) );
450 if ( domainMin >= domainMax )
457 if ( val >= domainMax )
461 else if ( val <= domainMin )
467 double m = ( rangeMax - rangeMin ) / ( domainMax - domainMin );
468 double c = rangeMin - ( domainMin * m );
471 return QVariant( m * val + c );
483 if ( domainMin >= domainMax )
495 if ( val >= domainMax )
499 else if ( val <= domainMin )
505 return QVariant((( rangeMax - rangeMin ) / pow( domainMax - domainMin, exponent ) ) * pow( val - domainMin, exponent ) + rangeMin );
514 for (
int i = 1; i < values.length(); ++i )
517 if ( testVal > maxVal )
523 return QVariant( maxVal );
532 for (
int i = 1; i < values.length(); ++i )
535 if ( testVal < minVal )
541 return QVariant( minVal );
551 if ( testValue <= minValue )
553 return QVariant( minValue );
555 else if ( testValue >= maxValue )
557 return QVariant( maxValue );
561 return QVariant( testValue );
568 return QVariant( floor( x ) );
574 return QVariant( ceil( x ) );
579 return QVariant(
getIntValue( values.at( 0 ), parent ) );
597 foreach (
const QVariant &value, values )
599 if ( value.isNull() )
608 return QVariant( str.toLower() );
613 return QVariant( str.toUpper() );
618 QStringList elems = str.split(
" " );
619 for (
int i = 0; i < elems.size(); i++ )
621 if ( elems[i].
size() > 1 )
622 elems[i] = elems[i].left( 1 ).toUpper() + elems[i].mid( 1 ).toLower();
624 return QVariant( elems.join(
" " ) );
630 return QVariant( str.trimmed() );
636 return QVariant( str.length() );
643 return QVariant( str.replace( before, after ) );
651 QRegExp re( regexp );
657 return QVariant( str.replace( re, after ) );
665 QRegExp re( regexp );
671 return QVariant( str.contains( re ) ? 1 : 0 );
679 QRegExp re( regexp );
688 if ( re.captureCount() > 0 )
691 return QVariant( re.capturedTexts()[1] );
695 return QVariant(
"" );
704 return QVariant( str.mid( from -1, len ) );
715 return f ? QVariant((
int )f->
id() ) : QVariant();
721 foreach (
const QVariant &value, values )
731 return string.indexOf( QRegExp(
getStringValue( values.at( 1 ), parent ) ) );
738 return string.right( pos );
745 return string.left( pos );
751 int length =
getIntValue( values.at( 1 ), parent );
753 return string.rightJustified( length, fill.at( 0 ), true );
759 int length =
getIntValue( values.at( 1 ), parent );
761 return string.leftJustified( length, fill.at( 0 ), true );
767 for (
int n = 1; n < values.length(); n++ )
777 return QVariant( QDateTime::currentDateTime() );
782 return QVariant(
getDateValue( values.at( 0 ), parent ) );
787 return QVariant(
getTimeValue( values.at( 0 ), parent ) );
792 return QVariant::fromValue(
getInterval( values.at( 0 ), parent ) );
799 int seconds = d2.secsTo( d1 );
805 QVariant value = values.at( 0 );
809 return QVariant( inter.
days() );
814 return QVariant( d1.date().day() );
820 QVariant value = values.at( 0 );
824 return QVariant( inter.
years() );
829 return QVariant( d1.date().year() );
835 QVariant value = values.at( 0 );
839 return QVariant( inter.
months() );
844 return QVariant( d1.date().month() );
850 QVariant value = values.at( 0 );
854 return QVariant( inter.
weeks() );
859 return QVariant( d1.date().weekNumber() );
865 QVariant value = values.at( 0 );
869 return QVariant( inter.
hours() );
874 return QVariant( d1.time().hour() );
880 QVariant value = values.at( 0 );
884 return QVariant( inter.
minutes() );
889 return QVariant( d1.time().minute() );
895 QVariant value = values.at( 0 );
899 return QVariant( inter.
seconds() );
904 return QVariant( d1.time().second() );
909 #define ENSURE_GEOM_TYPE(f, g, geomtype) if (!f) return QVariant(); \
910 QgsGeometry* g = f->geometry(); \
911 if (!g || g->type() != geomtype) return QVariant();
917 if ( g->isMultipart() )
919 return g->asMultiPoint()[ 0 ].x();
923 return g->asPoint().x();
929 if ( g->isMultipart() )
931 return g->asMultiPoint()[ 0 ].y();
935 return g->asPoint().y();
945 idx += polyline.count();
947 if ( idx < 0 || idx >= polyline.count() )
952 return QVariant( QPointF( polyline[idx].x(), polyline[idx].y() ) );
957 QVariant v =
pointAt( values, f, parent );
958 if ( v.type() == QVariant::PointF )
959 return QVariant( v.toPointF().x() );
965 QVariant v =
pointAt( values, f, parent );
966 if ( v.type() == QVariant::PointF )
967 return QVariant( v.toPointF().y() );
975 return QVariant::fromValue( *geom );
984 return QVariant::fromValue( *geom );
994 return QVariant::fromValue( *geom );
1068 if ( values.length() < 2 || values.length() > 3 )
1074 if ( values.length() == 3 )
1079 return QVariant::fromValue( *geom );
1087 return QVariant::fromValue( *geom );
1095 return QVariant::fromValue( *geom );
1104 return QVariant::fromValue( *geom );
1111 return QVariant( fGeom.
distance( sGeom ) );
1119 return QVariant::fromValue( *geom );
1128 return QVariant::fromValue( *geom );
1137 return QVariant::fromValue( *geom );
1144 return QVariant( wkt );
1150 if ( values.length() == 2 )
1153 double scaler = pow( 10.0,
getIntValue( values.at( 1 ), parent ) );
1154 return QVariant( qRound( number * scaler ) / scaler );
1157 if ( values.length() == 1 )
1159 double number =
getIntValue( values.at( 0 ), parent );
1160 return QVariant( qRound( number ) ).toInt();
1176 return QVariant( parent->
scale() );
1182 int places =
getIntValue( values.at( 1 ), parent );
1183 return QString(
"%L1" ).arg( value, 0,
'f', places );
1190 return dt.toString( format );
1196 int green =
getIntValue( values.at( 1 ), parent );
1198 QColor color = QColor( red, green, blue );
1199 if ( ! color.isValid() )
1202 color = QColor( 0, 0, 0 );
1205 return QString(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
1211 int green =
getIntValue( values.at( 1 ), parent );
1213 int alpha =
getIntValue( values.at( 3 ), parent );
1214 QColor color = QColor( red, green, blue, alpha );
1215 if ( ! color.isValid() )
1218 color = QColor( 0, 0, 0 );
1230 return QColor( 0, 0, 0 ).name();
1233 QColor color = mRamp->color( value );
1240 double hue =
getIntValue( values.at( 0 ), parent ) / 360.0;
1242 double saturation =
getIntValue( values.at( 1 ), parent ) / 100.0;
1244 double lightness =
getIntValue( values.at( 2 ), parent ) / 100.0;
1246 QColor color = QColor::fromHslF( hue, saturation, lightness );
1248 if ( ! color.isValid() )
1251 color = QColor( 0, 0, 0 );
1254 return QString(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
1260 double hue =
getIntValue( values.at( 0 ), parent ) / 360.0;
1262 double saturation =
getIntValue( values.at( 1 ), parent ) / 100.0;
1264 double lightness =
getIntValue( values.at( 2 ), parent ) / 100.0;
1266 double alpha =
getIntValue( values.at( 3 ), parent ) / 255.0;
1268 QColor color = QColor::fromHslF( hue, saturation, lightness, alpha );
1269 if ( ! color.isValid() )
1271 parent->
setEvalErrorString(
QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( lightness ).arg( alpha ) );
1272 color = QColor( 0, 0, 0 );
1280 double hue =
getIntValue( values.at( 0 ), parent ) / 360.0;
1282 double saturation =
getIntValue( values.at( 1 ), parent ) / 100.0;
1284 double value =
getIntValue( values.at( 2 ), parent ) / 100.0;
1286 QColor color = QColor::fromHsvF( hue, saturation, value );
1288 if ( ! color.isValid() )
1291 color = QColor( 0, 0, 0 );
1294 return QString(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
1300 double hue =
getIntValue( values.at( 0 ), parent ) / 360.0;
1302 double saturation =
getIntValue( values.at( 1 ), parent ) / 100.0;
1304 double value =
getIntValue( values.at( 2 ), parent ) / 100.0;
1306 double alpha =
getIntValue( values.at( 3 ), parent ) / 255.0;
1308 QColor color = QColor::fromHsvF( hue, saturation, value, alpha );
1309 if ( ! color.isValid() )
1311 parent->
setEvalErrorString(
QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( value ).arg( alpha ) );
1312 color = QColor( 0, 0, 0 );
1320 double cyan =
getIntValue( values.at( 0 ), parent ) / 100.0;
1322 double magenta =
getIntValue( values.at( 1 ), parent ) / 100.0;
1324 double yellow =
getIntValue( values.at( 2 ), parent ) / 100.0;
1326 double black =
getIntValue( values.at( 3 ), parent ) / 100.0;
1328 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black );
1330 if ( ! color.isValid() )
1333 color = QColor( 0, 0, 0 );
1336 return QString(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
1342 double cyan =
getIntValue( values.at( 0 ), parent ) / 100.0;
1344 double magenta =
getIntValue( values.at( 1 ), parent ) / 100.0;
1346 double yellow =
getIntValue( values.at( 2 ), parent ) / 100.0;
1348 double black =
getIntValue( values.at( 3 ), parent ) / 100.0;
1350 double alpha =
getIntValue( values.at( 4 ), parent ) / 255.0;
1352 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
1353 if ( ! color.isValid() )
1355 parent->
setEvalErrorString(
QObject::tr(
"Cannot convert '%1:%2:%3:%4:%5' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ).arg( alpha ) );
1356 color = QColor( 0, 0, 0 );
1403 <<
"abs" <<
"sqrt" <<
"cos" <<
"sin" <<
"tan"
1404 <<
"asin" <<
"acos" <<
"atan" <<
"atan2"
1405 <<
"exp" <<
"ln" <<
"log10" <<
"log"
1406 <<
"round" <<
"rand" <<
"randf" <<
"max" <<
"min" <<
"clamp"
1407 <<
"scale_linear" <<
"scale_exp" <<
"floor" <<
"ceil"
1408 <<
"toint" <<
"toreal" <<
"tostring"
1409 <<
"todatetime" <<
"todate" <<
"totime" <<
"tointerval"
1410 <<
"coalesce" <<
"regexp_match" <<
"$now" <<
"age" <<
"year"
1411 <<
"month" <<
"week" <<
"day" <<
"hour"
1412 <<
"minute" <<
"second" <<
"lower" <<
"upper"
1413 <<
"title" <<
"length" <<
"replace" <<
"trim"
1414 <<
"regexp_replace" <<
"regexp_substr"
1415 <<
"substr" <<
"concat" <<
"strpos" <<
"left"
1416 <<
"right" <<
"rpad" <<
"lpad"
1417 <<
"format_number" <<
"format_date"
1418 <<
"color_rgb" <<
"color_rgba" <<
"ramp_color"
1419 <<
"color_hsl" <<
"color_hsla" <<
"color_hsv" <<
"color_hsva"
1420 <<
"color_cymk" <<
"color_cymka"
1421 <<
"xat" <<
"yat" <<
"$area"
1422 <<
"$length" <<
"$perimeter" <<
"$x" <<
"$y"
1423 <<
"$rownum" <<
"$id" <<
"$scale" <<
"_specialcol_";
1581 QList<Function*> defs;
1597 for (
int i = 0; i < count; i++ )
1599 if ( QString::compare( name,
Functions()[i]->name(), Qt::CaseInsensitive ) == 0 )
1632 return QStringList();
1636 for (
int i = 0; i < columns.count(); i++ )
1638 QString col = columns.at( i );
1639 for (
int j = i + 1; j < columns.count(); j++ )
1641 if ( QString::compare( col, columns[j], Qt::CaseInsensitive ) == 0 )
1644 columns.removeAt( j-- );
1731 const QMap<QString, QVariant> *substitutionMap )
1733 QString expr_action;
1735 QMap<QString, QVariant> savedValues;
1736 if ( substitutionMap )
1739 for ( QMap<QString, QVariant>::const_iterator sit = substitutionMap->begin(); sit != substitutionMap->end(); ++sit )
1742 if ( !oldValue.isNull() )
1743 savedValues.insert( sit.key(), oldValue );
1751 while ( index < action.size() )
1753 QRegExp rx = QRegExp(
"\\[%([^\\]]+)%\\]" );
1755 int pos = rx.indexIn( action, index );
1760 index = pos + rx.matchedLength();
1761 QString to_replace = rx.cap( 1 ).trimmed();
1768 expr_action += action.mid( start, index - start );
1784 expr_action += action.mid( start, index - start );
1788 QgsDebugMsg(
"Expression result is: " + result.toString() );
1789 expr_action += action.mid( start, pos - start ) + result.toString();
1792 expr_action += action.mid( index );
1795 for ( QMap<QString, QVariant>::const_iterator sit = savedValues.begin(); sit != savedValues.end(); ++sit )
1806 const QMap<QString, QVariant> *substitutionMap )
1817 QString msg;
bool first =
true;
1820 if ( !first ) msg +=
", ";
else first =
false;
1831 QVariant val = mOperand->eval( parent, f );
1852 Q_ASSERT( 0 &&
"unknown unary operation" );
1859 return mOperand->prepare( parent, fields );
1864 return QString(
"%1 %2" ).arg(
UnaryOperatorText[mOp] ).arg( mOperand->dump() );
1871 QVariant vL = mOpLeft->eval( parent, f );
1873 QVariant vR = mOpRight->eval( parent, f );
1890 if ( mOp ==
boDiv && iR == 0 )
return QVariant();
1891 return QVariant( computeInt( iL, iR ) );
1902 return QVariant( computeDateTimeFromInterval( dL, &iL ) );
1909 if ( mOp ==
boDiv && fR == 0 )
1911 return QVariant( computeDouble( fL, fR ) );
1921 return QVariant( pow( fL, fR ) );
1960 int diff = QString::compare( sL, sR );
1983 equal = QString::compare( sL, sR ) == 0;
2006 QString esc_regexp = QRegExp::escape( regexp );
2008 esc_regexp.replace(
"%",
".*" );
2009 esc_regexp.replace(
"_",
"." );
2010 matches = QRegExp( esc_regexp, mOp ==
boLike || mOp ==
boNotLike ? Qt::CaseSensitive : Qt::CaseInsensitive ).exactMatch( str );
2014 matches = QRegExp( regexp ).indexIn( str ) != -1;
2032 return QVariant( sL + sR );
2045 case boEQ:
return diff == 0;
2046 case boNE:
return diff != 0;
2047 case boLT:
return diff < 0;
2048 case boGT:
return diff > 0;
2049 case boLE:
return diff <= 0;
2050 case boGE:
return diff >= 0;
2051 default: Q_ASSERT(
false );
return false;
2061 case boMul:
return x*y;
2062 case boDiv:
return x/y;
2063 case boMod:
return x%y;
2064 default: Q_ASSERT(
false );
return 0;
2074 default: Q_ASSERT(
false );
return QDateTime();
2084 case boMul:
return x*y;
2085 case boDiv:
return x/y;
2086 case boMod:
return fmod( x,y );
2087 default: Q_ASSERT(
false );
return 0;
2094 bool resL = mOpLeft->prepare( parent, fields );
2095 bool resR = mOpRight->prepare( parent, fields );
2096 return resL && resR;
2101 return QString(
"%1 %2 %3" ).arg( mOpLeft->dump() ).arg(
BinaryOperatorText[mOp] ).arg( mOpRight->dump() );
2108 if ( mList->count() == 0 )
2110 QVariant v1 = mNode->eval( parent, f );
2115 bool listHasNull =
false;
2117 foreach (
Node* n, mList->list() )
2119 QVariant v2 = n->
eval( parent, f );
2137 equal = QString::compare( s1, s2 ) == 0;
2154 bool res = mNode->prepare( parent, fields );
2155 foreach (
Node* n, mList->list() )
2157 res = res && n->
prepare( parent, fields );
2164 return QString(
"%1 IN (%2)" ).arg( mNode->dump() ).arg( mList->dump() );
2174 QVariantList argValues;
2177 foreach (
Node* n, mArgs->list() )
2179 QVariant v = n->
eval( parent, f );
2181 if (
isNull( v ) && fd->
name() !=
"coalesce" )
2183 argValues.append( v );
2188 QVariant res = fd->
func( argValues, f, parent );
2200 foreach (
Node* n, mArgs->list() )
2202 res = res && n->
prepare( parent, fields );
2214 return QString(
"%1(%2)" ).arg( fd->
name() ).arg( mArgs ? mArgs->dump() : QString() );
2232 if ( mValue.isNull() )
2235 switch ( mValue.type() )
2237 case QVariant::Int:
return QString::number( mValue.toInt() );
2238 case QVariant::Double:
return QString::number( mValue.toDouble() );
2239 case QVariant::String:
return QString(
"'%1'" ).arg( mValue.toString() );
2240 default:
return QObject::tr(
"[unsupported type;%1; value:%2]" ).arg( mValue.typeName() ).arg( mValue.toString() );
2255 return QVariant(
"[" + mName +
"]" );
2260 for (
int i = 0; i < fields.
count(); ++i )
2262 if ( QString::compare( fields[i].name(), mName, Qt::CaseInsensitive ) == 0 )
2282 foreach (
WhenThen* cond, mConditions )
2297 QVariant vElse = mElseExp->eval( parent, f );
2309 foreach (
WhenThen* cond, mConditions )
2313 if ( !res )
return false;
2317 return mElseExp->prepare( parent, fields );
2324 QString msg =
"CONDITION:\n";
2325 foreach (
WhenThen* cond, mConditions )
2330 msg += QString(
"- ELSE %1" ).arg( mElseExp->dump() );
2337 foreach (
WhenThen* cond, mConditions )
2343 lst += mElseExp->referencedColumns();
2350 foreach (
WhenThen* cond, mConditions )
2357 if ( mElseExp && mElseExp->needsGeometry() )
2390 return gGroups.value( name, name );