Revision 64

View differences:

org.gvsig.oracle/trunk/org.gvsig.oracle/org.gvsig.oracle.provider/src/main/java/org/gvsig/oracle/dal/operations/OracleFetchFeatureTypeOperation.java
6 6
import java.sql.ResultSetMetaData;
7 7
import java.sql.SQLException;
8 8
import java.sql.Statement;
9
import java.util.ArrayList;
9 10
import java.util.HashMap;
10 11
import java.util.List;
11 12
import java.util.Map;
12
import org.apache.commons.lang3.StringUtils;
13

  
13 14
import org.cresques.cts.IProjection;
14 15
import org.gvsig.fmap.dal.DataTypes;
15 16
import org.gvsig.fmap.dal.exception.DataException;
16 17
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
17 18
import org.gvsig.fmap.dal.feature.EditableFeatureType;
19
import org.gvsig.fmap.dal.feature.spi.ExpressionBuilderBase;
18 20
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
19 21
import org.gvsig.fmap.dal.store.jdbc2.JDBCUtils;
20 22
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase;
......
27 29
public class OracleFetchFeatureTypeOperation extends FetchFeatureTypeOperation {
28 30

  
29 31
    private static Map<String,GeometryType>databaseGeometryTypes = null;
32
    private static Map<Integer,GeometryType>databaseGeometryTypeNumbers = null;
30 33
    
34
    private static final int UNKNOWN_GEOMETRY = 0;
35
    private static final int POINT = 1;
36
    private static final int LINE_OR_CURVE = 2;
37
    private static final int POLYGON = 3;
38
    private static final int COLLECTION = 4;
39
    private static final int MULTIPOINT = 5;
40
    private static final int MULTILINE_OR_MULTICURVE = 6;
41
    private static final int MULTIPOLYGON = 7;
42
    
31 43
    public OracleFetchFeatureTypeOperation(
32 44
            JDBCHelper helper
33 45
        ) {
......
91 103
            return;
92 104
        }
93 105
        try {
106
        	/**
107
        	 * Directly querying the table to get the geometry type and srid.
108
        	 * This will perform a full scan on the table :-(
109
        	 * 
110
        	 * We can also get the SRID and number of dimensions from 
111
        	 * MDSYS.USER_SDO_GEOM_METADATA or MDSYS.SDO_GEOM_METADATA_TABLE,
112
        	 * but we can't get the geometry type (point, line, etc) from there.
113
        	 */
94 114
            JDBCSQLBuilderBase sqlbuilder = this.createSQLBuilder();
95
            sqlbuilder.select().column().name("f_table_catalog");
96
            sqlbuilder.select().column().name("f_table_schema");
97
            sqlbuilder.select().column().name("f_table_name");
98
            sqlbuilder.select().column().name("f_geometry_column");
99
            sqlbuilder.select().column().name("coord_dimension");
100
            sqlbuilder.select().column().name("srid");
101
            sqlbuilder.select().column().name("type");
102
            sqlbuilder.select().where().set(
103
                    sqlbuilder.eq(
104
                            sqlbuilder.column("f_table_name"),
105
                            sqlbuilder.constant(this.getTablename())
106
                    )
107
            );                
108
            sqlbuilder.select().where().and(
109
                    sqlbuilder.eq(
110
                            sqlbuilder.column("f_geometry_column"),
111
                            sqlbuilder.constant(attr.getName())
112
                    )
113
            );         
114
            sqlbuilder.select().from().table().name("geometry_columns");
115
            ;
116
            sqlbuilder.select().distinct();
117
            
118
            sqlbuilder.select().column().value(sqlbuilder.function("SDO_GTYPE", "({0}).SDO_GTYPE", sqlbuilder.variable(attr.getName())));
119
            sqlbuilder.select().column().value(sqlbuilder.ST_SRID(sqlbuilder.variable(attr.getName())));
120
            sqlbuilder.select().from().table().schema(this.getSchema());
121
            sqlbuilder.select().from().table().name(this.getTablename());
122

  
115 123
            Statement st = null;
116 124
            ResultSet rs = null;
117 125
            
118
            String srsid = null;
119
            String geometryTypeName = null;
126
            ArrayList<Integer> sridList = new ArrayList<Integer>();
127
            ArrayList<Integer> geometryCodeList = new ArrayList<Integer>();
120 128
            try {
121 129
                st = this.getConnection().createStatement();
122 130
                rs = JDBCUtils.executeQuery(st, sqlbuilder.toString());
123
                if (rs.next()) {
124
                    srsid = rs.getString("srid");
125
                    geometryTypeName = rs.getString("type");
131
                while (rs.next()) {
132
                	geometryCodeList.add(rs.getInt(1));
133
                	sridList.add(rs.getInt(2));
126 134
                }
127 135
            } finally {
128 136
                JDBCUtils.closeQuietly(rs);
129 137
                JDBCUtils.closeQuietly(st);
130 138
            }
131
            if( !StringUtils.isEmpty(geometryTypeName) ) {
132
                GeometryType gt = getGeometryTypeFromDatabaseTypeName(geometryTypeName);
139
            try {
140
	            if( sridList.size()==1 ) {
141
	                attr.setSRS(this.helper.getProjectionFromDatabaseCode(sridList.get(0).toString()));
142
	            }
143
	            else if (sridList.size()>1)  {
144
	            	logger.error("More than one CRS detected on the layer: "+sridList.toString()+". Some geometries will be incorrectly handled.");
145
	            }
146
            } catch (Exception ex) {
147
                logger.debug("Can't get srs from column '"+attr.getName()+"'.",ex);
148
            }
149
            if( geometryCodeList.size() == 1 ) {
150
                GeometryType gt = getGeometryTypeFromDatabaseTypeNumber(geometryCodeList.get(0));
133 151
                attr.setGeometryType(gt);
134 152
            }
135
            if( !StringUtils.isEmpty(srsid) ) {
136
                attr.setSRS(this.helper.getProjectionFromDatabaseCode(srsid));
137
            }
153
            return;
138 154
        } catch (Exception ex) {
139 155
            logger.debug("Can't get geometry type and srs from column '"+attr.getName()+"'.",ex);
140 156
        }
141
        // in case the table is not registered on the USER_SDO_GEOM_METADATA table
142 157
        attr.setGeometryType(getGeometryTypeFromDatabaseTypeName("GEOMETRY"));
143 158
    }
144 159

  
......
183 198
        }
184 199
        return databaseGeometryTypes.get(typeName);
185 200
    }
