Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.db / org.gvsig.fmap.dal.db.jdbc / src / main / java / org / gvsig / fmap / dal / store / jdbc2 / spi / operations / CalculateEnvelopeOfColumnOperation.java @ 44376

History | View | Annotate | Download (5.65 KB)

1
package org.gvsig.fmap.dal.store.jdbc2.spi.operations;
2

    
3
import java.sql.Connection;
4
import java.sql.ResultSet;
5
import java.sql.SQLException;
6
import java.sql.Statement;
7
import org.apache.commons.lang3.StringUtils;
8
import org.cresques.cts.IProjection;
9
import org.gvsig.expressionevaluator.ExpressionBuilder;
10
import org.gvsig.expressionevaluator.ExpressionBuilder.Variable;
11
import org.gvsig.fmap.dal.exception.DataException;
12
import org.gvsig.fmap.dal.feature.FeatureType;
13
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCSQLException;
14
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
15
import org.gvsig.fmap.dal.store.jdbc2.JDBCUtils;
16
import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory.TableReference;
17
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase;
18
import static org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase.PROP_TABLE;
19
import org.gvsig.fmap.geom.Geometry;
20
import org.gvsig.fmap.geom.primitive.Envelope;
21

    
22
public class CalculateEnvelopeOfColumnOperation extends AbstractConnectionOperation {
23

    
24
    private final TableReference table;
25
    private final String columnName;
26
    private final String baseFilter;
27
    private final Envelope limit;
28
    private final IProjection crs;
29
    private final FeatureType featureType;
30

    
31
    public CalculateEnvelopeOfColumnOperation(
32
            JDBCHelper helper,
33
            FeatureType featureType,
34
            TableReference table,
35
            String columnName,
36
            String baseFilter,
37
            Envelope limit,
38
            IProjection crs
39
    ) {
40
        super(helper);
41
        this.featureType = featureType;
42
        this.table = table;
43
        this.columnName = columnName;
44
        this.baseFilter = baseFilter;
45
        this.limit = limit;
46
        this.crs = crs;
47
    }
48

    
49
    @Override
50
    public final Object perform(Connection conn) throws DataException {
51
        Envelope env = calculateEnvelopeOfColumn(
52
            conn,
53
            featureType,
54
            table,
55
            columnName,
56
            baseFilter,
57
            limit,
58
            crs
59
        );
60
        return env;
61
    }
62

    
63
    public Envelope calculateEnvelopeOfColumn(
64
            Connection conn,
65
            FeatureType featureType,
66
            TableReference table,
67
            String columnName,
68
            String baseFilter,
69
            Envelope limit,
70
            IProjection crs
71
    ) throws DataException {
72

    
73
        //
74
        // Parece ser que en versiones anteriores a SQL Server 2012 no esta
75
        // disponible la funcion ST_ExtentAggregate.
76
        // Habria que determinar si es necesario implementar una alternativa
77
        // para estos casos.
78
        //
79
        // https://alastaira.wordpress.com/2011/07/26/determining-the-geographic-extent-of-spatial-features-in-a-sql-server-table/
80
        //
81
        JDBCSQLBuilderBase sqlbuilder = this.createSQLBuilder();
82
        ExpressionBuilder expbuilder = sqlbuilder.expression();
83
        
84
        sqlbuilder.select().column().value(
85
//            expbuilder.ifnull(
86
//                expbuilder.column(columnName), 
87
//                expbuilder.constant(null), 
88
                expbuilder.as_geometry(
89
                    expbuilder.ST_ExtentAggregate(
90
                            expbuilder.column(columnName)
91
                    )
92
                )
93
//            )
94
        );
95
//        sqlbuilder.select().group_by(expbuilder.column(columnName));
96
        sqlbuilder.select().from().table()
97
                .database(this.table.getDatabase())
98
                .schema(this.table.getSchema())
99
                .name(this.table.getTable());
100
        sqlbuilder.select().from().subquery(this.table.getSubquery());
101

    
102
        if (StringUtils.isEmpty(baseFilter)) {
103
            if (limit != null) {
104
                sqlbuilder.select().where().set(
105
                        expbuilder.ST_Intersects(
106
                                expbuilder.ST_Envelope(
107
                                        expbuilder.column(columnName)
108
                                ),
109
                                expbuilder.ST_Envelope(
110
                                        expbuilder.geometry(limit.getGeometry(), crs)
111
                                )
112
                        )
113
                );
114
            }
115
        } else {
116
            sqlbuilder.select().where().set( expbuilder.custom(baseFilter) );
117
            if (limit != null) {
118
                sqlbuilder.select().where().and(
119
                        expbuilder.ST_Intersects(
120
                            expbuilder.ST_Envelope(
121
                                    expbuilder.column(columnName)
122
                            ),
123
                            expbuilder.ST_Envelope(
124
                                    expbuilder.geometry(limit.getGeometry(), crs)
125
                            )
126
                        )
127
                );
128
            }
129
        }
130
        sqlbuilder.select().where().and(        
131
            expbuilder.not_is_null(expbuilder.column(columnName))
132
        );
133
        this.helper.replaceForeingValueFunction(sqlbuilder, featureType);
134
        sqlbuilder.setProperties(
135
                Variable.class, 
136
                PROP_TABLE, table
137
        );
138
        String sql = sqlbuilder.select().toString();
139

    
140
        Statement st = null;
141
        ResultSet rs = null;
142
        try {
143
            st = conn.createStatement();
144
            rs = JDBCUtils.executeQuery(st, sql);
145
            if (!rs.next()) {
146
                return null;
147
            }
148
            Geometry geom = this.helper.getGeometryFromColumn(rs, 1);
149
            if (geom == null) {
150
                return null;
151
            }
152
            return geom.getEnvelope();
153

    
154
        } catch (SQLException ex) {
155
            throw new JDBCSQLException(ex);
156
        } finally {
157
            JDBCUtils.closeQuietly(st);
158
            JDBCUtils.closeQuietly(rs);
159
        }
160
    }
161

    
162
}