Statistics
| Revision:

gvsig-sqlite / trunk / org.gvsig.spatialite / org.gvsig.spatialite.provider / src / main / java / org / gvsig / spatialite / dal / expressionbuilderformatter / ST_Intersects.java @ 196

History | View | Annotate | Download (4.67 KB)

1
package org.gvsig.spatialite.dal.expressionbuilderformatter;
2

    
3
import java.text.MessageFormat;
4
import java.util.List;
5
import org.apache.commons.lang3.StringUtils;
6
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_ST_ENVELOPE;
7
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_ST_INTERSECTS;
8
import org.gvsig.expressionevaluator.ExpressionBuilder.Function;
9
import org.gvsig.expressionevaluator.ExpressionBuilder.Value;
10
import org.gvsig.expressionevaluator.ExpressionBuilder.Variable;
11
import org.gvsig.expressionevaluator.Formatter;
12
import org.gvsig.fmap.dal.SQLBuilder;
13
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
14
import org.gvsig.fmap.dal.feature.FeatureType;
15
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters;
16
import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory.TableReference;
17
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase;
18

    
19
/**
20
 *
21
 * @author jjdelcerro
22
 */
23
class ST_Intersects implements Formatter<Value> {
24

    
25
    private final Formatter<Value> formatter;
26
    private final SQLBuilder builder;
27
    private String column;
28
    private String table;
29
    
30
    public ST_Intersects(SQLBuilder builder, Formatter<Value> formatter) {
31
        this.builder = builder;
32
        this.formatter = formatter;
33
    }
34
    
35
    @Override
36
    public boolean canApply(Value value) {
37
        if (value instanceof Function) {
38
            return StringUtils.equalsIgnoreCase(FUNCTION_ST_INTERSECTS, ((Function) value).name());
39
        }
40
        return false;
41
    }
42

    
43
    @Override
44
    public String format(Value function) {
45
        String r ;
46
        List<Value> parameters = ((Function) function).parameters();
47
        Value geom1 = parameters.get(0);
48
        Value geom2 = parameters.get(1);
49
        if( this.useSpatialIndex(geom1, geom2) ) {
50
            r = MessageFormat.format(
51
                "(ST_Intersects({0},{1}) AND ROWID IN ( SELECT ROWID FROM SpatialIndex WHERE f_table_name = ''{2}'' AND f_geometry_column = ''{3}'' AND search_frame = \"{2}\".\"{3}\"))",
52
                    geom1.toString(this.formatter),
53
                    geom2.toString(this.formatter),
54
                    this.table,
55
                    this.column
56
            );
57
        } else {
58
            r = MessageFormat.format(
59
                "(ST_Intersects({0},{1}))",
60
                    geom1.toString(this.formatter),
61
                    geom2.toString(this.formatter)
62
            );
63
        }
64
        return r;
65
    }
66

    
67
    private boolean useSpatialIndex(Value... values) {
68
        for (Value value : values) {
69
            if( value instanceof Variable ) {
70
                if( useSpatialIndex((Variable)value) ) {
71
                    return true;
72
                }
73
            } 
74
            // Tambien comprobamos si el argumento es la funcion 
75
            // ST_Envelope sobre un campo geometria, si es asi tambien usaremos el 
76
            // indice espacial, cubriendo el caso de que se use algo como:
77
            //   ST_Intersects(x, ST_Envelope("geom"))
78
            if( value instanceof Function ) {
79
                if( ((Function) value).name().equalsIgnoreCase(FUNCTION_ST_ENVELOPE) ) {
80
                    Value value2 = ((Function) value).parameters().get(0);
81
                    if( value2 instanceof Variable ) {
82
                        if( useSpatialIndex((Variable)value2) ) {
83
                            return true;
84
                        }
85
                    } 
86
                }
87
            }
88
        }
89
        return false;
90
    }    
91

    
92
    private boolean useSpatialIndex(Variable var) {
93
        // Usaremos indice espacial si podemos tener acceso al nombre del 
94
        // campo y la tabla.
95
        this.column = var.name();
96
        TableReference theTable = (TableReference) var.getProperty(
97
                JDBCSQLBuilderBase.PROP_TABLE
98
        );
99
        if( theTable!=null ) {
100
            this.table = theTable.getTable();
101
        }
102

    
103
        FeatureType type = (FeatureType) var.getProperty(
104
                JDBCSQLBuilderBase.PROP_FEATURE_TYPE
105
        );
106
        if( type != null ) {
107
            FeatureAttributeDescriptor attrdesc = type.getAttributeDescriptor(var.name());
108
            if( attrdesc != null ) {
109
                this.column = attrdesc.getName();
110
            }
111
            if( this.table == null ) {
112
                try {
113
                    JDBCStoreParameters jdbcparams = (JDBCStoreParameters) type
114
                            .getStore().getParameters();
115
                    this.table = jdbcparams.getTable();
116
                } catch(Exception ex) {
117
                }
118
            }
119
        }
120
        
121
        if( this.table == null || this.column == null ) {
122
            this.table = null;
123
            this.column = null;
124
            return false;
125
        }
126
        return true;
127
    }
128

    
129
}