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

History | View | Annotate | Download (4.97 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.spi.JDBCSQLBuilderBase;
14
import org.gvsig.fmap.geom.Geometry;
15
import org.gvsig.fmap.geom.primitive.Envelope;
16

    
17
public class CalculateEnvelopeOfColumnOperation extends AbstractConnectionOperation {
18

    
19
    private final String subquery;
20
    private final String schemaName;
21
    private final String tableName;
22
    private final String columnName;
23
    private final String baseFilter;
24
    private final Envelope limit;
25
    private final IProjection crs;
26
    private final String dbName;
27

    
28
    public CalculateEnvelopeOfColumnOperation(
29
            JDBCHelper helper,
30
            String subquery,
31
            String dbName,
32
            String schemaName,
33
            String tableName,
34
            String columnName,
35
            String baseFilter,
36
            Envelope limit,
37
            IProjection crs
38
    ) {
39
        super(helper);
40
        this.subquery = subquery;
41
        this.dbName = dbName;
42
        this.schemaName = schemaName;
43
        this.tableName = tableName;
44
        this.columnName = columnName;
45
        this.baseFilter = baseFilter;
46
        this.limit = limit;
47
        this.crs = crs;
48
    }
49

    
50
    @Override
51
    public final Object perform(Connection conn) throws DataException {
52
        Envelope env = calculateEnvelopeOfColumn(
53
            conn,
54
            subquery,
55
            dbName,
56
            schemaName,
57
            tableName,
58
            columnName,
59
            baseFilter,
60
            limit,
61
            crs
62
        );
63
        return env;
64
    }
65

    
66
    public Envelope calculateEnvelopeOfColumn(
67
            Connection conn,
68
            String subquery,
69
            String dbName,
70
            String schemaName,
71
            String tableName,
72
            String columnName,
73
            String baseFilter,
74
            Envelope limit,
75
            IProjection crs
76
    ) throws DataException {
77

    
78
        //
79
        // Parece ser que en versiones anteriores a SQL Server 2012 no esta
80
        // disponible la funcion ST_ExtentAggregate.
81
        // Habria que determinar si es necesario implementar una alternativa
82
        // para estos casos.
83
        //
84
        // https://alastaira.wordpress.com/2011/07/26/determining-the-geographic-extent-of-spatial-features-in-a-sql-server-table/
85
        //
86
        JDBCSQLBuilderBase sqlbuilder = this.createSQLBuilder();
87
        sqlbuilder.select().column().value(
88
            sqlbuilder.getAsGeometry(
89
                sqlbuilder.ST_ExtentAggregate(
90
                        sqlbuilder.column(columnName)
91
                )
92
            )
93
        );
94

    
95
        if (StringUtils.isEmpty(subquery)) {
96
            sqlbuilder.select().from().table().database(dbName).schema(schemaName).name(tableName);
97
        } else {
98
            sqlbuilder.select().from().subquery(subquery);
99
        }
100

    
101
        if (StringUtils.isEmpty(baseFilter)) {
102
            if (limit != null) {
103
                sqlbuilder.select().where().set(
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
        } else {
115
            sqlbuilder.select().where().set( sqlbuilder.custom(baseFilter) );
116
            if (limit != null) {
117
                sqlbuilder.select().where().and(
118
                        sqlbuilder.ST_Intersects(
119
                            sqlbuilder.ST_Envelope(
120
                                    sqlbuilder.column(columnName)
121
                            ),
122
                            sqlbuilder.ST_Envelope(
123
                                    sqlbuilder.geometry(limit.getGeometry(), crs)
124
                            )
125
                        )
126
                );
127
            }
128
        }
129

    
130
        String sql = sqlbuilder.select().toString();
131

    
132
        Statement st = null;
133
        ResultSet rs = null;
134
        try {
135
            st = conn.createStatement();
136
            rs = JDBCUtils.executeQuery(st, sql);
137
            if (!rs.next()) {
138
                return null;
139
            }
140
            Geometry geom = this.helper.getGeometryFromColumn(rs, 1);
141
            if (geom == null) {
142
                return null;
143
            }
144
            return geom.getEnvelope();
145

    
146
        } catch (SQLException ex) {
147
            throw new JDBCSQLException(ex);
148
        } finally {
149
            JDBCUtils.closeQuietly(st);
150
            JDBCUtils.closeQuietly(rs);
151
        }
152
    }
153

    
154
}