186
    
201

  
202
    private GeometryType getGeometryTypeFromDatabaseTypeNumber(int typeCode) {
203
    	int dimensions = typeCode/1000;
204
    	int typeCodeRemainder = typeCode - 1000*dimensions;
205
    	int mDimPos = typeCodeRemainder/100;
206
    	int geomType = typeCodeRemainder - 100*mDimPos;
207
    	
208
    	String baseType;
209
    	switch(geomType) {
210
    	case POINT:
211
    		baseType = "POINT";
212
    		break;
213
    	case LINE_OR_CURVE:
214
    		baseType = "LINESTRING";
215
    		break;
216
    	case POLYGON:
217
    		baseType = "POLYGON";
218
    		break;
219
    	case MULTIPOINT:
220
    		baseType = "MULTIPOINT";
221
    		break;
222
    	case MULTILINE_OR_MULTICURVE:
223
    		baseType = "MULTILINESTRING";
224
    		break;
225
    	case MULTIPOLYGON:
226
    		baseType = "MULTIPOLYGON";
227
    		break;
228
    	default:
229
    		baseType = "GEOMETRY";
230
    		break;
231
    	}
232
		if (dimensions==3) {
233
			if (mDimPos>0) {
234
				return getGeometryTypeFromDatabaseTypeName(baseType+"M");
235
			}
236
			return getGeometryTypeFromDatabaseTypeName(baseType+"Z");
237
		}
238
		if (dimensions==4) {
239
			return getGeometryTypeFromDatabaseTypeName(baseType+"ZM");
240
			
241
		}
242
		return getGeometryTypeFromDatabaseTypeName(baseType);
243

  
244
    }
245

  
187 246
}

Also available in: Unified diff