Revision 64
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