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.h2 / src / main / java / org / gvsig / fmap / dal / store / h2 / operations / H2SpatialFetchFeatureTypeOperation.java @ 44644

History | View | Annotate | Download (11 KB)

1 43377 jjdelcerro
2
package org.gvsig.fmap.dal.store.h2.operations;
3
4
import java.sql.Connection;
5
import java.sql.ResultSet;
6
import java.sql.ResultSetMetaData;
7
import java.sql.SQLException;
8
import java.sql.Statement;
9
import java.util.HashMap;
10
import java.util.List;
11
import java.util.Map;
12
import org.cresques.cts.IProjection;
13 44320 jjdelcerro
import org.gvsig.expressionevaluator.ExpressionBuilder;
14 43377 jjdelcerro
import org.gvsig.fmap.dal.DataTypes;
15
import org.gvsig.fmap.dal.exception.DataException;
16
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
17
import org.gvsig.fmap.dal.feature.EditableFeatureType;
18 44376 jjdelcerro
import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
19 43377 jjdelcerro
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
20
import org.gvsig.fmap.dal.store.jdbc2.JDBCUtils;
21 44058 jjdelcerro
import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory.TableReference;
22 44320 jjdelcerro
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase;
23 43687 jjdelcerro
import org.gvsig.fmap.dal.store.jdbc2.spi.SRSSolver;
24 43377 jjdelcerro
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.FetchFeatureTypeOperation;
25
import org.gvsig.fmap.geom.Geometry;
26
import org.gvsig.fmap.geom.GeometryLocator;
27
import org.gvsig.fmap.geom.GeometryManager;
28
import org.gvsig.fmap.geom.type.GeometryType;
29
30 44058 jjdelcerro
@SuppressWarnings("UseSpecificCatch")
31 43377 jjdelcerro
public class H2SpatialFetchFeatureTypeOperation extends FetchFeatureTypeOperation {
32
33
    private static Map<String,GeometryType>h2spatialGeometryTypes = null;
34
    private Map<String,GeometryColumnInfo> geometry_column;
35
36
    private static class GeometryColumnInfo {
37
38
        public String columnName;
39
        public int geometryType;
40
        public String geometryTypeName;
41
        public int dimensions;
42
        public int srid;
43
44
        public GeometryColumnInfo(String columnName, int geometryType, String geometryTypeName, int dimensions, int srid) {
45
            this.columnName = columnName;
46
            this.geometryType = geometryType;
47
            this.geometryTypeName = geometryTypeName;
48
            this.dimensions = dimensions;
49
            this.srid = srid;
50
        }
51
    }
52
53
54
    public H2SpatialFetchFeatureTypeOperation(
55
            JDBCHelper helper
56
        ) {
57
        super(helper);
58
    }
59
60
    private GeometryType getGT(
61
            GeometryManager manager,
62
            int type,
63
            int subtype
64
        ) {
65
        try {
66
            return manager.getGeometryType(type, subtype);
67
        } catch (Exception ex) {
68
            return null;
69
        }
70
    }
71
72
    public H2SpatialFetchFeatureTypeOperation(
73
            JDBCHelper helper,
74
            EditableFeatureType featureType,
75 44058 jjdelcerro
            TableReference table,
76 43377 jjdelcerro
            List<String> primaryKeys,
77
            String defaultGeometryColumn,
78
            IProjection crs
79
        ) {
80 44058 jjdelcerro
        super(helper, featureType, table, primaryKeys, defaultGeometryColumn, crs);
81 43377 jjdelcerro
    }
82
83 44376 jjdelcerro
    private GeometryColumnInfo getGeometryColumnInfo(String name) {
84
        if( geometry_column==null ) {
85
            geometry_column = new HashMap<>();
86
            try {
87
                //
88
                // https://github.com/orbisgis/h2gis/wiki/1.-Spatial-data#geometry-columns-view
89
                //
90
                StringBuilder where = null;
91
                if( table.hasDatabase() ) {
92
                    if( where == null ) {
93
                        where = new StringBuilder();
94
                    } else {
95
                        where.append(" AND ");
96
                    }
97
                    where.append("UPPER(F_TABLE_CATALOG) = '");
98
                    where.append(table.getDatabase().toUpperCase());
99
                    where.append("'");
100 43377 jjdelcerro
                }
101 44376 jjdelcerro
                if( table.hasSchema()) {
102
                    if( where == null ) {
103
                        where = new StringBuilder();
104
                    } else {
105
                        where.append(" AND ");
106
                    }
107
                    where.append("UPPER(F_TABLE_SCHEMA) = '");
108
                    where.append(table.getSchema().toUpperCase());
109
                    where.append("'");
110 43377 jjdelcerro
                }
111 44376 jjdelcerro
                if( table.hasTable()) {
112
                    if( where == null ) {
113
                        where = new StringBuilder();
114
                    } else {
115
                        where.append(" AND ");
116
                    }
117
                    where.append("UPPER(F_TABLE_NAME) = '");
118
                    where.append(table.getTable().toUpperCase());
119
                    where.append("'");
120
                }
121
                String sql = "SELECT F_GEOMETRY_COLUMN, GEOMETRY_TYPE, COORD_DIMENSION, SRID, TYPE FROM GEOMETRY_COLUMNS WHERE " + where;
122
                Statement st = this.getConnection().createStatement();
123
                ResultSet rs = JDBCUtils.executeQuery(st,sql);
124
                while( rs.next() ) {
125
                    geometry_column.put(
126
                        rs.getString("F_GEOMETRY_COLUMN"),
127
                        new GeometryColumnInfo(
128
                            rs.getString("F_GEOMETRY_COLUMN"),
129
                            rs.getInt("GEOMETRY_TYPE"),
130
                            rs.getString("TYPE"),
131
                            rs.getInt("COORD_DIMENSION"),
132
                            rs.getInt("SRID")
133
                        )
134
                    );
135 43377 jjdelcerro
                }
136 44376 jjdelcerro
            } catch (SQLException | AccessResourceException ex) {
137
                LOGGER.warn("Can't read metadata from table '"+table+"'.",ex);
138 43377 jjdelcerro
            }
139
        }
140 44376 jjdelcerro
        return this.geometry_column.get(name);
141
    }
142
143
    @Override
144
    public void fetch(EditableFeatureType featureType, Connection conn, TableReference table, List<String> pks, String defaultGeometryColumn, IProjection crs) throws DataException {
145 44058 jjdelcerro
        super.fetch(featureType, conn, table, pks, defaultGeometryColumn, crs);
146 43377 jjdelcerro
    }
147
148
    @Override
149
    protected void fetchGeometryTypeAndSRS(
150
            EditableFeatureAttributeDescriptor attr,
151
            ResultSetMetaData rsMetadata,
152
            int colIndex
153
        ) {
154 43687 jjdelcerro
        try {
155
            if( attr.getType()==DataTypes.GEOMETRY ) {
156 44376 jjdelcerro
                GeometryColumnInfo column_info = this.getGeometryColumnInfo(attr.getName());
157 43687 jjdelcerro
                String type = "GEOMETRY";
158
                if( column_info!=null ) {
159
                    // H2GIS solo soporte 2D y 3D no soporta Ms
160
                    if( column_info.dimensions==3 ) {
161
                        type = column_info.geometryTypeName+"Z";
162
                    } else {
163
                        type = column_info.geometryTypeName;
164
                    }
165
                    SRSSolver solver = this.helper.getSRSSolver();
166
                    attr.setSRS(
167
                        solver.getProjection(getConnection(), column_info.srid)
168
                    );
169 43377 jjdelcerro
                }
170 43687 jjdelcerro
                GeometryType gt = getGeometryTypeFromH2SpatialType(type);
171
                if( gt != null ) {
172
                    attr.setGeometryType(gt);
173
                }
174 43377 jjdelcerro
            }
175 43687 jjdelcerro
        } catch(Exception ex) {
176
            throw new RuntimeException("Can't fetch geometry type and SRS.", ex);
177 43377 jjdelcerro
        }
178
    }
179
180
    private GeometryType getGeometryTypeFromH2SpatialType(String typeName) {
181
        if( h2spatialGeometryTypes==null ) {
182
            //
183
            // https://github.com/orbisgis/h2gis/wiki/1.-Spatial-data#geometry-columns-view
184
            //
185
            GeometryManager manager = GeometryLocator.getGeometryManager();
186
            h2spatialGeometryTypes = new HashMap<>();
187
            h2spatialGeometryTypes.put("POINT", getGT(manager, Geometry.TYPES.POINT,Geometry.SUBTYPES.GEOM2D));
188
            h2spatialGeometryTypes.put("POINTZ", getGT(manager, Geometry.TYPES.POINT,Geometry.SUBTYPES.GEOM3D));
189
190
            h2spatialGeometryTypes.put("LINESTRING", getGT(manager, Geometry.TYPES.LINE,Geometry.SUBTYPES.GEOM2D));
191
            h2spatialGeometryTypes.put("LINESTRINGZ", getGT(manager, Geometry.TYPES.LINE,Geometry.SUBTYPES.GEOM3D));
192
193
            h2spatialGeometryTypes.put("POLYGON", getGT(manager, Geometry.TYPES.POLYGON,Geometry.SUBTYPES.GEOM2D));
194
            h2spatialGeometryTypes.put("POLYGONZ", getGT(manager, Geometry.TYPES.POLYGON,Geometry.SUBTYPES.GEOM3D));
195
196
            h2spatialGeometryTypes.put("MULTIPOINT", getGT(manager, Geometry.TYPES.MULTIPOINT,Geometry.SUBTYPES.GEOM2D));
197
            h2spatialGeometryTypes.put("MULTIPOINTZ", getGT(manager, Geometry.TYPES.MULTIPOINT,Geometry.SUBTYPES.GEOM3D));
198
199
            h2spatialGeometryTypes.put("MULTILINESTRING", getGT(manager, Geometry.TYPES.MULTILINE,Geometry.SUBTYPES.GEOM2D));
200
            h2spatialGeometryTypes.put("MULTILINESTRINGZ", getGT(manager, Geometry.TYPES.MULTILINE,Geometry.SUBTYPES.GEOM3D));
201
202
            h2spatialGeometryTypes.put("MULTIPOLYGON", getGT(manager, Geometry.TYPES.MULTIPOLYGON,Geometry.SUBTYPES.GEOM2D));
203
            h2spatialGeometryTypes.put("MULTIPOLYGONZ", getGT(manager, Geometry.TYPES.MULTIPOLYGON,Geometry.SUBTYPES.GEOM3D));
204
205
            h2spatialGeometryTypes.put("GEOMETRY", getGT(manager, Geometry.TYPES.GEOMETRY,Geometry.SUBTYPES.GEOM2D));
206
            h2spatialGeometryTypes.put("GEOMETRYZ", getGT(manager, Geometry.TYPES.GEOMETRY,Geometry.SUBTYPES.GEOM3D));
207
208
            h2spatialGeometryTypes.put("GEOMCOLLECTION", getGT(manager, Geometry.TYPES.GEOMETRY,Geometry.SUBTYPES.GEOM2D));
209
            h2spatialGeometryTypes.put("GEOMCOLLECTIONZ", getGT(manager, Geometry.TYPES.GEOMETRY,Geometry.SUBTYPES.GEOM3D));
210
        }
211
        return h2spatialGeometryTypes.get(typeName);
212
    }
213 44320 jjdelcerro
214
    @Override
215
    protected String getSQLToRetrievePrimaryKeysFromInformationSchema(
216
            String catalog,
217
            String schema,
218
            String table
219
        ) throws SQLException {
220
        JDBCSQLBuilderBase sqlbuilder = this.createSQLBuilder();
221
        ExpressionBuilder expbuilder = sqlbuilder.expression();
222
223
        sqlbuilder.select().column().name("COLUMN_LIST");
224
        sqlbuilder.select().column().name("CONSTRAINT_TYPE");
225
        sqlbuilder.select().from().table().schema("INFORMATION_SCHEMA").name("CONSTRAINTS");
226
        sqlbuilder.select().where().set(
227
                expbuilder.like(
228
                        expbuilder.column("TABLE_NAME"),
229
                        expbuilder.constant(table)
230
                )
231
        );
232
        if (schema != null) {
233
            sqlbuilder.select().where().and(
234
                    expbuilder.like(
235
                            expbuilder.column("TABLE_SCHEMA"),
236
                            expbuilder.constant(schema)
237
                    )
238
            );
239
        }
240
        if (catalog != null) {
241
            sqlbuilder.select().where().and(
242
                    expbuilder.like(
243
                            expbuilder.column("CONSTRAINT_CATALOG"),
244
                            expbuilder.constant(catalog)
245
                    )
246
            );
247
        }
248
        sqlbuilder.select().where().and(
249
                expbuilder.eq(
250
                        expbuilder.column("CONSTRAINT_TYPE"),
251
                        expbuilder.constant("PRIMARY KEY")
252
                )
253
        );
254
        return sqlbuilder.toString();
255
    }
256 43377 jjdelcerro
257 44320 jjdelcerro
258 43377 jjdelcerro
}