-
Notifications
You must be signed in to change notification settings - Fork 4
/
QServRegionConverter.java
146 lines (122 loc) · 4.45 KB
/
QServRegionConverter.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package org.opencadc.tap.impl;
import java.util.ArrayList;
import java.util.List;
import ca.nrc.cadc.tap.parser.navigator.ExpressionNavigator;
import ca.nrc.cadc.tap.parser.navigator.FromItemNavigator;
import ca.nrc.cadc.tap.parser.navigator.ReferenceNavigator;
import ca.nrc.cadc.tap.parser.RegionFinder;
import net.sf.jsqlparser.expression.BinaryExpression;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.Function;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.schema.Column;
import org.apache.log4j.Logger;
import org.opencadc.tap.impl.QServCircle;
import org.opencadc.tap.impl.QServPoint;
import org.opencadc.tap.impl.QServRegionColumn;
/**
* This class implements the rewriting of all ADQL geometry constructs
* as QServ specific geometry functions. This extends the RegionFinder,
* which by default for functions not overridden in this class throws
* UnsupportedOperationException.
*
* @author cbanek
*/
public class QServRegionConverter extends RegionFinder
{
private static Logger log = Logger.getLogger(QServRegionConverter.class);
public QServRegionConverter(ExpressionNavigator en, ReferenceNavigator rn, FromItemNavigator fn)
{
super(en, rn, fn);
}
/**
* This method is called when a REGION PREDICATE function is
* one of the arguments in a binary expression, and after the
* direct function conversion (like handleCircle, etc).
*
*/
@Override
protected Expression handleRegionPredicate(BinaryExpression biExpr)
{
log.debug("handleRegionPredicate(" + biExpr.getClass().getSimpleName() + "): " + biExpr);
return biExpr;
}
/**
* This function is called to parse out a CONTAINS, and the expressions are
* already parsed arguments.
*/
@Override
protected Expression handleContains(Expression left, Expression right)
{
if(!(left instanceof QServPoint)) {
throw new UnsupportedOperationException("CONTAINS first argument must be a point");
}
QServPoint point = (QServPoint)left;
if(right instanceof QServRegion) {
QServRegion region = (QServRegion)right;
return region.pointInRegion(point);
}
if(right instanceof Column && ((Column)right).getColumnName().equals("s_region")) {
return QServRegionColumn.pointInRegion(point);
}
throw new UnsupportedOperationException("CONTAINS second argument must be a region or s_region but got: " + right);
}
@Override
protected Expression handlePoint(Expression coordsys, Expression ra, Expression dec)
{
return new QServPoint(coordsys, ra, dec);
}
/**
* This method is called when a CIRCLE geometry value is found.
*
* From CIRCLE(coordinate_system, ra, dec, radius)
* To scisql_s2PtInCircle(long [deg], lat [deg], radius [deg])
*
*/
@Override
protected Expression handleCircle(Expression coordsys, Expression ra, Expression dec, Expression radius)
{
return new QServCircle(coordsys, ra, dec, radius);
}
/**
* This method is called whenever BOX geometry is found.
* We don't support this.
*/
@Override
protected Expression handleBox(Function adqlFunction)
{
throw new UnsupportedOperationException("ADQL BOX is not supported. You might be able to use qserv_areaspec_box and scisql_s2PtInBox.");
}
/**
* This method is called when a POLYGON geometry value is found.
**/
@Override
protected Expression handlePolygon(List<Expression> expressions)
{
return new QServPolygon(expressions);
}
/**
* This method is called when a DISTANCE function is found.
**/
@Override
protected Expression handleDistance(Expression left, Expression right)
{
if(!(left instanceof QServPoint)) {
throw new UnsupportedOperationException("DISTANCE first argument must be a point");
}
if(!(right instanceof QServPoint)) {
throw new UnsupportedOperationException("DISTANCE second argument must be a point");
}
QServPoint p1 = (QServPoint)left;
QServPoint p2 = (QServPoint)right;
List<Expression> params = new ArrayList<Expression>();
params.add(p1.getRA());
params.add(p1.getDec());
params.add(p2.getRA());
params.add(p2.getDec());
Function distanceFunction = new Function();
distanceFunction.setName("scisql_angSep");
distanceFunction.setParameters(new ExpressionList(params));
return distanceFunction;
}
}