Add alias support for expression functions

Standardise naming of all internal functions to lowercase with
underscore convention. Add aliases for old names to avoid
breakage.
This commit is contained in:
Nyall Dawson 2015-05-03 18:40:09 +10:00
parent bb648306b6
commit bd9e02be95
29 changed files with 198 additions and 128 deletions

View File

@ -202,6 +202,13 @@ class QgsExpression
/** Does this function use a geometry object. */
bool usesgeometry();
/** Returns a list of possible aliases for the function. These include
* other permissible names for the function, eg deprecated names.
* @return list of known aliases
* @note added in QGIS 2.9
*/
virtual QStringList aliases() const;
/** True if this function should use lazy evaluation. Lazy evaluation functions take QgsExpression::Node objects
* rather than the node results when called. You can use node->eval(parent, feature) to evaluate the node and return the result
* Functions are non lazy default and will be given the node return value when called **/
@ -231,7 +238,7 @@ class QgsExpression
static bool isFunctionName( QString name );
// return index of the function in Functions array
static int functionIndex( QString name );
static int functionIndex( const QString& name );
/** Returns the number of functions defined in the parser
* @return The number of function defined in the parser.

View File

@ -1,13 +0,0 @@
<h3>bbox function</h3>
Returns 1 if the geometries spatially intersect the bounding box defined and 0 if they don't.
<h4>Syntax</h4>
<pre>bbox( a, b )</pre>
<h4>Arguments</h4>
a &rarr; geometry
b &rarr; geometry
<h4>Example</h4>
<pre>bbox( geomFromWKT( 'POINT(4 5)' ) , geomFromWKT( 'LINESTRING(3 3 , 4 4 , 5 5)' )) &rarr; returns 1</pre>
<pre>bbox( geomFromWKT( 'POINT(6 5)' ) , geomFromWKT( 'POLYGON((3 3 , 4 4 , 5 5, 3 3))' )) &rarr; returns 0</pre>

View File

@ -1,12 +1,12 @@
<h3>convexHull function</h3>
<h3>convex_hull function</h3>
Returns the convex hull of a geometry. It represents the minimum convex geometry that encloses all geometries within the set.
<h4>Syntax</h4>
<pre>convexHull( a, b )</pre>
<pre>convex_hull( a, b )</pre>
<h4>Arguments</h4>
a &rarr; geometry
a &rarr; geometry
<h4>Example</h4>
<pre> geomToWKT( convexHull( geomFromWKT( 'LINESTRING(3 3 , 4 4 , 4 10)' )) ) &rarr; returns POLYGON((3 3,4 10,4 4,3 3)) </pre>
<pre> geom_to_wkt( convex_hull( geom_from_wkt( 'LINESTRING(3 3 , 4 4 , 4 10)' )) ) &rarr; returns POLYGON((3 3,4 10,4 4,3 3)) </pre>

View File

@ -1,12 +0,0 @@
<h3>geomFromGML function</h3>
Returns a geometry from a GML representation of geometry
<h4>Syntax</h4>
<pre>geomFromGML(text)</pre>
<h4>Arguments</h4>
text &rarr; GML representation of a geometry
<h4>Example</h4>
<pre> geomFromGML( '<gml:LineString srsName="EPSG:4326"><gml:coordinates>4,4 5,5 6,6</gml:coordinates></gml:LineString>') &rarr; returns a geometry</pre>

View File

@ -0,0 +1,12 @@
<h3>geom_from_gml function</h3>
Returns a geometry from a GML representation of geometry
<h4>Syntax</h4>
<pre>geom_from_gml(text)</pre>
<h4>Arguments</h4>
text &rarr; GML representation of a geometry
<h4>Example</h4>
<pre> geom_from_gml( '<gml:LineString srsName="EPSG:4326"><gml:coordinates>4,4 5,5 6,6</gml:coordinates></gml:LineString>') &rarr; returns a geometry</pre>

View File

@ -1,12 +1,12 @@
<h3>geomFromWKT function</h3>
<h3>geom_from_wkt function</h3>
Returns a geometry created from a Well-Known Text (WKT) representation.
<h4>Syntax</h4>
<pre>geomFromWKT(text)</pre>
<pre>geom_from_wkt(text)</pre>
<h4>Arguments</h4>
text &rarr; Well-Known Text (WKT) representation of a geometry
<h4>Example</h4>
<pre> geomFromWKT( 'POINT(4 5)' ) &rarr; returns a geometry</pre>
<pre> geom_from_wkt( 'POINT(4 5)' ) &rarr; returns a geometry</pre>

View File

@ -1,11 +1,11 @@
<h3>geomToWKT function</h3>
<h3>geom_to_wkt function</h3>
Returns the Well-Known Text (WKT) representation of the geometry without SRID metadata.
<h4>Syntax</h4>
<pre>geomToWKT(a)</pre>
<pre>geom_to_wkt(a)</pre>
<h4>Arguments</h4>
a &rarr; geometry
<h4>Example</h4>
<pre> geomToWKT( $geometry ) &rarr; POINT(6 50)</pre>
<pre> geom_to_wkt( $geometry ) &rarr; POINT(6 50)</pre>

View File

@ -1,6 +1,6 @@
<h3>getFeature function</h3>
<h3>get_feature function</h3>
Returns the first feature of a layer matching a given attribute value
<h4>Syntax</h4>
<pre>getFeature( layer, attributeField, value )</pre>
<pre>get_feature( layer, attributeField, value )</pre>

View File

@ -0,0 +1,13 @@
<h3>intersects_bbox function</h3>
Returns 1 if the geometries spatially intersect the bounding box defined and 0 if they don't.
<h4>Syntax</h4>
<pre>intersects_bbox( a, b )</pre>
<h4>Arguments</h4>
a &rarr; geometry
b &rarr; geometry
<h4>Example</h4>
<pre>intersects_bbox( geomFromWKT( 'POINT(4 5)' ) , geom_from_wkt( 'LINESTRING(3 3 , 4 4 , 5 5)' )) &rarr; returns 1</pre>
<pre>intersects_bbox( geomFromWKT( 'POINT(6 5)' ) , geom_from_wkt( 'POLYGON((3 3 , 4 4 , 5 5, 3 3))' )) &rarr; returns 0</pre>

View File

@ -1,12 +0,0 @@
<h3>symDifference function</h3>
Returns a geometry that represents the portions of a and b that do not intersect.
<h4>Syntax</h4>
<pre>symDifference( geometry a, geometry b)</pre>
<h4>Arguments</h4>
geometry &rarr; geometry
geometry &rarr; geometry
<h4>Example</h4>
<pre> geomToWKT( symDifference( geomFromWKT( 'LINESTRING(3 3 , 4 4 , 5 5)' ) , geomFromWKT( 'LINESTRING(3 3 , 8 8)' )) ) &rarr; returns LINESTRING(5 5, 8 8)</pre>

View File

@ -0,0 +1,12 @@
<h3>sym_difference function</h3>
Returns a geometry that represents the portions of a and b that do not intersect.
<h4>Syntax</h4>
<pre>sym_difference( geometry a, geometry b)</pre>
<h4>Arguments</h4>
geometry &rarr; geometry
geometry &rarr; geometry
<h4>Example</h4>
<pre> geom_to_wkt( sym_difference( geom_from_wkt( 'LINESTRING(3 3 , 4 4 , 5 5)' ) , geom_from_wkt( 'LINESTRING(3 3 , 8 8)' )) ) &rarr; returns LINESTRING(5 5, 8 8)</pre>

View File

@ -1,8 +1,8 @@
<h3>todate() function</h3>
<h3>to_date() function</h3>
Convert a string into Qt data type.
<h4>Syntax</h4>
<code>todate('string')</code><br>
<code>to_date('string')</code><br>
<h4>Arguments</h4>
<code>string</code> - is string in Qt date format.
@ -10,4 +10,4 @@ Convert a string into Qt data type.
<h4>Example</h4>
<!-- Show example of function.-->
<code>todate('2012-05-04') &rarr; 2012-05-04</code><br>
<code>to_date('2012-05-04') &rarr; 2012-05-04</code><br>

View File

@ -1,8 +1,8 @@
<h3>todatetime() function</h3>
<h3>to_datetime() function</h3>
Convert a string into Qt data time type.
<h4>Syntax</h4>
<code>todatetime('string')</code><br>
<code>to_datetime('string')</code><br>
<h4>Arguments</h4>
<code>string</code> - is string in Qt date time format.
@ -10,4 +10,4 @@ Convert a string into Qt data time type.
<h4>Example</h4>
<!-- Show example of function.-->
<code>todatetime('2012-05-04 12:50:00') &rarr; 2012-05-04T12:50:00</code><br>
<code>to_datetime('2012-05-04 12:50:00') &rarr; 2012-05-04T12:50:00</code><br>

View File

@ -1,8 +1,8 @@
<h3>toint() function</h3>
<h3>to_int() function</h3>
Converts a string to integer number. Nothing changed if a value cannot be converted to integer (e.g '123asd' is invalid).
<p><h4>Syntax</h4>
toint(<i>string</i>)</p>
to_int(<i>string</i>)</p>
<p><h4>Arguments</h4>
<!-- List args for functions here-->
@ -10,4 +10,4 @@ Converts a string to integer number. Nothing changed if a value cannot be conver
<p><h4>Example</h4>
<!-- Show example of function.-->
toint('123') &rarr; 123</p>
to_int('123') &rarr; 123</p>

View File

@ -1,8 +1,8 @@
<h3>tointerval() function</h3>
<h3>to_interval() function</h3>
Converts a string to a interval type. Can be used to take days, hours, month, etc off a date.
<h4>Syntax</h4>
<code>tointerval('string')</code><br>
<code>to_interval('string')</code><br>
<h4>Arguments</h4>
<code>string</code> - is string. Format {n} days {n} hours {n} months
@ -10,4 +10,4 @@ Converts a string to a interval type. Can be used to take days, hours, month, e
<h4>Example</h4>
<!-- Show example of function.-->
<code>todatetime('2012-05-05 12:00:00') - tointerval('1 day 2 hours') &rarr; 2012-05-04T10:00:00</code><br>
<code>todatetime('2012-05-05 12:00:00') - to_interval('1 day 2 hours') &rarr; 2012-05-04T10:00:00</code><br>

View File

@ -1,8 +1,8 @@
<h3>toreal() function</h3>
<h3>to_real() function</h3>
Converts a string to real number. Nothing changed if a value cannot be converted to real (e.g '123.56asd' is invalid). Numbers are rounded after saving changes if the precision is smaller than the result of the conversion.
<p><h4>Syntax</h4>
toreal(<i>string</i>)</p>
to_real(<i>string</i>)</p>
<p><h4>Arguments</h4>
<!-- List args for functions here-->
@ -10,4 +10,4 @@ Converts a string to real number. Nothing changed if a value cannot be converted
<p><h4>Example</h4>
<!-- Show example of function.-->
toreal('123.45') &rarr; 123.45</p>
to_real('123.45') &rarr; 123.45</p>

View File

@ -1,8 +1,8 @@
<h3>tostring() function</h3>
<h3>to_string() function</h3>
Converts a number to string.
<p><h4>Syntax</h4>
tostring(<i>number</i>)</p>
to_string(<i>number</i>)</p>
<p><h4>Arguments</h4>
<!-- List args for functions here-->
@ -10,4 +10,4 @@ Converts a number to string.
<p><h4>Example</h4>
<!-- Show example of function.-->
tostring(123) &rarr; '123'</p>
to_string(123) &rarr; '123'</p>

View File

@ -1,8 +1,8 @@
<h3>totime() function</h3>
<h3>to_time() function</h3>
Convert a string into Qt time type.
<h4>Syntax</h4>
<code>totime('string')</code><br>
<code>to_time('string')</code><br>
<h4>Arguments</h4>
<code>string</code> - is string in Qt time format.
@ -10,4 +10,4 @@ Convert a string into Qt time type.
<h4>Example</h4>
<!-- Show example of function.-->
<code>totime('12:30:01') &rarr; 12:30:01</code><br>
<code>to_time('12:30:01') &rarr; 12:30:01</code><br>

View File

@ -1,11 +1,11 @@
<h3>xat() function</h3>
<h3>x_at() function</h3>
Retrieves a x coordinate of the current feature
<h4>Syntax</h4>
<code>xat(i)</code>
<code>x_at(i)</code>
<h4>Arguments</h4>
<code>i<code> - is int. index of point of a line (indices start at 0; negative values apply to the last index).
<h4>Example</h4>
<pre>xat(1) &rarr; 5</pre>
<pre>x_at(1) &rarr; 5</pre>

View File

@ -1,12 +1,12 @@
<h3>xmax function</h3>
<h3>x_max function</h3>
Returns the maximum x coordinate of a geometry. Calculations are in the Spatial Reference System of this Geometry.
<h4>Syntax</h4>
<pre>xmax(geom)</pre>
<pre>x_max(geom)</pre>
<h4>Arguments</h4>
geom &rarr; a geometry
<h4>Example</h4>
<pre> xmax($geometry) &rarr; returns maximum x coordinate of $geometry</pre>
<pre> x_max($geometry) &rarr; returns maximum x coordinate of $geometry</pre>

View File

@ -1,12 +1,12 @@
<h3>xmin function</h3>
<h3>x_min function</h3>
Returns the minimum x coordinate of a geometry. Calculations are in the Spatial Reference System of this Geometry.
<h4>Syntax</h4>
<pre>xmin(geom)</pre>
<pre>x_min(geom)</pre>
<h4>Arguments</h4>
geom &rarr; a geometry
<h4>Example</h4>
<pre> xmin($geometry) &rarr; returns minimum x coordinate of $geometry</pre>
<pre> x_min($geometry) &rarr; returns minimum x coordinate of $geometry</pre>

View File

@ -1,11 +1,11 @@
<h3>yat() function</h3>
<h3>y_at() function</h3>
Retrieves a y coordinate of the current feature
<h4>Syntax</h4>
<code>yat(i)</code>
<code>y_at(i)</code>
<h4>Arguments</h4>
<code>i<code> - is int. index of point of a line (indices start at 0; negative values apply to the last index).
<h4>Example</h4>
<pre>yat(1) &rarr; 5</pre>
<pre>y_at(1) &rarr; 5</pre>

View File

@ -1,12 +1,12 @@
<h3>ymax function</h3>
<h3>y_max function</h3>
Returns the maximum y coordinate of a geometry. Calculations are in the Spatial Reference System of this Geometry.
<h4>Syntax</h4>
<pre>ymax(geom)</pre>
<pre>y_max(geom)</pre>
<h4>Arguments</h4>
geom &rarr; a geometry
<h4>Example</h4>
<pre> ymax($geometry) &rarr; returns maximum y coordinate of $geometry</pre>
<pre> y_max($geometry) &rarr; returns maximum y coordinate of $geometry</pre>

View File

@ -1,12 +1,12 @@
<h3>ymin function</h3>
<h3>y_min function</h3>
Returns the minimum y coordinate of a geometry. Calculations are in the Spatial Reference System of this Geometry.
<h4>Syntax</h4>
<pre>ymin(geom)</pre>
<pre>y_min(geom)</pre>
<h4>Arguments</h4>
geom &rarr; a geometry
<h4>Example</h4>
<pre> ymin($geometry) &rarr; returns minimum y coordinate of $geometry</pre>
<pre> y_min($geometry) &rarr; returns minimum y coordinate of $geometry</pre>

View File

@ -1666,22 +1666,33 @@ const QStringList &QgsExpression::BuiltinFunctions()
<< "asin" << "acos" << "atan" << "atan2"
<< "exp" << "ln" << "log10" << "log"
<< "round" << "rand" << "randf" << "max" << "min" << "clamp"
<< "scale_linear" << "scale_exp" << "floor" << "ceil"
<< "toint" << "toreal" << "tostring"
<< "todatetime" << "todate" << "totime" << "tointerval"
<< "coalesce" << "regexp_match" << "$now" << "age" << "year"
<< "scale_linear" << "scale_exp" << "floor" << "ceil" << "$pi"
<< "toint" << "to_int" << "toreal" << "to_real" << "tostring" << "to_string"
<< "todatetime" << "to_datetime" << "todate" << "to_date"
<< "totime" << "to_time" << "tointerval" << "to_interval"
<< "coalesce" << "if" << "regexp_match" << "age" << "year"
<< "month" << "week" << "day" << "hour"
<< "minute" << "second" << "lower" << "upper"
<< "title" << "length" << "replace" << "trim" << "wordwrap"
<< "regexp_replace" << "regexp_substr"
<< "substr" << "concat" << "strpos" << "left"
<< "right" << "rpad" << "lpad"
<< "right" << "rpad" << "lpad" << "format"
<< "format_number" << "format_date"
<< "color_rgb" << "color_rgba" << "ramp_color"
<< "color_hsl" << "color_hsla" << "color_hsv" << "color_hsva"
<< "color_cymk" << "color_cymka"
<< "xat" << "yat" << "$area"
<< "$length" << "$perimeter" << "$x" << "$y"
<< "x_at" << "xat" << "y_at" << "yat" << "x_min" << "xmin" << "x_max" << "xmax"
<< "y_min" << "ymin" << "y_max" << "ymax" << "geom_from_wkt" << "geomFromWKT"
<< "geom_from_gml" << "geomFromGML" << "intersects_bbox" << "bbox"
<< "disjoint" << "intersects" << "touches" << "crosses" << "contains"
<< "overlaps" << "within" << "buffer" << "centroid" << "bounds"
<< "bounds_width" << "bounds_height" << "convex_hull" << "difference"
<< "distance" << "intersection" << "sym_difference" << "combine"
<< "union" << "geom_to_wkt" << "geomToWKT" << "geometry"
<< "transform" << "get_feature" << "getFeature"
<< "attribute"
<< "$rownum" << "$id" << "$scale" << "_specialcol_";
}
return gmBuiltinFunctions;
@ -1718,13 +1729,13 @@ const QList<QgsExpression::Function*> &QgsExpression::Functions()
<< new StaticFunction( "floor", 1, fcnFloor, "Math" )
<< new StaticFunction( "ceil", 1, fcnCeil, "Math" )
<< new StaticFunction( "$pi", 0, fcnPi, "Math" )
<< new StaticFunction( "toint", 1, fcnToInt, "Conversions" )
<< new StaticFunction( "toreal", 1, fcnToReal, "Conversions" )
<< new StaticFunction( "tostring", 1, fcnToString, "Conversions" )
<< new StaticFunction( "todatetime", 1, fcnToDateTime, "Conversions" )
<< new StaticFunction( "todate", 1, fcnToDate, "Conversions" )
<< new StaticFunction( "totime", 1, fcnToTime, "Conversions" )
<< new StaticFunction( "tointerval", 1, fcnToInterval, "Conversions" )
<< new StaticFunction( "to_int", 1, fcnToInt, "Conversions", QString(), false, QStringList(), false, QStringList() << "toint" )
<< new StaticFunction( "to_real", 1, fcnToReal, "Conversions", QString(), false, QStringList(), false, QStringList() << "toreal" )
<< new StaticFunction( "to_string", 1, fcnToString, "Conversions", QString(), false, QStringList(), false, QStringList() << "tostring" )
<< new StaticFunction( "to_datetime", 1, fcnToDateTime, "Conversions", QString(), false, QStringList(), false, QStringList() << "todatetime" )
<< new StaticFunction( "to_date", 1, fcnToDate, "Conversions", QString(), false, QStringList(), false, QStringList() << "todate" )
<< new StaticFunction( "to_time", 1, fcnToTime, "Conversions", QString(), false, QStringList(), false, QStringList() << "totime" )
<< new StaticFunction( "to_interval", 1, fcnToInterval, "Conversions", QString(), false, QStringList(), false, QStringList() << "tointerval" )
<< new StaticFunction( "coalesce", -1, fcnCoalesce, "Conditionals" )
<< new StaticFunction( "if", 3, fcnIf, "Conditionals", "", False, QStringList(), true )
<< new StaticFunction( "regexp_match", 2, fcnRegexpMatch, "Conditionals" )
@ -1771,15 +1782,15 @@ const QList<QgsExpression::Function*> &QgsExpression::Functions()
<< new StaticFunction( "$perimeter", 0, fcnGeomPerimeter, "GeometryGroup", "", true )
<< new StaticFunction( "$x", 0, fcnX, "GeometryGroup", "", true )
<< new StaticFunction( "$y", 0, fcnY, "GeometryGroup", "", true )
<< new StaticFunction( "xat", 1, fcnXat, "GeometryGroup", "", true )
<< new StaticFunction( "yat", 1, fcnYat, "GeometryGroup", "", true )
<< new StaticFunction( "xmin", 1, fcnXMin, "GeometryGroup", "", true )
<< new StaticFunction( "xmax", 1, fcnXMax, "GeometryGroup", "", true )
<< new StaticFunction( "ymin", 1, fcnYMin, "GeometryGroup", "", true )
<< new StaticFunction( "ymax", 1, fcnYMax, "GeometryGroup", "", true )
<< new StaticFunction( "geomFromWKT", 1, fcnGeomFromWKT, "GeometryGroup" )
<< new StaticFunction( "geomFromGML", 1, fcnGeomFromGML, "GeometryGroup" )
<< new StaticFunction( "bbox", 2, fcnBbox, "GeometryGroup" )
<< new StaticFunction( "x_at", 1, fcnXat, "GeometryGroup", "", true, QStringList(), false, QStringList() << "xat" )
<< new StaticFunction( "y_at", 1, fcnYat, "GeometryGroup", "", true, QStringList(), false, QStringList() << "yat" )
<< new StaticFunction( "x_min", 1, fcnXMin, "GeometryGroup", "", true, QStringList(), false, QStringList() << "xmin" )
<< new StaticFunction( "x_max", 1, fcnXMax, "GeometryGroup", "", true, QStringList(), false, QStringList() << "xmax" )
<< new StaticFunction( "y_min", 1, fcnYMin, "GeometryGroup", "", true, QStringList(), false, QStringList() << "ymin" )
<< new StaticFunction( "y_max", 1, fcnYMax, "GeometryGroup", "", true, QStringList(), false, QStringList() << "ymax" )
<< new StaticFunction( "geom_from_wkt", 1, fcnGeomFromWKT, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "geomFromWKT" )
<< new StaticFunction( "geom_from_gml", 1, fcnGeomFromGML, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "geomFromGML" )
<< new StaticFunction( "intersects_bbox", 2, fcnBbox, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "bbox" )
<< new StaticFunction( "disjoint", 2, fcnDisjoint, "GeometryGroup" )
<< new StaticFunction( "intersects", 2, fcnIntersects, "GeometryGroup" )
<< new StaticFunction( "touches", 2, fcnTouches, "GeometryGroup" )
@ -1792,14 +1803,14 @@ const QList<QgsExpression::Function*> &QgsExpression::Functions()
<< new StaticFunction( "bounds", 1, fcnBounds, "GeometryGroup", "", true )
<< new StaticFunction( "bounds_width", 1, fcnBoundsWidth, "GeometryGroup", "", true )
<< new StaticFunction( "bounds_height", 1, fcnBoundsHeight, "GeometryGroup", "", true )
<< new StaticFunction( "convexHull", 1, fcnConvexHull, "GeometryGroup" )
<< new StaticFunction( "convex_hull", 1, fcnConvexHull, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "convexHull" )
<< new StaticFunction( "difference", 2, fcnDifference, "GeometryGroup" )
<< new StaticFunction( "distance", 2, fcnDistance, "GeometryGroup" )
<< new StaticFunction( "intersection", 2, fcnIntersection, "GeometryGroup" )
<< new StaticFunction( "symDifference", 2, fcnSymDifference, "GeometryGroup" )
<< new StaticFunction( "sym_difference", 2, fcnSymDifference, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "symDifference" )
<< new StaticFunction( "combine", 2, fcnCombine, "GeometryGroup" )
<< new StaticFunction( "union", 2, fcnCombine, "GeometryGroup" )
<< new StaticFunction( "geomToWKT", -1, fcnGeomToWKT, "GeometryGroup" )
<< new StaticFunction( "geom_to_wkt", -1, fcnGeomToWKT, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "geomToWKT" )
<< new StaticFunction( "geometry", 1, fcnGetGeometry, "GeometryGroup" )
<< new StaticFunction( "transform", 3, fcnTransformGeometry, "GeometryGroup" )
<< new StaticFunction( "$rownum", 0, fcnRowNumber, "Record" )
@ -1807,7 +1818,7 @@ const QList<QgsExpression::Function*> &QgsExpression::Functions()
<< new StaticFunction( "$currentfeature", 0, fcnFeature, "Record" )
<< new StaticFunction( "$scale", 0, fcnScale, "Record" )
<< new StaticFunction( "$uuid", 0, fcnUuid, "Record" )
<< new StaticFunction( "getFeature", 3, fcnGetFeature, "Record" )
<< new StaticFunction( "get_feature", 3, fcnGetFeature, "Record", QString(), false, QStringList(), false, QStringList() << "getFeature" )
//return all attributes string for referencedColumns - this is caught by
// QgsFeatureRequest::setSubsetOfAttributes and causes all attributes to be fetched by the
@ -1933,13 +1944,18 @@ bool QgsExpression::isFunctionName( QString name )
return functionIndex( name ) != -1;
}
int QgsExpression::functionIndex( QString name )
int QgsExpression::functionIndex( const QString &name )
{
int count = functionCount();
for ( int i = 0; i < count; i++ )
{
if ( QString::compare( name, Functions()[i]->name(), Qt::CaseInsensitive ) == 0 )
return i;
foreach ( QString alias, Functions()[i]->aliases() )
{
if ( QString::compare( name, alias, Qt::CaseInsensitive ) == 0 )
return i;
}
}
return -1;
}

View File

@ -295,6 +295,13 @@ class CORE_EXPORT QgsExpression
/** Does this function use a geometry object. */
bool usesgeometry() { return mUsesGeometry; }
/** Returns a list of possible aliases for the function. These include
* other permissible names for the function, eg deprecated names.
* @return list of known aliases
* @note added in QGIS 2.9
*/
virtual QStringList aliases() const { return QStringList(); }
/** True if this function should use lazy evaluation. Lazy evaluation functions take QgsExpression::Node objects
* rather than the node results when called. You can use node->eval(parent, feature) to evaluate the node and return the result
* Functions are non lazy default and will be given the node return value when called **/
@ -330,16 +337,19 @@ class CORE_EXPORT QgsExpression
class StaticFunction : public Function
{
public:
StaticFunction( QString fnname, int params, FcnEval fcn, QString group, QString helpText = QString(), bool usesGeometry = false, QStringList referencedColumns = QStringList(), bool lazyEval = false )
: Function( fnname, params, group, helpText, usesGeometry, referencedColumns, lazyEval ), mFnc( fcn ) {}
StaticFunction( QString fnname, int params, FcnEval fcn, QString group, QString helpText = QString(), bool usesGeometry = false, QStringList referencedColumns = QStringList(), bool lazyEval = false, const QStringList& aliases = QStringList() )
: Function( fnname, params, group, helpText, usesGeometry, referencedColumns, lazyEval ), mFnc( fcn ), mAliases( aliases ) {}
virtual QVariant func( const QVariantList& values, const QgsFeature* f, QgsExpression* parent ) override
{
return mFnc( values, f, parent );
}
virtual QStringList aliases() const override { return mAliases; }
private:
FcnEval mFnc;
QStringList mAliases;
};
static const QList<Function*> &Functions();
@ -355,7 +365,7 @@ class CORE_EXPORT QgsExpression
static bool isFunctionName( QString name );
// return index of the function in Functions array
static int functionIndex( QString name );
static int functionIndex( const QString& name );
/** Returns the number of functions defined in the parser
* @return The number of function defined in the parser.

View File

@ -2128,7 +2128,7 @@ static QgsGeometry* geometryFromConstExpr( const QgsExpression::Node* node )
{
const QgsExpression::NodeFunction* fnNode = static_cast<const QgsExpression::NodeFunction*>( node );
QgsExpression::Function* fnDef = QgsExpression::Functions()[fnNode->fnIndex()];
if ( fnDef->name() == "geomFromWKT" )
if ( fnDef->name() == "geom_from_wkt" )
{
const QList<QgsExpression::Node*>& args = fnNode->args()->list();
if ( args[0]->nodeType() == QgsExpression::ntLiteral )
@ -2146,7 +2146,7 @@ QDomElement QgsOgcUtils::expressionFunctionToOgcFilter( const QgsExpression::Nod
{
QgsExpression::Function* fd = QgsExpression::Functions()[node->fnIndex()];
if ( fd->name() == "bbox" )
if ( fd->name() == "intersects_bbox" )
{
QList<QgsExpression::Node*> argNodes = node->args()->list();
Q_ASSERT( argNodes.count() == 2 ); // binary spatial ops must have two args
@ -2203,12 +2203,12 @@ QDomElement QgsOgcUtils::expressionFunctionToOgcFilter( const QgsExpression::Nod
const QgsExpression::NodeFunction* otherFn = static_cast<const QgsExpression::NodeFunction*>( otherNode );
QgsExpression::Function* otherFnDef = QgsExpression::Functions()[otherFn->fnIndex()];
if ( otherFnDef->name() == "geomFromWKT" )
if ( otherFnDef->name() == "geom_from_wkt" )
{
QgsExpression::Node* firstFnArg = otherFn->args()->list()[0];
if ( firstFnArg->nodeType() != QgsExpression::ntLiteral )
{
errorMessage = "geomFromWKT: argument must be string literal";
errorMessage = "geom_from_wkt: argument must be string literal";
return QDomElement();
}
QString wkt = static_cast<const QgsExpression::NodeLiteral*>( firstFnArg )->value().toString();
@ -2216,12 +2216,12 @@ QDomElement QgsOgcUtils::expressionFunctionToOgcFilter( const QgsExpression::Nod
otherGeomElem = QgsOgcUtils::geometryToGML( geom, doc );
delete geom;
}
else if ( otherFnDef->name() == "geomFromGML" )
else if ( otherFnDef->name() == "geom_from_gml" )
{
QgsExpression::Node* firstFnArg = otherFn->args()->list()[0];
if ( firstFnArg->nodeType() != QgsExpression::ntLiteral )
{
errorMessage = "geomFromGML: argument must be string literal";
errorMessage = "geom_from_gml: argument must be string literal";
return QDomElement();
}
@ -2229,7 +2229,7 @@ QDomElement QgsOgcUtils::expressionFunctionToOgcFilter( const QgsExpression::Nod
QString gml = static_cast<const QgsExpression::NodeLiteral*>( firstFnArg )->value().toString();
if ( !geomDoc.setContent( gml, true ) )
{
errorMessage = "geomFromGML: unable to parse XML";
errorMessage = "geom_from_gml: unable to parse XML";
return QDomElement();
}

View File

@ -145,6 +145,43 @@ class TestQgsExpression: public QObject
QCOMPARE( v.toDouble(), 5.79 );
}
void alias_data()
{
//test function aliases
QTest::addColumn<QString>( "string" );
QTest::addColumn<bool>( "evalError" );
QTest::addColumn<QString>( "dump" );
QTest::addColumn<QVariant>( "result" );
QTest::newRow( "toint alias" ) << "toint(3.2)" << false << "to_int(3.2)" << QVariant( 3 );
QTest::newRow( "int to double" ) << "toreal(3)" << false << "to_real(3)" << QVariant( 3. );
QTest::newRow( "int to text" ) << "tostring(6)" << false << "to_string(6)" << QVariant( "6" );
}
void alias()
{
QFETCH( QString, string );
QFETCH( bool, evalError );
QFETCH( QString, dump );
QFETCH( QVariant, result );
QgsExpression exp( string );
QCOMPARE( exp.hasParserError(), false );
if ( exp.hasParserError() )
qDebug() << exp.parserErrorString();
QVariant res = exp.evaluate();
if ( exp.hasEvalError() )
qDebug() << exp.evalErrorString();
if ( res.type() != result.type() )
{
qDebug() << "got " << res.typeName() << " instead of " << result.typeName();
}
QCOMPARE( exp.hasEvalError(), evalError );
QCOMPARE( res, result );
QCOMPARE( exp.dump(), dump );
}
void evaluation_data()
{
QTest::addColumn<QString>( "string" );
@ -794,7 +831,7 @@ class TestQgsExpression: public QObject
QgsPolygon polygon;
polygon << polygon_ring;
QTest::newRow( "geomFromWKT Point" ) << "geomFromWKT('" + QgsGeometry::fromPoint( point )->exportToWkt() + "')" << ( void* ) QgsGeometry::fromPoint( point ) << false;
QTest::newRow( "geomFromWKT Point" ) << "geom_from_wkt('" + QgsGeometry::fromPoint( point )->exportToWkt() + "')" << ( void* ) QgsGeometry::fromPoint( point ) << false;
QTest::newRow( "geomFromWKT Line" ) << "geomFromWKT('" + QgsGeometry::fromPolyline( line )->exportToWkt() + "')" << ( void* ) QgsGeometry::fromPolyline( line ) << false;
QTest::newRow( "geomFromWKT Polyline" ) << "geomFromWKT('" + QgsGeometry::fromPolyline( polyline )->exportToWkt() + "')" << ( void* ) QgsGeometry::fromPolyline( polyline ) << false;
QTest::newRow( "geomFromWKT Polygon" ) << "geomFromWKT('" + QgsGeometry::fromPolygon( polygon )->exportToWkt() + "')" << ( void* ) QgsGeometry::fromPolygon( polygon ) << false;

View File

@ -174,7 +174,7 @@ void TestQgsOgcUtils::testExpressionFromOgcFilter_data()
"<BBOX><PropertyName>Name>NAME</PropertyName><gml:Box srsName='foo'>"
"<gml:coordinates>135.2239,34.4879 135.8578,34.8471</gml:coordinates></gml:Box></BBOX>"
"</Filter>" )
<< QString( "bbox($geometry, geomFromGML('<Box srsName=\"foo\"><coordinates>135.2239,34.4879 135.8578,34.8471</coordinates></Box>'))" );
<< QString( "intersects_bbox($geometry, geom_from_gml('<Box srsName=\"foo\"><coordinates>135.2239,34.4879 135.8578,34.8471</coordinates></Box>'))" );
QTest::newRow( "Intersects" ) << QString(
"<Filter>"
@ -185,7 +185,7 @@ void TestQgsOgcUtils::testExpressionFromOgcFilter_data()
"</gml:Point>"
"</Intersects>"
"</Filter>" )
<< QString( "intersects($geometry, geomFromGML('<Point><coordinates>123,456</coordinates></Point>'))" );
<< QString( "intersects($geometry, geom_from_gml('<Point><coordinates>123,456</coordinates></Point>'))" );
}
void TestQgsOgcUtils::testExpressionFromOgcFilter()
@ -326,7 +326,7 @@ void TestQgsOgcUtils::testExpressionToOgcFilter_data()
/*
QTest::newRow( "bbox with GML3 Envelope" )
<< QString( "bbox($geometry, geomFromGML('<gml:Envelope><gml:lowerCorner>13.0983 31.5899</gml:lowerCorner><gml:upperCorner>35.5472 42.8143</gml:upperCorner></gml:Envelope>'))" )
<< QString( "intersects_bbox($geometry, geomFromGML('<gml:Envelope><gml:lowerCorner>13.0983 31.5899</gml:lowerCorner><gml:upperCorner>35.5472 42.8143</gml:upperCorner></gml:Envelope>'))" )
<< QString(
"<ogc:Filter>"
"<ogc:BBOX>"