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 @ 44198

History | View | Annotate | Download (5 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.store.jdbc.exception.JDBCSQLException;
13
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
14
import org.gvsig.fmap.dal.store.jdbc2.JDBCUtils;
15
import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory.TableReference;
16
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase;
17
import static org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase.PROP_TABLE;
18
import org.gvsig.fmap.geom.Geometry;
19
import org.gvsig.fmap.geom.primitive.Envelope;
20

    
21
public class CalculateEnvelopeOfColumnOperation extends AbstractConnectionOperation {
22

    
23
    private final TableReference table;
24
    private final String columnName;
25
    private final String baseFilter;
26
    private final Envelope limit;
27
    private final IProjection crs;
28

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

    
45
    @Override
46
    public final Object perform(Connection conn) throws DataException {
47
        Envelope env = calculateEnvelopeOfColumn(
48
            conn,
49
            table,
50
            columnName,
51
            baseFilter,
52
            limit,
53
            crs
54
        );
55
        return env;
56
    }
57

    
58
    public Envelope calculateEnvelopeOfColumn(
59
            Connection conn,
60
            TableReference table,
61
            String columnName,
62
            String baseFilter,
63
            Envelope limit,
64
            IProjection crs
65
    ) throws DataException {
66

    
67
        //
68
        // Parece ser que en versiones anteriores a SQL Server 2012 no esta
69
        // disponible la funcion ST_ExtentAggregate.
70
        // Habria que determinar si es necesario implementar una alternativa
71
        // para estos casos.
72
        //
73
        // https://alastaira.wordpress.com/2011/07/26/determining-the-geographic-extent-of-spatial-features-in-a-sql-server-table/
74
        //
75
        JDBCSQLBuilderBase sqlbuilder = this.createSQLBuilder();
76
        ExpressionBuilder expbuilder = sqlbuilder.expression();
77
        
78
        sqlbuilder.select().column().value(
79
            expbuilder.as_geometry(
80
                expbuilder.ST_ExtentAggregate(
81
                        expbuilder.column(columnName)
82
                )
83
            )
84
        );
85

    
86
        sqlbuilder.select().from().table()
87
                .database(this.table.getDatabase())
88
                .schema(this.table.getSchema())
89
                .name(this.table.getTable());
90
        sqlbuilder.select().from().subquery(this.table.getSubquery());
91

    
92
        if (StringUtils.isEmpty(baseFilter)) {
93
            if (limit != null) {
94
                sqlbuilder.select().where().set(
95
                        expbuilder.ST_Intersects(
96
                                expbuilder.ST_Envelope(
97
                                        expbuilder.column(columnName)
98
                                ),
99
                                expbuilder.ST_Envelope(
100
                                        expbuilder.geometry(limit.getGeometry(), crs)
101
                                )
102
                        )
103
                );
104
            }
105
        } else {
106
            sqlbuilder.select().where().set( expbuilder.custom(baseFilter) );
107
            if (limit != null) {
108
                sqlbuilder.select().where().and(
109
                        expbuilder.ST_Intersects(
110
                            expbuilder.ST_Envelope(
111
                                    expbuilder.column(columnName)
112
                            ),
113
                            expbuilder.ST_Envelope(
114
                                    expbuilder.geometry(limit.getGeometry(), crs)
115
                            )
116
                        )
117
                );
118
            }
119
        }
120
        sqlbuilder.setProperties(
121
                Variable.class, 
122
                PROP_TABLE, table
123
        );
124
        String sql = sqlbuilder.select().toString();
125

    
126
        Statement st = null;
127
        ResultSet rs = null;
128
        try {
129
            st = conn.createStatement();
130
            rs = JDBCUtils.executeQuery(st, sql);
131
            if (!rs.next()) {
132
                return null;
133
            }
134
            Geometry geom = this.helper.getGeometryFromColumn(rs, 1);
135
            if (geom == null) {
136
                return null;
137
            }
138
            return geom.getEnvelope();
139

    
140
        } catch (SQLException ex) {
141
            throw new JDBCSQLException(ex);
142
        } finally {
143
            JDBCUtils.closeQuietly(st);
144
            JDBCUtils.closeQuietly(rs);
145
        }
146
    }
147

    
148
}