19 #include <QDomDocument>
54 QRegExp rx(
"(\\d?\\.?\\d+\\s+[a-z]+)", Qt::CaseInsensitive );
58 while (( pos = rx.indexIn(
string, pos ) ) != -1 )
61 pos += rx.matchedLength();
64 foreach ( QString match, list )
66 QStringList split = match.split( QRegExp(
"\\s+" ) );
68 int value = split.at( 0 ).toInt( &ok );
74 if ( match.contains(
"day", Qt::CaseInsensitive ) ||
75 match.contains(
QObject::tr(
"day",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
76 match.contains(
QObject::tr(
"days",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
78 if ( match.contains(
"week", Qt::CaseInsensitive ) ||
79 match.contains(
QObject::tr(
"week",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
80 match.contains(
QObject::tr(
"weeks",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
82 if ( match.contains(
"month", Qt::CaseInsensitive ) ||
83 match.contains(
QObject::tr(
"month",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
84 match.contains(
QObject::tr(
"months",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
86 if ( match.contains(
"year", Qt::CaseInsensitive ) ||
87 match.contains(
QObject::tr(
"year",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
88 match.contains(
QObject::tr(
"years",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
90 if ( match.contains(
"second", Qt::CaseInsensitive ) ||
91 match.contains(
QObject::tr(
"second",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
92 match.contains(
QObject::tr(
"seconds",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
94 if ( match.contains(
"minute", Qt::CaseInsensitive ) ||
95 match.contains(
QObject::tr(
"minute",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
96 match.contains(
QObject::tr(
"minutes",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
98 if ( match.contains(
"hour", Qt::CaseInsensitive ) ||
99 match.contains(
QObject::tr(
"hour",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
100 match.contains(
QObject::tr(
"hours",
"Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
113 return ( mSeconds == other.
mSeconds );
147 case False:
return 0;
155 #define TVL_True QVariant(1)
156 #define TVL_False QVariant(0)
157 #define TVL_Unknown QVariant()
164 if ( v.type() == QVariant::Int )
return true;
165 if ( v.type() == QVariant::Double )
return false;
166 if ( v.type() == QVariant::String ) {
bool ok; v.toString().toInt( &ok );
return ok; }
171 if ( v.type() == QVariant::Double || v.type() == QVariant::Int )
return true;
172 if ( v.type() == QVariant::String ) {
bool ok; v.toString().toDouble( &ok );
return ok; }
178 return v.type() == QVariant::DateTime || v.type() == QVariant::Date ||
179 v.type() == QVariant::Time;
189 if ( v.type() == QVariant::String )
196 inline bool isNull(
const QVariant& v ) {
return v.isNull(); }
201 #define ENSURE_NO_EVAL_ERROR { if (parent->hasEvalError()) return QVariant(); }
202 #define SET_EVAL_ERROR(x) { parent->setEvalErrorString(x); return QVariant(); }
210 "=",
"<>",
"<=",
">=",
"<",
">",
"~",
"LIKE",
"NOT LIKE",
"ILIKE",
"NOT ILIKE",
"IS",
"IS NOT",
211 "+",
"-",
"*",
"/",
"%",
"^",
226 return value.toString();
232 double x = value.toDouble( &ok );
244 qint64 x = value.toLongLong( &ok );
258 QDateTime d = value.toDateTime();
272 QDate d = value.toDate();
286 QTime t = value.toTime();
304 if ( inter.isValid() )
328 if ( value.isNull() )
331 if ( value.type() == QVariant::Int )
332 return value.toInt() != 0 ?
True :
False;
335 double x = value.toDouble( &ok );
349 return QVariant( sqrt( x ) );
355 return QVariant( fabs( val ) );
361 return QVariant( sin( x ) );
366 return QVariant( cos( x ) );
371 return QVariant( tan( x ) );
376 return QVariant( asin( x ) );
381 return QVariant( acos( x ) );
386 return QVariant( atan( x ) );
392 return QVariant( atan2( y, x ) );
397 return QVariant( exp( x ) );
404 return QVariant( log( x ) );
411 return QVariant( log10( x ) );
417 if ( x <= 0 || b <= 0 )
419 return QVariant( log( x ) / log( b ) );
429 double f = ( double )rand() / RAND_MAX;
430 return QVariant( min + f * ( max - min ) ) ;
440 return QVariant( min + ( rand() % (
int )( max - min + 1 ) ) );
451 if ( domainMin >= domainMax )
458 if ( val >= domainMax )
462 else if ( val <= domainMin )
468 double m = ( rangeMax - rangeMin ) / ( domainMax - domainMin );
469 double c = rangeMin - ( domainMin * m );
472 return QVariant( m * val + c );
484 if ( domainMin >= domainMax )
496 if ( val >= domainMax )
500 else if ( val <= domainMin )
506 return QVariant((( rangeMax - rangeMin ) / pow( domainMax - domainMin, exponent ) ) * pow( val - domainMin, exponent ) + rangeMin );
515 for (
int i = 1; i < values.length(); ++i )
518 if ( testVal > maxVal )
524 return QVariant( maxVal );
533 for (
int i = 1; i < values.length(); ++i )
536 if ( testVal < minVal )
542 return QVariant( minVal );
552 if ( testValue <= minValue )
554 return QVariant( minValue );
556 else if ( testValue >= maxValue )
558 return QVariant( maxValue );
562 return QVariant( testValue );
569 return QVariant( floor( x ) );
575 return QVariant( ceil( x ) );
580 return QVariant(
getIntValue( values.at( 0 ), parent ) );
598 foreach (
const QVariant &value, values )
600 if ( value.isNull() )
609 return QVariant( str.toLower() );
614 return QVariant( str.toUpper() );
619 QStringList elems = str.split(
" " );
620 for (
int i = 0; i < elems.size(); i++ )
622 if ( elems[i].
size() > 1 )
623 elems[i] = elems[i].left( 1 ).toUpper() + elems[i].mid( 1 ).toLower();
625 return QVariant( elems.join(
" " ) );
631 return QVariant( str.trimmed() );
637 return QVariant( str.length() );
644 return QVariant( str.replace( before, after ) );
652 QRegExp re( regexp );
658 return QVariant( str.replace( re, after ) );
666 QRegExp re( regexp );
672 return QVariant( str.contains( re ) ? 1 : 0 );
680 QRegExp re( regexp );
689 if ( re.captureCount() > 0 )
692 return QVariant( re.capturedTexts()[1] );
696 return QVariant(
"" );
702 return QUuid::createUuid().toString();
710 return QVariant( str.mid( from -1, len ) );
721 return f ? QVariant((
int )f->
id() ) : QVariant();
727 foreach (
const QVariant &value, values )
737 return string.indexOf( QRegExp(
getStringValue( values.at( 1 ), parent ) ) );
744 return string.right( pos );
751 return string.left( pos );
757 int length =
getIntValue( values.at( 1 ), parent );
759 return string.leftJustified( length, fill.at( 0 ), true );
765 int length =
getIntValue( values.at( 1 ), parent );
767 return string.rightJustified( length, fill.at( 0 ), true );
773 for (
int n = 1; n < values.length(); n++ )
783 return QVariant( QDateTime::currentDateTime() );
788 return QVariant(
getDateValue( values.at( 0 ), parent ) );
793 return QVariant(
getTimeValue( values.at( 0 ), parent ) );
798 return QVariant::fromValue(
getInterval( values.at( 0 ), parent ) );
805 int seconds = d2.secsTo( d1 );
811 QVariant value = values.at( 0 );
815 return QVariant( inter.
days() );
820 return QVariant( d1.date().day() );
826 QVariant value = values.at( 0 );
830 return QVariant( inter.
years() );
835 return QVariant( d1.date().year() );
841 QVariant value = values.at( 0 );
845 return QVariant( inter.
months() );
850 return QVariant( d1.date().month() );
856 QVariant value = values.at( 0 );
860 return QVariant( inter.
weeks() );
865 return QVariant( d1.date().weekNumber() );
871 QVariant value = values.at( 0 );
875 return QVariant( inter.
hours() );
880 return QVariant( d1.time().hour() );
886 QVariant value = values.at( 0 );
890 return QVariant( inter.
minutes() );
895 return QVariant( d1.time().minute() );
901 QVariant value = values.at( 0 );
905 return QVariant( inter.
seconds() );
910 return QVariant( d1.time().second() );
915 #define ENSURE_GEOM_TYPE(f, g, geomtype) if (!f) return QVariant(); \
916 QgsGeometry* g = f->geometry(); \
917 if (!g || g->type() != geomtype) return QVariant();
923 if ( g->isMultipart() )
925 return g->asMultiPoint()[ 0 ].x();
929 return g->asPoint().x();
935 if ( g->isMultipart() )
937 return g->asMultiPoint()[ 0 ].y();
941 return g->asPoint().y();
951 idx += polyline.count();
953 if ( idx < 0 || idx >= polyline.count() )
958 return QVariant( QPointF( polyline[idx].x(), polyline[idx].y() ) );
963 QVariant v =
pointAt( values, f, parent );
964 if ( v.type() == QVariant::PointF )
965 return QVariant( v.toPointF().x() );
971 QVariant v =
pointAt( values, f, parent );
972 if ( v.type() == QVariant::PointF )
973 return QVariant( v.toPointF().y() );
981 return QVariant::fromValue( *geom );
990 return QVariant::fromValue( *geom );
1000 return QVariant::fromValue( *geom );
1074 if ( values.length() < 2 || values.length() > 3 )
1080 if ( values.length() == 3 )
1085 return QVariant::fromValue( *geom );
1093 return QVariant::fromValue( *geom );
1101 return QVariant::fromValue( *geom );
1110 return QVariant::fromValue( *geom );
1117 return QVariant( fGeom.
distance( sGeom ) );
1125 return QVariant::fromValue( *geom );
1134 return QVariant::fromValue( *geom );
1143 return QVariant::fromValue( *geom );
1150 return QVariant( wkt );
1156 if ( values.length() == 2 )
1159 double scaler = pow( 10.0,
getIntValue( values.at( 1 ), parent ) );
1160 return QVariant( qRound( number * scaler ) / scaler );
1163 if ( values.length() == 1 )
1165 double number =
getIntValue( values.at( 0 ), parent );
1166 return QVariant( qRound( number ) ).toInt();
1182 return QVariant( parent->
scale() );
1188 int places =
getIntValue( values.at( 1 ), parent );
1189 return QString(
"%L1" ).arg( value, 0,
'f', places );
1196 return dt.toString( format );
1202 int green =
getIntValue( values.at( 1 ), parent );
1204 QColor color = QColor( red, green, blue );
1205 if ( ! color.isValid() )
1208 color = QColor( 0, 0, 0 );
1211 return QString(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
1217 int green =
getIntValue( values.at( 1 ), parent );
1219 int alpha =
getIntValue( values.at( 3 ), parent );
1220 QColor color = QColor( red, green, blue, alpha );
1221 if ( ! color.isValid() )
1224 color = QColor( 0, 0, 0 );
1236 return QColor( 0, 0, 0 ).name();
1239 QColor color = mRamp->color( value );
1246 double hue =
getIntValue( values.at( 0 ), parent ) / 360.0;
1248 double saturation =
getIntValue( values.at( 1 ), parent ) / 100.0;
1250 double lightness =
getIntValue( values.at( 2 ), parent ) / 100.0;
1252 QColor color = QColor::fromHslF( hue, saturation, lightness );
1254 if ( ! color.isValid() )
1257 color = QColor( 0, 0, 0 );
1260 return QString(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
1266 double hue =
getIntValue( values.at( 0 ), parent ) / 360.0;
1268 double saturation =
getIntValue( values.at( 1 ), parent ) / 100.0;
1270 double lightness =
getIntValue( values.at( 2 ), parent ) / 100.0;
1272 double alpha =
getIntValue( values.at( 3 ), parent ) / 255.0;
1274 QColor color = QColor::fromHslF( hue, saturation, lightness, alpha );
1275 if ( ! color.isValid() )
1277 parent->
setEvalErrorString(
QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( lightness ).arg( alpha ) );
1278 color = QColor( 0, 0, 0 );
1286 double hue =
getIntValue( values.at( 0 ), parent ) / 360.0;
1288 double saturation =
getIntValue( values.at( 1 ), parent ) / 100.0;
1290 double value =
getIntValue( values.at( 2 ), parent ) / 100.0;
1292 QColor color = QColor::fromHsvF( hue, saturation, value );
1294 if ( ! color.isValid() )
1297 color = QColor( 0, 0, 0 );
1300 return QString(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
1306 double hue =
getIntValue( values.at( 0 ), parent ) / 360.0;
1308 double saturation =
getIntValue( values.at( 1 ), parent ) / 100.0;
1310 double value =
getIntValue( values.at( 2 ), parent ) / 100.0;
1312 double alpha =
getIntValue( values.at( 3 ), parent ) / 255.0;
1314 QColor color = QColor::fromHsvF( hue, saturation, value, alpha );
1315 if ( ! color.isValid() )
1317 parent->
setEvalErrorString(
QObject::tr(
"Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( value ).arg( alpha ) );
1318 color = QColor( 0, 0, 0 );
1326 double cyan =
getIntValue( values.at( 0 ), parent ) / 100.0;
1328 double magenta =
getIntValue( values.at( 1 ), parent ) / 100.0;
1330 double yellow =
getIntValue( values.at( 2 ), parent ) / 100.0;
1332 double black =
getIntValue( values.at( 3 ), parent ) / 100.0;
1334 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black );
1336 if ( ! color.isValid() )
1339 color = QColor( 0, 0, 0 );
1342 return QString(
"%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
1348 double cyan =
getIntValue( values.at( 0 ), parent ) / 100.0;
1350 double magenta =
getIntValue( values.at( 1 ), parent ) / 100.0;
1352 double yellow =
getIntValue( values.at( 2 ), parent ) / 100.0;
1354 double black =
getIntValue( values.at( 3 ), parent ) / 100.0;
1356 double alpha =
getIntValue( values.at( 4 ), parent ) / 255.0;
1358 QColor color = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
1359 if ( ! color.isValid() )
1361 parent->
setEvalErrorString(
QObject::tr(
"Cannot convert '%1:%2:%3:%4:%5' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ).arg( alpha ) );
1362 color = QColor( 0, 0, 0 );
1409 <<
"abs" <<
"sqrt" <<
"cos" <<
"sin" <<
"tan"
1410 <<
"asin" <<
"acos" <<
"atan" <<
"atan2"
1411 <<
"exp" <<
"ln" <<
"log10" <<
"log"
1412 <<
"round" <<
"rand" <<
"randf" <<
"max" <<
"min" <<
"clamp"
1413 <<
"scale_linear" <<
"scale_exp" <<
"floor" <<
"ceil"
1414 <<
"toint" <<
"toreal" <<
"tostring"
1415 <<
"todatetime" <<
"todate" <<
"totime" <<
"tointerval"
1416 <<
"coalesce" <<
"regexp_match" <<
"$now" <<
"age" <<
"year"
1417 <<
"month" <<
"week" <<
"day" <<
"hour"
1418 <<
"minute" <<
"second" <<
"lower" <<
"upper"
1419 <<
"title" <<
"length" <<
"replace" <<
"trim"
1420 <<
"regexp_replace" <<
"regexp_substr"
1421 <<
"substr" <<
"concat" <<
"strpos" <<
"left"
1422 <<
"right" <<
"rpad" <<
"lpad"
1423 <<
"format_number" <<
"format_date"
1424 <<
"color_rgb" <<
"color_rgba" <<
"ramp_color"
1425 <<
"color_hsl" <<
"color_hsla" <<
"color_hsv" <<
"color_hsva"
1426 <<
"color_cymk" <<
"color_cymka"
1427 <<
"xat" <<
"yat" <<
"$area"
1428 <<
"$length" <<
"$perimeter" <<
"$x" <<
"$y"
1429 <<
"$rownum" <<
"$id" <<
"$scale" <<
"_specialcol_";
1588 static bool initialized =
false;
1596 lst <<
"$page" <<
"$feature" <<
"$numpages" <<
"$numfeatures" <<
"$atlasfeatureid" <<
"$atlasgeometry" <<
"$map";
1597 foreach ( QString c, lst )
1610 QList<Function*> defs;
1626 for (
int i = 0; i < count; i++ )
1628 if ( QString::compare( name,
Functions()[i]->name(), Qt::CaseInsensitive ) == 0 )
1661 return QStringList();
1665 for (
int i = 0; i < columns.count(); i++ )
1667 QString col = columns.at( i );
1668 for (
int j = i + 1; j < columns.count(); j++ )
1670 if ( QString::compare( col, columns[j], Qt::CaseInsensitive ) == 0 )
1673 columns.removeAt( j-- );
1755 const QMap<QString, QVariant> *substitutionMap )
1757 QString expr_action;
1759 QMap<QString, QVariant> savedValues;
1760 if ( substitutionMap )
1763 for ( QMap<QString, QVariant>::const_iterator sit = substitutionMap->begin(); sit != substitutionMap->end(); ++sit )
1766 if ( !oldValue.isNull() )
1767 savedValues.insert( sit.key(), oldValue );
1775 while ( index < action.size() )
1777 QRegExp rx = QRegExp(
"\\[%([^\\]]+)%\\]" );
1779 int pos = rx.indexIn( action, index );
1784 index = pos + rx.matchedLength();
1785 QString to_replace = rx.cap( 1 ).trimmed();
1792 expr_action += action.mid( start, index - start );
1808 expr_action += action.mid( start, index - start );
1812 QgsDebugMsg(
"Expression result is: " + result.toString() );
1813 expr_action += action.mid( start, pos - start ) + result.toString();
1816 expr_action += action.mid( index );
1819 for ( QMap<QString, QVariant>::const_iterator sit = savedValues.begin(); sit != savedValues.end(); ++sit )
1833 QString msg;
bool first =
true;
1836 if ( !first ) msg +=
", ";
else first =
false;
1847 QVariant val = mOperand->eval( parent, f );
1868 Q_ASSERT( 0 &&
"unknown unary operation" );
1875 return mOperand->prepare( parent, fields );
1880 return QString(
"%1 %2" ).arg(
UnaryOperatorText[mOp] ).arg( mOperand->dump() );
1887 QVariant vL = mOpLeft->eval( parent, f );
1889 QVariant vR = mOpRight->eval( parent, f );
1906 if ( mOp ==
boDiv && iR == 0 )
return QVariant();
1907 return QVariant( computeInt( iL, iR ) );
1918 return QVariant( computeDateTimeFromInterval( dL, &iL ) );
1925 if ( mOp ==
boDiv && fR == 0 )
1927 return QVariant( computeDouble( fL, fR ) );
1937 return QVariant( pow( fL, fR ) );
1976 int diff = QString::compare( sL, sR );
1999 equal = QString::compare( sL, sR ) == 0;
2022 QString esc_regexp = QRegExp::escape( regexp );
2024 esc_regexp.replace(
"%",
".*" );
2025 esc_regexp.replace(
"_",
"." );
2026 matches = QRegExp( esc_regexp, mOp ==
boLike || mOp ==
boNotLike ? Qt::CaseSensitive : Qt::CaseInsensitive ).exactMatch( str );
2030 matches = QRegExp( regexp ).indexIn( str ) != -1;
2048 return QVariant( sL + sR );
2061 case boEQ:
return diff == 0;
2062 case boNE:
return diff != 0;
2063 case boLT:
return diff < 0;
2064 case boGT:
return diff > 0;
2065 case boLE:
return diff <= 0;
2066 case boGE:
return diff >= 0;
2067 default: Q_ASSERT(
false );
return false;
2077 case boMul:
return x*y;
2078 case boDiv:
return x/y;
2079 case boMod:
return x%y;
2080 default: Q_ASSERT(
false );
return 0;
2090 default: Q_ASSERT(
false );
return QDateTime();
2100 case boMul:
return x*y;
2101 case boDiv:
return x/y;
2102 case boMod:
return fmod( x,y );
2103 default: Q_ASSERT(
false );
return 0;
2110 bool resL = mOpLeft->prepare( parent, fields );
2111 bool resR = mOpRight->prepare( parent, fields );
2112 return resL && resR;
2117 return QString(
"%1 %2 %3" ).arg( mOpLeft->dump() ).arg(
BinaryOperatorText[mOp] ).arg( mOpRight->dump() );
2124 if ( mList->count() == 0 )
2126 QVariant v1 = mNode->eval( parent, f );
2131 bool listHasNull =
false;
2133 foreach (
Node* n, mList->list() )
2135 QVariant v2 = n->
eval( parent, f );
2153 equal = QString::compare( s1, s2 ) == 0;
2170 bool res = mNode->prepare( parent, fields );
2171 foreach (
Node* n, mList->list() )
2173 res = res && n->
prepare( parent, fields );
2180 return QString(
"%1 IN (%2)" ).arg( mNode->dump() ).arg( mList->dump() );
2190 QVariantList argValues;
2193 foreach (
Node* n, mArgs->list() )
2195 QVariant v = n->
eval( parent, f );
2197 if (
isNull( v ) && fd->
name() !=
"coalesce" )
2199 argValues.append( v );
2204 QVariant res = fd->
func( argValues, f, parent );
2216 foreach (
Node* n, mArgs->list() )
2218 res = res && n->
prepare( parent, fields );
2230 return QString(
"%1(%2)" ).arg( fd->
name() ).arg( mArgs ? mArgs->dump() : QString() );
2248 if ( mValue.isNull() )
2251 switch ( mValue.type() )
2253 case QVariant::Int:
return QString::number( mValue.toInt() );
2254 case QVariant::Double:
return QString::number( mValue.toDouble() );
2255 case QVariant::String:
return QString(
"'%1'" ).arg( mValue.toString() );
2256 default:
return QObject::tr(
"[unsupported type;%1; value:%2]" ).arg( mValue.typeName() ).arg( mValue.toString() );
2271 return QVariant(
"[" + mName +
"]" );
2276 for (
int i = 0; i < fields.
count(); ++i )
2278 if ( QString::compare( fields[i].name(), mName, Qt::CaseInsensitive ) == 0 )
2291 return QRegExp(
"^[A-Za-z_\x80-\xff][A-Za-z0-9_\x80-\xff]*$" ).exactMatch( mName ) ? mName :
quotedColumnRef( mName );
2298 foreach (
WhenThen* cond, mConditions )
2313 QVariant vElse = mElseExp->eval( parent, f );
2325 foreach (
WhenThen* cond, mConditions )
2329 if ( !res )
return false;
2333 return mElseExp->prepare( parent, fields );
2340 QString msg = QString(
"CASE " );
2341 foreach (
WhenThen* cond, mConditions )
2346 msg += QString(
"ELSE %1" ).arg( mElseExp->dump() );
2347 msg += QString(
" END" );
2354 foreach (
WhenThen* cond, mConditions )
2360 lst += mElseExp->referencedColumns();
2367 foreach (
WhenThen* cond, mConditions )
2374 if ( mElseExp && mElseExp->needsGeometry() )
2407 return gGroups.value( name, name );