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

History | View | Annotate | Download (4.63 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.fmap.dal.exception.DataException;
10
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCSQLException;
11
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
12
import org.gvsig.fmap.dal.store.jdbc2.JDBCUtils;
13
import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory.TableReference;
14
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase;
15
import org.gvsig.fmap.geom.Geometry;
16
import org.gvsig.fmap.geom.primitive.Envelope;
17

    
18
public class CalculateEnvelopeOfColumnOperation extends AbstractConnectionOperation {
19

    
20
    private final TableReference table;
21
    private final String columnName;
22
    private final String baseFilter;
23
    private final Envelope limit;
24
    private final IProjection crs;
25

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

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

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

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

    
81
        sqlbuilder.select().from().table()
82
                .database(this.table.getDatabase())
83
                .schema(this.table.getSchema())
84
                .name(this.table.getTable());
85
        sqlbuilder.select().from().subquery(this.table.getSubquery());
86

    
87
        if (StringUtils.isEmpty(baseFilter)) {
88
            if (limit != null) {
89
                sqlbuilder.select().where().set(
90
                        sqlbuilder.ST_Intersects(
91
                                sqlbuilder.ST_Envelope(
92
                                        sqlbuilder.column(columnName)
93
                                ),
94
                                sqlbuilder.ST_Envelope(
95
                                        sqlbuilder.geometry(limit.getGeometry(), crs)
96
                                )
97
                        )
98
                );
99
            }
100
        } else {
101
            sqlbuilder.select().where().set( sqlbuilder.custom(baseFilter) );
102
            if (limit != null) {
103
                sqlbuilder.select().where().and(
104
                        sqlbuilder.ST_Intersects(
105
                            sqlbuilder.ST_Envelope(
106
                                    sqlbuilder.column(columnName)
107
                            ),
108
                            sqlbuilder.ST_Envelope(
109
                                    sqlbuilder.geometry(limit.getGeometry(), crs)
110
                            )
111
                        )
112
                );
113
            }
114
        }
115

    
116
        String sql = sqlbuilder.select().toString();
117

    
118
        Statement st = null;
119
        ResultSet rs = null;
120
        try {
121
            st = conn.createStatement();
122
            rs = JDBCUtils.executeQuery(st, sql);
123
            if (!rs.next()) {
124
                return null;
125
            }
126
            Geometry geom = this.helper.getGeometryFromColumn(rs, 1);
127
            if (geom == null) {
128
                return null;
129
            }
130
            return geom.getEnvelope();
131

    
132
        } catch (SQLException ex) {
133
            throw new JDBCSQLException(ex);
134
        } finally {
135
            JDBCUtils.closeQuietly(st);
136
            JDBCUtils.closeQuietly(rs);
137
        }
138
    }
139

    
140
}