root / branches / v10 / extensions / extOracleSpatial / src / es / prodevelop / cit / gvsig / fmap / drivers / jdbc / oracle / OracleSpatialDriver.java @ 13995
History | View | Annotate | Download (128 KB)
1 | 13991 | jldominguez@prodevelop.es | /* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
|
---|---|---|---|
2 | *
|
||
3 | * Copyright (C) 2006 Prodevelop and Generalitat Valenciana.
|
||
4 | *
|
||
5 | * This program is free software; you can redistribute it and/or
|
||
6 | * modify it under the terms of the GNU General Public License
|
||
7 | * as published by the Free Software Foundation; either version 2
|
||
8 | * of the License, or (at your option) any later version.
|
||
9 | *
|
||
10 | * This program is distributed in the hope that it will be useful,
|
||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
13 | * GNU General Public License for more details.
|
||
14 | *
|
||
15 | * You should have received a copy of the GNU General Public License
|
||
16 | * along with this program; if not, write to the Free Software
|
||
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA.
|
||
18 | *
|
||
19 | * For more information, contact:
|
||
20 | *
|
||
21 | * Generalitat Valenciana
|
||
22 | * Conselleria d'Infraestructures i Transport
|
||
23 | * Av. Blasco Ib??ez, 50
|
||
24 | * 46010 VALENCIA
|
||
25 | * SPAIN
|
||
26 | *
|
||
27 | * +34 963862235
|
||
28 | * gvsig@gva.es
|
||
29 | * www.gvsig.gva.es
|
||
30 | *
|
||
31 | * or
|
||
32 | *
|
||
33 | * Prodevelop Integraci?n de Tecnolog?as SL
|
||
34 | * Conde Salvatierra de ?lava , 34-10
|
||
35 | * 46004 Valencia
|
||
36 | * Spain
|
||
37 | *
|
||
38 | * +34 963 510 612
|
||
39 | * +34 963 510 968
|
||
40 | * gis@prodevelop.es
|
||
41 | * http://www.prodevelop.es
|
||
42 | */
|
||
43 | package es.prodevelop.cit.gvsig.fmap.drivers.jdbc.oracle; |
||
44 | |||
45 | import com.hardcode.driverManager.IDelayedDriver; |
||
46 | |||
47 | import com.hardcode.gdbms.engine.data.DataSource; |
||
48 | import com.hardcode.gdbms.engine.data.DataSourceFactory; |
||
49 | import com.hardcode.gdbms.engine.data.SourceInfo; |
||
50 | import com.hardcode.gdbms.engine.data.edition.DataWare; |
||
51 | import com.hardcode.gdbms.engine.data.file.FileSourceInfo; |
||
52 | import com.hardcode.gdbms.engine.spatial.fmap.FShapeGeneralPathX; |
||
53 | import com.hardcode.gdbms.engine.values.DoubleValue; |
||
54 | import com.hardcode.gdbms.engine.values.Value; |
||
55 | import com.hardcode.gdbms.engine.values.ValueFactory; |
||
56 | |||
57 | import com.iver.cit.gvsig.fmap.DriverException; |
||
58 | import com.iver.cit.gvsig.fmap.core.DefaultFeature; |
||
59 | import com.iver.cit.gvsig.fmap.core.FGeometryCollection; |
||
60 | import com.iver.cit.gvsig.fmap.core.FMultiPoint2D; |
||
61 | import com.iver.cit.gvsig.fmap.core.FNullGeometry; |
||
62 | import com.iver.cit.gvsig.fmap.core.FPoint2D; |
||
63 | import com.iver.cit.gvsig.fmap.core.FPolygon2D; |
||
64 | import com.iver.cit.gvsig.fmap.core.FPolyline2D; |
||
65 | import com.iver.cit.gvsig.fmap.core.FShape; |
||
66 | import com.iver.cit.gvsig.fmap.core.GeneralPathX; |
||
67 | import com.iver.cit.gvsig.fmap.core.ICanReproject; |
||
68 | import com.iver.cit.gvsig.fmap.core.IFeature; |
||
69 | import com.iver.cit.gvsig.fmap.core.IGeometry; |
||
70 | import com.iver.cit.gvsig.fmap.core.ShapeFactory; |
||
71 | import com.iver.cit.gvsig.fmap.core.v02.FConverter; |
||
72 | import com.iver.cit.gvsig.fmap.crs.CRSFactory; |
||
73 | import com.iver.cit.gvsig.fmap.drivers.DBLayerDefinition; |
||
74 | import com.iver.cit.gvsig.fmap.drivers.DefaultDBDriver; |
||
75 | import com.iver.cit.gvsig.fmap.drivers.DriverAttributes; |
||
76 | import com.iver.cit.gvsig.fmap.drivers.FieldDescription; |
||
77 | import com.iver.cit.gvsig.fmap.drivers.IFeatureIterator; |
||
78 | import com.iver.cit.gvsig.fmap.drivers.dbf.DBFDriver; |
||
79 | import com.iver.cit.gvsig.fmap.edition.EditableAdapter; |
||
80 | import com.iver.cit.gvsig.fmap.edition.EditionException; |
||
81 | import com.iver.cit.gvsig.fmap.edition.IWriteable; |
||
82 | import com.iver.cit.gvsig.fmap.edition.IWriter; |
||
83 | import com.iver.cit.gvsig.fmap.layers.LayerFactory; |
||
84 | import com.iver.cit.gvsig.fmap.layers.SelectableDataSource; |
||
85 | import com.iver.cit.gvsig.project.documents.table.ProjectTable; |
||
86 | import com.iver.cit.gvsig.project.documents.table.ProjectTableFactory; |
||
87 | import com.iver.utiles.NumberUtilities; |
||
88 | |||
89 | import com.vividsolutions.jts.algorithm.CGAlgorithms; |
||
90 | import com.vividsolutions.jts.geom.Coordinate; |
||
91 | import com.vividsolutions.jts.geom.Geometry; |
||
92 | import com.vividsolutions.jts.geom.GeometryFactory; |
||
93 | import com.vividsolutions.jts.geom.LineString; |
||
94 | import com.vividsolutions.jts.geom.LinearRing; |
||
95 | import com.vividsolutions.jts.geom.MultiPolygon; |
||
96 | import com.vividsolutions.jts.geom.Polygon; |
||
97 | import com.vividsolutions.jts.geom.impl.CoordinateArraySequence; |
||
98 | |||
99 | import oracle.jdbc.OracleConnection; |
||
100 | |||
101 | import oracle.spatial.geometry.JGeometry; |
||
102 | |||
103 | import oracle.sql.ARRAY; |
||
104 | import oracle.sql.Datum; |
||
105 | import oracle.sql.NUMBER; |
||
106 | import oracle.sql.ROWID; |
||
107 | import oracle.sql.STRUCT; |
||
108 | import oracle.sql.StructDescriptor; |
||
109 | |||
110 | import org.apache.log4j.Logger; |
||
111 | import org.cresques.cts.ICoordTrans; |
||
112 | import org.cresques.cts.IProjection; |
||
113 | |||
114 | //import org.geotools.data.oracle.sdo.GeometryConverter;
|
||
115 | |||
116 | import java.awt.Shape; |
||
117 | import java.awt.geom.Point2D; |
||
118 | import java.awt.geom.Rectangle2D; |
||
119 | |||
120 | import java.io.File; |
||
121 | import java.io.IOException; |
||
122 | 13995 | jldominguez@prodevelop.es | import java.math.BigDecimal; |
123 | 13991 | jldominguez@prodevelop.es | |
124 | import java.sql.Connection; |
||
125 | import java.sql.DatabaseMetaData; |
||
126 | import java.sql.PreparedStatement; |
||
127 | import java.sql.ResultSet; |
||
128 | import java.sql.ResultSetMetaData; |
||
129 | import java.sql.SQLException; |
||
130 | import java.sql.Statement; |
||
131 | import java.sql.Types; |
||
132 | |||
133 | import java.text.ParseException; |
||
134 | |||
135 | import java.util.ArrayList; |
||
136 | import java.util.HashMap; |
||
137 | import java.util.Hashtable; |
||
138 | import java.util.Iterator; |
||
139 | import java.util.Random; |
||
140 | import java.util.TreeMap; |
||
141 | |||
142 | |||
143 | /**
|
||
144 | * Vectorial driver to access Oracle databases geometries.
|
||
145 | * Should work on Oracle Locator.
|
||
146 | *
|
||
147 | * It contains switches to test different modules to perform the
|
||
148 | * translation oracle structs --> gvsig geometries:
|
||
149 | *
|
||
150 | * - Parsing the structs directly.
|
||
151 | * - Using Oracle's JGeometry static methods
|
||
152 | * - Using Geotools utilities
|
||
153 | *
|
||
154 | * (currently, the driver parses the structs directly)
|
||
155 | *
|
||
156 | * @author jldominguez
|
||
157 | *
|
||
158 | */
|
||
159 | public class OracleSpatialDriver extends DefaultDBDriver |
||
160 | implements IDelayedDriver, ICanReproject, IWriteable {
|
||
161 | private static Logger logger = Logger.getLogger(OracleSpatialDriver.class.getName()); |
||
162 | private static int FETCH_SIZE = 15000; |
||
163 | |||
164 | // constants
|
||
165 | public static final int GEODETIC_FULLEXTENT_SAMPLE_SIZE = 50; |
||
166 | public static final String GEODETIC_SRID = "8307"; |
||
167 | public static final String ASSUMED_ORACLE_SRID = "8307"; |
||
168 | |||
169 | // ------------------------------------------------
|
||
170 | public static final String NAME = "Oracle Spatial Database Driver"; |
||
171 | public static final int ID_COLUMN_INDEX = 1; |
||
172 | 13993 | fran.penarrubia@iver.es | public static final String ORACLE_GEOMETADATA_VIEW = "ALL_SDO_GEOM_METADATA"; |
173 | 13991 | jldominguez@prodevelop.es | public static final String ORACLE_EPSG_TABLE_NAME = "ORA_EPSG"; |
174 | public static final String ORACLE_EPSG_FILE_NAME = "ora_epsg.dbf"; |
||
175 | public static final String DEFAULT_GEO_FIELD = "GEOMETRY"; |
||
176 | public static final String ORACLE_ID_FIELD = "ROWID"; |
||
177 | public static final String DEFAULT_ID_FIELD = "GID"; |
||
178 | public static final String ORACLE_GEO_SCHEMA = "MDSYS"; |
||
179 | public static final String CONN_STR_BEGIN = "jdbc:oracle:thin:"; |
||
180 | public static final int VARCHAR2_STANDARD_SIZE = 80; |
||
181 | public static final int VARCHAR2_LONG_SIZE = 256; |
||
182 | public static final int MAX_ID_LENGTH = 30; |
||
183 | private final static GeometryFactory geomFactory = new GeometryFactory(); |
||
184 | public static final double IRRELEVANT_DISTANCE = 0.00000001; |
||
185 | private static final String EXTENSION_DIR_NAME = "com.iver.cit.gvsig.jdbc_spatial"; |
||
186 | |||
187 | static {
|
||
188 | try {
|
||
189 | Class.forName("oracle.jdbc.driver.OracleDriver"); |
||
190 | } |
||
191 | catch (ClassNotFoundException e) { |
||
192 | throw new RuntimeException(e); |
||
193 | } |
||
194 | createOracleEpsgTable(); |
||
195 | } |
||
196 | |||
197 | private OracleSpatialWriter writer = null; |
||
198 | |||
199 | // utility object to convert geometries.
|
||
200 | // private GeometryConverter geotools_conv;
|
||
201 | |||
202 | // switch variable
|
||
203 | private boolean use_geotools = false; |
||
204 | private boolean tableHasSrid = true; |
||
205 | |||
206 | // ------------------------------------------------
|
||
207 | private boolean isNotAvailableYet = true; |
||
208 | private IGeometry nullGeom = new FNullGeometry(); |
||
209 | private Value nullVal = ValueFactory.createNullValue();
|
||
210 | private IdLoaderThread idLoader;
|
||
211 | private DriverAttributes drvAtts;
|
||
212 | private int[] pkOneBasedIndexes; |
||
213 | private String[] fieldNames; |
||
214 | private String not_restricted_sql = ""; |
||
215 | |||
216 | private Rectangle2D workingAreaInViewsCS = null; |
||
217 | private Rectangle2D workingAreaInTablesCS = null; |
||
218 | private STRUCT workingAreaInTablesCSStruct = null; |
||
219 | |||
220 | private String idFieldNames; |
||
221 | private int oneBasedGeoColInd = 0; |
||
222 | private int shapeType = -1; |
||
223 | private boolean needsCollectionLayer = true; |
||
224 | |||
225 | // ----------------------------------------------
|
||
226 | // one feature is cached to avoid querying for each attribute request:
|
||
227 | private IFeature singleCachedFeature = null; |
||
228 | private long singleCachedFeatureRowNum = -1; |
||
229 | |||
230 | // ----------------------------------------------
|
||
231 | private boolean cancelIDLoad = false; |
||
232 | |||
233 | // ----------------------------------------------
|
||
234 | private String geoColName = ""; |
||
235 | private String oracleSRID; |
||
236 | private String epsgSRID; |
||
237 | private String destProj = ""; |
||
238 | private Rectangle2D full_Extent = null; |
||
239 | private boolean emptyWhereClause = true; |
||
240 | private boolean isGeogCS = false; |
||
241 | private boolean hasRealiableExtent = true; |
||
242 | |||
243 | // new hash map to perform queries by row number:
|
||
244 | private HashMap rowToId = new HashMap(); |
||
245 | private String standardSelectExpressionFalse = null; |
||
246 | private String destProjOracle; |
||
247 | private boolean isDestGeogCS = false; |
||
248 | |||
249 | public OracleSpatialDriver() {
|
||
250 | drvAtts = new DriverAttributes();
|
||
251 | drvAtts.setLoadedInMemory(false);
|
||
252 | } |
||
253 | |||
254 | /**
|
||
255 | * This method is called when the user creates a new oracle
|
||
256 | * table from a vectorial layer
|
||
257 | *
|
||
258 | * @param params this array simply contains the parameters <tt>Connection</tt> and
|
||
259 | * <tt>DBLayerDefinition</tt>
|
||
260 | */
|
||
261 | public void setData(Object[] params) { |
||
262 | createOracleEpsgTable(); |
||
263 | setData((Connection) params[0], (DBLayerDefinition) params[1]); |
||
264 | } |
||
265 | |||
266 | private void adjustLyrDef() throws SQLException { |
||
267 | DBLayerDefinition ldef = getLyrDef(); |
||
268 | int cnt = metaData.getColumnCount();
|
||
269 | |||
270 | FieldDescription[] _new = new FieldDescription[cnt]; |
||
271 | |||
272 | for (int i = 0; i < cnt; i++) { |
||
273 | _new[i] = new FieldDescription();
|
||
274 | _new[i].setFieldName(metaData.getColumnName(i + 1));
|
||
275 | _new[i].setDefaultValue(ValueFactory.createNullValue()); |
||
276 | _new[i].setFieldAlias(_new[i].getFieldName()); |
||
277 | _new[i].setFieldLength(getFieldWidth(i)); |
||
278 | |||
279 | int _type = metaData.getColumnType(i + 1); |
||
280 | _new[i].setFieldType(_type); |
||
281 | |||
282 | if ((_type == Types.FLOAT) || (_type == Types.DOUBLE) || |
||
283 | (_type == Types.DECIMAL) || (_type == Types.REAL)) { |
||
284 | _new[i].setFieldDecimalCount(6);
|
||
285 | } |
||
286 | else {
|
||
287 | _new[i].setFieldDecimalCount(0);
|
||
288 | } |
||
289 | } |
||
290 | |||
291 | ldef.setFieldsDesc(_new); |
||
292 | setLyrDef(ldef); |
||
293 | } |
||
294 | |||
295 | /**
|
||
296 | * Standard initializing method.
|
||
297 | */
|
||
298 | public void setData(Connection _conn, DBLayerDefinition lyrDef) { |
||
299 | createOracleEpsgTable(); |
||
300 | |||
301 | conn = _conn; |
||
302 | |||
303 | // geotools_conv = new GeometryConverter((OracleConnection) conn);
|
||
304 | lyrDef.setConnection(conn); |
||
305 | |||
306 | setLyrDef(lyrDef); |
||
307 | |||
308 | geoColName = lyrDef.getFieldGeometry(); |
||
309 | not_restricted_sql = "select " + getStandardSelectExpression() +
|
||
310 | " from " + getTableName() + " c "; |
||
311 | |||
312 | // various metadata settings
|
||
313 | // getMetaDataInThisThread();
|
||
314 | cleanWhereClause(); |
||
315 | loadSdoMetadata(); |
||
316 | oneRowMetadata(); |
||
317 | |||
318 | 13992 | jldominguez@prodevelop.es | setDestProjection(lyrDef.getSRID_EPSG()); |
319 | |||
320 | 13991 | jldominguez@prodevelop.es | IProjection viewProj = CRSFactory.getCRS("EPSG:" + destProj);
|
321 | IProjection tableProj = CRSFactory.getCRS("EPSG:" + epsgSRID);
|
||
322 | ICoordTrans reprojecter = viewProj.getCT(tableProj); |
||
323 | |||
324 | workingAreaInViewsCS = lyrDef.getWorkingArea(); |
||
325 | if (workingAreaInViewsCS != null) { |
||
326 | workingAreaInTablesCS = reprojecter.convert(workingAreaInViewsCS); |
||
327 | } |
||
328 | workingAreaInTablesCSStruct = shapeToStruct(workingAreaInTablesCS, |
||
329 | FShape.NULL, tableHasSrid, false, true); |
||
330 | |||
331 | cancelIDLoad = false;
|
||
332 | idLoader = new IdLoaderThread(this); |
||
333 | idLoader.start(); |
||
334 | } |
||
335 | |||
336 | /**
|
||
337 | * Utility method to load IDs in a different thred, so that gvsig's gui
|
||
338 | * does not get blocked.
|
||
339 | *
|
||
340 | */
|
||
341 | public void getMetaDataInThisThread() { |
||
342 | getMetadata(); |
||
343 | } |
||
344 | |||
345 | private void getMetadata() { |
||
346 | setIdRowTable(); |
||
347 | |||
348 | if (!hasRealiableExtent) {
|
||
349 | full_Extent = getEstimatedGeodeticExtent( |
||
350 | getTableName(), geoColName, conn, 20, 1.5); |
||
351 | } |
||
352 | |||
353 | |||
354 | if (cancelIDLoad) {
|
||
355 | return;
|
||
356 | } |
||
357 | } |
||
358 | |||
359 | private boolean needsCollectionLayer() { |
||
360 | try {
|
||
361 | // SELECT DISTINCT(C.GEOM.SDO_GTYPE) FROM COMUICV C
|
||
362 | // String qry = "select distinct(c." + geoColName + ".SDO_GTYPE) from " + getTableName() + " c";
|
||
363 | String qry = "select c." + geoColName + ".SDO_ELEM_INFO from " + |
||
364 | getTableName() + " c";
|
||
365 | |||
366 | // SDO_ELEM_INFO
|
||
367 | Statement _st = conn.createStatement();
|
||
368 | ResultSet _rs = _st.executeQuery(qry);
|
||
369 | |||
370 | ArrayList types = new ArrayList(); |
||
371 | int aux = 0; |
||
372 | |||
373 | ARRAY info_aux; |
||
374 | int[] info_aux_int; |
||
375 | int size;
|
||
376 | |||
377 | while (_rs.next()) {
|
||
378 | // aux = _rs.getInt(1);
|
||
379 | info_aux = (ARRAY) _rs.getObject(1);
|
||
380 | info_aux_int = info_aux.getIntArray(); |
||
381 | size = info_aux_int.length / 3;
|
||
382 | |||
383 | for (int i = 0; i < size; i++) { |
||
384 | aux = info_aux_int[(3 * i) + 1]; |
||
385 | } |
||
386 | |||
387 | types.add(new Integer(aux % 1000)); |
||
388 | |||
389 | if ((aux % 1000) != 3) { |
||
390 | System.err.println("x"); |
||
391 | } |
||
392 | } |
||
393 | |||
394 | _rs.close(); |
||
395 | _st.close(); |
||
396 | |||
397 | boolean resp = hasSeveralGeometryTypes(types, false); |
||
398 | |||
399 | return resp;
|
||
400 | } |
||
401 | catch (Exception se) { |
||
402 | System.err.println("Error while getting SDO metadata: " + |
||
403 | se.getMessage()); |
||
404 | } |
||
405 | |||
406 | return false; |
||
407 | } |
||
408 | |||
409 | private boolean hasSeveralGeometryTypes(ArrayList tt, boolean are_dims) { |
||
410 | if (tt.size() == 0) { |
||
411 | return false; |
||
412 | } |
||
413 | |||
414 | HashMap m = new HashMap(); |
||
415 | |||
416 | for (int i = 0; i < tt.size(); i++) { |
||
417 | Integer integ = (Integer) tt.get(i); |
||
418 | int val = integ.intValue();
|
||
419 | |||
420 | if ((val == 4) && (!are_dims)) { |
||
421 | return true; |
||
422 | } |
||
423 | |||
424 | m.put("" + (val % 4), "a type"); |
||
425 | } |
||
426 | |||
427 | Iterator iter = m.keySet().iterator();
|
||
428 | iter.next(); |
||
429 | |||
430 | return iter.hasNext();
|
||
431 | } |
||
432 | |||
433 | private String getOracleSridFromCurrentRecord(ResultSet _rs) |
||
434 | throws SQLException { |
||
435 | Object obj = _rs.getObject("SRID"); |
||
436 | |||
437 | if (obj == null) { |
||
438 | logger.warn("No SRID found for this table.");
|
||
439 | tableHasSrid = false;
|
||
440 | |||
441 | return ASSUMED_ORACLE_SRID;
|
||
442 | } |
||
443 | |||
444 | return obj.toString();
|
||
445 | } |
||
446 | |||
447 | private Rectangle2D getFullExtentFromCurrentRecord(ResultSet _rs) |
||
448 | throws SQLException { |
||
449 | ARRAY dim_info_array = (ARRAY) _rs.getObject("DIMINFO");
|
||
450 | |||
451 | if (dim_info_array == null) { |
||
452 | // no full extent found:
|
||
453 | return null; |
||
454 | } |
||
455 | else {
|
||
456 | Datum[] da = dim_info_array.getOracleArray();
|
||
457 | |||
458 | STRUCT sx = (STRUCT) da[0];
|
||
459 | STRUCT sy = (STRUCT) da[1];
|
||
460 | |||
461 | try {
|
||
462 | double minx = Double.parseDouble(sx.getAttributes()[1].toString()); |
||
463 | double maxx = Double.parseDouble(sx.getAttributes()[2].toString()); |
||
464 | double miny = Double.parseDouble(sy.getAttributes()[1].toString()); |
||
465 | double maxy = Double.parseDouble(sy.getAttributes()[2].toString()); |
||
466 | |||
467 | if (minx > maxx) {
|
||
468 | double aux = minx;
|
||
469 | minx = maxx; |
||
470 | maxx = aux; |
||
471 | } |
||
472 | |||
473 | if (miny > maxy) {
|
||
474 | double aux = miny;
|
||
475 | miny = maxy; |
||
476 | maxy = aux; |
||
477 | } |
||
478 | |||
479 | return getRectangle(minx, maxx, miny, maxy);
|
||
480 | |||
481 | // fullExtentJTS = shapeToGeometry(fullExtent);
|
||
482 | } |
||
483 | catch (Exception ex) { |
||
484 | System.err.println(
|
||
485 | "Error while getting full extent from metadata table.");
|
||
486 | |||
487 | return null; |
||
488 | |||
489 | // fullExtentJTS = null;
|
||
490 | } |
||
491 | } |
||
492 | } |
||
493 | |||
494 | private void loadSdoMetadata() { |
||
495 | try {
|
||
496 | Statement _st = conn.createStatement();
|
||
497 | 13994 | fran.penarrubia@iver.es | String[] tokens = getTableName().split("\\u002E", 2); |
498 | String qry;
|
||
499 | if (tokens.length > 1) |
||
500 | { |
||
501 | qry = "select * from " + ORACLE_GEOMETADATA_VIEW +
|
||
502 | " where OWNER = '" + tokens[0] + "' AND TABLE_NAME = '" + |
||
503 | tokens[1] + "'"; |
||
504 | } |
||
505 | else
|
||
506 | { |
||
507 | qry = "select * from " + ORACLE_GEOMETADATA_VIEW +
|
||
508 | 13991 | jldominguez@prodevelop.es | " where TABLE_NAME = " + "'" + getTableName() + "'"; |
509 | 13994 | fran.penarrubia@iver.es | |
510 | } |
||
511 | // String qry = "select * from " + ORACLE_GEOMETADATA_VIEW +
|
||
512 | // " where TABLE_NAME = " + "'" + getTableName() + "'";
|
||
513 | 13991 | jldominguez@prodevelop.es | ResultSet _rs = _st.executeQuery(qry);
|
514 | |||
515 | if (_rs.next()) {
|
||
516 | oracleSRID = getOracleSridFromCurrentRecord(_rs); |
||
517 | |||
518 | isGeogCS = getIsGCS(oracleSRID, tableHasSrid); |
||
519 | |||
520 | try {
|
||
521 | epsgSRID = oracleSridToEpsgSrid(oracleSRID); |
||
522 | } catch (Exception e) { |
||
523 | logger.error("Unknown oracle SRID: " + oracleSRID);
|
||
524 | tableHasSrid = false;
|
||
525 | } |
||
526 | full_Extent = getFullExtentFromCurrentRecord(_rs); |
||
527 | |||
528 | hasRealiableExtent = realiableExtent(full_Extent, isGeogCS); |
||
529 | |||
530 | if (!hasRealiableExtent) {
|
||
531 | full_Extent = getFastEstimatedGeodeticExtent( |
||
532 | getTableName(), geoColName, conn, 20, 10); |
||
533 | } |
||
534 | |||
535 | _rs.close(); |
||
536 | _st.close(); |
||
537 | } |
||
538 | else {
|
||
539 | throw new SQLException("Empty resultset from this query: " + |
||
540 | qry); |
||
541 | } |
||
542 | } |
||
543 | catch (SQLException se) { |
||
544 | System.err.println("Error while getting SDO metadata: " + |
||
545 | se.getMessage()); |
||
546 | } |
||
547 | } |
||
548 | |||
549 | /**
|
||
550 | * Utility method to find out if a coordinate system is geodetic or not.
|
||
551 | *
|
||
552 | * @param oracleSRID2 the coordinate system's oracle code
|
||
553 | * @param thas whether the table has a coordinate system set.
|
||
554 | * if not, the method returns false.
|
||
555 | * @return whether the coordinate system is geodetic or not.
|
||
556 | */
|
||
557 | public static boolean getIsGCS(String oracleSRID2, boolean thas) { |
||
558 | |||
559 | if (!thas) return false; |
||
560 | int ora_cs = 0; |
||
561 | |||
562 | try {
|
||
563 | ora_cs = Integer.parseInt(oracleSRID2);
|
||
564 | } |
||
565 | catch (Exception ex) { |
||
566 | return false; |
||
567 | } |
||
568 | |||
569 | if (((ora_cs >= 8000) && (ora_cs <= 8999)) || (ora_cs == 524288)) { |
||
570 | return true; |
||
571 | } else {
|
||
572 | return false; |
||
573 | } |
||
574 | } |
||
575 | |||
576 | private Rectangle2D getRectangle(double minx, double maxx, double miny, |
||
577 | double maxy) {
|
||
578 | Rectangle2D resp = new Rectangle2D.Double(minx, miny, maxx - minx, |
||
579 | maxy - miny); |
||
580 | |||
581 | return resp;
|
||
582 | } |
||
583 | |||
584 | private void oneRowMetadata() { |
||
585 | try {
|
||
586 | String _sql = "select " + getStandardSelectExpression() + ", c." + |
||
587 | geoColName + " from " + getTableName() + " c "; |
||
588 | |||
589 | st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||
590 | ResultSet.CONCUR_READ_ONLY);
|
||
591 | |||
592 | ResultSet _rs = st.executeQuery(_sql + " where (rownum = 1)"); |
||
593 | |||
594 | if (_rs.next()) {
|
||
595 | STRUCT sample_geo = (STRUCT) _rs.getObject(geoColName); |
||
596 | shapeType = getShapeTypeOfStruct(sample_geo); |
||
597 | } |
||
598 | else {
|
||
599 | shapeType = FShape.MULTI; |
||
600 | } |
||
601 | |||
602 | // -----------------------
|
||
603 | _rs = st.executeQuery(not_restricted_sql + " where (rownum = 1)");
|
||
604 | metaData = _rs.getMetaData(); |
||
605 | 13995 | jldominguez@prodevelop.es | userName = conn.getMetaData().getUserName(); |
606 | |||
607 | 13991 | jldominguez@prodevelop.es | |
608 | // geoColInd = _rs.findColumn(geoColName);
|
||
609 | oneBasedGeoColInd = metaData.getColumnCount() + 1;
|
||
610 | |||
611 | DatabaseMetaData dbmd = conn.getMetaData();
|
||
612 | pkOneBasedIndexes = getPKIndexes(dbmd, _rs); |
||
613 | |||
614 | int cnt = metaData.getColumnCount();
|
||
615 | fieldNames = new String[cnt]; |
||
616 | |||
617 | for (int i = 0; i < cnt; i++) { |
||
618 | fieldNames[i] = metaData.getColumnName(i + 1);
|
||
619 | } |
||
620 | |||
621 | getIdFieldNames(); |
||
622 | |||
623 | adjustLyrDef(); |
||
624 | |||
625 | _rs.close(); // st no debe cerrarse ya que las llamadas a metadata lo encesitan
|
||
626 | } |
||
627 | catch (SQLException se) { |
||
628 | logger.error("While getting metadata. " + se.getMessage());
|
||
629 | } |
||
630 | } |
||
631 | |||
632 | private int getShapeTypeOfStruct(STRUCT sample) throws SQLException { |
||
633 | int code = ((NUMBER) sample.getOracleAttributes()[0]).intValue() % 10; |
||
634 | |||
635 | switch (code) {
|
||
636 | case 1: |
||
637 | return FShape.POINT;
|
||
638 | |||
639 | case 2: |
||
640 | return FShape.LINE;
|
||
641 | |||
642 | case 3: |
||
643 | return FShape.POLYGON;
|
||
644 | |||
645 | case 5: |
||
646 | return FShape.MULTIPOINT;
|
||
647 | |||
648 | case 6: |
||
649 | return FShape.LINE;
|
||
650 | |||
651 | case 7: |
||
652 | return FShape.POLYGON;
|
||
653 | } |
||
654 | |||
655 | logger.error("Unknown geometry type: " + code);
|
||
656 | |||
657 | return FShape.NULL;
|
||
658 | } |
||
659 | |||
660 | private String getIdFieldNames() { |
||
661 | try {
|
||
662 | idFieldNames = "";
|
||
663 | |||
664 | for (int i = 0; i < pkOneBasedIndexes.length; i++) { |
||
665 | idFieldNames = idFieldNames + |
||
666 | metaData.getColumnName(pkOneBasedIndexes[i]) + ", ";
|
||
667 | } |
||
668 | } |
||
669 | catch (SQLException se) { |
||
670 | } |
||
671 | |||
672 | idFieldNames = idFieldNames.substring(0, idFieldNames.length() - 2); |
||
673 | |||
674 | return idFieldNames;
|
||
675 | } |
||
676 | |||
677 | private int[] getPKIndexes(DatabaseMetaData metaData, ResultSet table_rs) { |
||
678 | int[] _res = new int[1]; |
||
679 | _res[0] = 1; |
||
680 | |||
681 | return _res;
|
||
682 | } |
||
683 | |||
684 | public String getSqlTotal() { |
||
685 | // TODO Auto-generated method stub
|
||
686 | return ""; |
||
687 | } |
||
688 | |||
689 | public String getCompleteWhere() { |
||
690 | // TODO Auto-generated method stub
|
||
691 | return ""; |
||
692 | } |
||
693 | |||
694 | /**
|
||
695 | * Gets the feature iterator for a given SQL sentence (ignores previous filters
|
||
696 | * and uses directly that sentence to query the table).
|
||
697 | */
|
||
698 | public IFeatureIterator getFeatureIterator(String sql) |
||
699 | throws DriverException {
|
||
700 | if (isNotAvailableYet) {
|
||
701 | return null; |
||
702 | } |
||
703 | |||
704 | singleCachedFeatureRowNum = -1;
|
||
705 | |||
706 | Object[] rs_st = getViewResultSet(null, sql, tableHasSrid); |
||
707 | |||
708 | ResultSet localrs = (ResultSet) rs_st[0]; |
||
709 | Statement _st = (Statement) rs_st[1]; |
||
710 | |||
711 | return new OracleSpatialFeatureIterator(this, localrs, _st, |
||
712 | oneBasedGeoColInd, use_geotools); |
||
713 | } |
||
714 | |||
715 | /**
|
||
716 | * Gets Oracle particular connection string beginning: "jdbc:oracle:thin:"
|
||
717 | */
|
||
718 | public String getConnectionStringBeginning() { |
||
719 | // oracle
|
||
720 | return CONN_STR_BEGIN;
|
||
721 | } |
||
722 | |||
723 | public void open() throws DriverException { |
||
724 | } |
||
725 | |||
726 | /**
|
||
727 | * Gets Oracle's default port: 1521
|
||
728 | */
|
||
729 | public int getDefaultPort() { |
||
730 | // oracle port
|
||
731 | return 1521; |
||
732 | } |
||
733 | |||
734 | /**
|
||
735 | * Gets the feature iterator for a given rectangle (the view's bounding box)
|
||
736 | * and a SRS.
|
||
737 | */
|
||
738 | public IFeatureIterator getFeatureIterator(Rectangle2D r, String strEPSG) |
||
739 | throws DriverException {
|
||
740 | if (isNotAvailableYet) {
|
||
741 | return null; |
||
742 | } |
||
743 | |||
744 | singleCachedFeatureRowNum = -1;
|
||
745 | |||
746 | STRUCT local_st = shapeToStruct(r, FShape.NULL, true, false, true); |
||
747 | |||
748 | Object[] rs_st = getViewResultSet(local_st, null, tableHasSrid); |
||
749 | |||
750 | ResultSet localrs = (ResultSet) rs_st[0]; |
||
751 | Statement _st = (Statement) rs_st[1]; |
||
752 | |||
753 | return new OracleSpatialFeatureIterator(this, localrs, _st, |
||
754 | oneBasedGeoColInd, use_geotools); |
||
755 | } |
||
756 | |||
757 | private Rectangle2D intersectWithWorkingArea(Rectangle2D r) { |
||
758 | if (workingAreaInTablesCS == null) return r; |
||
759 | return doIntersect(r, workingAreaInTablesCS);
|
||
760 | } |
||
761 | |||
762 | /**
|
||
763 | * This method reverts to the one without the fields specification.
|
||
764 | * The fields have been selected from the start.
|
||
765 | */
|
||
766 | public IFeatureIterator getFeatureIterator(Rectangle2D r, String strEPSG, |
||
767 | String[] alphaNumericFieldsNeeded) throws DriverException { |
||
768 | if (isNotAvailableYet) {
|
||
769 | return null; |
||
770 | |||
771 | // return emptyIt;
|
||
772 | } |
||
773 | |||
774 | singleCachedFeatureRowNum = -1;
|
||
775 | |||
776 | return getFeatureIterator(r, strEPSG);
|
||
777 | } |
||
778 | |||
779 | public String getGeometryField(String fieldName) { |
||
780 | return fieldName;
|
||
781 | |||
782 | // return "ASBINARY(" + fieldName + ")";
|
||
783 | } |
||
784 | |||
785 | public DriverAttributes getDriverAttributes() {
|
||
786 | return drvAtts;
|
||
787 | } |
||
788 | |||
789 | /**
|
||
790 | * Gets the requested geometry. Always performs a new query in this case.
|
||
791 | * This should be a rare way to get the geometries. The standard way is by using
|
||
792 | * the iterators.
|
||
793 | */
|
||
794 | public IGeometry getShape(int _ind) throws IOException { |
||
795 | if (isNotAvailableYet) {
|
||
796 | return nullGeom;
|
||
797 | } |
||
798 | |||
799 | ROWID r_id = (ROWID) rowToId.get(new Integer(_ind)); |
||
800 | |||
801 | String _sql = "select " + geoColName + " from " + getTableName() + |
||
802 | " where rowid = ?";
|
||
803 | |||
804 | try {
|
||
805 | java.sql.PreparedStatement ps = conn.prepareStatement(_sql); |
||
806 | ps.setObject(1, r_id);
|
||
807 | |||
808 | // Statement stmnt = conn.createStatement();
|
||
809 | ps.execute(); |
||
810 | |||
811 | ResultSet _res = ps.getResultSet();
|
||
812 | |||
813 | if (_res.next()) {
|
||
814 | STRUCT _st = (oracle.sql.STRUCT) _res.getObject(1); // geocolind); |
||
815 | IGeometry theGeom = getGeometryUsing(_st, use_geotools); |
||
816 | _res.close(); |
||
817 | ps.close(); |
||
818 | |||
819 | return theGeom;
|
||
820 | } |
||
821 | else {
|
||
822 | logger.error("Unable to get shape: " + _ind +
|
||
823 | " (probably due to edition)");
|
||
824 | |||
825 | return nullGeom;
|
||
826 | } |
||
827 | } |
||
828 | catch (SQLException se) { |
||
829 | throw new IOException("SQLException: " + se.getMessage()); |
||
830 | } |
||
831 | } |
||
832 | |||
833 | public boolean isWritable() { |
||
834 | return true; |
||
835 | } |
||
836 | |||
837 | public String getName() { |
||
838 | return NAME;
|
||
839 | } |
||
840 | |||
841 | public int[] getPrimaryKeys() |
||
842 | throws com.hardcode.gdbms.engine.data.driver.DriverException {
|
||
843 | return pkOneBasedIndexes;
|
||
844 | } |
||
845 | |||
846 | public void write(DataWare dataWare) |
||
847 | throws com.hardcode.gdbms.engine.data.driver.DriverException {
|
||
848 | } |
||
849 | |||
850 | private void setIdRowTable() { |
||
851 | hashRelate = new Hashtable(); |
||
852 | |||
853 | java.sql.PreparedStatement ps = null;
|
||
854 | |||
855 | try {
|
||
856 | String _sql = getIdAndElemInfoFullResulltSetQuery();
|
||
857 | |||
858 | logger.debug("SQL para leer ids: " + _sql);
|
||
859 | Statement st = null; |
||
860 | |||
861 | |||
862 | st = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY,
|
||
863 | ResultSet.CONCUR_READ_ONLY);
|
||
864 | |||
865 | st.setFetchSize(FETCH_SIZE); |
||
866 | logger.info("FETCH_SIZE = " + FETCH_SIZE);
|
||
867 | |||
868 | ResultSet _r = null; |
||
869 | _r = st.executeQuery(_sql); |
||
870 | |||
871 | ROWID ri = null;
|
||
872 | |||
873 | int row = 0; |
||
874 | String gid;
|
||
875 | Value aux = null;
|
||
876 | |||
877 | // ----------------------------------- types init
|
||
878 | ArrayList types = new ArrayList(); |
||
879 | int types_aux = 0; |
||
880 | |||
881 | ARRAY info_aux; |
||
882 | int[] info_aux_int; |
||
883 | int size;
|
||
884 | |||
885 | // ----------------------------------- types init
|
||
886 | logger.debug("Beginning of result set:");
|
||
887 | |||
888 | while (_r.next()) {
|
||
889 | // ---------------------------------------
|
||
890 | ri = (ROWID) _r.getObject(1);
|
||
891 | gid = ri.stringValue(); |
||
892 | aux = ValueFactory.createValue(gid); |
||
893 | |||
894 | Integer intobj = new Integer(row); |
||
895 | hashRelate.put(aux, intobj); |
||
896 | rowToId.put(intobj, ri); |
||
897 | |||
898 | if ((row % 5000) == 0) { |
||
899 | // ------------------------------------------- cancel load
|
||
900 | if (cancelIDLoad) {
|
||
901 | hashRelate.clear(); |
||
902 | rowToId.clear(); |
||
903 | |||
904 | return;
|
||
905 | } |
||
906 | |||
907 | // -------------------------------------------
|
||
908 | String fmt = OracleSpatialUtils.getFormattedInteger(row);
|
||
909 | logger.info("IDs read: " + fmt);
|
||
910 | } |
||
911 | |||
912 | row++; |
||
913 | |||
914 | // --------------------------------------- types
|
||
915 | info_aux = (ARRAY) _r.getObject(2);
|
||
916 | |||
917 | if (info_aux == null) { |
||
918 | // logger.debug("NULL info array found in record: " + row);
|
||
919 | } |
||
920 | else {
|
||
921 | info_aux_int = info_aux.getIntArray(); |
||
922 | size = info_aux_int.length / 3;
|
||
923 | |||
924 | for (int i = 0; i < size; i++) { |
||
925 | types_aux = info_aux_int[(3 * i) + 1]; |
||
926 | types.add(new Integer(types_aux % 1000)); |
||
927 | } |
||
928 | } |
||
929 | |||
930 | // --------------------------------------- types end
|
||
931 | } |
||
932 | |||
933 | _r.close(); |
||
934 | // ps.close();
|
||
935 | st.close(); |
||
936 | numReg = row; |
||
937 | |||
938 | needsCollectionLayer = hasSeveralGeometryTypes(types, false);
|
||
939 | |||
940 | if (needsCollectionLayer) {
|
||
941 | shapeType = FShape.MULTI; |
||
942 | } |
||
943 | } |
||
944 | catch (SQLException e) { |
||
945 | System.err.println("While setting id-row hashmap: " + |
||
946 | e.getMessage()); |
||
947 | } |
||
948 | } |
||
949 | |||
950 | public int getFieldCount() |
||
951 | throws com.hardcode.gdbms.engine.data.driver.DriverException {
|
||
952 | try {
|
||
953 | return metaData.getColumnCount();
|
||
954 | } |
||
955 | catch (SQLException e) { |
||
956 | System.err.println("While getting field count: " + e.getMessage()); |
||
957 | throw new com.hardcode.gdbms.engine.data.driver.DriverException(e.getMessage()); |
||
958 | } |
||
959 | } |
||
960 | |||
961 | public String[] getFieldNames() { |
||
962 | return fieldNames;
|
||
963 | } |
||
964 | |||
965 | public String getTotalFields() { |
||
966 | String strAux = ""; |
||
967 | |||
968 | for (int i = 0; i < fieldNames.length; i++) { |
||
969 | if (i == 0) { |
||
970 | strAux = fieldNames[i]; |
||
971 | } |
||
972 | else {
|
||
973 | strAux = strAux + ", " + fieldNames[i];
|
||
974 | } |
||
975 | } |
||
976 | |||
977 | return strAux;
|
||
978 | } |
||
979 | |||
980 | public int getFieldType(int idField) |
||
981 | throws com.hardcode.gdbms.engine.data.driver.DriverException {
|
||
982 | int i = 0; |
||
983 | |||
984 | try {
|
||
985 | i = idField + 1; // idField viene basado en 0 |
||
986 | |||
987 | int __type = metaData.getColumnType(i);
|
||
988 | |||
989 | // we must add this entry because we did not remove the 'geometry' column
|
||
990 | if (__type == Types.STRUCT) { |
||
991 | return Types.VARCHAR; // .STRUCT; |
||
992 | // ----------------------------------------------------------------------
|
||
993 | } |
||
994 | |||
995 | if (__type == Types.VARCHAR) { |
||
996 | return Types.VARCHAR; |
||
997 | } |
||
998 | |||
999 | if (__type == Types.FLOAT) { |
||
1000 | return Types.FLOAT; |
||
1001 | } |
||
1002 | |||
1003 | if (__type == Types.DOUBLE) { |
||
1004 | return Types.DOUBLE; |
||
1005 | } |
||
1006 | |||
1007 | if (__type == Types.INTEGER) { |
||
1008 | return Types.INTEGER; |
||
1009 | } |
||
1010 | |||
1011 | if (__type == Types.SMALLINT) { |
||
1012 | return Types.SMALLINT; |
||
1013 | } |
||
1014 | |||
1015 | if (__type == Types.TINYINT) { |
||
1016 | return Types.TINYINT; |
||
1017 | } |
||
1018 | |||
1019 | if (__type == Types.BIGINT) { |
||
1020 | return Types.BIGINT; |
||
1021 | } |
||
1022 | |||
1023 | if (__type == Types.BIT) { |
||
1024 | return Types.BIT; |
||
1025 | } |
||
1026 | |||
1027 | if (__type == Types.DATE) { |
||
1028 | return Types.DATE; |
||
1029 | } |
||
1030 | |||
1031 | if (__type == Types.DECIMAL) { |
||
1032 | return Types.DOUBLE; |
||
1033 | } |
||
1034 | |||
1035 | if (__type == Types.NUMERIC) { |
||
1036 | return Types.DOUBLE; |
||
1037 | } |
||
1038 | |||
1039 | if (__type == Types.DATE) { |
||
1040 | return Types.DATE; |
||
1041 | } |
||
1042 | |||
1043 | if (__type == Types.TIME) { |
||
1044 | return Types.TIME; |
||
1045 | } |
||
1046 | |||
1047 | if (__type == Types.TIMESTAMP) { |
||
1048 | return Types.TIMESTAMP; |
||
1049 | } |
||
1050 | } |
||
1051 | catch (SQLException e) { |
||
1052 | System.err.println("i = " + i); |
||
1053 | throw new com.hardcode.gdbms.engine.data.driver.DriverException(e); |
||
1054 | } |
||
1055 | |||
1056 | return -1; |
||
1057 | } |
||
1058 | |||
1059 | public Value[] getAttributes(ResultSet rs) { |
||
1060 | Value[] res = null; |
||
1061 | |||
1062 | try {
|
||
1063 | int fcount = rs.getMetaData().getColumnCount();
|
||
1064 | res = new Value[fcount];
|
||
1065 | |||
1066 | for (int i = 0; i < fcount; i++) { |
||
1067 | Object obj = rs.getObject(i + 1); |
||
1068 | String objToString = null; |
||
1069 | int _type = -1; |
||
1070 | |||
1071 | if (obj instanceof String) { |
||
1072 | objToString = (String) obj;
|
||
1073 | _type = Types.VARCHAR;
|
||
1074 | } |
||
1075 | else {
|
||
1076 | if (obj instanceof ROWID) { |
||
1077 | objToString = ((ROWID) obj).stringValue(); |
||
1078 | _type = Types.VARCHAR;
|
||
1079 | } |
||
1080 | else {
|
||
1081 | if (obj instanceof STRUCT) { |
||
1082 | objToString = "STRUCT";
|
||
1083 | _type = Types.VARCHAR;
|
||
1084 | } |
||
1085 | else {
|
||
1086 | objToString = (obj == null) ? "NULL" : obj.toString(); |
||
1087 | _type = getFieldType(i); |
||
1088 | } |
||
1089 | } |
||
1090 | } |
||
1091 | |||
1092 | // /*
|
||
1093 | if (_type == -1) { |
||
1094 | obj = null;
|
||
1095 | } |
||
1096 | |||
1097 | // */
|
||
1098 | if (obj == null) { |
||
1099 | res[i] = ValueFactory.createNullValue(); |
||
1100 | } |
||
1101 | else {
|
||
1102 | if (_type == Types.DATE) { |
||
1103 | objToString = objToString.replace('-', '/'); |
||
1104 | } |
||
1105 | |||
1106 | res[i] = ValueFactory.createValueByType(objToString, _type); |
||
1107 | } |
||
1108 | } |
||
1109 | } |
||
1110 | catch (SQLException se) { |
||
1111 | System.err.println("Error while getting attributes: " + |
||
1112 | se.getMessage()); |
||
1113 | |||
1114 | return null; |
||
1115 | } |
||
1116 | catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
|
||
1117 | System.err.println("Error while getting attributes: " + |
||
1118 | e.getMessage()); |
||
1119 | |||
1120 | return null; |
||
1121 | } |
||
1122 | catch (ParseException e) { |
||
1123 | System.err.println("Error while getting attributes: " + |
||
1124 | e.getMessage()); |
||
1125 | |||
1126 | return null; |
||
1127 | } |
||
1128 | |||
1129 | return res;
|
||
1130 | } |
||
1131 | |||
1132 | public Value[] getAttributesUsingMainMetadata(ResultSet rs) { |
||
1133 | Value[] res = null; |
||
1134 | |||
1135 | try {
|
||
1136 | int fcount = metaData.getColumnCount();
|
||
1137 | res = new Value[fcount];
|
||
1138 | |||
1139 | for (int i = 0; i < fcount; i++) { |
||
1140 | Object obj = rs.getObject(i + 1); |
||
1141 | String objToString = null; |
||
1142 | int _type = -1; |
||
1143 | |||
1144 | if (obj instanceof String) { |
||
1145 | objToString = (String) obj;
|
||
1146 | _type = Types.VARCHAR;
|
||
1147 | } |
||
1148 | else {
|
||
1149 | if (obj instanceof ROWID) { |
||
1150 | objToString = ((ROWID) obj).stringValue(); |
||
1151 | _type = Types.VARCHAR;
|
||
1152 | } |
||
1153 | else {
|
||
1154 | if (obj instanceof STRUCT) { |
||
1155 | objToString = "STRUCT";
|
||
1156 | _type = Types.VARCHAR;
|
||
1157 | } |
||
1158 | else {
|
||
1159 | objToString = (obj == null) ? "NULL" : obj.toString(); |
||
1160 | _type = getFieldType(i); |
||
1161 | } |
||
1162 | } |
||
1163 | } |
||
1164 | |||
1165 | // /*
|
||
1166 | if (_type == -1) { |
||
1167 | obj = null;
|
||
1168 | } |
||
1169 | |||
1170 | // */
|
||
1171 | if (obj == null) { |
||
1172 | res[i] = ValueFactory.createNullValue(); |
||
1173 | } |
||
1174 | else {
|
||
1175 | if (_type == Types.DATE) { |
||
1176 | objToString = objToString.replace('-', '/'); |
||
1177 | } |
||
1178 | |||
1179 | res[i] = ValueFactory.createValueByType(objToString, _type); |
||
1180 | } |
||
1181 | } |
||
1182 | } |
||
1183 | catch (SQLException se) { |
||
1184 | System.err.println("Error while getting attributes: " + |
||
1185 | se.getMessage()); |
||
1186 | |||
1187 | return null; |
||
1188 | } |
||
1189 | catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
|
||
1190 | System.err.println("Error while getting attributes: " + |
||
1191 | e.getMessage()); |
||
1192 | |||
1193 | return null; |
||
1194 | } |
||
1195 | catch (ParseException e) { |
||
1196 | System.err.println("Error while getting attributes: " + |
||
1197 | e.getMessage()); |
||
1198 | |||
1199 | return null; |
||
1200 | } |
||
1201 | |||
1202 | return res;
|
||
1203 | } |
||
1204 | |||
1205 | |||
1206 | public String getFieldName(int fieldId) |
||
1207 | throws com.hardcode.gdbms.engine.data.driver.DriverException {
|
||
1208 | return fieldNames[fieldId];
|
||
1209 | } |
||
1210 | |||
1211 | public int getFieldWidth(int fieldId) { |
||
1212 | int i = -1; |
||
1213 | |||
1214 | try {
|
||
1215 | int aux = fieldId + 1; // fieldId viene basado en 0 |
||
1216 | i = metaData.getColumnDisplaySize(aux); |
||
1217 | } |
||
1218 | catch (SQLException e) { |
||
1219 | System.err.println("While getting field width: " + e.getMessage()); |
||
1220 | } |
||
1221 | |||
1222 | if (i < 0) { |
||
1223 | i = 255;
|
||
1224 | } |
||
1225 | |||
1226 | return i;
|
||
1227 | } |
||
1228 | |||
1229 | public Value getFieldValue(long rowIndex, int field_Id) |
||
1230 | throws com.hardcode.gdbms.engine.data.driver.DriverException {
|
||
1231 | if (isNotAvailableYet) {
|
||
1232 | return nullVal;
|
||
1233 | } |
||
1234 | |||
1235 | if ((singleCachedFeature != null) && |
||
1236 | (rowIndex == singleCachedFeatureRowNum)) { |
||
1237 | return singleCachedFeature.getAttributes()[field_Id];
|
||
1238 | } |
||
1239 | |||
1240 | // return ValueFactory.createNullValue();
|
||
1241 | ResultSet _r = null; |
||
1242 | java.sql.PreparedStatement ps = null;
|
||
1243 | |||
1244 | try {
|
||
1245 | String rnq = getSearchId();
|
||
1246 | ROWID _id = (ROWID) rowToId.get(new Integer((int) rowIndex)); |
||
1247 | |||
1248 | ps = conn.prepareStatement(rnq); |
||
1249 | ps.setObject(1, _id);
|
||
1250 | |||
1251 | ps.execute(); |
||
1252 | _r = ps.getResultSet(); |
||
1253 | _r.next(); |
||
1254 | } |
||
1255 | catch (SQLException se) { |
||
1256 | throw new com.hardcode.gdbms.engine.data.driver.DriverException(se.getMessage()); |
||
1257 | } |
||
1258 | |||
1259 | IFeature ife = null;
|
||
1260 | Value[] atts = null; |
||
1261 | |||
1262 | try {
|
||
1263 | ROWID ri = (ROWID) _r.getObject(1);
|
||
1264 | atts = getAttributesUsingMainMetadata(_r); |
||
1265 | |||
1266 | String gid = ri.stringValue();
|
||
1267 | STRUCT _st = (oracle.sql.STRUCT) _r.getObject(oneBasedGeoColInd); |
||
1268 | IGeometry theGeom = getGeometryUsing(_st, use_geotools); |
||
1269 | ife = new DefaultFeature(theGeom, atts, gid);
|
||
1270 | _r.close(); |
||
1271 | ps.close(); |
||
1272 | } |
||
1273 | catch (SQLException se) { |
||
1274 | logger.error("Error while doing next(): " + se.getMessage(), se);
|
||
1275 | } |
||
1276 | |||
1277 | // -------------------------------
|
||
1278 | singleCachedFeature = ife; |
||
1279 | singleCachedFeatureRowNum = rowIndex; |
||
1280 | |||
1281 | // -------------------------------
|
||
1282 | if (atts == null) { |
||
1283 | return ValueFactory.createNullValue();
|
||
1284 | } |
||
1285 | else {
|
||
1286 | return atts[field_Id];
|
||
1287 | } |
||
1288 | } |
||
1289 | |||
1290 | public static void showMemory() { |
||
1291 | Runtime r = Runtime.getRuntime(); |
||
1292 | long mem = r.totalMemory() - r.freeMemory();
|
||
1293 | System.err.println("Memoria total: " + mem); |
||
1294 | } |
||
1295 | |||
1296 | public Rectangle2D getFullExtent() { |
||
1297 | return full_Extent;
|
||
1298 | } |
||
1299 | |||
1300 | /**
|
||
1301 | * Utility method to get a geometry from a struct.
|
||
1302 | *
|
||
1303 | * @param theStruct the struct to be converted
|
||
1304 | * @param use_gtools switch to use geotools classes or not
|
||
1305 | * @return the geometry
|
||
1306 | * @throws SQLException
|
||
1307 | */
|
||
1308 | public IGeometry getGeometryUsing(STRUCT theStruct, boolean use_gtools) |
||
1309 | throws SQLException { |
||
1310 | IGeometry _igeom = null;
|
||
1311 | |||
1312 | if (theStruct == null) { |
||
1313 | return nullGeom;
|
||
1314 | } |
||
1315 | |||
1316 | if (use_gtools) { // geotools |
||
1317 | // _igeom = getGeotoolsIGeometry(theStruct);
|
||
1318 | } |
||
1319 | else { // jgeometry |
||
1320 | _igeom = getFMapGeometry(theStruct, false);
|
||
1321 | } |
||
1322 | |||
1323 | return _igeom;
|
||
1324 | } |
||
1325 | |||
1326 | private IGeometry getFMapGeometry(JGeometry jg, boolean force_not_collection) { |
||
1327 | int jgtype = jg.getType();
|
||
1328 | int dim = jg.getDimensions();
|
||
1329 | IGeometry ig = null;
|
||
1330 | |||
1331 | if ((jgtype != JGeometry.GTYPE_COLLECTION) &&
|
||
1332 | (isActuallyACollection(jg))) { |
||
1333 | jgtype = JGeometry.GTYPE_COLLECTION; |
||
1334 | } |
||
1335 | |||
1336 | switch (jgtype) {
|
||
1337 | case JGeometry.GTYPE_COLLECTION:
|
||
1338 | |||
1339 | int srid = jg.getSRID();
|
||
1340 | ig = getFMapGeometryCollection(jg, dim, srid); |
||
1341 | |||
1342 | break;
|
||
1343 | |||
1344 | case JGeometry.GTYPE_POINT:
|
||
1345 | case JGeometry.GTYPE_MULTIPOINT:
|
||
1346 | ig = getFMapGeometryPoint(jg, dim); |
||
1347 | |||
1348 | break;
|
||
1349 | |||
1350 | case JGeometry.GTYPE_CURVE:
|
||
1351 | case JGeometry.GTYPE_MULTICURVE:
|
||
1352 | ig = getFMapGeometryMultiLineString(jg, dim); |
||
1353 | |||
1354 | break;
|
||
1355 | |||
1356 | case JGeometry.GTYPE_POLYGON:
|
||
1357 | case JGeometry.GTYPE_MULTIPOLYGON:
|
||
1358 | ig = getFMapGeometryMultipolygon(jg, dim); |
||
1359 | |||
1360 | break;
|
||
1361 | } |
||
1362 | |||
1363 | return ig;
|
||
1364 | } |
||
1365 | |||
1366 | private IGeometry getFMapGeometryCollection(Datum[] the_data, int dim, |
||
1367 | int __srid) {
|
||
1368 | NUMBER main_type = new NUMBER((dim * 1000) + |
||
1369 | OracleSpatialUtils.getStructType(the_data)); |
||
1370 | NUMBER _srid = new NUMBER(__srid);
|
||
1371 | |||
1372 | Datum[] all_info_array = null; |
||
1373 | Object[] elems_info_aray = null; |
||
1374 | Datum[] all_ords = null; |
||
1375 | |||
1376 | try {
|
||
1377 | all_info_array = ((ARRAY) the_data[3]).getOracleArray();
|
||
1378 | elems_info_aray = groupByElement(all_info_array); |
||
1379 | all_ords = ((ARRAY) the_data[4]).getOracleArray();
|
||
1380 | } |
||
1381 | catch (SQLException e) { |
||
1382 | logger.error("Unexpected error: " + e.getMessage());
|
||
1383 | } |
||
1384 | |||
1385 | Object[] ords_of_groups = getOrdOfGroups(all_ords, elems_info_aray); |
||
1386 | Object[] _elems_info_aray = new Object[elems_info_aray.length]; |
||
1387 | |||
1388 | for (int i = 0; i < elems_info_aray.length; i++) { |
||
1389 | _elems_info_aray[i] = updateIndexes((Datum[]) elems_info_aray[i]);
|
||
1390 | } |
||
1391 | |||
1392 | // _elems_info_aray, ords_of_groups
|
||
1393 | int no_of_elems = ords_of_groups.length;
|
||
1394 | IGeometry[] geoms = new IGeometry[no_of_elems]; |
||
1395 | |||
1396 | for (int i = 0; i < no_of_elems; i++) { |
||
1397 | Datum[] item_info_array = null; |
||
1398 | Datum[] item_ords = null; |
||
1399 | NUMBER gtype = null;
|
||
1400 | |||
1401 | try {
|
||
1402 | item_info_array = (Datum[]) _elems_info_aray[i];
|
||
1403 | item_ords = (Datum[]) ords_of_groups[i];
|
||
1404 | |||
1405 | gtype = new NUMBER((dim * 1000) + |
||
1406 | (item_info_array[1].intValue() % 1000)); |
||
1407 | } |
||
1408 | catch (SQLException se) { |
||
1409 | logger.error("Unexpected error: " + se.getMessage());
|
||
1410 | } |
||
1411 | |||
1412 | // if it's the first geometry, the type is the collection's main type (no?)
|
||
1413 | if (i == 0) { |
||
1414 | gtype = main_type; |
||
1415 | } |
||
1416 | |||
1417 | STRUCT itemst = null;
|
||
1418 | |||
1419 | if (tableHasSrid) {
|
||
1420 | itemst = OracleSpatialUtils.createStruct(gtype, _srid, |
||
1421 | item_info_array, item_ords, conn); |
||
1422 | } |
||
1423 | else {
|
||
1424 | itemst = OracleSpatialUtils.createStruct(gtype, null,
|
||
1425 | item_info_array, item_ords, conn); |
||
1426 | } |
||
1427 | |||
1428 | geoms[i] = getFMapGeometry(itemst, true);
|
||
1429 | } |
||
1430 | |||
1431 | return new FGeometryCollection(geoms); |
||
1432 | } |
||
1433 | |||
1434 | /**
|
||
1435 | * Utility method to transform a struct into a IGeometry.
|
||
1436 | *
|
||
1437 | * @param st the struct to be converted
|
||
1438 | * @param force_not_collection t5his parameter is currently ignored
|
||
1439 | * @return the IGeometry
|
||
1440 | */
|
||
1441 | public IGeometry getFMapGeometry(STRUCT st, boolean force_not_collection) { |
||
1442 | Datum[] the_data = null; |
||
1443 | |||
1444 | try {
|
||
1445 | the_data = st.getOracleAttributes(); |
||
1446 | |||
1447 | int jgtype = ((NUMBER) the_data[0]).intValue() % 1000; |
||
1448 | jgtype = OracleSpatialUtils.oracleGTypeToFShapeType(jgtype); |
||
1449 | |||
1450 | int dim = ((NUMBER) the_data[0]).intValue() / 1000; |
||
1451 | |||
1452 | if (dim < 2) { |
||
1453 | dim = 2;
|
||
1454 | } |
||
1455 | |||
1456 | IGeometry ig = null;
|
||
1457 | |||
1458 | if (isActuallyACollection(the_data)) {
|
||
1459 | jgtype = FShape.MULTI; |
||
1460 | } |
||
1461 | |||
1462 | switch (jgtype) {
|
||
1463 | case FShape.MULTI:
|
||
1464 | |||
1465 | int srid = ((NUMBER) the_data[1]).intValue(); |
||
1466 | ig = getFMapGeometryCollection(the_data, dim, srid); |
||
1467 | |||
1468 | break;
|
||
1469 | |||
1470 | case FShape.POINT:
|
||
1471 | ig = getFMapGeometryPoint(the_data, dim); |
||
1472 | |||
1473 | break;
|
||
1474 | |||
1475 | case FShape.LINE:
|
||
1476 | ig = getFMapGeometryMultiLineString(the_data, dim); |
||
1477 | |||
1478 | break;
|
||
1479 | |||
1480 | case FShape.POLYGON:
|
||
1481 | ig = getFMapGeometryMultipolygon(the_data, dim); |
||
1482 | |||
1483 | break;
|
||
1484 | } |
||
1485 | |||
1486 | return ig;
|
||
1487 | } |
||
1488 | catch (SQLException e) { |
||
1489 | logger.error(e); |
||
1490 | } |
||
1491 | |||
1492 | return null; |
||
1493 | } |
||
1494 | |||
1495 | private double[] getIndDoublesModule(double[] input, int ind, int n) { |
||
1496 | int size = input.length / n;
|
||
1497 | double[] resp = new double[size]; |
||
1498 | |||
1499 | for (int i = 0; i < size; i++) { |
||
1500 | resp[i] = input[(i * n) + ind]; |
||
1501 | } |
||
1502 | |||
1503 | return resp;
|
||
1504 | } |
||
1505 | |||
1506 | private double[] getIndBigDecimalModule(double[] input, int ind, int n) { |
||
1507 | int size = input.length / n;
|
||
1508 | double[] resp = new double[size]; |
||
1509 | |||
1510 | for (int i = 0; i < size; i++) { |
||
1511 | resp[i] = input[(i * n) + ind]; |
||
1512 | } |
||
1513 | |||
1514 | return resp;
|
||
1515 | } |
||
1516 | |||
1517 | private IGeometry getFMapGeometryMultipolygon(JGeometry jg, int dim) { |
||
1518 | IGeometry ig = null;
|
||
1519 | |||
1520 | if (jg.isCircle()) {
|
||
1521 | ig = getCircleFromJGeometry(jg); |
||
1522 | } |
||
1523 | else {
|
||
1524 | Shape shape = jg.createShape();
|
||
1525 | GeneralPathX gpx = new GeneralPathX(shape);
|
||
1526 | |||
1527 | if (dim == 2) { |
||
1528 | ig = ShapeFactory.createPolygon2D(gpx); |
||
1529 | } |
||
1530 | else {
|
||
1531 | double[] z = getIndDoublesModule(jg.getOrdinatesArray(), 2, dim); |
||
1532 | ig = ShapeFactory.createPolygon3D(gpx, z); |
||
1533 | } |
||
1534 | } |
||
1535 | |||
1536 | return ig;
|
||
1537 | } |
||
1538 | |||
1539 | private IGeometry getFMapGeometryMultipolygon(Datum[] the_data, int dim) { |
||
1540 | IGeometry ig = null;
|
||
1541 | |||
1542 | if (OracleSpatialUtils.isCircle(the_data)) {
|
||
1543 | ig = getCircleFromStruct(the_data); |
||
1544 | } |
||
1545 | else {
|
||
1546 | GeneralPathX gpx = OracleSpatialUtils.structToGPX(the_data); |
||
1547 | |||
1548 | if (dim == 2) { |
||
1549 | ig = ShapeFactory.createPolygon2D(gpx); |
||
1550 | } |
||
1551 | else {
|
||
1552 | double[] ords = null; |
||
1553 | |||
1554 | try {
|
||
1555 | ords = ((ARRAY) the_data[4]).getDoubleArray();
|
||
1556 | } |
||
1557 | catch (SQLException se) { |
||
1558 | logger.error("While getting ordinates: " + se.getMessage(),
|
||
1559 | se); |
||
1560 | } |
||
1561 | |||
1562 | double[] z = getIndBigDecimalModule(ords, 2, dim); |
||
1563 | ig = ShapeFactory.createPolygon3D(gpx, z); |
||
1564 | } |
||
1565 | } |
||
1566 | |||
1567 | return ig;
|
||
1568 | } |
||
1569 | |||
1570 | private IGeometry getCircleFromJGeometry(JGeometry jg) {
|
||
1571 | double[] threep = jg.getOrdinatesArray(); |
||
1572 | Point2D[] three = new Point2D.Double[3]; |
||
1573 | three[0] = new Point2D.Double(threep[0], threep[1]); |
||
1574 | three[1] = new Point2D.Double(threep[2], threep[3]); |
||
1575 | three[2] = new Point2D.Double(threep[4], threep[5]); |
||
1576 | |||
1577 | Object[] cent_rad = OracleSpatialUtils.getCenterAndRadiousOfCirc(three); |
||
1578 | |||
1579 | Point2D cent = (Point2D) cent_rad[0]; |
||
1580 | double radius = ((Double) cent_rad[1]).doubleValue(); |
||
1581 | |||
1582 | IGeometry circ = ShapeFactory.createCircle(cent, radius); |
||
1583 | |||
1584 | return circ;
|
||
1585 | } |
||
1586 | |||
1587 | private IGeometry getCircleFromStruct(Datum[] the_data) { |
||
1588 | double[] threep = null; |
||
1589 | |||
1590 | try {
|
||
1591 | threep = ((ARRAY) the_data[4]).getDoubleArray();
|
||
1592 | } |
||
1593 | catch (SQLException se) { |
||
1594 | logger.error("While getting ords from struct: " + se.getMessage(),
|
||
1595 | se); |
||
1596 | |||
1597 | return new FNullGeometry(); |
||
1598 | } |
||
1599 | |||
1600 | Point2D[] three = new Point2D.Double[3]; |
||
1601 | three[0] = new Point2D.Double(threep[0], threep[1]); |
||
1602 | three[1] = new Point2D.Double(threep[2], threep[3]); |
||
1603 | three[2] = new Point2D.Double(threep[4], threep[5]); |
||
1604 | |||
1605 | Object[] cent_rad = OracleSpatialUtils.getCenterAndRadiousOfCirc(three); |
||
1606 | |||
1607 | Point2D cent = (Point2D) cent_rad[0]; |
||
1608 | double radius = ((Double) cent_rad[1]).doubleValue(); |
||
1609 | |||
1610 | IGeometry circ = ShapeFactory.createCircle(cent, radius); |
||
1611 | |||
1612 | return circ;
|
||
1613 | } |
||
1614 | |||
1615 | private IGeometry getFMapGeometryMultiLineString(JGeometry jg, int dim) { |
||
1616 | Shape shape = jg.createShape();
|
||
1617 | GeneralPathX gpx = new GeneralPathX(shape);
|
||
1618 | IGeometry ig = null;
|
||
1619 | |||
1620 | if (dim == 2) { |
||
1621 | ig = ShapeFactory.createPolyline2D(gpx); |
||
1622 | } |
||
1623 | else {
|
||
1624 | double[] z = getIndDoublesModule(jg.getOrdinatesArray(), 2, dim); |
||
1625 | ig = ShapeFactory.createPolyline3D(gpx, z); |
||
1626 | } |
||
1627 | |||
1628 | return ig;
|
||
1629 | } |
||
1630 | |||
1631 | private IGeometry getFMapGeometryMultiLineString(Datum[] the_data, int dim) { |
||
1632 | GeneralPathX gpx = OracleSpatialUtils.structToGPX(the_data); |
||
1633 | IGeometry ig = null;
|
||
1634 | double[] ords = null; |
||
1635 | |||
1636 | if (dim == 2) { |
||
1637 | ig = ShapeFactory.createPolyline2D(gpx); |
||
1638 | } |
||
1639 | else {
|
||
1640 | ords = OracleSpatialUtils.getOrds(the_data); |
||
1641 | |||
1642 | double[] z = getIndBigDecimalModule(ords, 2, dim); |
||
1643 | ig = ShapeFactory.createPolyline3D(gpx, z); |
||
1644 | } |
||
1645 | |||
1646 | return ig;
|
||
1647 | } |
||
1648 | |||
1649 | private IGeometry getFMapGeometryPoint(JGeometry jg_point, int dim) { |
||
1650 | if (jg_point.getOrdinatesArray() == null) { // sdo_point |
||
1651 | |||
1652 | return getFMapGeometrySdoPoint(jg_point, dim);
|
||
1653 | } |
||
1654 | |||
1655 | IGeometry ig = null;
|
||
1656 | int total_size = jg_point.getOrdinatesArray().length;
|
||
1657 | int no_po = total_size / dim;
|
||
1658 | double[] x = new double[no_po]; |
||
1659 | double[] y = new double[no_po]; |
||
1660 | double[] z = new double[no_po]; |
||
1661 | |||
1662 | for (int i = 0; i < no_po; i++) { |
||
1663 | x[i] = jg_point.getOrdinatesArray()[i * dim]; // pp[i].getX();
|
||
1664 | y[i] = jg_point.getOrdinatesArray()[(i * dim) + 1];
|
||
1665 | |||
1666 | if (dim >= 3) { |
||
1667 | z[i] = jg_point.getOrdinatesArray()[(i * dim) + 2];
|
||
1668 | } |
||
1669 | } |
||
1670 | |||
1671 | if (dim == 2) { |
||
1672 | if (no_po == 1) { |
||
1673 | ig = ShapeFactory.createPoint2D(x[0], y[0]); |
||
1674 | } |
||
1675 | else {
|
||
1676 | ig = ShapeFactory.createMultipoint2D(x, y); |
||
1677 | } |
||
1678 | } |
||
1679 | else {
|
||
1680 | if (no_po == 1) { |
||
1681 | ig = ShapeFactory.createPoint3D(x[0], y[0], z[0]); |
||
1682 | } |
||
1683 | else {
|
||
1684 | ig = ShapeFactory.createMultipoint3D(x, y, z); |
||
1685 | } |
||
1686 | } |
||
1687 | |||
1688 | return ig;
|
||
1689 | } |
||
1690 | |||
1691 | private IGeometry getFMapGeometryPoint(Datum[] the_data, int dim) { |
||
1692 | double[] ords = OracleSpatialUtils.getOrds(the_data); |
||
1693 | |||
1694 | if (ords == null) { // sdo_point |
||
1695 | |||
1696 | return getFMapGeometrySdoPoint(the_data, dim);
|
||
1697 | } |
||
1698 | |||
1699 | IGeometry ig = null;
|
||
1700 | int total_size = ords.length;
|
||
1701 | int no_po = total_size / dim;
|
||
1702 | double[] x = new double[no_po]; |
||
1703 | double[] y = new double[no_po]; |
||
1704 | double[] z = new double[no_po]; |
||
1705 | |||
1706 | for (int i = 0; i < no_po; i++) { |
||
1707 | x[i] = ords[i * dim]; // pp[i].getX();
|
||
1708 | y[i] = ords[(i * dim) + 1];
|
||
1709 | |||
1710 | if (dim >= 3) { |
||
1711 | z[i] = ords[(i * dim) + 2];
|
||
1712 | } |
||
1713 | } |
||
1714 | |||
1715 | if (dim == 2) { |
||
1716 | if (no_po == 1) { |
||
1717 | ig = ShapeFactory.createPoint2D(x[0], y[0]); |
||
1718 | } |
||
1719 | else {
|
||
1720 | ig = ShapeFactory.createMultipoint2D(x, y); |
||
1721 | } |
||
1722 | } |
||
1723 | else {
|
||
1724 | if (no_po == 1) { |
||
1725 | ig = ShapeFactory.createPoint3D(x[0], y[0], z[0]); |
||
1726 | } |
||
1727 | else {
|
||
1728 | ig = ShapeFactory.createMultipoint3D(x, y, z); |
||
1729 | } |
||
1730 | } |
||
1731 | |||
1732 | return ig;
|
||
1733 | } |
||
1734 | |||
1735 | private IGeometry getFMapGeometrySdoPoint(JGeometry jgp, int d) { |
||
1736 | double[] p = jgp.getPoint(); |
||
1737 | IGeometry ig = null;
|
||
1738 | |||
1739 | if (d == 2) { |
||
1740 | ig = ShapeFactory.createPoint2D(p[0], p[1]); |
||
1741 | } |
||
1742 | else {
|
||
1743 | ig = ShapeFactory.createPoint3D(p[0], p[1], p[2]); |
||
1744 | } |
||
1745 | |||
1746 | return ig;
|
||
1747 | } |
||
1748 | |||
1749 | private IGeometry getFMapGeometrySdoPoint(Datum[] the_data, int d) { |
||
1750 | double x = 0; |
||
1751 | double y = 0; |
||
1752 | double z = 0; |
||
1753 | |||
1754 | try {
|
||
1755 | Datum[] aux = ((STRUCT) the_data[2]).getOracleAttributes(); |
||
1756 | x = ((NUMBER) aux[0]).doubleValue();
|
||
1757 | y = ((NUMBER) aux[1]).doubleValue();
|
||
1758 | |||
1759 | if (d > 2) { |
||
1760 | z = ((NUMBER) aux[2]).doubleValue();
|
||
1761 | } |
||
1762 | } |
||
1763 | catch (SQLException se) { |
||
1764 | logger.error("While getting sdo point ordinates: " +
|
||
1765 | se.getMessage(), se); |
||
1766 | } |
||
1767 | |||
1768 | IGeometry ig = null;
|
||
1769 | |||
1770 | if (d == 2) { |
||
1771 | ig = ShapeFactory.createPoint2D(x, y); |
||
1772 | } |
||
1773 | else {
|
||
1774 | ig = ShapeFactory.createPoint3D(x, y, z); |
||
1775 | } |
||
1776 | |||
1777 | return ig;
|
||
1778 | } |
||
1779 | |||
1780 | private boolean isActuallyACollection(JGeometry jg) { |
||
1781 | int[] info = jg.getElemInfo(); |
||
1782 | |||
1783 | if (info == null) { |
||
1784 | return false; // sdo_point |
||
1785 | } |
||
1786 | |||
1787 | int size = info.length / 3; |
||
1788 | |||
1789 | if (size == 1) { |
||
1790 | return false; |
||
1791 | } |
||
1792 | |||
1793 | if (size == 2) { |
||
1794 | return ((info[1] % 1000) != (info[4] % 1000)); |
||
1795 | } |
||
1796 | |||
1797 | int second = info[4] % 1000; |
||
1798 | |||
1799 | for (int i = 2; i < size; i++) { |
||
1800 | if ((info[(i * 3) + 1] % 1000) != second) { |
||
1801 | return true; |
||
1802 | } |
||
1803 | } |
||
1804 | |||
1805 | return false; |
||
1806 | } |
||
1807 | |||
1808 | private boolean isActuallyACollection(Datum[] the_data) { |
||
1809 | int[] info = null; |
||
1810 | |||
1811 | try {
|
||
1812 | ARRAY aux = (ARRAY) the_data[3];
|
||
1813 | |||
1814 | if (aux == null) { |
||
1815 | return false; |
||
1816 | } |
||
1817 | |||
1818 | info = aux.getIntArray(); |
||
1819 | } |
||
1820 | catch (SQLException se) { |
||
1821 | logger.error("While checking collection: " + se.getMessage());
|
||
1822 | |||
1823 | return false; |
||
1824 | } |
||
1825 | |||
1826 | if (info == null) { |
||
1827 | return false; // sdo_point |
||
1828 | } |
||
1829 | |||
1830 | int size = info.length / 3; |
||
1831 | |||
1832 | if (size == 1) { |
||
1833 | return false; |
||
1834 | } |
||
1835 | |||
1836 | if (size == 2) { |
||
1837 | return ((info[1] % 1000) != (info[4] % 1000)); |
||
1838 | } |
||
1839 | |||
1840 | int second = info[4] % 1000; |
||
1841 | |||
1842 | for (int i = 2; i < size; i++) { |
||
1843 | if ((info[(i * 3) + 1] % 1000) != second) { |
||
1844 | return true; |
||
1845 | } |
||
1846 | } |
||
1847 | |||
1848 | return false; |
||
1849 | } |
||
1850 | |||
1851 | private IGeometry getFMapGeometryCollection(JGeometry jg, int dim, int _srid) { |
||
1852 | int main_type = jg.getType();
|
||
1853 | |||
1854 | int[] all_info_array = jg.getElemInfo(); |
||
1855 | Object[] elems_info_aray = groupByElement(all_info_array); |
||
1856 | double[] all_ords = jg.getOrdinatesArray(); |
||
1857 | Object[] ords_of_groups = getOrdOfGroups(all_ords, elems_info_aray); |
||
1858 | Object[] _elems_info_aray = new Object[elems_info_aray.length]; |
||
1859 | |||
1860 | for (int i = 0; i < elems_info_aray.length; i++) { |
||
1861 | _elems_info_aray[i] = updateIndexes((int[]) elems_info_aray[i]); |
||
1862 | } |
||
1863 | |||
1864 | // _elems_info_aray, ords_of_groups
|
||
1865 | int no_of_elems = ords_of_groups.length;
|
||
1866 | IGeometry[] geoms = new IGeometry[no_of_elems]; |
||
1867 | |||
1868 | for (int i = 0; i < no_of_elems; i++) { |
||
1869 | int[] item_info_array = (int[]) _elems_info_aray[i]; |
||
1870 | double[] item_ords = (double[]) ords_of_groups[i]; |
||
1871 | int gtype = (dim * 1000) + (item_info_array[1] % 1000); |
||
1872 | |||
1873 | // if it's the first geometry, the type is the collection's main type (no?)
|
||
1874 | if (i == 0) { |
||
1875 | gtype = main_type; |
||
1876 | } |
||
1877 | |||
1878 | JGeometry itemjg = null;
|
||
1879 | |||
1880 | if (tableHasSrid) {
|
||
1881 | itemjg = new JGeometry(gtype, _srid, item_info_array, item_ords);
|
||
1882 | } |
||
1883 | else {
|
||
1884 | itemjg = new JGeometry(gtype, 0, item_info_array, item_ords); |
||
1885 | } |
||
1886 | |||
1887 | geoms[i] = getFMapGeometry(itemjg, true);
|
||
1888 | } |
||
1889 | |||
1890 | return new FGeometryCollection(geoms); |
||
1891 | } |
||
1892 | |||
1893 | private Datum[] updateIndexes(Datum[] info) { |
||
1894 | int size = info.length / 3; |
||
1895 | NUMBER[] resp = new NUMBER[3 * size]; |
||
1896 | |||
1897 | try {
|
||
1898 | int rest = info[0].intValue() - 1; |
||
1899 | |||
1900 | for (int i = 0; i < size; i++) { |
||
1901 | resp[3 * i] = new NUMBER(info[3 * i].intValue() - rest); |
||
1902 | resp[(3 * i) + 1] = new NUMBER(info[(3 * i) + 1].intValue()); |
||
1903 | resp[(3 * i) + 2] = new NUMBER(info[(3 * i) + 2].intValue()); |
||
1904 | } |
||
1905 | } |
||
1906 | catch (SQLException se) { |
||
1907 | logger.error("Unexpected error: " + se.getMessage());
|
||
1908 | } |
||
1909 | |||
1910 | return resp;
|
||
1911 | } |
||
1912 | |||
1913 | private int[] updateIndexes(int[] info) { |
||
1914 | int size = info.length / 3; |
||
1915 | int[] resp = new int[3 * size]; |
||
1916 | int rest = info[0] - 1; |
||
1917 | |||
1918 | for (int i = 0; i < size; i++) { |
||
1919 | resp[3 * i] = info[3 * i] - rest; |
||
1920 | resp[(3 * i) + 1] = info[(3 * i) + 1]; |
||
1921 | resp[(3 * i) + 2] = info[(3 * i) + 2]; |
||
1922 | } |
||
1923 | |||
1924 | return resp;
|
||
1925 | } |
||
1926 | |||
1927 | private int[] appendIntArrays(int[] head, int[] tail) { |
||
1928 | int[] resp = new int[head.length + tail.length]; |
||
1929 | int hsize = head.length;
|
||
1930 | |||
1931 | for (int i = 0; i < hsize; i++) { |
||
1932 | resp[i] = head[i]; |
||
1933 | } |
||
1934 | |||
1935 | for (int i = 0; i < tail.length; i++) { |
||
1936 | resp[hsize + i] = tail[i]; |
||
1937 | } |
||
1938 | |||
1939 | return resp;
|
||
1940 | } |
||
1941 | |||
1942 | private Datum[] appendDatArrays(Datum[] head, Datum[] tail) { |
||
1943 | Datum[] resp = new Datum[head.length + tail.length]; |
||
1944 | int hsize = head.length;
|
||
1945 | |||
1946 | for (int i = 0; i < hsize; i++) { |
||
1947 | resp[i] = head[i]; |
||
1948 | } |
||
1949 | |||
1950 | for (int i = 0; i < tail.length; i++) { |
||
1951 | resp[hsize + i] = tail[i]; |
||
1952 | } |
||
1953 | |||
1954 | return resp;
|
||
1955 | } |
||
1956 | |||
1957 | private int[] getNthGroupOfThree(int[] list, int n) { |
||
1958 | int[] resp = new int[3]; |
||
1959 | resp[0] = list[3 * n]; |
||
1960 | resp[1] = list[(3 * n) + 1]; |
||
1961 | resp[2] = list[(3 * n) + 2]; |
||
1962 | |||
1963 | return resp;
|
||
1964 | } |
||
1965 | |||
1966 | private Datum[] getNthGroupOfThree(Datum[] list, int n) { |
||
1967 | Datum[] resp = new Datum[3]; |
||
1968 | resp[0] = list[3 * n]; |
||
1969 | resp[1] = list[(3 * n) + 1]; |
||
1970 | resp[2] = list[(3 * n) + 2]; |
||
1971 | |||
1972 | return resp;
|
||
1973 | } |
||
1974 | |||
1975 | private Datum[] getSubSet(Datum[] all, int first_inc, int last_inc) { |
||
1976 | Datum[] resp = new Datum[last_inc - first_inc + 1]; |
||
1977 | |||
1978 | for (int i = first_inc; i <= last_inc; i++) { |
||
1979 | resp[i - first_inc] = all[i]; |
||
1980 | } |
||
1981 | |||
1982 | return resp;
|
||
1983 | } |
||
1984 | |||
1985 | private double[] getSubSet(double[] all, int first_inc, int last_inc) { |
||
1986 | double[] resp = new double[last_inc - first_inc + 1]; |
||
1987 | |||
1988 | for (int i = first_inc; i <= last_inc; i++) { |
||
1989 | resp[i - first_inc] = all[i]; |
||
1990 | } |
||
1991 | |||
1992 | return resp;
|
||
1993 | } |
||
1994 | |||
1995 | private Object[] getOrdOfGroups(Datum[] all, Object[] groups) { |
||
1996 | Object[] resp = new Object[groups.length]; |
||
1997 | |||
1998 | if (resp.length == 1) { |
||
1999 | resp[0] = all;
|
||
2000 | |||
2001 | return resp;
|
||
2002 | } |
||
2003 | |||
2004 | int ind = 0; |
||
2005 | int[] aux = (int[]) groups[1]; |
||
2006 | int _end = aux[0] - 2; |
||
2007 | Datum[] ord_aux = getSubSet(all, 0, _end); |
||
2008 | |||
2009 | int _start = _end + 1; |
||
2010 | resp[ind] = ord_aux; |
||
2011 | ind++; |
||
2012 | |||
2013 | for (int i = 2; i < groups.length; i++) { |
||
2014 | aux = (int[]) groups[i]; |
||
2015 | _end = aux[0] - 2; |
||
2016 | ord_aux = getSubSet(all, _start, _end); |
||
2017 | resp[ind] = ord_aux; |
||
2018 | ind++; |
||
2019 | _start = _end + 1;
|
||
2020 | } |
||
2021 | |||
2022 | // last
|
||
2023 | _end = all.length - 1;
|
||
2024 | ord_aux = getSubSet(all, _start, _end); |
||
2025 | resp[groups.length - 1] = ord_aux;
|
||
2026 | |||
2027 | return resp;
|
||
2028 | } |
||
2029 | |||
2030 | private Object[] getOrdOfGroups(double[] all, Object[] groups) { |
||
2031 | Object[] resp = new Object[groups.length]; |
||
2032 | |||
2033 | if (resp.length == 1) { |
||
2034 | resp[0] = all;
|
||
2035 | |||
2036 | return resp;
|
||
2037 | } |
||
2038 | |||
2039 | int ind = 0; |
||
2040 | int[] aux = (int[]) groups[1]; |
||
2041 | int _end = aux[0] - 2; |
||
2042 | double[] ord_aux = getSubSet(all, 0, _end); |
||
2043 | |||
2044 | int _start = _end + 1; |
||
2045 | resp[ind] = ord_aux; |
||
2046 | ind++; |
||
2047 | |||
2048 | for (int i = 2; i < groups.length; i++) { |
||
2049 | aux = (int[]) groups[i]; |
||
2050 | _end = aux[0] - 2; |
||
2051 | ord_aux = getSubSet(all, _start, _end); |
||
2052 | resp[ind] = ord_aux; |
||
2053 | ind++; |
||
2054 | _start = _end + 1;
|
||
2055 | } |
||
2056 | |||
2057 | // last
|
||
2058 | _end = all.length - 1;
|
||
2059 | ord_aux = getSubSet(all, _start, _end); |
||
2060 | resp[groups.length - 1] = ord_aux;
|
||
2061 | |||
2062 | return resp;
|
||
2063 | } |
||
2064 | |||
2065 | private Object[] groupByElement(int[] all_elem) { |
||
2066 | ArrayList resp = new ArrayList(); |
||
2067 | |||
2068 | int size = all_elem.length / 3; |
||
2069 | |||
2070 | int[] aux = getNthGroupOfThree(all_elem, 0); |
||
2071 | |||
2072 | int[] newaux; |
||
2073 | int i = 1; |
||
2074 | |||
2075 | while (i < size) {
|
||
2076 | newaux = getNthGroupOfThree(all_elem, i); |
||
2077 | |||
2078 | if (newaux[0] == aux[0]) { |
||
2079 | // aux[2] says how many components
|
||
2080 | for (int j = 0; j < aux[2]; j++) { |
||
2081 | aux = appendIntArrays(aux, |
||
2082 | getNthGroupOfThree(all_elem, j + i)); |
||
2083 | } |
||
2084 | |||
2085 | resp.add(aux); |
||
2086 | i = i + aux[2];
|
||
2087 | aux = getNthGroupOfThree(all_elem, i); |
||
2088 | } |
||
2089 | else {
|
||
2090 | if (newaux[1] == 2003) { |
||
2091 | aux = appendIntArrays(aux, newaux); |
||
2092 | } |
||
2093 | else {
|
||
2094 | resp.add(aux); |
||
2095 | aux = getNthGroupOfThree(all_elem, i); |
||
2096 | } |
||
2097 | } |
||
2098 | |||
2099 | i++; |
||
2100 | } |
||
2101 | |||
2102 | resp.add(aux); |
||
2103 | |||
2104 | return resp.toArray();
|
||
2105 | } |
||
2106 | |||
2107 | private Object[] groupByElement(Datum[] all_elem) { |
||
2108 | ArrayList resp = new ArrayList(); |
||
2109 | |||
2110 | int size = all_elem.length / 3; |
||
2111 | |||
2112 | Datum[] aux = getNthGroupOfThree(all_elem, 0); |
||
2113 | |||
2114 | Datum[] newaux;
|
||
2115 | int i = 1; |
||
2116 | |||
2117 | try {
|
||
2118 | while (i < size) {
|
||
2119 | newaux = getNthGroupOfThree(all_elem, i); |
||
2120 | |||
2121 | if (newaux[0] == aux[0]) { |
||
2122 | // aux[2] says how many components
|
||
2123 | for (int j = 0; j < ((NUMBER) aux[2]).intValue(); j++) { |
||
2124 | aux = appendDatArrays(aux, |
||
2125 | getNthGroupOfThree(all_elem, j + i)); |
||
2126 | } |
||
2127 | |||
2128 | resp.add(aux); |
||
2129 | i = i + ((NUMBER) aux[2]).intValue();
|
||
2130 | aux = getNthGroupOfThree(all_elem, i); |
||
2131 | } |
||
2132 | else {
|
||
2133 | if (((NUMBER) newaux[1]).intValue() == 2003) { |
||
2134 | aux = appendDatArrays(aux, newaux); |
||
2135 | } |
||
2136 | else {
|
||
2137 | resp.add(aux); |
||
2138 | aux = getNthGroupOfThree(all_elem, i); |
||
2139 | } |
||
2140 | } |
||
2141 | |||
2142 | i++; |
||
2143 | } |
||
2144 | } |
||
2145 | catch (SQLException se) { |
||
2146 | logger.error("Unexpected error: " + se.getMessage());
|
||
2147 | } |
||
2148 | |||
2149 | resp.add(aux); |
||
2150 | |||
2151 | return resp.toArray();
|
||
2152 | } |
||
2153 | |||
2154 | private IGeometry getJGeometryPoint2D(JGeometry _jgeom) {
|
||
2155 | Point2D p = _jgeom.getJavaPoint();
|
||
2156 | IGeometry ig = ShapeFactory.createPoint2D(p.getX(), p.getY()); |
||
2157 | |||
2158 | return ig;
|
||
2159 | } |
||
2160 | |||
2161 | private IGeometry getJGeometryMultiPoint2D(JGeometry _jgeom) {
|
||
2162 | Point2D[] pp = _jgeom.getJavaPoints(); |
||
2163 | int l = pp.length;
|
||
2164 | double[] x = new double[l]; |
||
2165 | double[] y = new double[l]; |
||
2166 | |||
2167 | for (int i = 0; i < l; i++) { |
||
2168 | x[i] = pp[i].getX(); |
||
2169 | y[i] = pp[i].getY(); |
||
2170 | } |
||
2171 | |||
2172 | IGeometry ig = ShapeFactory.createMultipoint2D(x, y); |
||
2173 | |||
2174 | return ig;
|
||
2175 | } |
||
2176 | |||
2177 | private IGeometry getJGeometryOther(JGeometry _jgeom) {
|
||
2178 | int type = oracleTypeToFShapeTypeExceptPointTypes(_jgeom.getType());
|
||
2179 | Shape shape = _jgeom.createShape();
|
||
2180 | GeneralPathX gpx = new GeneralPathX(shape);
|
||
2181 | IGeometry ig = null;
|
||
2182 | |||
2183 | switch (type) {
|
||
2184 | case FShape.LINE:
|
||
2185 | |||
2186 | FPolyline2D fpl = new FPolyline2D(gpx);
|
||
2187 | ig = ShapeFactory.createPolyline2D(gpx); |
||
2188 | |||
2189 | break;
|
||
2190 | |||
2191 | case FShape.POLYGON:
|
||
2192 | |||
2193 | FPolygon2D fpg = new FPolygon2D(gpx);
|
||
2194 | ig = ShapeFactory.createPolygon2D(gpx); |
||
2195 | |||
2196 | break;
|
||
2197 | } |
||
2198 | |||
2199 | return ig;
|
||
2200 | } |
||
2201 | |||
2202 | // private IGeometry getGeotoolsIGeometry(oracle.sql.STRUCT _struct) {
|
||
2203 | // Geometry geo_jts = null;
|
||
2204 | //
|
||
2205 | // try {
|
||
2206 | // geo_jts = geotools_conv.asGeometry(_struct);
|
||
2207 | // }
|
||
2208 | // catch (SQLException e) {
|
||
2209 | // System.err.println("While using geotools converter: " +
|
||
2210 | // e.getMessage());
|
||
2211 | // }
|
||
2212 | //
|
||
2213 | // IGeometry ig = FConverter.jts_to_igeometry(geo_jts);
|
||
2214 | //
|
||
2215 | // return ig;
|
||
2216 | // }
|
||
2217 | |||
2218 | private int oracleTypeToFShapeTypeExceptPointTypes(int type) { |
||
2219 | /*
|
||
2220 | * Tipos en Oracle Spatial usando JGeometry
|
||
2221 | *
|
||
2222 | * GTYPE_COLLECTION collection geometry type
|
||
2223 | * GTYPE_CURVE curve geoemtry type
|
||
2224 | * GTYPE_MULTICURVE multi-curve geometry type
|
||
2225 | * GTYPE_MULTIPOINT multi-point geometry type
|
||
2226 | * GTYPE_MULTIPOLYGON multi-polygon geometry type
|
||
2227 | * GTYPE_POINT point geometry type
|
||
2228 | * GTYPE_POLYGON polygon geometry type
|
||
2229 | *
|
||
2230 | * Tipos gvSIG FShape
|
||
2231 | *
|
||
2232 | * NULL = 0;
|
||
2233 | * POINT = 1;
|
||
2234 | * LINE = 2;
|
||
2235 | * POLYGON = 4;
|
||
2236 | * TEXT = 8;
|
||
2237 | * MULTI = 16;
|
||
2238 | * MULTIPOINT = 32;
|
||
2239 | * CIRCLE = 64;
|
||
2240 | * ARC = 128;
|
||
2241 | * ELLIPSE=256;
|
||
2242 | * Z=512
|
||
2243 | */
|
||
2244 | switch (type) {
|
||
2245 | case JGeometry.GTYPE_POLYGON:
|
||
2246 | case JGeometry.GTYPE_MULTIPOLYGON:
|
||
2247 | return FShape.POLYGON;
|
||
2248 | |||
2249 | case JGeometry.GTYPE_CURVE:
|
||
2250 | case JGeometry.GTYPE_MULTICURVE:
|
||
2251 | return FShape.LINE;
|
||
2252 | } |
||
2253 | |||
2254 | System.err.println("Unhandled Oracle Spatial geometry type: " + type + |
||
2255 | " (conversion returned FShape.NULL)");
|
||
2256 | |||
2257 | return FShape.NULL;
|
||
2258 | } |
||
2259 | |||
2260 | private void cleanWhereClause() { |
||
2261 | emptyWhereClause = false;
|
||
2262 | |||
2263 | String aux = getWhereClauseWithoutWhere();
|
||
2264 | |||
2265 | for (int i = 0; i < aux.length(); i++) |
||
2266 | if (aux.substring(i, i + 1).compareTo(" ") != 0) { |
||
2267 | return;
|
||
2268 | } |
||
2269 | |||
2270 | getLyrDef().setWhereClause("");
|
||
2271 | emptyWhereClause = true;
|
||
2272 | } |
||
2273 | |||
2274 | private String getValidViewConstructor( |
||
2275 | STRUCT _st, |
||
2276 | String ora_srid,
|
||
2277 | boolean _hassrid,
|
||
2278 | boolean _isgeocs) {
|
||
2279 | |||
2280 | String sdo = getSdoConstructor(_st, _hassrid, _isgeocs);
|
||
2281 | String resp = ""; |
||
2282 | if ((_hassrid) && (_isgeocs)) {
|
||
2283 | resp = "SDO_CS.VIEWPORT_TRANSFORM( " + sdo + " , " + ora_srid + ")"; |
||
2284 | } else {
|
||
2285 | resp = sdo; |
||
2286 | } |
||
2287 | |||
2288 | return resp;
|
||
2289 | } |
||
2290 | |||
2291 | private String getMainSelect(String viewsdo, String idsLoadWhere) { |
||
2292 | String resp = ""; |
||
2293 | |||
2294 | if (isGeogCS) {
|
||
2295 | String vport = "sdo_filter(" + geoColName + |
||
2296 | ", SDO_CS.VIEWPORT_TRANSFORM(" + viewsdo + ", " + oracleSRID + |
||
2297 | "), 'querytype=window') = 'TRUE'";
|
||
2298 | |||
2299 | resp = "select " + getStandardSelectExpression() + ", c." + |
||
2300 | geoColName + " from " + getTableName() + " c where "; |
||
2301 | if (idsLoadWhere.length() > 0) { |
||
2302 | resp = resp + " (" + idsLoadWhere + ") AND "; |
||
2303 | } |
||
2304 | resp = resp + "(" + vport + ")"; |
||
2305 | } |
||
2306 | else {
|
||
2307 | resp = "select " + getStandardSelectExpression() + ", c." + |
||
2308 | geoColName + " from " + getTableName() + " c where "; |
||
2309 | if (idsLoadWhere.length() > 0) { |
||
2310 | resp = resp + " (" + idsLoadWhere + ") AND "; |
||
2311 | } |
||
2312 | resp = resp + "(" + "sdo_relate(" + geoColName + ", " + viewsdo + |
||
2313 | ", 'mask=anyinteract querytype=window') = 'TRUE')";
|
||
2314 | } |
||
2315 | return resp;
|
||
2316 | } |
||
2317 | |||
2318 | public void setWorkingArea(Rectangle2D rect) { |
||
2319 | } |
||
2320 | |||
2321 | private void setWAStructt() { |
||
2322 | } |
||
2323 | |||
2324 | private Geometry shapeToGeometry(Shape shp) { |
||
2325 | if (shp == null) { |
||
2326 | return null; |
||
2327 | } |
||
2328 | |||
2329 | int type = FShape.POLYGON;
|
||
2330 | |||
2331 | if ((shp instanceof FPolyline2D) && (!(shp instanceof FPolygon2D))) { |
||
2332 | type = FShape.LINE; |
||
2333 | } |
||
2334 | |||
2335 | if (shp instanceof FPoint2D) { |
||
2336 | type = FShape.POINT; |
||
2337 | } |
||
2338 | |||
2339 | if (shp instanceof FMultiPoint2D) { |
||
2340 | type = FShape.MULTIPOINT; |
||
2341 | } |
||
2342 | |||
2343 | GeneralPathX wagp = new GeneralPathX(shp);
|
||
2344 | FShapeGeneralPathX fwagp = new FShapeGeneralPathX(wagp, type);
|
||
2345 | |||
2346 | return FConverter.java2d_to_jts(fwagp);
|
||
2347 | } |
||
2348 | |||
2349 | public static Rectangle2D getBoundingBox(JGeometry _jg) { |
||
2350 | Shape shape = _jg.createShape();
|
||
2351 | |||
2352 | return shape.getBounds2D();
|
||
2353 | } |
||
2354 | |||
2355 | private void printStruct(STRUCT st) { |
||
2356 | System.out.println("----------------------------------------------"); |
||
2357 | |||
2358 | try {
|
||
2359 | Object[] att = st.getAttributes(); |
||
2360 | int l = att.length;
|
||
2361 | |||
2362 | for (int i = 0; i < l; i++) { |
||
2363 | System.out.println("ATT " + i + ": " + att[i].toString()); |
||
2364 | } |
||
2365 | } |
||
2366 | catch (Exception ex) { |
||
2367 | System.out.println(
|
||
2368 | "- Error ---------------------------------------");
|
||
2369 | } |
||
2370 | |||
2371 | System.out.println("----------------------------------------------"); |
||
2372 | } |
||
2373 | |||
2374 | private static STRUCT rectangleToStruct(Rectangle2D r, boolean hasSrid, |
||
2375 | boolean isView, boolean _isGeogCS, String _oracleSRID, Connection __conn) { |
||
2376 | Point2D c1 = new Point2D.Double(r.getMinX(), r.getMinY()); |
||
2377 | Point2D c2 = new Point2D.Double(r.getMaxX(), r.getMaxY()); |
||
2378 | |||
2379 | if ((_isGeogCS) && (isView)) {
|
||
2380 | c1.setLocation(Math.max(c1.getX(), -180), Math.max(c1.getY(), -90)); |
||
2381 | c2.setLocation(Math.min(c2.getX(), 180), Math.min(c2.getY(), 90)); |
||
2382 | } |
||
2383 | |||
2384 | STRUCT resp = null;
|
||
2385 | |||
2386 | try {
|
||
2387 | // System.out.println("ABIERTA: " + (!conn.isClosed()));
|
||
2388 | // resp = structCreator.toSTRUCT(rect_wkt.getBytes(), conn);
|
||
2389 | // Object[] old_obj = resp.getAttributes();
|
||
2390 | int size = 5; |
||
2391 | Object[] new_obj = new Object[size]; |
||
2392 | |||
2393 | // for (int i=0; i<size; i++) new_obj[i] = old_obj[i];
|
||
2394 | new_obj[0] = new NUMBER(2003); |
||
2395 | |||
2396 | if (hasSrid) {
|
||
2397 | new_obj[1] = new NUMBER(_oracleSRID); |
||
2398 | } |
||
2399 | else {
|
||
2400 | new_obj[1] = null; |
||
2401 | } |
||
2402 | |||
2403 | new_obj[2] = null; |
||
2404 | |||
2405 | NUMBER[] elem_info = new NUMBER[3]; |
||
2406 | elem_info[0] = new NUMBER(1); |
||
2407 | elem_info[1] = new NUMBER(1003); |
||
2408 | elem_info[2] = new NUMBER(3); |
||
2409 | new_obj[3] = elem_info;
|
||
2410 | |||
2411 | NUMBER[] ords = null; |
||
2412 | ords = new NUMBER[4]; |
||
2413 | ords[0] = new NUMBER(c1.getX()); |
||
2414 | ords[1] = new NUMBER(c1.getY()); |
||
2415 | ords[2] = new NUMBER(c2.getX()); |
||
2416 | ords[3] = new NUMBER(c2.getY()); |
||
2417 | new_obj[4] = ords;
|
||
2418 | |||
2419 | // StructDescriptor dsc = StructDescriptor.createDescriptor("STRUCT", conn);
|
||
2420 | StructDescriptor dsc = StructDescriptor.createDescriptor("MDSYS.SDO_GEOMETRY",
|
||
2421 | __conn); |
||
2422 | |||
2423 | resp = new STRUCT(dsc, __conn, new_obj);
|
||
2424 | } |
||
2425 | catch (Exception ex) { |
||
2426 | logger.error("Error while creating rect struct: " +
|
||
2427 | ex.getMessage(), ex); |
||
2428 | } |
||
2429 | |||
2430 | return resp;
|
||
2431 | } |
||
2432 | |||
2433 | private Object[] getViewResultSet(STRUCT geoStruct, String fixsql, |
||
2434 | boolean hasSrid) throws DriverException { |
||
2435 | String sdo_intersect = getSdoConstructor(geoStruct, hasSrid, isGeogCS);
|
||
2436 | String main_sel = ""; |
||
2437 | |||
2438 | if (fixsql == null) { |
||
2439 | // main_sel = getMainSelect3(var_name);
|
||
2440 | String idswhere = getIdsQueryWhereClause(false); |
||
2441 | main_sel = getMainSelect(sdo_intersect, idswhere); |
||
2442 | } |
||
2443 | else {
|
||
2444 | main_sel = fixsql; |
||
2445 | } |
||
2446 | |||
2447 | System.err.println("main sel = " + main_sel); |
||
2448 | |||
2449 | ResultSet _rs = null; |
||
2450 | Statement _stmnt = null; |
||
2451 | Object[] _resp = new Object[2]; |
||
2452 | |||
2453 | try {
|
||
2454 | _stmnt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY,
|
||
2455 | ResultSet.CONCUR_READ_ONLY);
|
||
2456 | _stmnt.setFetchDirection(ResultSet.FETCH_FORWARD);
|
||
2457 | _stmnt.setFetchSize(FETCH_SIZE); |
||
2458 | |||
2459 | _rs = _stmnt.executeQuery(main_sel); |
||
2460 | |||
2461 | // stmnt.close();
|
||
2462 | } |
||
2463 | catch (SQLException se) { |
||
2464 | logger.error("Tablename: " + getTableName() + ". Error while getting main cursor: " + se.getMessage(), |
||
2465 | se); |
||
2466 | throw new DriverException(se); |
||
2467 | } |
||
2468 | |||
2469 | // this method returns the statement too, so that it can be closed afterwards
|
||
2470 | _resp[0] = _rs;
|
||
2471 | _resp[1] = _stmnt;
|
||
2472 | |||
2473 | return _resp;
|
||
2474 | } |
||
2475 | |||
2476 | private String getSdoConstructor(STRUCT geoStruct, boolean hasSrid, boolean _isGeogCS) { |
||
2477 | String resp = ""; |
||
2478 | |||
2479 | try {
|
||
2480 | String mdsys_sdo_elem_info_array = "mdsys.sdo_elem_info_array(1, 1003, 3)"; |
||
2481 | String mdsys_sdo_ordinate_array = ""; |
||
2482 | Datum[] vertices = ((ARRAY) geoStruct.getOracleAttributes()[4]).getOracleArray(); |
||
2483 | |||
2484 | for (int i = 0; i < vertices.length; i++) { |
||
2485 | mdsys_sdo_ordinate_array = mdsys_sdo_ordinate_array + |
||
2486 | vertices[i].doubleValue() + ", ";
|
||
2487 | } |
||
2488 | |||
2489 | mdsys_sdo_ordinate_array = mdsys_sdo_ordinate_array.substring(0,
|
||
2490 | mdsys_sdo_ordinate_array.length() - 2);
|
||
2491 | mdsys_sdo_ordinate_array = "mdsys.sdo_ordinate_array(" +
|
||
2492 | mdsys_sdo_ordinate_array + ")";
|
||
2493 | |||
2494 | String aux = ""; |
||
2495 | |||
2496 | if (hasSrid) {
|
||
2497 | aux = oracleSRID; |
||
2498 | |||
2499 | if (_isGeogCS) {
|
||
2500 | aux = "0";
|
||
2501 | } |
||
2502 | } |
||
2503 | else {
|
||
2504 | aux = "null";
|
||
2505 | } |
||
2506 | |||
2507 | resp = "mdsys.sdo_geometry(2003, " + aux + ", null, " + |
||
2508 | mdsys_sdo_elem_info_array + ", " + mdsys_sdo_ordinate_array +
|
||
2509 | ")";
|
||
2510 | } |
||
2511 | catch (Exception ex) { |
||
2512 | System.err.println("Error while getting sdo contructor: " + |
||
2513 | ex.getMessage()); |
||
2514 | } |
||
2515 | |||
2516 | return resp;
|
||
2517 | } |
||
2518 | |||
2519 | private String getIdsQueryWhereClause(boolean with_where) { |
||
2520 | String resp = ""; |
||
2521 | |||
2522 | String _where = ""; |
||
2523 | if (with_where) _where = " where "; |
||
2524 | |||
2525 | if (workingAreaInTablesCSStruct == null) { |
||
2526 | if (emptyWhereClause) {
|
||
2527 | // return "select rowid from " + getTableName();
|
||
2528 | } else {
|
||
2529 | resp = resp + _where + "(" + getWhereClauseWithoutWhere()
|
||
2530 | + ")";
|
||
2531 | } |
||
2532 | } else {
|
||
2533 | String waqry = getValidViewConstructor(workingAreaInTablesCSStruct,
|
||
2534 | oracleSRID, tableHasSrid, isGeogCS); |
||
2535 | |||
2536 | if (emptyWhereClause) {
|
||
2537 | resp = resp + _where + "(sdo_relate(" + geoColName + ", " + waqry |
||
2538 | + ", 'mask=anyinteract querytype=window') = 'TRUE')";
|
||
2539 | } else {
|
||
2540 | resp = resp + _where + "((" + getWhereClauseWithoutWhere()
|
||
2541 | + ") AND (" + "sdo_relate(" + geoColName + ", " + waqry |
||
2542 | + ", 'mask=anyinteract querytype=window') = 'TRUE'))";
|
||
2543 | } |
||
2544 | } |
||
2545 | |||
2546 | // resp = resp + " order by rowid";
|
||
2547 | return resp;
|
||
2548 | } |
||
2549 | |||
2550 | public String getIdAndElemInfoFullResulltSetQuery() { |
||
2551 | String resp = "select rowid, c." + geoColName + ".SDO_ELEM_INFO from " + |
||
2552 | getTableName() + " c";
|
||
2553 | |||
2554 | resp = resp + getIdsQueryWhereClause(true);
|
||
2555 | return resp;
|
||
2556 | } |
||
2557 | |||
2558 | private String getSearchId() { |
||
2559 | if (emptyWhereClause) {
|
||
2560 | return "select " + getStandardSelectExpression() + ", c." + |
||
2561 | geoColName + " from " + getTableName() + " c where rowid = ?"; |
||
2562 | } |
||
2563 | else {
|
||
2564 | return "select " + getStandardSelectExpression() + ", c." + |
||
2565 | geoColName + " from " + getTableName() + " c " + " where " + "((" + |
||
2566 | getWhereClauseWithoutWhere() + ") and (rowid = ?))";
|
||
2567 | } |
||
2568 | } |
||
2569 | |||
2570 | public int getShapeType() { |
||
2571 | return shapeType;
|
||
2572 | } |
||
2573 | |||
2574 | private String getWhereClauseWithoutWhere() { |
||
2575 | String resp = ""; |
||
2576 | String old = getLyrDef().getWhereClause();
|
||
2577 | resp = old; |
||
2578 | |||
2579 | if (old.length() <= 6) { |
||
2580 | return old;
|
||
2581 | } |
||
2582 | |||
2583 | if (old.substring(0, 6).compareToIgnoreCase("where ") == 0) { |
||
2584 | resp = resp.substring(6, resp.length());
|
||
2585 | } |
||
2586 | |||
2587 | return resp;
|
||
2588 | } |
||
2589 | |||
2590 | private Rectangle2D doIntersect(Rectangle2D r1, Rectangle2D r2) { |
||
2591 | if (r1.getMaxX() <= r2.getMinX()) {
|
||
2592 | return null; |
||
2593 | } |
||
2594 | |||
2595 | if (r2.getMaxX() <= r1.getMinX()) {
|
||
2596 | return null; |
||
2597 | } |
||
2598 | |||
2599 | if (r1.getMaxY() <= r2.getMinY()) {
|
||
2600 | return null; |
||
2601 | } |
||
2602 | |||
2603 | if (r2.getMaxY() <= r1.getMinY()) {
|
||
2604 | return null; |
||
2605 | } |
||
2606 | |||
2607 | double minx = Math.max(r1.getMinX(), r2.getMinX()); |
||
2608 | double miny = Math.max(r1.getMinY(), r2.getMinY()); |
||
2609 | double maxx = Math.min(r1.getMaxX(), r2.getMaxX()); |
||
2610 | double maxy = Math.min(r1.getMaxY(), r2.getMaxY()); |
||
2611 | |||
2612 | double w = maxx - minx;
|
||
2613 | double h = maxy - miny;
|
||
2614 | |||
2615 | return new Rectangle2D.Double(minx, miny, w, h); |
||
2616 | } |
||
2617 | |||
2618 | private static int maxSizeForFieldType(int _type) { |
||
2619 | switch (_type) {
|
||
2620 | case Types.VARCHAR: |
||
2621 | return OracleSpatialDriver.VARCHAR2_STANDARD_SIZE;
|
||
2622 | |||
2623 | case Types.LONGVARCHAR: |
||
2624 | return OracleSpatialDriver.VARCHAR2_LONG_SIZE;
|
||
2625 | } |
||
2626 | |||
2627 | return -1; |
||
2628 | } |
||
2629 | |||
2630 | public static String fieldTypeToSqlStringType(FieldDescription fieldDesc) { |
||
2631 | String aux = "VARCHAR2(" + VARCHAR2_STANDARD_SIZE + " BYTE)"; // Por defecto. |
||
2632 | |||
2633 | switch (fieldDesc.getFieldType()) {
|
||
2634 | case Types.SMALLINT: |
||
2635 | aux = "NUMBER(5, 0)";
|
||
2636 | |||
2637 | break;
|
||
2638 | |||
2639 | case Types.INTEGER: |
||
2640 | aux = "NUMBER(10, 0)";
|
||
2641 | |||
2642 | break;
|
||
2643 | |||
2644 | case Types.BIGINT: |
||
2645 | aux = "NUMBER(38, 0)";
|
||
2646 | |||
2647 | break;
|
||
2648 | |||
2649 | case Types.BOOLEAN: |
||
2650 | aux = "NUMBER(1, 0)";
|
||
2651 | |||
2652 | break;
|
||
2653 | |||
2654 | case Types.DECIMAL: |
||
2655 | aux = "NUMBER";
|
||
2656 | |||
2657 | break;
|
||
2658 | |||
2659 | case Types.NUMERIC: |
||
2660 | aux = "NUMBER";
|
||
2661 | |||
2662 | break;
|
||
2663 | |||
2664 | case Types.DOUBLE: |
||
2665 | aux = "FLOAT";
|
||
2666 | |||
2667 | break;
|
||
2668 | |||
2669 | case Types.FLOAT: |
||
2670 | aux = "FLOAT";
|
||
2671 | |||
2672 | break;
|
||
2673 | |||
2674 | case Types.CHAR: |
||
2675 | aux = "CHAR(1 BYTE)";
|
||
2676 | |||
2677 | break;
|
||
2678 | |||
2679 | case Types.VARCHAR: |
||
2680 | aux = "NVARCHAR2(" + fieldDesc.getFieldLength() + ")"; |
||
2681 | |||
2682 | break;
|
||
2683 | |||
2684 | case Types.LONGVARCHAR: |
||
2685 | aux = "NVARCHAR2(" + fieldDesc.getFieldLength() + ")"; |
||
2686 | |||
2687 | break;
|
||
2688 | } |
||
2689 | |||
2690 | return aux;
|
||
2691 | } |
||
2692 | |||
2693 | // -----------------------------------------------------------
|
||
2694 | // -----------------------------------------------------------
|
||
2695 | public static String getDropTableSql(DBLayerDefinition dbLayerDef) { |
||
2696 | return "DROP TABLE \"" + dbLayerDef.getTableName() + |
||
2697 | "\" CASCADE CONSTRAINTS";
|
||
2698 | } |
||
2699 | |||
2700 | public static String getTableCreationSql(DBLayerDefinition dbLayerDef) { |
||
2701 | FieldDescription[] flds = dbLayerDef.getFieldsDesc();
|
||
2702 | |||
2703 | String type = ""; |
||
2704 | String name = ""; |
||
2705 | |||
2706 | String resp = "CREATE TABLE \"" + dbLayerDef.getTableName() + "\" ( "; |
||
2707 | |||
2708 | for (int i = 0; i < flds.length; i++) { |
||
2709 | name = flds[i].getFieldName(); |
||
2710 | |||
2711 | // -------------- FORBIDDEN FIELD NAMES -----------------
|
||
2712 | if (!isOracleAllowedFieldname(name)) {
|
||
2713 | continue;
|
||
2714 | } |
||
2715 | |||
2716 | // ------------------------------------------------------
|
||
2717 | if (name.compareToIgnoreCase(DEFAULT_GEO_FIELD) == 0) { |
||
2718 | } |
||
2719 | else {
|
||
2720 | name = getValidOracleID(name, i); |
||
2721 | resp = resp + "\"" + name + "\" "; |
||
2722 | type = fieldTypeToSqlStringType(flds[i]); |
||
2723 | resp = resp + type + ", ";
|
||
2724 | } |
||
2725 | } |
||
2726 | |||
2727 | resp = resp + "\"" + DEFAULT_GEO_FIELD + "\" "; |
||
2728 | resp = resp + "\"MDSYS\".\"SDO_GEOMETRY\"";
|
||
2729 | resp = resp + ", ";
|
||
2730 | |||
2731 | String pk = "CONSTRAINT \"" + dbLayerDef.getTableName() + |
||
2732 | "_PK\" PRIMARY KEY (\"" + OracleSpatialDriver.DEFAULT_ID_FIELD +
|
||
2733 | "\") ENABLE";
|
||
2734 | |||
2735 | resp = resp + pk + " )";
|
||
2736 | |||
2737 | return resp;
|
||
2738 | } |
||
2739 | |||
2740 | public static String getIndexCreationSql(DBLayerDefinition dbLayerDef) { |
||
2741 | String resp = "CREATE INDEX \"" + dbLayerDef.getTableName() + |
||
2742 | "_SX\" ON \"" + dbLayerDef.getTableName() + "\" (\"" + |
||
2743 | OracleSpatialDriver.DEFAULT_GEO_FIELD + |
||
2744 | "\") INDEXTYPE IS \"MDSYS\".\"SPATIAL_INDEX\" ";
|
||
2745 | |||
2746 | return resp;
|
||
2747 | } |
||
2748 | |||
2749 | public static String getRemoveMetadataSql(DBLayerDefinition dbLayerDef) { |
||
2750 | return "DELETE FROM " + ORACLE_GEOMETADATA_VIEW + |
||
2751 | " WHERE TABLE_NAME = '" + dbLayerDef.getTableName() + "'"; |
||
2752 | } |
||
2753 | |||
2754 | /**
|
||
2755 | * UTility method to get the SQL sentence needed to update the geographic metadata table
|
||
2756 | * with a new bounding box and SRS
|
||
2757 | *
|
||
2758 | * @param tName table name
|
||
2759 | * @param ora_srid new SRS
|
||
2760 | * @param bbox new bounding box
|
||
2761 | * @param dim geometries dimension
|
||
2762 | * @param withsrid False if the SRS is set to NULL. True otherwise.
|
||
2763 | * @return the SQL sentence to perform the update
|
||
2764 | */
|
||
2765 | 13995 | jldominguez@prodevelop.es | public static String getMetadataUpdateSql(String schema, String tName, String ora_srid, |
2766 | 13991 | jldominguez@prodevelop.es | Rectangle2D bbox, int dim, boolean withsrid) { |
2767 | String[] dim_name = new String[dim]; |
||
2768 | double tolerance = 0.5; |
||
2769 | |||
2770 | if (ora_srid.compareTo(GEODETIC_SRID) == 0) { |
||
2771 | dim_name[0] = "LONGITUDE"; |
||
2772 | dim_name[1] = "LATITUDE"; |
||
2773 | } |
||
2774 | else {
|
||
2775 | dim_name[0] = "X"; |
||
2776 | dim_name[1] = "Y"; |
||
2777 | |||
2778 | if (dim > 2) { |
||
2779 | dim_name[2] = "Z"; |
||
2780 | |||
2781 | if (dim > 3) { |
||
2782 | dim_name[3] = "T"; |
||
2783 | } |
||
2784 | } |
||
2785 | } |
||
2786 | |||
2787 | String resp = "INSERT INTO " + ORACLE_GEOMETADATA_VIEW + " " + |
||
2788 | 13995 | jldominguez@prodevelop.es | " ( OWNER, TABLE_NAME, COLUMN_NAME, DIMINFO, SRID ) " + " VALUES (" |
2789 | + "'" + schema + "', " |
||
2790 | + "'" + tName + "', " |
||
2791 | + "'" + DEFAULT_GEO_FIELD + "', " + |
||
2792 | "MDSYS.SDO_DIM_ARRAY( " + "MDSYS.SDO_DIM_ELEMENT ('" + dim_name[0] + "', " + |
||
2793 | 13991 | jldominguez@prodevelop.es | bbox.getMinX() + ", " + bbox.getMaxX() + ", " + tolerance + " ), " + |
2794 | 13995 | jldominguez@prodevelop.es | "MDSYS.SDO_DIM_ELEMENT ('" + dim_name[1] + "', " + bbox.getMinY() + ", " + |
2795 | 13991 | jldominguez@prodevelop.es | bbox.getMaxY() + ", " + tolerance + " ))"; |
2796 | |||
2797 | if (dim > 2) { |
||
2798 | resp = resp.substring(0, resp.length() - 1) + ","; |
||
2799 | 13995 | jldominguez@prodevelop.es | resp = resp + "MDSYS.SDO_DIM_ELEMENT ('" + dim_name[2] + |
2800 | 13991 | jldominguez@prodevelop.es | "', 0.0, 100.0, " + tolerance + " ))"; |
2801 | |||
2802 | if (dim > 3) { |
||
2803 | resp = resp.substring(0, resp.length() - 1) + ","; |
||
2804 | 13995 | jldominguez@prodevelop.es | resp = resp + "MDSYS.SDO_DIM_ELEMENT ('" + dim_name[3] + |
2805 | 13991 | jldominguez@prodevelop.es | "', 0.0, 100.0, " + tolerance + " ))"; |
2806 | } |
||
2807 | } |
||
2808 | |||
2809 | if (withsrid) {
|
||
2810 | resp = resp + ", " + ora_srid + " )"; |
||
2811 | } |
||
2812 | else {
|
||
2813 | resp = resp + ", NULL )";
|
||
2814 | } |
||
2815 | |||
2816 | return resp;
|
||
2817 | } |
||
2818 | |||
2819 | /**
|
||
2820 | * Gets the SQL sentence to perform an insertion.
|
||
2821 | *
|
||
2822 | * @param feat feature to be added
|
||
2823 | * @param dbLayerDef layer definition
|
||
2824 | * @param rowInd row index
|
||
2825 | * @param _geoColName geometry field name
|
||
2826 | * @return the SQL sentence to perform the insertion
|
||
2827 | */
|
||
2828 | public static String getRowInsertSql(IFeature feat, |
||
2829 | DBLayerDefinition dbLayerDef, int rowInd, String _geoColName) { |
||
2830 | String name = ""; |
||
2831 | int ftype = -1; |
||
2832 | String aux_orig = ""; |
||
2833 | String aux_limited = ""; |
||
2834 | String aux_quotes_ok = ""; |
||
2835 | |||
2836 | FieldDescription[] fieldsDescr = dbLayerDef.getFieldsDesc();
|
||
2837 | |||
2838 | String resp = "INSERT INTO \"" + dbLayerDef.getTableName() + "\" ( "; |
||
2839 | |||
2840 | for (int i = 0; i < fieldsDescr.length; i++) { |
||
2841 | name = fieldsDescr[i].getFieldName(); |
||
2842 | ftype = fieldsDescr[i].getFieldType(); |
||
2843 | |||
2844 | // -------------- FORBIDDEN FIELD NAMES & TYPES ---------
|
||
2845 | if (!isOracleAllowedFieldname(name)) continue; |
||
2846 | if (!isUserEditableType(ftype, name, _geoColName)) continue; |
||
2847 | // ------------------------------------------------------
|
||
2848 | if (name.compareToIgnoreCase(_geoColName) == 0) { |
||
2849 | } |
||
2850 | else {
|
||
2851 | name = getValidOracleID(name, i); |
||
2852 | resp = resp + "\"" + name + "\"" + " , "; |
||
2853 | } |
||
2854 | } |
||
2855 | |||
2856 | resp = resp + _geoColName + " ) VALUES ( ";
|
||
2857 | |||
2858 | for (int i = 0; i < fieldsDescr.length; i++) { |
||
2859 | name = fieldsDescr[i].getFieldName(); |
||
2860 | ftype = fieldsDescr[i].getFieldType(); |
||
2861 | |||
2862 | // -------------- FORBIDDEN FIELD NAMES/Types -----------
|
||
2863 | if (!isOracleAllowedFieldname(name)) continue; |
||
2864 | if (!isUserEditableType(ftype, name, _geoColName)) continue; |
||
2865 | // ------------------------------------------------------
|
||
2866 | String sur = getValueSurroundFromType(fieldsDescr[i]);
|
||
2867 | |||
2868 | if (name.compareToIgnoreCase(_geoColName) == 0) { |
||
2869 | } |
||
2870 | else {
|
||
2871 | if (name.compareToIgnoreCase(
|
||
2872 | OracleSpatialDriver.DEFAULT_ID_FIELD) == 0) {
|
||
2873 | resp = resp + rowInd + " , ";
|
||
2874 | } |
||
2875 | else {
|
||
2876 | Value attValue = feat.getAttribute(i); |
||
2877 | |||
2878 | if (attValue.toString() == null) { |
||
2879 | resp = resp + "NULL , ";
|
||
2880 | } |
||
2881 | else {
|
||
2882 | if (sur.length() > 0) { |
||
2883 | aux_orig = attValue.toString(); |
||
2884 | aux_limited = cropStringValue(aux_orig, i, |
||
2885 | fieldsDescr); |
||
2886 | aux_quotes_ok = avoidQuoteProblem(aux_limited); |
||
2887 | |||
2888 | resp = resp + sur + aux_quotes_ok + sur + " , ";
|
||
2889 | } |
||
2890 | else {
|
||
2891 | String _aux = attValue.toString();
|
||
2892 | |||
2893 | if (_aux.length() == 0) { |
||
2894 | _aux = "NULL";
|
||
2895 | } |
||
2896 | |||
2897 | resp = resp + _aux + " , ";
|
||
2898 | } |
||
2899 | } |
||
2900 | } |
||
2901 | } |
||
2902 | } |
||
2903 | |||
2904 | resp = resp + " ? )";
|
||
2905 | |||
2906 | return resp;
|
||
2907 | } |
||
2908 | |||
2909 | private static boolean isUserEditableType(int ftype, String item_name, String geo_name) { |
||
2910 | |||
2911 | if (item_name.compareToIgnoreCase(geo_name) == 0) { |
||
2912 | return true; |
||
2913 | } |
||
2914 | |||
2915 | if ((ftype == Types.BINARY) |
||
2916 | || (ftype == Types.ARRAY)
|
||
2917 | || (ftype == Types.BLOB)
|
||
2918 | || (ftype == Types.CLOB)
|
||
2919 | || (ftype == Types.STRUCT)
|
||
2920 | ) { |
||
2921 | return false; |
||
2922 | } |
||
2923 | return true; |
||
2924 | } |
||
2925 | |||
2926 | /**
|
||
2927 | * Gets the SQL sentence to perform an update.
|
||
2928 | *
|
||
2929 | * @param feat feature to be updated
|
||
2930 | * @param dbLayerDef layer definition
|
||
2931 | * @param rowInd row index
|
||
2932 | * @param geoFieldName geometry field name
|
||
2933 | * @return the SQL sentence to perform the update
|
||
2934 | */
|
||
2935 | public static String getRowUpdateSql(IFeature feat, |
||
2936 | DBLayerDefinition dbLayerDef, int rowInd, String geoFieldName) { |
||
2937 | String name = ""; |
||
2938 | String aux_orig = ""; |
||
2939 | String aux_limited = ""; |
||
2940 | String aux_quotes_ok = ""; |
||
2941 | |||
2942 | Value[] atts = feat.getAttributes();
|
||
2943 | FieldDescription[] _fieldsDescr = dbLayerDef.getFieldsDesc();
|
||
2944 | |||
2945 | String resp = "UPDATE \"" + dbLayerDef.getTableName() + "\" SET "; |
||
2946 | |||
2947 | for (int i = 0; i < _fieldsDescr.length; i++) { |
||
2948 | name = _fieldsDescr[i].getFieldName(); |
||
2949 | |||
2950 | // -------------- FORBIDDEN FIELD NAMES -----------------
|
||
2951 | if (!isOracleAllowedFieldname(name)) {
|
||
2952 | logger.info("Field: " + name + " will not be updated."); |
||
2953 | continue;
|
||
2954 | } |
||
2955 | |||
2956 | if (isStructAndNotGeoField(_fieldsDescr[i].getFieldType(), name,
|
||
2957 | geoFieldName)) { |
||
2958 | logger.info("Field: " + name + " will not be updated (it's a struct)."); |
||
2959 | continue;
|
||
2960 | } |
||
2961 | |||
2962 | // ------------------------------------------------------
|
||
2963 | if (name.compareToIgnoreCase(geoFieldName) == 0) { |
||
2964 | // resp = resp + "\"" + name + "\"" + " = ?, ";
|
||
2965 | } |
||
2966 | else {
|
||
2967 | String sur = getValueSurroundFromType(_fieldsDescr[i]);
|
||
2968 | aux_orig = atts[i].toString(); |
||
2969 | aux_limited = cropStringValue(aux_orig, i, _fieldsDescr); |
||
2970 | aux_quotes_ok = avoidQuoteProblem(aux_limited); |
||
2971 | resp = resp + "\"" + name + "\"" + " = " + sur + aux_quotes_ok + |
||
2972 | sur + ", ";
|
||
2973 | } |
||
2974 | } |
||
2975 | |||
2976 | resp = resp + "\"" + geoFieldName + "\" = ?"; |
||
2977 | resp = resp + " WHERE ROWID ='" + feat.getID() + "'"; |
||
2978 | |||
2979 | return resp;
|
||
2980 | } |
||
2981 | |||
2982 | private static boolean isStructAndNotGeoField(int ftype, String fldname, |
||
2983 | String geoname) {
|
||
2984 | if (ftype == Types.STRUCT) { |
||
2985 | if (fldname.compareToIgnoreCase(geoname) != 0) { |
||
2986 | return true; |
||
2987 | } |
||
2988 | } |
||
2989 | |||
2990 | return false; |
||
2991 | } |
||
2992 | |||
2993 | /**
|
||
2994 | * Gets the SQL sentence to perform a deletion.
|
||
2995 | *
|
||
2996 | * @param dbLayerDef layer definition
|
||
2997 | * @param id ROWID of the record to be deleted
|
||
2998 | * @return the SQL sentence to perform the deletion
|
||
2999 | */
|
||
3000 | public static String getRowDeleteSql(DBLayerDefinition dbLayerDef, String id) { |
||
3001 | String resp = "DELETE FROM \"" + dbLayerDef.getTableName() + "\""; |
||
3002 | resp = resp + " WHERE ROWID ='" + id + "'"; |
||
3003 | |||
3004 | return resp;
|
||
3005 | } |
||
3006 | |||
3007 | private static String cropStringValue(String orig_val, int i, |
||
3008 | FieldDescription[] _flds) {
|
||
3009 | if (orig_val == null) { |
||
3010 | return "NULL"; |
||
3011 | } |
||
3012 | |||
3013 | int tpe = _flds[i].getFieldType();
|
||
3014 | int max_size = maxSizeForFieldType(tpe);
|
||
3015 | |||
3016 | if (max_size == -1) { |
||
3017 | return orig_val;
|
||
3018 | } |
||
3019 | |||
3020 | int or_size = orig_val.length();
|
||
3021 | |||
3022 | if (or_size <= max_size) {
|
||
3023 | return orig_val;
|
||
3024 | } |
||
3025 | |||
3026 | return orig_val.substring(0, max_size); |
||
3027 | } |
||
3028 | |||
3029 | private static String avoidQuoteProblem(String str) { |
||
3030 | return str.replaceAll("'", "''"); |
||
3031 | } |
||
3032 | |||
3033 | private static String getValueSurroundFromType(FieldDescription fieldDesc) { |
||
3034 | if (NumberUtilities.isNumeric(fieldDesc.getFieldType())) {
|
||
3035 | return ""; |
||
3036 | } |
||
3037 | |||
3038 | return "'"; |
||
3039 | } |
||
3040 | |||
3041 | /**
|
||
3042 | * Utility function to translate a SRS code from EPSG to Oracle.
|
||
3043 | * Uses a datasource based on a DBF file.
|
||
3044 | *
|
||
3045 | * @param epsg the EPSG code
|
||
3046 | * @return the Oracle code
|
||
3047 | */
|
||
3048 | public static String epsgSridToOracleSrid(String epsg) throws Exception { |
||
3049 | String resp = "8307"; |
||
3050 | |||
3051 | // --------------------------------------------
|
||
3052 | String sql = "select ORACLE from " + ORACLE_EPSG_TABLE_NAME + |
||
3053 | " where EPSG = " + epsg + " and PRF_ORACLE = 1;"; |
||
3054 | DataSource ds = null; |
||
3055 | |||
3056 | try {
|
||
3057 | ds = LayerFactory.getDataSourceFactory() |
||
3058 | .executeSQL(sql, |
||
3059 | DataSourceFactory.AUTOMATIC_OPENING); //.MANUAL_OPENING);
|
||
3060 | |||
3061 | if (ds.getRowCount() == 0) { |
||
3062 | logger.error("EPSG code not found in table: " + epsg);
|
||
3063 | throw new Exception("Unknown EPSG: " + epsg); |
||
3064 | } |
||
3065 | |||
3066 | if (ds.getRowCount() > 1) { |
||
3067 | logger.error("===============");
|
||
3068 | logger.error( |
||
3069 | "DBF file is wrong: More than one preferred Oracle Spatial code found for EPSG code: " +
|
||
3070 | epsg); |
||
3071 | |||
3072 | for (int i = 0; i < ds.getRowCount(); i++) { |
||
3073 | int aux = (int) Math.round(((DoubleValue) ds.getRow(i)[0]).doubleValue()); |
||
3074 | |||
3075 | if (i == 0) { |
||
3076 | resp = "" + aux;
|
||
3077 | } |
||
3078 | |||
3079 | logger.error("" + aux);
|
||
3080 | } |
||
3081 | |||
3082 | logger.error("===============");
|
||
3083 | |||
3084 | return resp;
|
||
3085 | } |
||
3086 | |||
3087 | resp = "" +
|
||
3088 | Math.round(((DoubleValue) ds.getRow(0)[0]).doubleValue()); |
||
3089 | } |
||
3090 | catch (Exception pe) { |
||
3091 | logger.error("Error with SQL statement. " + pe.getMessage());
|
||
3092 | } |
||
3093 | |||
3094 | return resp;
|
||
3095 | } |
||
3096 | |||
3097 | /**
|
||
3098 | * Utility function to translate a SRS code from Oracle to EPSG.
|
||
3099 | * Uses a datasource based on a DBF file.
|
||
3100 | *
|
||
3101 | * @param ora the Oracle code
|
||
3102 | * @return the EPSG code
|
||
3103 | */
|
||
3104 | public static String oracleSridToEpsgSrid(String ora) throws Exception { |
||
3105 | String resp = "4326"; |
||
3106 | |||
3107 | // --------------------------------------------
|
||
3108 | String sql = "select EPSG from " + ORACLE_EPSG_TABLE_NAME + |
||
3109 | " where ORACLE = " + ora + ";"; |
||
3110 | DataSource ds = null; |
||
3111 | |||
3112 | try {
|
||
3113 | ds = LayerFactory.getDataSourceFactory() |
||
3114 | .executeSQL(sql, |
||
3115 | DataSourceFactory.AUTOMATIC_OPENING); |
||
3116 | |||
3117 | if (ds.getRowCount() == 0) { |
||
3118 | logger.error("Oracle Spatial code not found in table: " + ora);
|
||
3119 | throw new Exception("Unknown Oracle code: " + ora); |
||
3120 | } |
||
3121 | |||
3122 | if (ds.getRowCount() > 1) { |
||
3123 | logger.error("===============");
|
||
3124 | logger.error( |
||
3125 | "DBF file is wrong: More than one EPSG code found for Oracle Spatial code: " +
|
||
3126 | ora); |
||
3127 | |||
3128 | for (int i = 0; i < ds.getRowCount(); i++) { |
||
3129 | String aux = "" + |
||
3130 | Math.round(((DoubleValue) ds.getRow(i)[0]).doubleValue()); |
||
3131 | |||
3132 | if (i == 0) { |
||
3133 | resp = aux; |
||
3134 | } |
||
3135 | |||
3136 | logger.error("" + aux);
|
||
3137 | } |
||
3138 | |||
3139 | logger.error("===============");
|
||
3140 | |||
3141 | return resp;
|
||
3142 | } |
||
3143 | |||
3144 | resp = "" +
|
||
3145 | Math.round(((DoubleValue) ds.getRow(0)[0]).doubleValue()); |
||
3146 | } |
||
3147 | catch (Exception pe) { |
||
3148 | logger.error("Error with SQL statement. " + pe.getMessage());
|
||
3149 | } |
||
3150 | |||
3151 | return resp;
|
||
3152 | } |
||
3153 | |||
3154 | /**
|
||
3155 | * This methos creates the datasource used to translate the SRS codes:
|
||
3156 | * EPSG <--> Oracle.
|
||
3157 | *
|
||
3158 | * It's called from several places, so checks that the datasource does not exist.
|
||
3159 | */
|
||
3160 | public static void createOracleEpsgTable() { |
||
3161 | SourceInfo si = LayerFactory.getDataSourceFactory() |
||
3162 | .getDriverInfo(ORACLE_EPSG_TABLE_NAME); |
||
3163 | |||
3164 | if (si != null) { // already created, nothing done |
||
3165 | return;
|
||
3166 | } |
||
3167 | |||
3168 | // Create 'oracle codes - epsg codes' table
|
||
3169 | DBFDriver dbfdrv = new DBFDriver();
|
||
3170 | |||
3171 | // dbfdrv.setDataSourceFactory()
|
||
3172 | OFileDataSourceAdapter fdsa = new OFileDataSourceAdapter();
|
||
3173 | |||
3174 | fdsa.setDriver(dbfdrv); |
||
3175 | |||
3176 | // ---------------------------------------------
|
||
3177 | FileSourceInfo fsi = new FileSourceInfo();
|
||
3178 | fsi.file = createFileString("dbf/" + ORACLE_EPSG_FILE_NAME);
|
||
3179 | fsi.spatial = false;
|
||
3180 | fsi.name = ORACLE_EPSG_TABLE_NAME; |
||
3181 | fsi.driverName = dbfdrv.getName(); //"DBF Driver";
|
||
3182 | // ---------------------------------------------
|
||
3183 | |||
3184 | fdsa.setSourceInfo(fsi); |
||
3185 | |||
3186 | SelectableDataSource sds = null;
|
||
3187 | EditableAdapter ea = new EditableAdapter();
|
||
3188 | ProjectTable pt = null;
|
||
3189 | |||
3190 | try {
|
||
3191 | sds = new SelectableDataSource(fdsa);
|
||
3192 | ea.setOriginalDataSource(sds); |
||
3193 | pt = ProjectTableFactory.createTable(ORACLE_EPSG_TABLE_NAME, ea); |
||
3194 | } |
||
3195 | catch (Exception ex) { |
||
3196 | System.err.println("While creating datasource: " + ex.getMessage()); |
||
3197 | } |
||
3198 | |||
3199 | sds.setSourceInfo(fsi); |
||
3200 | |||
3201 | DataSourceFactory dsf = LayerFactory.getDataSourceFactory(); |
||
3202 | dsf.addFileDataSource(fsi.driverName, fsi.name, fsi.file); |
||
3203 | sds.setDataSourceFactory(dsf); |
||
3204 | } |
||
3205 | |||
3206 | private static String createFileString(String path) { |
||
3207 | try {
|
||
3208 | File f = new File( |
||
3209 | "./gvSIG/extensiones/" + EXTENSION_DIR_NAME + "/" + |
||
3210 | path); |
||
3211 | |||
3212 | return f.getCanonicalPath();
|
||
3213 | } |
||
3214 | catch (Exception ex) { |
||
3215 | return "./gvSIG/extensiones/" + EXTENSION_DIR_NAME + "/" + |
||
3216 | path; |
||
3217 | } |
||
3218 | } |
||
3219 | |||
3220 | /**
|
||
3221 | * Utility method to get a valid Oracle identifier (in terms of length)
|
||
3222 | *
|
||
3223 | * @param str Proposed string
|
||
3224 | * @param ind field index of the given field name (used by the method to
|
||
3225 | * improve the renaming)
|
||
3226 | * @return an acceptable oracle identifier.
|
||
3227 | */
|
||
3228 | public static String getValidOracleID(String str, int ind) { |
||
3229 | if (str.length() <= MAX_ID_LENGTH) {
|
||
3230 | return str;
|
||
3231 | } |
||
3232 | |||
3233 | String resp = str.substring(0, MAX_ID_LENGTH - 7); |
||
3234 | resp = resp + str.substring(MAX_ID_LENGTH - 6, MAX_ID_LENGTH - 5); |
||
3235 | resp = resp + str.substring(MAX_ID_LENGTH - 4, MAX_ID_LENGTH - 3); |
||
3236 | resp = resp + str.substring(MAX_ID_LENGTH - 2, MAX_ID_LENGTH - 1); |
||
3237 | resp = resp + "_" + (ind % 1000); |
||
3238 | |||
3239 | return resp;
|
||
3240 | } |
||
3241 | |||
3242 | private static ArrayList ensureSensibleShell(ArrayList cc) { |
||
3243 | if (sameCoordinate((Coordinate) cc.get(0), |
||
3244 | (Coordinate) cc.get(cc.size() - 1))) {
|
||
3245 | if (cc.size() == 2) { |
||
3246 | ArrayList resp = new ArrayList(); |
||
3247 | resp.add(cc.get(0));
|
||
3248 | |||
3249 | Coordinate newcoo = new Coordinate((Coordinate) cc.get(0)); |
||
3250 | newcoo.x = newcoo.x + IRRELEVANT_DISTANCE; |
||
3251 | resp.add(newcoo); |
||
3252 | |||
3253 | newcoo = new Coordinate((Coordinate) cc.get(0)); |
||
3254 | newcoo.x = newcoo.x + IRRELEVANT_DISTANCE; |
||
3255 | newcoo.y = newcoo.y - IRRELEVANT_DISTANCE; |
||
3256 | resp.add(newcoo); |
||
3257 | |||
3258 | resp.add(cc.get(0));
|
||
3259 | |||
3260 | return resp;
|
||
3261 | } |
||
3262 | |||
3263 | if (cc.size() == 3) { |
||
3264 | cc.remove(1);
|
||
3265 | |||
3266 | return ensureSensibleShell(cc);
|
||
3267 | } |
||
3268 | |||
3269 | return cc;
|
||
3270 | } |
||
3271 | else {
|
||
3272 | cc.add(cc.get(0));
|
||
3273 | |||
3274 | return cc;
|
||
3275 | } |
||
3276 | } |
||
3277 | |||
3278 | private static ArrayList ensureSensibleHole(ArrayList cc) { |
||
3279 | if (sameCoordinate((Coordinate) cc.get(0), |
||
3280 | (Coordinate) cc.get(cc.size() - 1))) {
|
||
3281 | if (cc.size() == 2) { |
||
3282 | ArrayList resp = new ArrayList(); |
||
3283 | resp.add(cc.get(0));
|
||
3284 | |||
3285 | Coordinate newcoo = new Coordinate((Coordinate) cc.get(0)); |
||
3286 | newcoo.x = newcoo.x - IRRELEVANT_DISTANCE; |
||
3287 | resp.add(newcoo); |
||
3288 | |||
3289 | newcoo = new Coordinate((Coordinate) cc.get(0)); |
||
3290 | newcoo.x = newcoo.x - IRRELEVANT_DISTANCE; |
||
3291 | newcoo.y = newcoo.y + IRRELEVANT_DISTANCE; |
||
3292 | resp.add(newcoo); |
||
3293 | |||
3294 | resp.add(cc.get(0));
|
||
3295 | |||
3296 | return resp;
|
||
3297 | } |
||
3298 | |||
3299 | if (cc.size() == 3) { |
||
3300 | cc.remove(1);
|
||
3301 | |||
3302 | return ensureSensibleHole(cc);
|
||
3303 | } |
||
3304 | |||
3305 | return cc;
|
||
3306 | } |
||
3307 | else {
|
||
3308 | cc.add(cc.get(0));
|
||
3309 | |||
3310 | return cc;
|
||
3311 | } |
||
3312 | } |
||
3313 | |||
3314 | private static ArrayList ensureSensibleLineString(ArrayList cc) { |
||
3315 | if (cc.size() == 2) { |
||
3316 | if (sameCoordinate((Coordinate) cc.get(0), |
||
3317 | (Coordinate) cc.get(cc.size() - 1))) {
|
||
3318 | ArrayList resp = new ArrayList(); |
||
3319 | resp.add(cc.get(0));
|
||
3320 | |||
3321 | Coordinate newc = new Coordinate((Coordinate) cc.get(0)); |
||
3322 | newc.x = newc.x + IRRELEVANT_DISTANCE; |
||
3323 | resp.add(newc); |
||
3324 | |||
3325 | return resp;
|
||
3326 | } |
||
3327 | } |
||
3328 | |||
3329 | return cc;
|
||
3330 | } |
||
3331 | |||
3332 | private static boolean sameCoordinate(Coordinate c1, Coordinate c2) { |
||
3333 | if (c1.x != c2.x) {
|
||
3334 | return false; |
||
3335 | } |
||
3336 | |||
3337 | if (c1.y != c2.y) {
|
||
3338 | return false; |
||
3339 | } |
||
3340 | |||
3341 | return true; |
||
3342 | } |
||
3343 | |||
3344 | private static ArrayList getClosedRelevantPolygon(ArrayList cc) { |
||
3345 | if (cc.size() == 2) { |
||
3346 | return null; |
||
3347 | } |
||
3348 | |||
3349 | if (cc.size() == 3) { |
||
3350 | if (sameCoordinate((Coordinate) cc.get(0), (Coordinate) cc.get(1))) { |
||
3351 | return null; |
||
3352 | } |
||
3353 | |||
3354 | if (sameCoordinate((Coordinate) cc.get(0), (Coordinate) cc.get(2))) { |
||
3355 | return null; |
||
3356 | } |
||
3357 | |||
3358 | if (sameCoordinate((Coordinate) cc.get(1), (Coordinate) cc.get(2))) { |
||
3359 | return null; |
||
3360 | } |
||
3361 | |||
3362 | cc.add(cc.get(0));
|
||
3363 | |||
3364 | return cc;
|
||
3365 | } |
||
3366 | |||
3367 | if (!sameCoordinate((Coordinate) cc.get(0), |
||
3368 | (Coordinate) cc.get(cc.size() - 1))) {
|
||
3369 | cc.add(cc.get(0));
|
||
3370 | } |
||
3371 | |||
3372 | return cc;
|
||
3373 | } |
||
3374 | |||
3375 | private static MultiPolygon getMinMultiPolygon(Coordinate c) { |
||
3376 | Coordinate[] p = new Coordinate[4]; |
||
3377 | p[0] = c;
|
||
3378 | |||
3379 | Coordinate nc = new Coordinate(c);
|
||
3380 | nc.x = nc.x + IRRELEVANT_DISTANCE; |
||
3381 | |||
3382 | Coordinate nc2 = new Coordinate(nc);
|
||
3383 | nc2.y = nc2.y - IRRELEVANT_DISTANCE; |
||
3384 | p[1] = nc;
|
||
3385 | p[2] = nc2;
|
||
3386 | p[3] = new Coordinate(c); |
||
3387 | |||
3388 | CoordinateArraySequence cs = new CoordinateArraySequence(p);
|
||
3389 | LinearRing ls = new LinearRing(cs, geomFactory);
|
||
3390 | Polygon po = new Polygon(ls, null, geomFactory); |
||
3391 | Polygon[] pos = new Polygon[1]; |
||
3392 | pos[0] = po;
|
||
3393 | |||
3394 | MultiPolygon mpo = new MultiPolygon(pos, geomFactory);
|
||
3395 | |||
3396 | return mpo;
|
||
3397 | } |
||
3398 | |||
3399 | public String getSourceProjection() { |
||
3400 | // TODO Auto-generated method stub
|
||
3401 | if (tableHasSrid) {
|
||
3402 | return epsgSRID;
|
||
3403 | } |
||
3404 | |||
3405 | return destProj;
|
||
3406 | } |
||
3407 | |||
3408 | public String getDestProjection() { |
||
3409 | return destProj;
|
||
3410 | } |
||
3411 | |||
3412 | public void setDestProjection(String toEPSG) { |
||
3413 | destProj = toEPSG; |
||
3414 | try {
|
||
3415 | destProjOracle = epsgSridToOracleSrid(destProj); |
||
3416 | isDestGeogCS = getIsGCS(destProjOracle, true);
|
||
3417 | |||
3418 | } catch (Exception e) { |
||
3419 | logger.error("Unknown EPSG code: " + destProj);
|
||
3420 | destProjOracle = oracleSRID; |
||
3421 | isDestGeogCS = false;
|
||
3422 | } |
||
3423 | |||
3424 | } |
||
3425 | |||
3426 | public String getDestProjectionOracleCode() { |
||
3427 | return destProjOracle;
|
||
3428 | } |
||
3429 | |||
3430 | public boolean getIsDestProjectionGeog() { |
||
3431 | return isDestGeogCS;
|
||
3432 | } |
||
3433 | |||
3434 | public String getTableProjectionOracleCode() { |
||
3435 | return oracleSRID;
|
||
3436 | } |
||
3437 | |||
3438 | public boolean canReproject(String toEPSGdestinyProjection) { |
||
3439 | return false; |
||
3440 | } |
||
3441 | |||
3442 | /**
|
||
3443 | * Utility function. Says whether a given field name can be a user field name
|
||
3444 | * or not (for example, "ROWID" is not a valid one because it's a system
|
||
3445 | * reserved word).
|
||
3446 | *
|
||
3447 | * @param str proposed firld name
|
||
3448 | * @return whether it is valid or not for Oracle databases
|
||
3449 | */
|
||
3450 | private static boolean isOracleAllowedFieldname(String str) { |
||
3451 | if (str.compareToIgnoreCase("rowid") == 0) { |
||
3452 | return false; |
||
3453 | } |
||
3454 | |||
3455 | if (str.compareToIgnoreCase("rownum") == 0) { |
||
3456 | return false; |
||
3457 | } |
||
3458 | |||
3459 | return true; |
||
3460 | } |
||
3461 | |||
3462 | public Hashtable getHashRelate() { |
||
3463 | return hashRelate;
|
||
3464 | } |
||
3465 | |||
3466 | public void setHashRelate(Hashtable m) { |
||
3467 | hashRelate = m; |
||
3468 | } |
||
3469 | |||
3470 | public void setNumReg(int n) { |
||
3471 | numReg = n; |
||
3472 | } |
||
3473 | |||
3474 | private int[] getRandomSample(int maxn_one_based, int n) { |
||
3475 | int[] resp = new int[n]; |
||
3476 | |||
3477 | if (maxn_one_based <= n) {
|
||
3478 | resp = new int[maxn_one_based]; |
||
3479 | |||
3480 | for (int i = 0; i < maxn_one_based; i++) { |
||
3481 | resp[i] = i; |
||
3482 | } |
||
3483 | } |
||
3484 | else {
|
||
3485 | Random rnd = new Random(); |
||
3486 | |||
3487 | for (int i = 0; i < n; i++) { |
||
3488 | resp[i] = rnd.nextInt(maxn_one_based); |
||
3489 | } |
||
3490 | } |
||
3491 | |||
3492 | return resp;
|
||
3493 | } |
||
3494 | |||
3495 | private String getRowIdRestrictionCondition(int nrecords) { |
||
3496 | int[] zero_based_rows = getRandomSample(nrecords, |
||
3497 | GEODETIC_FULLEXTENT_SAMPLE_SIZE); |
||
3498 | String resp = "("; |
||
3499 | Object aux = ""; |
||
3500 | ROWID riaux = null;
|
||
3501 | |||
3502 | for (int i = 0; i < zero_based_rows.length; i++) { |
||
3503 | aux = rowToId.get(new Integer(zero_based_rows[i])); |
||
3504 | riaux = (ROWID) aux; |
||
3505 | resp = resp + "(ROWID = '" + riaux.stringValue() + "') OR "; |
||
3506 | } |
||
3507 | |||
3508 | resp = resp.substring(0, resp.length() - 4); |
||
3509 | resp = resp + ")";
|
||
3510 | |||
3511 | return resp;
|
||
3512 | } |
||
3513 | |||
3514 | private Rectangle2D getBoundingFromSample(int n_max) { |
||
3515 | String _qry = "SELECT " + geoColName + " FROM " + getTableName() + |
||
3516 | " WHERE " + getRowIdRestrictionCondition(n_max);
|
||
3517 | STRUCT auxstr = null;
|
||
3518 | IGeometry theGeom = null;
|
||
3519 | Rectangle2D resp = null; |
||
3520 | |||
3521 | try {
|
||
3522 | Statement st = conn.createStatement();
|
||
3523 | ResultSet rs = st.executeQuery(_qry);
|
||
3524 | |||
3525 | if (rs.next()) {
|
||
3526 | auxstr = (STRUCT) rs.getObject(1);
|
||
3527 | |||
3528 | if (auxstr != null) { |
||
3529 | theGeom = getGeometryUsing(auxstr, use_geotools); |
||
3530 | |||
3531 | if (resp == null) { |
||
3532 | resp = theGeom.getBounds2D(); |
||
3533 | } |
||
3534 | else {
|
||
3535 | resp.add(theGeom.getBounds2D()); |
||
3536 | } |
||
3537 | } |
||
3538 | |||
3539 | while (rs.next()) {
|
||
3540 | auxstr = (STRUCT) rs.getObject(1);
|
||
3541 | |||
3542 | if (auxstr != null) { |
||
3543 | theGeom = getGeometryUsing(auxstr, use_geotools); |
||
3544 | |||
3545 | if (resp == null) { |
||
3546 | resp = theGeom.getBounds2D(); |
||
3547 | } |
||
3548 | else {
|
||
3549 | resp.add(theGeom.getBounds2D()); |
||
3550 | } |
||
3551 | } |
||
3552 | } |
||
3553 | |||
3554 | rs.close(); |
||
3555 | st.close(); |
||
3556 | } |
||
3557 | else {
|
||
3558 | throw new SQLException("Empty resultset from this query: " + |
||
3559 | _qry); |
||
3560 | } |
||
3561 | } |
||
3562 | catch (SQLException se) { |
||
3563 | System.err.println("Error while getting sample full extent: " + |
||
3564 | se.getMessage()); |
||
3565 | } |
||
3566 | |||
3567 | if (resp == null) { |
||
3568 | logger.warn( |
||
3569 | "Did not find a geometry to compute sample bbox. Returned geographic bbox for whole world.");
|
||
3570 | |||
3571 | return new Rectangle2D.Double(-180, -90, 360, 180); |
||
3572 | } |
||
3573 | |||
3574 | return resp;
|
||
3575 | } |
||
3576 | |||
3577 | /**
|
||
3578 | * Does what it says, puts the LinearRing in counter clock wise
|
||
3579 | * order.
|
||
3580 | * @param ls The ring to set.
|
||
3581 | * @param gf a GeometryFactory object
|
||
3582 | * @return A new ring in CCW order.
|
||
3583 | *
|
||
3584 | */
|
||
3585 | public static LinearRing putInCCWOrderLR(LineString ls, GeometryFactory gf) { |
||
3586 | Coordinate[] cc = ls.getCoordinates();
|
||
3587 | |||
3588 | if (CGAlgorithms.isCCW(cc)) {
|
||
3589 | return gf.createLinearRing(cc);
|
||
3590 | } |
||
3591 | else {
|
||
3592 | if (ls instanceof LinearRing) { |
||
3593 | return reverseRing((LinearRing) ls, gf);
|
||
3594 | } |
||
3595 | else {
|
||
3596 | return reverseLineString(ls, gf);
|
||
3597 | } |
||
3598 | } |
||
3599 | } |
||
3600 | |||
3601 | /**
|
||
3602 | * Does what it says, reverses the order of the Coordinates in the ring.
|
||
3603 | * @param lr The ring to reverse.
|
||
3604 | * @return A new ring with the reversed Coordinates.
|
||
3605 | *
|
||
3606 | */
|
||
3607 | public static LinearRing reverseRing(LinearRing lr, GeometryFactory gf) { |
||
3608 | int numPoints = lr.getNumPoints() - 1; |
||
3609 | Coordinate[] newCoords = new Coordinate[numPoints + 1]; |
||
3610 | |||
3611 | for (int t = numPoints; t >= 0; t--) { |
||
3612 | newCoords[t] = lr.getCoordinateN(numPoints - t); |
||
3613 | } |
||
3614 | |||
3615 | return gf.createLinearRing(newCoords);
|
||
3616 | } |
||
3617 | |||
3618 | /**
|
||
3619 | * Does what it says, reverses the order of the Coordinates in the linestring.
|
||
3620 | * @param ls The ls to reverse.
|
||
3621 | * @param gf a GeometryFactory object
|
||
3622 | * @return A new ls with the reversed Coordinates.
|
||
3623 | *
|
||
3624 | */
|
||
3625 | public static LinearRing reverseLineString(LineString ls, GeometryFactory gf) { |
||
3626 | int numPoints = ls.getNumPoints() - 1; |
||
3627 | Coordinate[] newCoords = new Coordinate[numPoints + 1]; |
||
3628 | |||
3629 | for (int t = numPoints; t >= 0; t--) { |
||
3630 | newCoords[t] = ls.getCoordinateN(numPoints - t); |
||
3631 | } |
||
3632 | |||
3633 | return gf.createLinearRing(newCoords);
|
||
3634 | } |
||
3635 | |||
3636 | private static Geometry putInCCWOrder(Geometry ge, GeometryFactory gf) { |
||
3637 | if (ge instanceof MultiPolygon) { |
||
3638 | MultiPolygon mp = (MultiPolygon) ge; |
||
3639 | int size = ge.getNumGeometries();
|
||
3640 | Polygon[] pols = new Polygon[size]; |
||
3641 | |||
3642 | for (int i = 0; i < size; i++) |
||
3643 | pols[i] = (Polygon) putInCCWOrder((Polygon) mp.getGeometryN(i), |
||
3644 | gf); |
||
3645 | |||
3646 | return new MultiPolygon(pols, gf); |
||
3647 | } |
||
3648 | else {
|
||
3649 | if (ge instanceof Polygon) { |
||
3650 | Polygon p = (Polygon) ge; |
||
3651 | LinearRing exterior = putInCCWOrderLR(p.getExteriorRing(), gf); |
||
3652 | int nholes = p.getNumInteriorRing();
|
||
3653 | |||
3654 | if (nholes > 0) { |
||
3655 | LinearRing[] holes = new LinearRing[nholes]; |
||
3656 | |||
3657 | for (int i = 0; i < nholes; i++) { |
||
3658 | holes[i] = putInCCWOrderLR(p.getInteriorRingN(i), gf); |
||
3659 | } |
||
3660 | |||
3661 | return gf.createPolygon(exterior, holes);
|
||
3662 | } |
||
3663 | else {
|
||
3664 | return gf.createPolygon(exterior, null); |
||
3665 | } |
||
3666 | } |
||
3667 | else {
|
||
3668 | return ge;
|
||
3669 | } |
||
3670 | } |
||
3671 | } |
||
3672 | |||
3673 | /**
|
||
3674 | * Converts from IGeometry to STRUCT
|
||
3675 | *
|
||
3676 | * @param ig the geometry to convert
|
||
3677 | * @param _forced_type forced type to use
|
||
3678 | * @param _conn connection
|
||
3679 | * @param _o_srid SRS (oracle code)
|
||
3680 | * @param withSrid whether this STRUCT has a non-NULL SRS
|
||
3681 | * @param agu_bien whether or not to check the correctness of the holes
|
||
3682 | * @param _isGeoCS whether the SRS is geodetic or not
|
||
3683 | * @return the generated STRUCT
|
||
3684 | */
|
||
3685 | public static STRUCT iGeometryToSTRUCT(IGeometry ig, int _forced_type, |
||
3686 | Connection _conn, String _o_srid, boolean withSrid, boolean agu_bien, |
||
3687 | boolean _isGeoCS) {
|
||
3688 | if (ig instanceof FGeometryCollection) { |
||
3689 | FGeometryCollection coll = (FGeometryCollection) ig; |
||
3690 | |||
3691 | return OracleSpatialUtils.appendGeometriesInStruct(coll,
|
||
3692 | _forced_type, _conn, _o_srid, withSrid, agu_bien, _isGeoCS); |
||
3693 | |||
3694 | // logger.error("Collections no soportadas por ahora.");
|
||
3695 | // return null;
|
||
3696 | } |
||
3697 | else {
|
||
3698 | Shape shp = ig.getInternalShape();
|
||
3699 | |||
3700 | return shapeToStruct(shp, _forced_type, _conn, _o_srid, withSrid,
|
||
3701 | agu_bien, false, _isGeoCS);
|
||
3702 | } |
||
3703 | } |
||
3704 | |||
3705 | public STRUCT shapeToStruct(Shape shp, int force_type, boolean hasSrid, |
||
3706 | boolean agu_bien, boolean isView) { |
||
3707 | |||
3708 | if (shp == null) return null; |
||
3709 | return shapeToStruct(shp, force_type, conn, oracleSRID, hasSrid,
|
||
3710 | agu_bien, isView, isGeogCS); |
||
3711 | } |
||
3712 | |||
3713 | public static STRUCT shapeToStruct(Shape shp, int forced_type, |
||
3714 | Connection _conn, String o_srid, boolean hasSrid, boolean agu_bien, |
||
3715 | boolean isView, boolean _isGeoCS) { |
||
3716 | int _srid = -1; |
||
3717 | |||
3718 | if (o_srid.length() > 0) { |
||
3719 | _srid = Integer.parseInt(o_srid);
|
||
3720 | } |
||
3721 | |||
3722 | if (shp == null) { |
||
3723 | logger.info("Shape is null. shapeToStruct(Shape) returned null.");
|
||
3724 | |||
3725 | return null; |
||
3726 | } |
||
3727 | |||
3728 | if (shp instanceof Rectangle2D) { |
||
3729 | return rectangleToStruct((Rectangle2D) shp, hasSrid, isView, |
||
3730 | _isGeoCS, o_srid, _conn); |
||
3731 | } |
||
3732 | |||
3733 | try {
|
||
3734 | STRUCT the_struct = OracleSpatialUtils.fShapeToSTRUCT(shp, _conn, |
||
3735 | _srid, agu_bien, hasSrid); |
||
3736 | |||
3737 | return the_struct;
|
||
3738 | } |
||
3739 | catch (SQLException ex) { |
||
3740 | logger.error("While creating STRUCT: " + ex.getMessage());
|
||
3741 | |||
3742 | return null; |
||
3743 | } |
||
3744 | } |
||
3745 | |||
3746 | // -------------------------- not ready yet ----------------
|
||
3747 | public int getRowIndexByFID(IFeature _fid) { |
||
3748 | if (isNotAvailableYet) {
|
||
3749 | return -1; |
||
3750 | } |
||
3751 | else {
|
||
3752 | return super.getRowIndexByFID(_fid); |
||
3753 | } |
||
3754 | } |
||
3755 | |||
3756 | public int getShapeCount() throws IOException { |
||
3757 | if (isNotAvailableYet) {
|
||
3758 | return 0; |
||
3759 | } |
||
3760 | else {
|
||
3761 | return numReg;
|
||
3762 | } |
||
3763 | } |
||
3764 | |||
3765 | public void setNotAvailableYet(boolean nav) { |
||
3766 | isNotAvailableYet = nav; |
||
3767 | } |
||
3768 | |||
3769 | // -------------------------------------------------------
|
||
3770 | // -------------------------------------------------------
|
||
3771 | public String[] getTableNames(Connection conn, String catalog) |
||
3772 | throws SQLException { |
||
3773 | DatabaseMetaData dbmd = conn.getMetaData();
|
||
3774 | String[] types = { "TABLE", "VIEW" }; |
||
3775 | 13995 | jldominguez@prodevelop.es | // String[] types = { "VIEW" };
|
3776 | 13991 | jldominguez@prodevelop.es | |
3777 | ResultSet rs = null; |
||
3778 | rs = getTableNamesFromTable(dbmd.getTables(catalog, ORACLE_GEO_SCHEMA, |
||
3779 | ORACLE_GEOMETADATA_VIEW, types), conn); |
||
3780 | 13993 | fran.penarrubia@iver.es | // rs = dbmd.getTables(catalog, ORACLE_GEO_SCHEMA,
|
3781 | // ORACLE_GEOMETADATA_VIEW, types);
|
||
3782 | 13991 | jldominguez@prodevelop.es | TreeMap ret = new TreeMap(); |
3783 | |||
3784 | while (rs.next()) {
|
||
3785 | 13994 | fran.penarrubia@iver.es | String nomCompleto = rs.getString("OWNER") + "." +rs.getString("TABLE_NAME"); |
3786 | ret.put(nomCompleto, nomCompleto); |
||
3787 | 13991 | jldominguez@prodevelop.es | } |
3788 | |||
3789 | return (String[]) ret.keySet().toArray(new String[0]); |
||
3790 | } |
||
3791 | |||
3792 | private ResultSet getTableNamesFromTable(ResultSet res, Connection con) |
||
3793 | throws SQLException { |
||
3794 | String tablename = ""; |
||
3795 | |||
3796 | |||
3797 | |||
3798 | if (res.next()) {
|
||
3799 | tablename = res.getString("TABLE_NAME");
|
||
3800 | |||
3801 | // debug
|
||
3802 | // writeMetaTableToLog(con, tablename);
|
||
3803 | |||
3804 | Statement __st = con.createStatement();
|
||
3805 | |||
3806 | String sql = "(" + "(select TABLE_NAME from USER_TABLES) " + |
||
3807 | "union (select VIEW_NAME from USER_VIEWS)) " +
|
||
3808 | "intersect (select TABLE_NAME from " + tablename + ")"; |
||
3809 | 13994 | fran.penarrubia@iver.es | sql = "SELECT TABLE_NAME, OWNER FROM " + tablename + ""; |
3810 | 13991 | jldominguez@prodevelop.es | ResultSet rs = __st.executeQuery(sql);
|
3811 | |||
3812 | return rs;
|
||
3813 | } |
||
3814 | else {
|
||
3815 | logger.error("Error while getting geometry tables.");
|
||
3816 | |||
3817 | return null; |
||
3818 | } |
||
3819 | } |
||
3820 | |||
3821 | private void writeMetaTableToLog(Connection con, String tname) { |
||
3822 | |||
3823 | logger.debug("======================================================");
|
||
3824 | logger.debug("= USER_SDO_GEOM_METADATA =====================");
|
||
3825 | logger.debug("======================================================");
|
||
3826 | |||
3827 | try {
|
||
3828 | Statement _stmt = con.createStatement();
|
||
3829 | String sql = "SELECT * FROM " + tname; |
||
3830 | ResultSet res = _stmt.executeQuery(sql);
|
||
3831 | while (res.next()) {
|
||
3832 | logger.debug("======================================================");
|
||
3833 | logger.debug("TABLE_NAME: " + res.getString("TABLE_NAME")); |
||
3834 | logger.debug("COLUMN_NAME: " + res.getString("COLUMN_NAME")); |
||
3835 | logger.debug("SRID: " + res.getString("SRID")); |
||
3836 | |||
3837 | ARRAY _aux = (ARRAY) res.getObject("DIMINFO");
|
||
3838 | String dinfo = OracleSpatialUtils.getDimInfoAsString(_aux);
|
||
3839 | logger.debug("DIMINFO: " + dinfo);
|
||
3840 | logger.debug("======================================================");
|
||
3841 | |||
3842 | } |
||
3843 | } catch (Throwable th) { |
||
3844 | |||
3845 | } |
||
3846 | |||
3847 | |||
3848 | |||
3849 | |||
3850 | |||
3851 | // TODO Auto-generated method stub
|
||
3852 | |||
3853 | } |
||
3854 | |||
3855 | /**
|
||
3856 | * Gets the field names that can act as row id (always ROWID)
|
||
3857 | */
|
||
3858 | public String[] getIdFieldsCandidates(Connection conn, String table_name) |
||
3859 | throws SQLException { |
||
3860 | 13995 | jldominguez@prodevelop.es | |
3861 | String rowid_avail_test = "SELECT ROWID FROM " + table_name + " WHERE ROWNUM = 1"; |
||
3862 | Statement _st = conn.createStatement();
|
||
3863 | ResultSet _rs = _st.executeQuery(rowid_avail_test);
|
||
3864 | _rs.close(); |
||
3865 | _st.close(); |
||
3866 | 13991 | jldominguez@prodevelop.es | |
3867 | 13995 | jldominguez@prodevelop.es | String[] resp = { "ROWID" }; |
3868 | 13991 | jldominguez@prodevelop.es | return resp;
|
3869 | } |
||
3870 | |||
3871 | /**
|
||
3872 | * Gets the field names that can act as geometry fields
|
||
3873 | * (queries the user's geographic metadata).
|
||
3874 | */
|
||
3875 | public String[] getGeometryFieldsCandidates(Connection conn, |
||
3876 | String table_name) throws SQLException { |
||
3877 | 13995 | jldominguez@prodevelop.es | |
3878 | 13991 | jldominguez@prodevelop.es | Statement _st = conn.createStatement();
|
3879 | 13994 | fran.penarrubia@iver.es | String[] tokens = table_name.split("\\u002E", 2); |
3880 | String qry;
|
||
3881 | if (tokens.length > 1) |
||
3882 | { |
||
3883 | qry = "select * from " + ORACLE_GEOMETADATA_VIEW +
|
||
3884 | " where OWNER = '" + tokens[0] + "' AND TABLE_NAME = '" + |
||
3885 | tokens[1] + "'"; |
||
3886 | } |
||
3887 | else
|
||
3888 | { |
||
3889 | qry = "select * from " + ORACLE_GEOMETADATA_VIEW +
|
||
3890 | 13991 | jldominguez@prodevelop.es | " where TABLE_NAME = " + "'" + table_name + "'"; |
3891 | 13994 | fran.penarrubia@iver.es | |
3892 | } |
||
3893 | 13991 | jldominguez@prodevelop.es | ResultSet _rs = _st.executeQuery(qry);
|
3894 | |||
3895 | ArrayList aux = new ArrayList(); |
||
3896 | |||
3897 | while (_rs.next()) {
|
||
3898 | String _geo = _rs.getString("COLUMN_NAME"); |
||
3899 | aux.add(_geo); |
||
3900 | } |
||
3901 | |||
3902 | _rs.close(); |
||
3903 | _st.close(); |
||
3904 | |||
3905 | 13995 | jldominguez@prodevelop.es | String[] resp = (String[]) aux.toArray(new String[0]); |
3906 | |||
3907 | return checkIndexes(conn, resp, table_name);
|
||
3908 | 13991 | jldominguez@prodevelop.es | } |
3909 | |||
3910 | 13995 | jldominguez@prodevelop.es | private String[] checkIndexes(Connection c, String[] all, String __t) throws SQLException { |
3911 | |||
3912 | ArrayList good_ones = new ArrayList(); |
||
3913 | String t = __t;
|
||
3914 | if (t.lastIndexOf(".") != -1) t = t.substring(t.lastIndexOf(".") + 1, t.length()); |
||
3915 | |||
3916 | for (int i=0; i<all.length; i++) { |
||
3917 | |||
3918 | String qry = "SELECT SRID, DIMINFO FROM " + ORACLE_GEOMETADATA_VIEW + |
||
3919 | " WHERE TABLE_NAME = " + "'" + t.toUpperCase() + |
||
3920 | "' AND COLUMN_NAME = '" + all[i].toUpperCase() + "'"; |
||
3921 | |||
3922 | Statement _st = c.createStatement();
|
||
3923 | ResultSet _rs = _st.executeQuery(qry);
|
||
3924 | if (_rs.next()) {
|
||
3925 | String _srid = toString((BigDecimal) _rs.getObject(1)); |
||
3926 | ARRAY diminfo = (ARRAY) _rs.getObject(2);
|
||
3927 | int len = diminfo.getOracleArray().length;
|
||
3928 | if (allowsGeoQueries(c, t, all[i], _srid, len)) {
|
||
3929 | good_ones.add(all[i]); |
||
3930 | } |
||
3931 | } |
||
3932 | _rs.close(); |
||
3933 | _st.close(); |
||
3934 | } |
||
3935 | |||
3936 | if (good_ones.size() == 0) { |
||
3937 | throw new SQLException("no_indexes_on_declared_geo_fields"); |
||
3938 | } |
||
3939 | return (String[]) good_ones.toArray(new String[0]); |
||
3940 | } |
||
3941 | |||
3942 | private String toString(BigDecimal number) { |
||
3943 | |||
3944 | if (number == null) return "NULL"; |
||
3945 | return "" + number.intValue(); |
||
3946 | } |
||
3947 | |||
3948 | private boolean allowsGeoQueries(Connection c, String _t, String gf, String _srid, int dims) { |
||
3949 | String p = getPointConstructor(dims, _srid);
|
||
3950 | String qry = "SELECT * FROM " + _t.toUpperCase() + " WHERE (ROWNUM = 1)"; |
||
3951 | qry = "SELECT * FROM (" + qry + ") WHERE SDO_RELATE(" + "\"" + gf + "\", " + p + ", 'mask=TOUCH') = 'TRUE'"; |
||
3952 | |||
3953 | try {
|
||
3954 | Statement _st = c.createStatement();
|
||
3955 | ResultSet _rs = _st.executeQuery(qry);
|
||
3956 | _rs.close(); |
||
3957 | _st.close(); |
||
3958 | } catch (Exception ex) { |
||
3959 | return false; |
||
3960 | } |
||
3961 | return true; |
||
3962 | } |
||
3963 | |||
3964 | private String getPointConstructor(int dims, String _srid) { |
||
3965 | |||
3966 | String coord = ""; |
||
3967 | for (int i=0; i<dims; i++) coord = coord + "0, "; |
||
3968 | coord = coord.substring(0, coord.length() - 2); |
||
3969 | |||
3970 | return "MDSYS.SDO_GEOMETRY(" + (dims * 1000 + 1) + ", " + _srid + ", NULL, " + |
||
3971 | "MDSYS.SDO_ELEM_INFO_ARRAY(1, 1, 1), MDSYS.SDO_ORDINATE_ARRAY(" + coord + "))"; |
||
3972 | } |
||
3973 | |||
3974 | private boolean stringInArrayListOfStrings(ArrayList l, String str) { |
||
3975 | |||
3976 | if (l == null) return false; |
||
3977 | if (str == null) return false; |
||
3978 | |||
3979 | String item = ""; |
||
3980 | for (int i=0; i<l.size(); i++) { |
||
3981 | if (l.get(i) instanceof String) { |
||
3982 | item = (String) l.get(i);
|
||
3983 | if (item.compareToIgnoreCase(str) == 0) return true; |
||
3984 | } |
||
3985 | } |
||
3986 | return false; |
||
3987 | } |
||
3988 | |||
3989 | /**
|
||
3990 | 13991 | jldominguez@prodevelop.es | * Utility method to check if a given table is empty.
|
3991 | */
|
||
3992 | public boolean isEmptyTable(Connection conn, String tableName) { |
||
3993 | boolean res = true; |
||
3994 | |||
3995 | try {
|
||
3996 | Statement st = conn.createStatement();
|
||
3997 | ResultSet rs = null; |
||
3998 | rs = st.executeQuery("select * from " + tableName +
|
||
3999 | " where rownum = 1");
|
||
4000 | res = !rs.next(); |
||
4001 | rs.close(); |
||
4002 | st.close(); |
||
4003 | } |
||
4004 | catch (Exception ex) { |
||
4005 | res = true;
|
||
4006 | } |
||
4007 | |||
4008 | return res;
|
||
4009 | } |
||
4010 | |||
4011 | /**
|
||
4012 | * Gets all the fields from a table name.
|
||
4013 | */
|
||
4014 | public String[] getAllFields(Connection conn, String table_name) |
||
4015 | throws SQLException { |
||
4016 | Statement st = conn.createStatement();
|
||
4017 | ResultSet rs = st.executeQuery("select * from " + table_name + |
||
4018 | " where rownum = 1");
|
||
4019 | ResultSetMetaData rsmd = rs.getMetaData();
|
||
4020 | String[] ret = new String[rsmd.getColumnCount()]; |
||
4021 | |||
4022 | for (int i = 0; i < ret.length; i++) { |
||
4023 | ret[i] = rsmd.getColumnName(i + 1);
|
||
4024 | } |
||
4025 | |||
4026 | rs.close(); |
||
4027 | st.close(); |
||
4028 | |||
4029 | return ret;
|
||
4030 | } |
||
4031 | |||
4032 | /**
|
||
4033 | * Gets all field type names from a table.
|
||
4034 | */
|
||
4035 | public String[] getAllFieldTypeNames(Connection conn, String table_name) |
||
4036 | throws SQLException { |
||
4037 | Statement st = conn.createStatement();
|
||
4038 | ResultSet rs = st.executeQuery("select * from " + table_name + |
||
4039 | " where rownum = 1");
|
||
4040 | ResultSetMetaData rsmd = rs.getMetaData();
|
||
4041 | String[] ret = new String[rsmd.getColumnCount()]; |
||
4042 | |||
4043 | for (int i = 0; i < ret.length; i++) { |
||
4044 | ret[i] = rsmd.getColumnTypeName(i + 1);
|
||
4045 | } |
||
4046 | |||
4047 | rs.close(); |
||
4048 | st.close(); |
||
4049 | |||
4050 | close(); |
||
4051 | |||
4052 | return ret;
|
||
4053 | } |
||
4054 | |||
4055 | /**
|
||
4056 | * Gets Oracle's specific connection string for the given parameters.
|
||
4057 | */
|
||
4058 | public String getConnectionString(String host, String port, String dbname, |
||
4059 | String user, String pw) { |
||
4060 | String _pw = pw;
|
||
4061 | |||
4062 | if (_pw == null) { |
||
4063 | _pw = "null";
|
||
4064 | } |
||
4065 | |||
4066 | String fullstr = CONN_STR_BEGIN;
|
||
4067 | fullstr = fullstr + user.toLowerCase() + "/" + _pw;
|
||
4068 | fullstr = fullstr + "@" + host.toLowerCase();
|
||
4069 | fullstr = fullstr + ":" + port;
|
||
4070 | fullstr = fullstr + ":" + dbname.toLowerCase();
|
||
4071 | |||
4072 | return fullstr;
|
||
4073 | } |
||
4074 | |||
4075 | /**
|
||
4076 | * Gets the Pracle geometries writer associated with this driver.
|
||
4077 | */
|
||
4078 | public IWriter getWriter() {
|
||
4079 | // on(VectorialEditableDBAdapter.java:290)
|
||
4080 | if (writer == null) { |
||
4081 | writer = new OracleSpatialWriter(getRowCount());
|
||
4082 | writer.setDriver(this);
|
||
4083 | writer.setLyrShapeType(getShapeType()); |
||
4084 | writer.setGeoCS(isGeogCS()); |
||
4085 | writer.setGeoColName(geoColName); |
||
4086 | writer.setSRID(oracleSRID); |
||
4087 | |||
4088 | try {
|
||
4089 | writer.initialize(getLyrDef()); |
||
4090 | } |
||
4091 | catch (EditionException e) {
|
||
4092 | logger.error("While initializing OS Writer: " + e.getMessage(),
|
||
4093 | e); |
||
4094 | } |
||
4095 | |||
4096 | writer.setStoreWithSrid(tableHasSrid); |
||
4097 | } |
||
4098 | |||
4099 | return writer;
|
||
4100 | } |
||
4101 | |||
4102 | /**
|
||
4103 | * Tells whether the SRS is geodetic or not
|
||
4104 | * @return whether the SRS is geodetic or not
|
||
4105 | */
|
||
4106 | public boolean isGeogCS() { |
||
4107 | return isGeogCS;
|
||
4108 | } |
||
4109 | |||
4110 | /**
|
||
4111 | * Adds a row id to the inner set od IDs.
|
||
4112 | * @param id
|
||
4113 | */
|
||
4114 | public void addRow(String id) { |
||
4115 | Value aux = ValueFactory.createValue(id); |
||
4116 | Integer intobj = new Integer(numReg); |
||
4117 | hashRelate.put(aux, intobj); |
||
4118 | rowToId.put(intobj, id); |
||
4119 | |||
4120 | numReg++; |
||
4121 | } |
||
4122 | |||
4123 | /**
|
||
4124 | * Removes a row id to the inner set od IDs.
|
||
4125 | * @param id
|
||
4126 | */
|
||
4127 | public void deleteRow(String id) { |
||
4128 | Value aux = ValueFactory.createValue(id); |
||
4129 | Integer intobj = (Integer) hashRelate.get(aux); |
||
4130 | hashRelate.remove(aux); |
||
4131 | rowToId.remove(intobj); |
||
4132 | |||
4133 | numReg--; |
||
4134 | } |
||
4135 | |||
4136 | private String getStandardSelectExpression() { |
||
4137 | if (standardSelectExpressionFalse == null) { |
||
4138 | standardSelectExpressionFalse = "";
|
||
4139 | |||
4140 | String[] flds = getLyrDef().getFieldNames(); |
||
4141 | int size = flds.length;
|
||
4142 | |||
4143 | for (int i = 0; i < size; i++) { |
||
4144 | if (i > 0) { |
||
4145 | standardSelectExpressionFalse = standardSelectExpressionFalse + |
||
4146 | "c.\"" + flds[i] + "\", "; |
||
4147 | } |
||
4148 | else {
|
||
4149 | standardSelectExpressionFalse = standardSelectExpressionFalse + |
||
4150 | flds[i] + ", ";
|
||
4151 | } |
||
4152 | } |
||
4153 | |||
4154 | // standardSelectExpressionFalse = standardSelectExpressionFalse + "c." + geoColName;
|
||
4155 | standardSelectExpressionFalse = standardSelectExpressionFalse.substring(0,
|
||
4156 | standardSelectExpressionFalse.length() - 2);
|
||
4157 | } |
||
4158 | |||
4159 | return standardSelectExpressionFalse;
|
||
4160 | } |
||
4161 | |||
4162 | /**
|
||
4163 | * Allows the method to decide what to do with the geometry field name
|
||
4164 | * (remove/add it from the user selected fields).
|
||
4165 | *
|
||
4166 | * @param flds
|
||
4167 | * @param geof
|
||
4168 | * @return the possibly modified field names
|
||
4169 | */
|
||
4170 | public String[] manageGeometryField(String[] flds, String geof) { |
||
4171 | return addEndIfNotContained(flds, geof);
|
||
4172 | } |
||
4173 | |||
4174 | /**
|
||
4175 | * Allows the method to decide what to do with the ID field name
|
||
4176 | * (remove/add it from the user selected fields).
|
||
4177 | *
|
||
4178 | * @param flds
|
||
4179 | * @param idf
|
||
4180 | * @return the possibly modified field names
|
||
4181 | */
|
||
4182 | public String[] manageIdField(String[] flds, String idf) { |
||
4183 | return addStartIfNotContained(flds, idf);
|
||
4184 | } |
||
4185 | |||
4186 | private String[] addEndIfNotContained(String[] arr, String item) { |
||
4187 | if (contains(arr, item)) {
|
||
4188 | return arr;
|
||
4189 | } |
||
4190 | else {
|
||
4191 | int size = arr.length;
|
||
4192 | String[] resp = new String[size + 1]; |
||
4193 | |||
4194 | for (int i = 0; i < size; i++) { |
||
4195 | resp[i] = arr[i]; |
||
4196 | } |
||
4197 | |||
4198 | resp[size] = item; |
||
4199 | |||
4200 | return resp;
|
||
4201 | } |
||
4202 | } |
||
4203 | |||
4204 | private String[] addStartIfNotContained(String[] arr, String item) { |
||
4205 | if (contains(arr, item)) {
|
||
4206 | return arr;
|
||
4207 | } |
||
4208 | else {
|
||
4209 | int size = arr.length;
|
||
4210 | String[] resp = new String[size + 1]; |
||
4211 | |||
4212 | for (int i = 1; i <= size; i++) { |
||
4213 | resp[i] = arr[i]; |
||
4214 | } |
||
4215 | |||
4216 | resp[0] = item;
|
||
4217 | |||
4218 | return resp;
|
||
4219 | } |
||
4220 | } |
||
4221 | |||
4222 | private boolean contains(String[] arr, String item) { |
||
4223 | for (int i = 0; i < arr.length; i++) { |
||
4224 | if (arr[i].compareTo(item) == 0) { |
||
4225 | return true; |
||
4226 | } |
||
4227 | } |
||
4228 | |||
4229 | return false; |
||
4230 | } |
||
4231 | |||
4232 | /**
|
||
4233 | * This method is called when the user removes the layer from the view.
|
||
4234 | * If the IDs were being loaded, the driver will check this field and will
|
||
4235 | * let the thread 'die' quietly.
|
||
4236 | *
|
||
4237 | */
|
||
4238 | public void remove() { |
||
4239 | cancelIDLoad = true;
|
||
4240 | } |
||
4241 | |||
4242 | private boolean realiableExtent(Rectangle2D ext, boolean isgeodetic) { |
||
4243 | if (!isgeodetic) return true; |
||
4244 | if (ext.getMinX() > -179.99) return true; |
||
4245 | if (ext.getMinY() > -89.99) return true; |
||
4246 | if (ext.getWidth() < 359.99) return true; |
||
4247 | if (ext.getHeight() < 179.99) return true; |
||
4248 | return false; |
||
4249 | } |
||
4250 | |||
4251 | private Rectangle2D getFastEstimatedGeodeticExtent( |
||
4252 | String tname, String gfield, Connection c, int sample_size, double enlargement) { |
||
4253 | |||
4254 | Rectangle2D world = new Rectangle2D.Double(-180, -90, 360, 180); |
||
4255 | Rectangle2D resp_aux = null; |
||
4256 | String qry = "SELECT " + gfield + " FROM " + tname + " WHERE ROWNUM <= " + sample_size; |
||
4257 | ResultSet _rs = null; |
||
4258 | |||
4259 | try {
|
||
4260 | PreparedStatement _st = c.prepareStatement(qry);
|
||
4261 | _rs = _st.executeQuery(); |
||
4262 | while (_rs.next()) {
|
||
4263 | STRUCT aux = (STRUCT) _rs.getObject(1);
|
||
4264 | IGeometry ig = getGeometryUsing(aux, false);
|
||
4265 | |||
4266 | if (ig == null) continue; |
||
4267 | |||
4268 | if (resp_aux == null) { |
||
4269 | resp_aux = ig.getBounds2D(); |
||
4270 | } else {
|
||
4271 | resp_aux.add(ig.getBounds2D()); |
||
4272 | } |
||
4273 | |||
4274 | } |
||
4275 | } catch (Exception ex) { |
||
4276 | logger.error("While getting random sample: " + ex.getMessage());
|
||
4277 | return world;
|
||
4278 | } |
||
4279 | |||
4280 | if (resp_aux == null) return world; |
||
4281 | double w = resp_aux.getWidth();
|
||
4282 | double h = resp_aux.getHeight();
|
||
4283 | double x = resp_aux.getMinX();
|
||
4284 | double y = resp_aux.getMinY();
|
||
4285 | |||
4286 | // enlarge 10 times:
|
||
4287 | double newx = x - (0.5 * (enlargement - 1)) * w; |
||
4288 | double newy = y - (0.5 * (enlargement - 1)) * w; |
||
4289 | Rectangle2D resp_aux_large = new Rectangle2D.Double(newx, newy, |
||
4290 | enlargement * w, |
||
4291 | enlargement * h); |
||
4292 | |||
4293 | |||
4294 | Rectangle2D.intersect(world, resp_aux_large, resp_aux);
|
||
4295 | |||
4296 | logger.debug("FAST BB:");
|
||
4297 | logger.debug(" min x:" + resp_aux.getMinX());
|
||
4298 | logger.debug(" min y:" + resp_aux.getMinY());
|
||
4299 | logger.debug(" w:" + resp_aux.getWidth());
|
||
4300 | logger.debug(" h:" + resp_aux.getHeight());
|
||
4301 | return resp_aux;
|
||
4302 | } |
||
4303 | |||
4304 | private Rectangle2D getEstimatedGeodeticExtent( |
||
4305 | String tname, String gfield, Connection c, int sample_size, double enlargement) { |
||
4306 | |||
4307 | Rectangle2D world = new Rectangle2D.Double(-180, -90, 360, 180); |
||
4308 | |||
4309 | ArrayList ids = new ArrayList(); |
||
4310 | int _rnd_index = 0; |
||
4311 | ROWID _id = null;
|
||
4312 | Random rnd = new Random(System.currentTimeMillis()); |
||
4313 | |||
4314 | for (int i=0; i<sample_size; i++) { |
||
4315 | _rnd_index = rnd.nextInt(numReg); |
||
4316 | _id = (ROWID) rowToId.get(new Integer((int) _rnd_index)); |
||
4317 | ids.add(_id.stringValue()); |
||
4318 | } |
||
4319 | |||
4320 | String qry = "SELECT " + gfield + " FROM " + tname + " WHERE ("; |
||
4321 | for (int i=0; i<ids.size(); i++) { |
||
4322 | qry = qry + "(ROWID = '" + ((String) ids.get(i)) + "') OR "; |
||
4323 | } |
||
4324 | qry = qry.substring(0, qry.length() - 4) + ")"; |
||
4325 | |||
4326 | Rectangle2D resp_aux = null; |
||
4327 | ResultSet _rs = null; |
||
4328 | |||
4329 | try {
|
||
4330 | PreparedStatement _st = c.prepareStatement(qry);
|
||
4331 | _rs = _st.executeQuery(); |
||
4332 | while (_rs.next()) {
|
||
4333 | STRUCT aux = (STRUCT) _rs.getObject(1);
|
||
4334 | IGeometry ig = getGeometryUsing(aux, false);
|
||
4335 | |||
4336 | if (ig == null) continue; |
||
4337 | |||
4338 | if (resp_aux == null) { |
||
4339 | resp_aux = ig.getBounds2D(); |
||
4340 | } else {
|
||
4341 | resp_aux.add(ig.getBounds2D()); |
||
4342 | } |
||
4343 | |||
4344 | } |
||
4345 | } catch (Exception ex) { |
||
4346 | logger.error("While getting random sample: " + ex.getMessage());
|
||
4347 | return world;
|
||
4348 | } |
||
4349 | |||
4350 | if (resp_aux == null) return world; |
||
4351 | double w = resp_aux.getWidth();
|
||
4352 | double h = resp_aux.getHeight();
|
||
4353 | double x = resp_aux.getMinX();
|
||
4354 | double y = resp_aux.getMinY();
|
||
4355 | |||
4356 | // enlarge 10 times:
|
||
4357 | double newx = x - (0.5 * (enlargement - 1)) * w; |
||
4358 | double newy = y - (0.5 * (enlargement - 1)) * w; |
||
4359 | Rectangle2D resp_aux_large = new Rectangle2D.Double(newx, newy, |
||
4360 | enlargement * w, |
||
4361 | enlargement * h); |
||
4362 | |||
4363 | |||
4364 | Rectangle2D.intersect(world, resp_aux_large, resp_aux);
|
||
4365 | return resp_aux;
|
||
4366 | } |
||
4367 | |||
4368 | 13995 | jldominguez@prodevelop.es | public void setUserName(String u) { |
4369 | userName = u; |
||
4370 | } |
||
4371 | 13991 | jldominguez@prodevelop.es | |
4372 | 13995 | jldominguez@prodevelop.es | public String getUserName() { |
4373 | return userName;
|
||
4374 | } |
||
4375 | 13991 | jldominguez@prodevelop.es | |
4376 | 13995 | jldominguez@prodevelop.es | |
4377 | |||
4378 | 13991 | jldominguez@prodevelop.es | } |