svn-gvsig-desktop / tags / Root_v10 / extensions / extSDE / src / com / iver / cit / gvsig / fmap / drivers / sde / ArcSdeDriver.java @ 13670
History | View | Annotate | Download (17.8 KB)
1 |
/*
|
---|---|
2 |
* Created on 13-may-2005
|
3 |
*
|
4 |
* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
|
5 |
*
|
6 |
* Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
|
7 |
*
|
8 |
* This program is free software; you can redistribute it and/or
|
9 |
* modify it under the terms of the GNU General Public License
|
10 |
* as published by the Free Software Foundation; either version 2
|
11 |
* of the License, or (at your option) any later version.
|
12 |
*
|
13 |
* This program is distributed in the hope that it will be useful,
|
14 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16 |
* GNU General Public License for more details.
|
17 |
*
|
18 |
* You should have received a copy of the GNU General Public License
|
19 |
* along with this program; if not, write to the Free Software
|
20 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
21 |
*
|
22 |
* For more information, contact:
|
23 |
*
|
24 |
* Generalitat Valenciana
|
25 |
* Conselleria d'Infraestructures i Transport
|
26 |
* Av. Blasco Ib??ez, 50
|
27 |
* 46010 VALENCIA
|
28 |
* SPAIN
|
29 |
*
|
30 |
* +34 963862235
|
31 |
* gvsig@gva.es
|
32 |
* www.gvsig.gva.es
|
33 |
*
|
34 |
* or
|
35 |
*
|
36 |
* IVER T.I. S.A
|
37 |
* Salamanca 50
|
38 |
* 46005 Valencia
|
39 |
* Spain
|
40 |
*
|
41 |
* +34 963163400
|
42 |
* dac@iver.es
|
43 |
*/
|
44 |
package com.iver.cit.gvsig.fmap.drivers.sde; |
45 |
|
46 |
import java.awt.geom.Rectangle2D; |
47 |
import java.io.IOException; |
48 |
import java.sql.Types; |
49 |
import java.util.Hashtable; |
50 |
import java.util.Vector; |
51 |
|
52 |
import com.esri.sde.sdk.client.SeColumnDefinition; |
53 |
import com.esri.sde.sdk.client.SeConnection; |
54 |
import com.esri.sde.sdk.client.SeException; |
55 |
import com.esri.sde.sdk.client.SeExtent; |
56 |
import com.esri.sde.sdk.client.SeFilter; |
57 |
import com.esri.sde.sdk.client.SeLayer; |
58 |
import com.esri.sde.sdk.client.SeObjectId; |
59 |
import com.esri.sde.sdk.client.SeQuery; |
60 |
import com.esri.sde.sdk.client.SeQueryInfo; |
61 |
import com.esri.sde.sdk.client.SeRow; |
62 |
import com.esri.sde.sdk.client.SeShape; |
63 |
import com.esri.sde.sdk.client.SeShapeFilter; |
64 |
import com.esri.sde.sdk.client.SeSqlConstruct; |
65 |
import com.esri.sde.sdk.client.SeTable; |
66 |
import com.hardcode.gdbms.engine.data.driver.ObjectDriver; |
67 |
import com.hardcode.gdbms.engine.data.edition.DataWare; |
68 |
import com.hardcode.gdbms.engine.values.Value; |
69 |
import com.hardcode.gdbms.engine.values.ValueFactory; |
70 |
import com.iver.cit.gvsig.fmap.DriverException; |
71 |
import com.iver.cit.gvsig.fmap.core.FShape; |
72 |
import com.iver.cit.gvsig.fmap.core.IFeature; |
73 |
import com.iver.cit.gvsig.fmap.core.IGeometry; |
74 |
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes; |
75 |
import com.iver.cit.gvsig.fmap.drivers.IFeatureIterator; |
76 |
import com.iver.cit.gvsig.fmap.drivers.VectorialDatabaseDriver; |
77 |
|
78 |
public class ArcSdeDriver implements VectorialDatabaseDriver, ObjectDriver { |
79 |
|
80 |
private SeLayer layer;
|
81 |
private SeQuery query;
|
82 |
private SeQuery queryAux;
|
83 |
private SeSqlConstruct sqlConstruct;
|
84 |
private SeColumnDefinition[] colDefs; |
85 |
private SeRow row = null; |
86 |
private int numReg = -1; |
87 |
private Rectangle2D fullExtent = null; |
88 |
private Hashtable hashRelate = null; |
89 |
private int idSpatialColumn = -1; |
90 |
private String[] fields; |
91 |
private int[] fieldTypes; |
92 |
private long lastRowServed = -1; |
93 |
private SeConnection conn = null; |
94 |
/**
|
95 |
* Recorre el recordset creando una tabla Hash que usaremos para
|
96 |
* relacionar el n?mero de un registro con su identificador ?nico.
|
97 |
* Debe ser llamado en el setData justo despu?s de crear el recorset
|
98 |
* principal
|
99 |
*/
|
100 |
private void doRelateID_FID() |
101 |
{ |
102 |
hashRelate = new Hashtable(); |
103 |
try {
|
104 |
// query.execute();
|
105 |
// row = query.fetch();
|
106 |
if( row == null ) { |
107 |
|
108 |
System.out.println(" No rows fetched"); |
109 |
return;
|
110 |
} |
111 |
int index = 0; |
112 |
while( row != null ) |
113 |
{ |
114 |
SeShape shpVal = row.getShape(idSpatialColumn); |
115 |
SeObjectId objID = shpVal.getFeatureId(); |
116 |
String theKey = "" + objID.longValue(); |
117 |
// System.out.println("Antes de meter en el hash " + theKey);
|
118 |
hashRelate.put(theKey, new Integer(index)); |
119 |
row = query.fetch(); |
120 |
index++; |
121 |
} |
122 |
numReg = index; |
123 |
// Close the query.
|
124 |
// query.close();
|
125 |
} catch (SeException e)
|
126 |
{ |
127 |
e.printStackTrace(); |
128 |
} |
129 |
|
130 |
} |
131 |
|
132 |
public void setData(String host, int port, String db, String userDB, String pwdDB, |
133 |
String tableName, String[] cols, |
134 |
String whereClause)
|
135 |
{ |
136 |
// Conexi?n:
|
137 |
|
138 |
String server = host;
|
139 |
int instance = port;
|
140 |
String database = db;
|
141 |
String user = userDB;
|
142 |
String password = pwdDB;
|
143 |
try {
|
144 |
conn = new SeConnection(server, instance, database, user, password);
|
145 |
}catch (SeException e) {
|
146 |
e.printStackTrace(); |
147 |
return;
|
148 |
} |
149 |
|
150 |
// Fetching data
|
151 |
|
152 |
String layerName = tableName;
|
153 |
SeObjectId layerID = null;
|
154 |
String strSpatialColumn = ""; |
155 |
try {
|
156 |
Vector theLayers = conn.getLayers();
|
157 |
for (int i=0; i < theLayers.size(); i++) |
158 |
{ |
159 |
SeLayer layer = (SeLayer)theLayers.elementAt(i); |
160 |
if (layer.getName().compareToIgnoreCase(layerName) == 0 ); |
161 |
{ |
162 |
layerID = layer.getID(); |
163 |
strSpatialColumn = layer.getSpatialColumn(); |
164 |
} |
165 |
} |
166 |
if (layerID == null) |
167 |
{ |
168 |
System.err.println("Capa no encontrada"); |
169 |
return;
|
170 |
} |
171 |
// layerName = layer.getName();
|
172 |
layer = new SeLayer( conn, layerName, strSpatialColumn );
|
173 |
|
174 |
if (cols != null) |
175 |
this.fields = cols;
|
176 |
else
|
177 |
{ |
178 |
SeSqlConstruct sqlConstruct = new SeSqlConstruct( tableName );
|
179 |
SeTable table1 = new SeTable(conn, tableName );
|
180 |
/*
|
181 |
* Get the table's column definition.
|
182 |
*/
|
183 |
SeColumnDefinition[] tableDef = table1.describe();
|
184 |
this.fields = new String[tableDef.length]; |
185 |
|
186 |
/*
|
187 |
* Store the names of all the table's columns in the
|
188 |
* String array cols. This array specifies the columns
|
189 |
* to be retrieved from the database.
|
190 |
*/
|
191 |
int idField=1; |
192 |
for( int i = 0 ; i < tableDef.length ; i++ ) { |
193 |
if (tableDef[i].getType() == SeColumnDefinition.TYPE_SHAPE)
|
194 |
{ |
195 |
this.fields[0] = tableDef[i].getName(); |
196 |
} |
197 |
else
|
198 |
{ |
199 |
this.fields[idField] = tableDef[i].getName();
|
200 |
idField++; |
201 |
} |
202 |
} |
203 |
} |
204 |
|
205 |
|
206 |
sqlConstruct = new SeSqlConstruct( layerName);
|
207 |
// Create a query stream between the client and server
|
208 |
|
209 |
query = new SeQuery( conn, fields, sqlConstruct );
|
210 |
query.prepareQuery(); |
211 |
query.execute(); |
212 |
row = query.fetch(); |
213 |
if (row == null) |
214 |
{ |
215 |
System.out.println("La tabla " + getName() + " no tiene registros"); |
216 |
return;
|
217 |
} |
218 |
|
219 |
colDefs = row.getColumns(); |
220 |
fieldTypes = new int[colDefs.length-1]; |
221 |
for (int colNum = 0; colNum < colDefs.length; colNum++) |
222 |
{ |
223 |
SeColumnDefinition colDef = colDefs[colNum]; |
224 |
int dataType = colDef.getType();
|
225 |
if (dataType == SeColumnDefinition.TYPE_SHAPE)
|
226 |
{ |
227 |
if (colNum != 0) |
228 |
{ |
229 |
System.err.println("Por favor, el campo de shapes deber ser el primero"); |
230 |
return;
|
231 |
} |
232 |
idSpatialColumn = colNum; |
233 |
} |
234 |
if (dataType == SeColumnDefinition.TYPE_STRING)
|
235 |
fieldTypes[colNum-1] = Types.VARCHAR; |
236 |
if (dataType == SeColumnDefinition.TYPE_FLOAT)
|
237 |
fieldTypes[colNum-1] = Types.FLOAT; |
238 |
if (dataType == SeColumnDefinition.TYPE_DOUBLE)
|
239 |
fieldTypes[colNum-1] = Types.DOUBLE; |
240 |
if (dataType == SeColumnDefinition.TYPE_INTEGER)
|
241 |
fieldTypes[colNum-1] = Types.INTEGER; |
242 |
if (dataType == SeColumnDefinition.TYPE_SMALLINT)
|
243 |
fieldTypes[colNum-1] = Types.INTEGER; |
244 |
if (dataType == SeColumnDefinition.TYPE_DATE)
|
245 |
fieldTypes[colNum-1] = Types.DATE; |
246 |
|
247 |
} |
248 |
// query.close();
|
249 |
SeQuery extentQuery = new SeQuery( conn, fields, sqlConstruct );
|
250 |
SeQueryInfo queryInfo = new SeQueryInfo();
|
251 |
queryInfo.setConstruct(sqlConstruct); |
252 |
// queryInfo.setQueryType(SeQueryInfo.SE_QUERYTYPE_JFA);
|
253 |
// extentQuery.prepareQueryInfo(queryInfo);
|
254 |
|
255 |
SeExtent seExtent = extentQuery.calculateLayerExtent(queryInfo); |
256 |
fullExtent = new Rectangle2D.Double( |
257 |
seExtent.getMinX(), seExtent.getMinY(), |
258 |
seExtent.getMaxX()- seExtent.getMinX(), |
259 |
seExtent.getMaxY()- seExtent.getMinY()); |
260 |
extentQuery.close(); |
261 |
|
262 |
doRelateID_FID(); |
263 |
|
264 |
} |
265 |
catch (SeException e)
|
266 |
{ |
267 |
e.printStackTrace(); |
268 |
} |
269 |
|
270 |
|
271 |
} |
272 |
|
273 |
public Rectangle2D getFullExtent() { |
274 |
return fullExtent;
|
275 |
} |
276 |
|
277 |
public int getShapeType() { |
278 |
// TODO Auto-generated method stub
|
279 |
int shapeType = -1; |
280 |
switch (layer.getShapeTypes())
|
281 |
{ |
282 |
case SeLayer.TYPE_POINT:
|
283 |
shapeType = FShape.POINT; |
284 |
break;
|
285 |
case SeLayer.TYPE_LINE:
|
286 |
case SeLayer.TYPE_MULTI_LINE:
|
287 |
case SeLayer.TYPE_MULTI_SIMPLE_LINE:
|
288 |
shapeType = FShape.LINE; |
289 |
break;
|
290 |
case SeLayer.TYPE_POLYGON:
|
291 |
case SeLayer.TYPE_MULTI_POLYGON:
|
292 |
shapeType = FShape.POLYGON; |
293 |
break;
|
294 |
|
295 |
} |
296 |
return FShape.MULTI;
|
297 |
} |
298 |
|
299 |
public IGeometry getShape(int index) { |
300 |
SeRow row; |
301 |
try {
|
302 |
row = obtainRow(index); |
303 |
SeShape spVal = row.getShape(idSpatialColumn); |
304 |
IGeometry geom = ArcSdeFeatureIterator.getGeometry(spVal); |
305 |
// queryAux.close();
|
306 |
return geom;
|
307 |
} catch (SeException e) {
|
308 |
// TODO Auto-generated catch block
|
309 |
e.printStackTrace(); |
310 |
} |
311 |
return null; |
312 |
} |
313 |
|
314 |
public IFeatureIterator getFeatureIterator(String sql) |
315 |
throws DriverException {
|
316 |
// TODO Auto-generated method stub
|
317 |
return null; |
318 |
} |
319 |
|
320 |
public IFeatureIterator getFeatureIterator(Rectangle2D r, String strEPSG) |
321 |
throws DriverException {
|
322 |
/*
|
323 |
* Generate a rectangular shape that will be used as a filter
|
324 |
*/
|
325 |
try {
|
326 |
SeShape shape = new SeShape(layer.getCoordRef());
|
327 |
|
328 |
SeExtent extent = new SeExtent( r.getMinX(),
|
329 |
r.getMinY(),r.getMaxX(),r.getMaxY()); |
330 |
shape.generateRectangle(extent); |
331 |
|
332 |
SeShape[] shapes = new SeShape[1]; |
333 |
shapes[0] = shape;
|
334 |
|
335 |
/*
|
336 |
* Retrieve all the shapes that are contained within the
|
337 |
* rectangles envelope.
|
338 |
*/
|
339 |
SeShapeFilter filters[] = new SeShapeFilter[1]; |
340 |
SeShapeFilter filter = null;
|
341 |
|
342 |
filter = new SeShapeFilter( layer.getName(), layer.getSpatialColumn(), shape, SeFilter.METHOD_ENVP);
|
343 |
filters[0] = filter;
|
344 |
|
345 |
SeQuery spatialQuery = null;
|
346 |
SeSqlConstruct sqlCons = new SeSqlConstruct( layer.getName() );
|
347 |
|
348 |
spatialQuery = new SeQuery(conn, fields, sqlCons);
|
349 |
/*
|
350 |
* Set spatial constraints
|
351 |
*/
|
352 |
spatialQuery.setSpatialConstraints(SeQuery.SE_OPTIMIZE, false, filters);
|
353 |
|
354 |
spatialQuery.prepareQuery(); |
355 |
|
356 |
spatialQuery.execute(); |
357 |
|
358 |
return new ArcSdeFeatureIterator(spatialQuery); |
359 |
} catch (SeException e) {
|
360 |
// TODO Auto-generated catch block
|
361 |
e.printStackTrace(); |
362 |
return null; |
363 |
} |
364 |
|
365 |
} |
366 |
|
367 |
|
368 |
public void close() { |
369 |
// TODO Auto-generated method stub
|
370 |
|
371 |
} |
372 |
|
373 |
public void open() throws DriverException { |
374 |
// TODO Auto-generated method stub
|
375 |
|
376 |
} |
377 |
|
378 |
public int getRowIndexByFID(IFeature FID) { |
379 |
int resul;
|
380 |
String strID = FID.getID();
|
381 |
// System.out.println("Recuperando " + strID + " del hash");
|
382 |
Integer rowIndex = (Integer) hashRelate.get(strID); |
383 |
if (rowIndex == null) |
384 |
{ |
385 |
System.err.println("Error: No se ha encontrado " + strID + " dentro del Hash"); |
386 |
} |
387 |
resul = rowIndex.intValue(); |
388 |
return resul;
|
389 |
} |
390 |
|
391 |
public String getGeometryField(String fieldName) { |
392 |
return layer.getSpatialColumn();
|
393 |
} |
394 |
|
395 |
public int getShapeCount() throws IOException { |
396 |
return numReg;
|
397 |
} |
398 |
|
399 |
public DriverAttributes getDriverAttributes() {
|
400 |
// TODO Auto-generated method stub
|
401 |
return null; |
402 |
} |
403 |
|
404 |
public String getName() { |
405 |
return "ArcSDE driver"; |
406 |
} |
407 |
|
408 |
public String[] getFields() { |
409 |
String[] attributes = new String[fields.length-1]; |
410 |
for (int i=1; i < fields.length; i++) |
411 |
attributes[i-1] = fields[i];
|
412 |
return attributes;
|
413 |
} |
414 |
|
415 |
public String getWhereClause() { |
416 |
// TODO Auto-generated method stub
|
417 |
return ""; |
418 |
} |
419 |
|
420 |
public String getTableName() { |
421 |
return layer.getName();
|
422 |
} |
423 |
|
424 |
private SeRow obtainRow(long rowIndex) throws SeException |
425 |
{ |
426 |
if (rowIndex == 0) |
427 |
{ |
428 |
if (query != null) |
429 |
{ |
430 |
if (query.inProgress())
|
431 |
query.close(); |
432 |
} |
433 |
query = new SeQuery( conn, fields, sqlConstruct );
|
434 |
query.prepareQuery(); |
435 |
query.execute(); |
436 |
|
437 |
lastRowServed = -1;
|
438 |
} |
439 |
if (lastRowServed == rowIndex-1) |
440 |
{ |
441 |
row = query.fetch(); |
442 |
lastRowServed++; |
443 |
} |
444 |
else
|
445 |
{ |
446 |
if (queryAux != null) queryAux.close(); |
447 |
queryAux = new SeQuery( conn, fields, sqlConstruct );
|
448 |
SeObjectId rowID = new SeObjectId(rowIndex+1); |
449 |
row = queryAux.fetchRow(layer.getName(), rowID, fields); |
450 |
} |
451 |
// queryAux.close();
|
452 |
return row;
|
453 |
|
454 |
|
455 |
} |
456 |
public Value getFieldValue(long rowIndex, int fieldId) throws com.hardcode.gdbms.engine.data.driver.DriverException { |
457 |
SeRow row; |
458 |
Value val = null;
|
459 |
try {
|
460 |
int idFieldArcSDE = fieldId + 1; // SIEMPRE CONTANDO CON |
461 |
// QUE NOS HAN PASADO EL PRIMER CAMPO EL DE SHAPE
|
462 |
row = obtainRow(rowIndex); |
463 |
int dataType = colDefs[idFieldArcSDE].getType();
|
464 |
if ( dataType == SeColumnDefinition.TYPE_STRING)
|
465 |
{ |
466 |
String strAux = row.getString(idFieldArcSDE);
|
467 |
if (strAux == null) strAux = ""; |
468 |
val = ValueFactory.createValue(strAux); |
469 |
} |
470 |
if (dataType == SeColumnDefinition.TYPE_FLOAT)
|
471 |
{ |
472 |
val = ValueFactory.createValue(row.getFloat(idFieldArcSDE).floatValue()); |
473 |
} |
474 |
if (dataType == SeColumnDefinition.TYPE_DOUBLE)
|
475 |
{ |
476 |
val = ValueFactory.createValue(row.getDouble(idFieldArcSDE).doubleValue()); |
477 |
} |
478 |
if (dataType == SeColumnDefinition.TYPE_INTEGER)
|
479 |
{ |
480 |
val = ValueFactory.createValue(row.getInteger(idFieldArcSDE).intValue()); |
481 |
} |
482 |
if (dataType == SeColumnDefinition.TYPE_SMALLINT)
|
483 |
{ |
484 |
val = ValueFactory.createValue(row.getShort(idFieldArcSDE).intValue()); |
485 |
} |
486 |
|
487 |
if (dataType == SeColumnDefinition.TYPE_DATE)
|
488 |
{ |
489 |
val = ValueFactory.createValue(row.getDate(idFieldArcSDE)); |
490 |
} |
491 |
// queryAux.close();
|
492 |
return val;
|
493 |
|
494 |
} catch (SeException e) {
|
495 |
// TODO Auto-generated catch block
|
496 |
e.printStackTrace(); |
497 |
|
498 |
} |
499 |
|
500 |
return ValueFactory.createNullValue();
|
501 |
} |
502 |
|
503 |
public int getFieldCount() throws com.hardcode.gdbms.engine.data.driver.DriverException { |
504 |
return fields.length-1; |
505 |
} |
506 |
|
507 |
public String getFieldName(int fieldId) throws com.hardcode.gdbms.engine.data.driver.DriverException { |
508 |
// System.out.println("En ArcSdeDriver: getFieldName(" + fieldId + ")=" + fields[fieldId+1]);
|
509 |
return fields[fieldId+1]; |
510 |
} |
511 |
|
512 |
public long getRowCount() throws com.hardcode.gdbms.engine.data.driver.DriverException { |
513 |
return numReg;
|
514 |
} |
515 |
|
516 |
public int getFieldType(int i) throws com.hardcode.gdbms.engine.data.driver.DriverException { |
517 |
return fieldTypes[i];
|
518 |
} |
519 |
|
520 |
/**
|
521 |
* @see com.hardcode.gdbms.engine.data.driver.ObjectDriver#getPrimaryKeys()
|
522 |
*/
|
523 |
public int[] getPrimaryKeys() throws com.hardcode.gdbms.engine.data.driver.DriverException { |
524 |
throw new UnsupportedOperationException(); |
525 |
} |
526 |
|
527 |
/**
|
528 |
* @see com.hardcode.gdbms.engine.data.driver.ObjectDriver#write(com.hardcode.gdbms.engine.data.edition.DataWare)
|
529 |
*/
|
530 |
public void write(DataWare arg0) throws com.hardcode.gdbms.engine.data.driver.DriverException { |
531 |
// TODO Auto-generated method stub
|
532 |
|
533 |
} |
534 |
|
535 |
} |