18
18
19
19
QgsPostgresExpressionCompiler::QgsPostgresExpressionCompiler ( QgsPostgresFeatureSource* source )
20
20
: QgsSqlExpressionCompiler( source->mFields )
21
+ , mGeometryColumn( source->mGeometryColumn )
22
+ , mSpatialColType( source->mSpatialColType )
23
+ , mDetectedGeomType( source->mDetectedGeomType )
24
+ , mRequestedGeomType( source->mRequestedGeomType )
25
+ , mRequestedSrid( source->mRequestedSrid )
26
+ , mDetectedSrid( source->mDetectedSrid )
21
27
{
22
28
}
23
29
@@ -32,3 +38,150 @@ QString QgsPostgresExpressionCompiler::quotedValue( const QVariant& value, bool&
32
38
return QgsPostgresConn::quotedValue ( value );
33
39
}
34
40
41
+ static const QMap<QString, QString>& functionNamesSqlFunctionsMap ()
42
+ {
43
+ static QMap<QString, QString> fnNames;
44
+ if ( fnNames.isEmpty () )
45
+ {
46
+ fnNames =
47
+ {
48
+ { " sqrt" , " sqrt" },
49
+ { " radians" , " radians" },
50
+ { " degrees" , " degrees" },
51
+ { " abs" , " abs" },
52
+ { " cos" , " cos" },
53
+ { " sin" , " sin" },
54
+ { " tan" , " tan" },
55
+ { " acos" , " acos" },
56
+ { " asin" , " asin" },
57
+ { " atan" , " atan" },
58
+ { " atan2" , " atan2" },
59
+ { " exp" , " exp" },
60
+ { " ln" , " ln" },
61
+ { " log" , " log" },
62
+ { " log10" , " log" },
63
+ { " round" , " round" },
64
+ { " floor" , " floor" },
65
+ { " ceil" , " ceil" },
66
+ { " pi" , " pi" },
67
+ // geometry functions
68
+ // { "azimuth", "ST_Azimuth" },
69
+ { " x" , " ST_X" },
70
+ { " y" , " ST_Y" },
71
+ // { "z", "ST_Z" },
72
+ // { "m", "ST_M" },
73
+ { " x_min" , " ST_XMin" },
74
+ { " y_min" , " ST_YMin" },
75
+ { " x_max" , " ST_XMax" },
76
+ { " y_max" , " ST_YMax" },
77
+ { " area" , " ST_Area" },
78
+ { " perimeter" , " ST_Perimeter" },
79
+ { " relate" , " ST_Relate" },
80
+ { " disjoint" , " ST_Disjoint" },
81
+ { " intersects" , " ST_Intersects" },
82
+ // { "touches", "ST_Touches" },
83
+ { " crosses" , " ST_Crosses" },
84
+ { " contains" , " ST_Contains" },
85
+ { " overlaps" , " ST_Overlaps" },
86
+ { " within" , " ST_Within" },
87
+ { " translate" , " ST_Translate" },
88
+ { " buffer" , " ST_Buffer" },
89
+ { " centroid" , " ST_Centroid" },
90
+ { " point_on_surface" , " ST_PointOnSurface" },
91
+ // { "reverse", "ST_Reverse" },
92
+ // { "is_closed", "ST_IsClosed" },
93
+ // { "convex_hull", "ST_ConvexHull" },
94
+ // { "difference", "ST_Difference" },
95
+ { " distance" , " ST_Distance" },
96
+ // { "intersection", "ST_Intersection" },
97
+ // { "sym_difference", "ST_SymDifference" },
98
+ // { "combine", "ST_Union" },
99
+ // { "union", "ST_Union" },
100
+ { " geom_from_wkt" , " ST_GeomFromText" },
101
+ { " geom_from_gml" , " ST_GeomFromGML" }
102
+ };
103
+ }
104
+ return fnNames;
105
+ }
106
+
107
+ QString QgsPostgresExpressionCompiler::sqlFunctionFromFunctionName ( const QString& fnName ) const
108
+ {
109
+ return functionNamesSqlFunctionsMap ().value ( fnName, QString () );
110
+ }
111
+
112
+ QStringList QgsPostgresExpressionCompiler::sqlArgumentsFromFunctionName ( const QString& fnName, const QStringList& fnArgs ) const
113
+ {
114
+ QStringList args ( fnArgs );
115
+ if ( fnName == " geom_from_wkt" )
116
+ {
117
+ args << ( mRequestedSrid .isEmpty () ? mDetectedSrid : mRequestedSrid );
118
+ }
119
+ else if ( fnName == " geom_from_gml" )
120
+ {
121
+ args << ( mRequestedSrid .isEmpty () ? mDetectedSrid : mRequestedSrid );
122
+ }
123
+ else if ( fnName == " x" || fnName == " y" )
124
+ {
125
+ args = QStringList ( QStringLiteral ( " ST_Centroid(%1)" ).arg ( args[0 ] ) );
126
+ }
127
+ else if ( fnName == " buffer" && args.length () == 2 )
128
+ {
129
+ args << " 8" ;
130
+ }
131
+ // x and y functions have to be adapted
132
+ return args;
133
+ }
134
+
135
+ QgsSqlExpressionCompiler::Result QgsPostgresExpressionCompiler::compileNode ( const QgsExpression::Node* node, QString& result )
136
+ {
137
+ switch ( node->nodeType () )
138
+ {
139
+ case QgsExpression::ntFunction:
140
+ {
141
+ const QgsExpression::NodeFunction* n = static_cast <const QgsExpression::NodeFunction*>( node );
142
+
143
+ QgsExpression::Function* fd = QgsExpression::Functions ()[n->fnIndex ()];
144
+ if ( fd->name () == " $geometry" )
145
+ {
146
+ result = quotedIdentifier ( mGeometryColumn );
147
+ return Complete;
148
+ }
149
+ /*
150
+ * These methods are tricky
151
+ * QGIS expression versions of these return ellipsoidal measurements
152
+ * based on the project settings, and also convert the result to the
153
+ * units specified in project properties.
154
+ else if ( fd->name() == "$area" )
155
+ {
156
+ result = QStringLiteral( "ST_Area(%1)" ).arg( quotedIdentifier( mGeometryColumn ) );
157
+ return Complete;
158
+ }
159
+ else if ( fd->name() == "$length" )
160
+ {
161
+ result = QStringLiteral( "ST_Length(%1)" ).arg( quotedIdentifier( mGeometryColumn ) );
162
+ return Complete;
163
+ }
164
+ else if ( fd->name() == "$perimeter" )
165
+ {
166
+ result = QStringLiteral( "ST_Perimeter(%1)" ).arg( quotedIdentifier( mGeometryColumn ) );
167
+ return Complete;
168
+ }
169
+ else if ( fd->name() == "$x" )
170
+ {
171
+ result = QStringLiteral( "ST_X(%1)" ).arg( quotedIdentifier( mGeometryColumn ) );
172
+ return Complete;
173
+ }
174
+ else if ( fd->name() == "$y" )
175
+ {
176
+ result = QStringLiteral( "ST_Y(%1)" ).arg( quotedIdentifier( mGeometryColumn ) );
177
+ return Complete;
178
+ }
179
+ */
180
+ }
181
+
182
+ default :
183
+ return QgsSqlExpressionCompiler::compileNode ( node, result );
184
+ }
185
+
186
+ return Fail;
187
+ }
0 commit comments