Statistics
| Revision:

root / trunk / extensions / extJDBC / src / com / iver / cit / gvsig / fmap / drivers / jdbc / postgis / PostGisDriver.java @ 13881

History | View | Annotate | Download (26.9 KB)

1
/*
2
 * Created on 04-mar-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.jdbc.postgis;
45

    
46
import java.awt.geom.Rectangle2D;
47
import java.math.BigDecimal;
48
import java.nio.ByteBuffer;
49
import java.sql.Date;
50
import java.sql.ResultSet;
51
import java.sql.SQLException;
52
import java.sql.Statement;
53
import java.sql.Timestamp;
54
import java.sql.Types;
55
import java.util.ArrayList;
56
import java.util.Hashtable;
57

    
58
import org.apache.log4j.Logger;
59
import org.postgis.PGbox2d;
60
import org.postgis.PGbox3d;
61

    
62
import com.hardcode.gdbms.driver.exceptions.InitializeWriterException;
63
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
64
import com.hardcode.gdbms.engine.data.edition.DataWare;
65
import com.hardcode.gdbms.engine.values.Value;
66
import com.hardcode.gdbms.engine.values.ValueFactory;
67
import com.iver.cit.gvsig.fmap.core.FShape;
68
import com.iver.cit.gvsig.fmap.core.ICanReproject;
69
import com.iver.cit.gvsig.fmap.core.IGeometry;
70
import com.iver.cit.gvsig.fmap.drivers.ConnectionJDBC;
71
import com.iver.cit.gvsig.fmap.drivers.DBException;
72
import com.iver.cit.gvsig.fmap.drivers.DBLayerDefinition;
73
import com.iver.cit.gvsig.fmap.drivers.DefaultJDBCDriver;
74
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
75
import com.iver.cit.gvsig.fmap.drivers.IConnection;
76
import com.iver.cit.gvsig.fmap.drivers.IFeatureIterator;
77
import com.iver.cit.gvsig.fmap.drivers.WKBParser2;
78
import com.iver.cit.gvsig.fmap.drivers.XTypes;
79
import com.iver.cit.gvsig.fmap.edition.IWriteable;
80
import com.iver.cit.gvsig.fmap.edition.IWriter;
81

    
82
/**
83
 * @author FJP
84
 *
85
 * TODO To change the template for this generated type comment go to Window -
86
 * Preferences - Java - Code Generation - Code and Comments
87
 */
88
public class PostGisDriver extends DefaultJDBCDriver implements ICanReproject, IWriteable {
89
        private static Logger logger = Logger.getLogger(PostGisDriver.class
90
                        .getName());
91

    
92
        private static int FETCH_SIZE = 5000;
93

    
94
        // To avoid problems when using wkb_cursor with same layer.
95
        // I mean, when you add twice or more the same layer using
96
        // the same connection
97

    
98
        private static int CURSOR_ID = 0;
99

    
100
        private int myCursorId;
101

    
102
        private PostGISWriter writer = new PostGISWriter();
103

    
104
        private WKBParser2 parser = new WKBParser2();
105

    
106
        private int fetch_min = -1;
107

    
108
        private int fetch_max = -1;
109

    
110
        private String sqlOrig;
111

    
112
        /**
113
         * Used by setAbsolutePosition
114
         */
115
        private String sqlTotal;
116

    
117
        private String strEPSG = null;
118

    
119
        private String originalEPSG = null;
120

    
121
        private Rectangle2D fullExtent = null;
122

    
123
        private String strAux;
124

    
125
        private String completeWhere;
126

    
127
        private String provCursorName = null;
128

    
129
        int numProvCursors = 0;
130

    
131
        boolean bShapeTypeRevised = false;
132

    
133
        private int actual_position;
134

    
135
        static {
136
                try {
137
                        Class.forName("org.postgresql.Driver");
138
                } catch (ClassNotFoundException e) {
139
                        throw new RuntimeException(e);
140
                }
141
        }
142

    
143
        /**
144
         *
145
         */
146
        public PostGisDriver() {
147
                // To avoid problems when using wkb_cursor with same layer.
148
                // I mean, when you add twice or more the same layer using
149
                // the same connection
150
                CURSOR_ID++;
151
                myCursorId = CURSOR_ID;
152
        }
153

    
154
        /*
155
         * (non-Javadoc)
156
         *
157
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialDriver#getDriverAttributes()
158
         */
159
        public DriverAttributes getDriverAttributes() {
160
                return null;
161
        }
162

    
163
        /*
164
         * (non-Javadoc)
165
         *
166
         * @see com.hardcode.driverManager.Driver#getName()
167
         */
168
        public String getName() {
169
                return "PostGIS JDBC Driver";
170
        }
171

    
172
        /**
173
         * @throws ReadDriverException
174
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShape(int)
175
         */
176
        public IGeometry getShape(int index) throws ReadDriverException {
177
                IGeometry geom = null;
178
                boolean resul;
179
                try {
180
                        setAbsolutePosition(index);
181
                        // strAux = rs.getString(1);
182
                        // geom = parser.read(strAux);
183
                        if (rs != null) {
184
                                byte[] data = rs.getBytes(1);
185
                                if (data == null) // null geometry.
186
                                        return null;
187
                                geom = parser.parse(data);
188
                        }
189
                } catch (SQLException e) {
190
                        throw new ReadDriverException(this.getName(),e);
191
                }
192

    
193
                return geom;
194
        }
195

    
196
        /**
197
         * First, the geometry field. After, the rest of fields
198
         *
199
         * @return
200
         */
201
        /*
202
         * public String getTotalFields() { String strAux = "AsBinary(" +
203
         * getLyrDef().getFieldGeometry() + ")"; String[] fieldNames =
204
         * getLyrDef().getFieldNames(); for (int i=0; i< fieldNames.length; i++) {
205
         * strAux = strAux + ", " + fieldNames[i]; } return strAux; }
206
         */
207

    
208
        /**
209
         * Antes de llamar a esta funci?n hay que haber fijado el workingArea si se
210
         * quiere usar.
211
         *
212
         * @param conn
213
         * @throws DBException
214
         */
215
        public void setData(IConnection conn, DBLayerDefinition lyrDef) throws DBException {
216
                this.conn = conn;
217
                // TODO: Deber?amos poder quitar Conneciton de la llamada y meterlo
218
                // en lyrDef desde el principio.
219

    
220
                lyrDef.setConnection(conn);
221
                setLyrDef(lyrDef);
222

    
223
                getTableEPSG_and_shapeType(conn, lyrDef);
224

    
225
                getLyrDef().setSRID_EPSG(originalEPSG);
226

    
227
                try {
228
                        ((ConnectionJDBC)conn).getConnection().setAutoCommit(false);
229
                        sqlOrig = "SELECT " + getTotalFields() + " FROM "
230
                                        + getLyrDef().getComposedTableName() + " ";
231
                                        // + getLyrDef().getWhereClause();
232
                        if (canReproject(strEPSG)) {
233
                                completeWhere = getCompoundWhere(sqlOrig, workingArea, strEPSG);
234
                        } else {
235
                                completeWhere = getCompoundWhere(sqlOrig, workingArea,
236
                                                originalEPSG);
237
                        }
238
                        // completeWhere = getLyrDef().getWhereClause() + completeWhere;
239

    
240
                        String sqlAux = sqlOrig + completeWhere + " ORDER BY "
241
                        + getLyrDef().getFieldID();
242

    
243
                        sqlTotal = sqlAux;
244
                        logger.info("Cadena SQL:" + sqlAux);
245
                        st = ((ConnectionJDBC)conn).getConnection().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
246
                                        ResultSet.CONCUR_READ_ONLY);
247
                        // st.setFetchSize(FETCH_SIZE);
248
                        myCursorId++;
249
                        st.execute("declare " + getTableName() + myCursorId + "_wkb_cursor binary scroll cursor with hold for " + sqlAux);
250
                        rs = st.executeQuery("fetch forward " + FETCH_SIZE
251
                                        + " in " + getTableName() + myCursorId + "_wkb_cursor");
252
                        fetch_min = 0;
253
                        fetch_max = FETCH_SIZE - 1;
254
                        actual_position = 0;
255
                        metaData = rs.getMetaData();
256
                        doRelateID_FID();
257

    
258
                        writer.setCreateTable(false);
259
                        writer.setWriteAll(false);
260
                        writer.initialize(lyrDef);
261

    
262

    
263
                } catch (SQLException e) {
264
                        throw new DBException(e);
265
                } catch (InitializeWriterException e) {
266
                        throw new DBException(e);
267
                }
268
        }
269

    
270
        /**
271
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getFullExtent()
272
         */
273
        public Rectangle2D getFullExtent() throws ReadDriverException {
274
                if (fullExtent == null) {
275
                        try {
276
                                Statement s = ((ConnectionJDBC)conn).getConnection().createStatement();
277
                                ResultSet r = s.executeQuery("SELECT extent("
278
                                                + getLyrDef().getFieldGeometry()
279
                                                + ") AS FullExtent FROM " + getLyrDef().getComposedTableName()
280
                                                + " " + getCompleteWhere());
281
                                r.next();
282
                                String strAux = r.getString(1);
283
                                System.out.println("fullExtent = " + strAux);
284
                                if (strAux == null)
285
                                {
286
                                        logger.debug("La capa " + getLyrDef().getName() + " no tiene FULLEXTENT");
287
                                        return null;
288
                                }
289
                                if (strAux.startsWith("BOX3D")) {
290
                                        PGbox3d regeom = new PGbox3d(strAux);
291
                                        double x = regeom.getLLB().x;
292
                                        double y = regeom.getLLB().y;
293
                                        double w = regeom.getURT().x - x;
294
                                        double h = regeom.getURT().y - y;
295
                                        fullExtent = new Rectangle2D.Double(x, y, w, h);
296
                                } else {
297
                                        PGbox2d regeom = new PGbox2d(strAux);
298
                                        double x = regeom.getLLB().x;
299
                                        double y = regeom.getLLB().y;
300
                                        double w = regeom.getURT().x - x;
301
                                        double h = regeom.getURT().y - y;
302
                                        fullExtent = new Rectangle2D.Double(x, y, w, h);
303
                                }
304
                        } catch (SQLException e) {
305
                                throw new ReadDriverException(this.getName(),e);
306
                        }
307

    
308
                }
309
                return fullExtent;
310
        }
311

    
312
        /*
313
         * (non-Javadoc)
314
         *
315
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialDatabaseDriver#getGeometryIterator(java.lang.String)
316
         */
317
        public IFeatureIterator getFeatureIterator(String sql) throws ReadDriverException {
318
                PostGisFeatureIterator geomIterator = null;
319
                try {
320
                        // st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
321
                        // ResultSet.CONCUR_READ_ONLY);
322

    
323

    
324
                        if (provCursorName != null) {
325
                                /* st.execute("BEGIN");
326
                                st.execute("CLOSE " + provCursorName);
327
                                bCursorActivo = false;
328
                                st.execute("COMMIT"); */
329
                                numProvCursors++;
330
                        }
331
                        // st.execute("BEGIN");
332
                        provCursorName = getTableName() + myCursorId + "wkb_cursor_prov_" + System.currentTimeMillis() + "" + numProvCursors;
333

    
334
                        // st.execute("BEGIN");
335
                        bCursorActivo = true;
336
                        // ResultSet rs = st.executeQuery(sql);
337
                        geomIterator = new PostGisFeatureIterator(((ConnectionJDBC)conn).getConnection(), provCursorName, sql);
338
                        geomIterator.setLyrDef(getLyrDef());
339
                } catch (SQLException e) {
340
//                        e.printStackTrace();
341
//                        e.printStackTrace();
342
//                        SqlDriveExceptionType type = new SqlDriveExceptionType();
343
//            type.setDriverName("PostGIS Driver");
344
//            type.setSql(sql);
345
//            type.setLayerName(getTableName());
346
//            type.setSchema(null);
347
            throw new ReadDriverException("PostGIS Driver",e);
348
//                        throw new DriverException(e);
349
                        // return null;
350
                }
351

    
352
                return geomIterator;
353
        }
354

    
355
        public IFeatureIterator getFeatureIterator(Rectangle2D r, String strEPSG)
356
                        throws ReadDriverException {
357
                if (workingArea != null)
358
                        r = r.createIntersection(workingArea);
359

    
360
                String sqlAux;
361
                if (canReproject(strEPSG)) {
362
                        sqlAux = sqlOrig + getCompoundWhere(sqlOrig, r, strEPSG);
363
                } else {
364
                        sqlAux = sqlOrig + getCompoundWhere(sqlOrig, r, originalEPSG);
365
                }
366

    
367
                System.out.println("SqlAux getFeatureIterator = " + sqlAux);
368

    
369
                return getFeatureIterator(sqlAux);
370
        }
371

    
372
        /**
373
         * Le pasas el rect?ngulo que quieres pedir. La primera vez es el
374
         * workingArea, y las siguientes una interseccion de este rectangulo con el
375
         * workingArea
376
         *
377
         * @param r
378
         * @param strEPSG
379
         * @return
380
         */
381
        private String getCompoundWhere(String sql, Rectangle2D r, String strEPSG) {
382
                if (r == null)
383
                        return getWhereClause();
384

    
385
                double xMin = r.getMinX();
386
                double yMin = r.getMinY();
387
                double xMax = r.getMaxX();
388
                double yMax = r.getMaxY();
389
                String wktBox = "GeometryFromText('LINESTRING(" + xMin + " " + yMin
390
                                + ", " + xMax + " " + yMin + ", " + xMax + " " + yMax + ", "
391
                                + xMin + " " + yMax + ")', " + strEPSG + ")";
392
                String sqlAux;
393
                if (getWhereClause().indexOf("WHERE") != -1)
394
                        sqlAux = getWhereClause() + " AND " + getLyrDef().getFieldGeometry() + " && " + wktBox;
395
                else
396
                        sqlAux = "WHERE " + getLyrDef().getFieldGeometry() + " && "
397
                                        + wktBox;
398
                return sqlAux;
399
        }
400

    
401
        /**
402
         * @see com.iver.cit.gvsig.fmap.drivers.IVectorialDatabaseDriver#getConnectionStringBeginning()
403
         */
404
        public String getConnectionStringBeginning() {
405
                return "jdbc:postgresql:";
406
        }
407

    
408
        /*
409
         * (non-Javadoc)
410
         *
411
         * @see com.iver.cit.gvsig.fmap.drivers.DefaultDBDriver#getFieldValue(long,
412
         *      int)
413
         */
414
        public Value getFieldValue(long rowIndex, int idField)
415
                        throws ReadDriverException {
416
                boolean resul;
417
                // EL ABSOLUTE NO HACE QUE SE VUELVAN A LEER LAS
418
                // FILAS, ASI QUE MONTAMOS ESTA HISTORIA PARA QUE
419
                // LO HAGA
420
                // System.out.println("getShape " + index);
421
                int index = (int) (rowIndex);
422
                try {
423
                        setAbsolutePosition(index);
424
                        int fieldId = idField + 2;
425
                        byte[] byteBuf = rs.getBytes(fieldId);
426
                        if (byteBuf == null)
427
                                return ValueFactory.createNullValue();
428
                        else {
429
                                ByteBuffer buf = ByteBuffer.wrap(byteBuf);
430
                                if (metaData.getColumnType(fieldId) == Types.VARCHAR)
431
                                        return ValueFactory.createValue(rs.getString(fieldId));
432
                                if (metaData.getColumnType(fieldId) == Types.FLOAT)
433
                                        return ValueFactory.createValue(buf.getFloat());
434
                                if (metaData.getColumnType(fieldId) == Types.DOUBLE)
435
                                        return ValueFactory.createValue(buf.getDouble());
436
                                if (metaData.getColumnType(fieldId) == Types.REAL)
437
                                     return ValueFactory.createValue(buf.getFloat());
438
                                if (metaData.getColumnType(fieldId) == Types.INTEGER)
439
                                        return ValueFactory.createValue(buf.getInt());
440
                                if (metaData.getColumnType(fieldId) == Types.BIGINT)
441
                                        return ValueFactory.createValue(buf.getLong());
442
                                if (metaData.getColumnType(fieldId) == Types.BIT)
443
                                        // TODO
444
                                        return ValueFactory.createValue(rs.getBoolean(fieldId));
445
                                if (metaData.getColumnType(fieldId) == Types.DATE)
446
                                {
447
                        long daysAfter2000 = buf.getInt() + 1;
448
                        long msecs = daysAfter2000*24*60*60*1000;
449
                        long real_msecs_date1 = (long) (XTypes.NUM_msSecs2000 + msecs);
450
                        Date realDate1 = new Date(real_msecs_date1);
451
                                        return ValueFactory.createValue(realDate1);
452
                                }
453
                                if (metaData.getColumnType(fieldId) == Types.TIME)
454
                                {
455
                                        // TODO:
456
                                        // throw new RuntimeException("TIME type not implemented yet");
457
                                        return ValueFactory.createValue("NOT IMPLEMENTED YET");
458
                                }
459
                                if (metaData.getColumnType(fieldId) == Types.TIMESTAMP)
460
                                {
461
                                        double segsReferredTo2000 = buf.getDouble();
462
                                        long real_msecs = (long) (XTypes.NUM_msSecs2000 + segsReferredTo2000*1000);
463
                                        Timestamp valTimeStamp = new Timestamp(real_msecs);
464
                                        return ValueFactory.createValue(valTimeStamp);
465
                                }
466

    
467
                                if (metaData.getColumnType(fieldId) == Types.NUMERIC) {
468
                                        // System.out.println(metaData.getColumnName(fieldId) + " "
469
                                        // + metaData.getColumnClassName(fieldId));
470
                                        short ndigits = buf.getShort();
471
                                        short weight = buf.getShort();
472
                                        short sign = buf.getShort();
473
                                        short dscale = buf.getShort();
474
                                        String strAux;
475
                                        if (sign == 0)
476
                                                strAux = "+";
477
                                        else
478
                                                strAux = "-";
479

    
480
                                        for (int iDigit = 0; iDigit < ndigits; iDigit++) {
481
                                                short digit = buf.getShort();
482
                                                strAux = strAux + digit;
483
                                                if (iDigit == weight)
484
                                                        strAux = strAux + ".";
485

    
486
                                        }
487
                                        strAux = strAux + "0";
488
                                        BigDecimal dec;
489
                                        dec = new BigDecimal(strAux);
490
                                        // System.out.println(ndigits + "_" + weight + "_" + dscale
491
                                        // + "_" + strAux);
492
                                        // System.out.println(strAux + " Big= " + dec);
493
                                        return ValueFactory.createValue(dec.doubleValue());
494
                                }
495

    
496
                        }
497
                } catch (SQLException e) {
498
                        throw new ReadDriverException("PostGIS Driver",e);
499
                }
500
                return ValueFactory.createNullValue();
501

    
502
        }
503

    
504
        public void open() {
505
                /*
506
                 * try { st = conn.createStatement(); st.setFetchSize(2000); if
507
                 * (bCursorActivo) close(); st.execute("declare wkb_cursor binary cursor
508
                 * for " + sqlOrig); rs = st.executeQuery("fetch forward all in
509
                 * wkb_cursor"); // st.execute("BEGIN"); bCursorActivo = true; } catch
510
                 * (SQLException e) { e.printStackTrace(); throw new
511
                 * com.iver.cit.gvsig.fmap.DriverException(e); }
512
                 */
513

    
514
        }
515

    
516
        private void setAbsolutePosition(int index) throws SQLException {
517
                // TODO: USAR LIMIT Y ORDER BY, Y HACERLO TAMBI?N PARA
518
                // MYSQL
519

    
520
                // EL ABSOLUTE NO HACE QUE SE VUELVAN A LEER LAS
521
                // FILAS, ASI QUE MONTAMOS ESTA HISTORIA PARA QUE
522
                // LO HAGA
523
                // System.out.println("getShape " + index + " fetchMin=" + fetch_min + "
524
                // fetchMax=" + fetch_max);
525

    
526
                if ((index >= fetch_min) && (index <= fetch_max))
527
                {
528
                        // Est? en el intervalo, as? que lo podemos posicionar
529

    
530
                }
531
                else
532
                {
533
                        // calculamos el intervalo correcto
534
                        fetch_min = (index / FETCH_SIZE) * FETCH_SIZE;
535
                        fetch_max = fetch_min +  FETCH_SIZE;
536
                        // y cogemos ese cacho
537
                        rs.close();
538
                        st.executeQuery("fetch absolute " + fetch_min
539
                                        + " in " + getTableName() + myCursorId + "_wkb_cursor");
540

    
541
                        rs = st.executeQuery("fetch forward " + FETCH_SIZE
542
                                        + " in " + getTableName() + myCursorId + "_wkb_cursor");
543

    
544
                }
545
                rs.absolute(index - fetch_min + 1);
546
                actual_position = index;
547

    
548
        }
549

    
550
        /**
551
         * @see com.iver.cit.gvsig.fmap.drivers.IVectorialDatabaseDriver#getGeometryField(java.lang.String)
552
         */
553
        public String getGeometryField(String fieldName) {
554
                return "ASBINARY(" + fieldName + ", 'XDR')";
555
        }
556

    
557
        /**
558
         * @see com.hardcode.gdbms.engine.data.driver.ObjectDriver#getPrimaryKeys()
559
         */
560
        public int[] getPrimaryKeys() {
561
                // TODO Auto-generated method stub
562
                return null;
563
        }
564

    
565
        /**
566
         * @see com.iver.cit.gvsig.fmap.drivers.IVectorialJDBCDriver#getDefaultPort()
567
         */
568
        public int getDefaultPort() {
569
                return 5432;
570
        }
571

    
572
        /**
573
         * @see com.hardcode.gdbms.engine.data.driver.ObjectDriver#write(com.hardcode.gdbms.engine.data.edition.DataWare)
574
         */
575
        public void write(DataWare arg0) {
576
                // TODO Auto-generated method stub
577

    
578
        }
579

    
580
        /*
581
         * (non-Javadoc)
582
         *
583
         * @see com.iver.cit.gvsig.fmap.core.ICanReproject#getSourceProjection()
584
         */
585
        public String getSourceProjection(IConnection conn,DBLayerDefinition dbld) {
586
                if (originalEPSG == null)
587
                        getTableEPSG_and_shapeType(conn,dbld);
588
                return originalEPSG;
589
        }
590

    
591
        /**
592
         * Las tablas con geometr?as est?n en la tabla GEOMETRY_COLUMNS y de
593
         * ah? sacamos en qu? proyecci?n est?n.
594
         * El problema es que si el usuario hace una vista de esa
595
         * tabla, no estar? dada de alta aqu? y entonces gvSIG
596
         * no se entera en qu? proyecci?n est? trabajando (y le
597
         * ponemos un -1 como mal menor). El -1 implica que luego
598
         * no podremos reproyectar al vuelo desde la base de datos.
599
         * OJO: ES SENSIBLE A MAYUSCULAS / MINUSCULAS!!!
600
         */
601
        private void getTableEPSG_and_shapeType(IConnection conn, DBLayerDefinition dbld) {
602
                try {
603
                        Statement stAux = ((ConnectionJDBC)conn).getConnection().createStatement();
604

    
605
//                        String sql = "SELECT * FROM GEOMETRY_COLUMNS WHERE F_TABLE_NAME = '"
606
//                                        + getTableName() + "' AND F_GEOMETRY_COLUMN = '" + getLyrDef().getFieldGeometry() + "'";
607
                        String sql;
608
                        if (dbld.getSchema() == null || dbld.getSchema().equals("")){
609
                                sql = "SELECT * FROM GEOMETRY_COLUMNS WHERE F_TABLE_SCHEMA = current_schema() AND F_TABLE_NAME = '"
610
                                        + dbld.getTableName() + "' AND F_GEOMETRY_COLUMN = '" + dbld.getFieldGeometry() + "'";
611
                        }else{
612
                                sql = "SELECT * FROM GEOMETRY_COLUMNS WHERE F_TABLE_SCHEMA = '"+ dbld.getSchema() + "' AND F_TABLE_NAME = '"
613
                                                + dbld.getTableName() + "' AND F_GEOMETRY_COLUMN = '" + dbld.getFieldGeometry() + "'";
614
                        }
615

    
616
                        ResultSet rs = stAux.executeQuery(sql);
617
                        rs.next();
618
                        originalEPSG = "" + rs.getInt("SRID");
619
                        String geometryType = rs.getString("TYPE");
620
                        int shapeType = FShape.MULTI;
621
                        if (geometryType.compareToIgnoreCase("POINT") == 0)
622
                                shapeType = FShape.POINT;
623
                        else if (geometryType.compareToIgnoreCase("LINESTRING") == 0)
624
                                shapeType = FShape.LINE;
625
                        else if (geometryType.compareToIgnoreCase("POLYGON") == 0)
626
                                shapeType = FShape.POLYGON;
627
                        else if (geometryType.compareToIgnoreCase("MULTIPOINT") == 0)
628
                                shapeType = FShape.POINT;
629
                        else if (geometryType.compareToIgnoreCase("MULTILINESTRING") == 0)
630
                                shapeType = FShape.LINE;
631
                        else if (geometryType.compareToIgnoreCase("MULTIPOLYGON") == 0)
632
                                shapeType = FShape.POLYGON;
633

    
634
                        dbld.setShapeType(shapeType);
635
                        rs.close();
636
                } catch (SQLException e) {
637
                        // TODO Auto-generated catch block
638
                        originalEPSG = "-1";
639
                        logger.error(e);
640
                        e.printStackTrace();
641
                }
642

    
643
        }
644

    
645
        /*
646
         * (non-Javadoc)
647
         *
648
         * @see com.iver.cit.gvsig.fmap.core.ICanReproject#getDestProjection()
649
         */
650
        public String getDestProjection() {
651
                return strEPSG;
652
        }
653

    
654
        /*
655
         * (non-Javadoc)
656
         *
657
         * @see com.iver.cit.gvsig.fmap.core.ICanReproject#setDestProjection(java.lang.String)
658
         */
659
        public void setDestProjection(String toEPSG) {
660
                this.strEPSG = toEPSG;
661
        }
662

    
663
        /*
664
         * (non-Javadoc)
665
         *
666
         * @see com.iver.cit.gvsig.fmap.core.ICanReproject#canReproject(java.lang.String)
667
         */
668
        public boolean canReproject(String toEPSGdestinyProjection) {
669
                // TODO POR AHORA, REPROYECTA SIEMPRE gvSIG.
670
                return false;
671
        }
672

    
673
        /*
674
         * (non-Javadoc)
675
         *
676
         * @see com.iver.cit.gvsig.fmap.drivers.DefaultDBDriver#doRelateID_FID()
677
         */
678
        protected void doRelateID_FID() throws DBException {
679
                hashRelate = new Hashtable();
680
                try {
681
                        String strSQL = "SELECT " + getLyrDef().getFieldID() + " FROM "
682
                                        + getLyrDef().getComposedTableName() + " ";
683
                                        // + getLyrDef().getWhereClause();
684
                        if (canReproject(strEPSG)) {
685
                                strSQL = strSQL
686
                                                + getCompoundWhere(strSQL, workingArea, strEPSG);
687
                        } else {
688
                                strSQL = strSQL
689
                                                + getCompoundWhere(strSQL, workingArea, originalEPSG);
690
                        }
691
                        strSQL = strSQL + " ORDER BY " + getLyrDef().getFieldID();
692
                        Statement s = ((ConnectionJDBC)getConnection()).getConnection().createStatement(
693
                                        ResultSet.TYPE_SCROLL_INSENSITIVE,
694
                                        ResultSet.CONCUR_READ_ONLY);
695
                        int fetchSize = 5000;
696
                        ResultSet r = s.executeQuery(strSQL);
697
                        int id = 0;
698
                        String gid;
699
                        while (r.next()) {
700
                                gid = r.getString(1);
701
                                Value aux = ValueFactory.createValue(gid);
702
                                hashRelate.put(aux, new Integer(id));
703
                                // System.out.println("ASOCIANDO CLAVE " + aux + " CON VALOR " + id);
704
                                id++;
705
                                // System.out.println("Row " + id + ":" + strAux);
706
                        }
707
                        s.close();
708
                        numReg = id;
709

    
710
                        /*
711
                         * for (int index = 0; index < getShapeCount(); index++) { Value aux =
712
                         * getFieldValue(index, idFID_FieldName-2); hashRelate.put(aux, new
713
                         * Integer(index)); // System.out.println("Row " + index + " clave=" +
714
                         * aux); }
715
                         */
716
                        /*
717
                         * int index = 0;
718
                         *
719
                         * while (rs.next()) { Value aux = getFieldValue(index,
720
                         * idFID_FieldName-2); hashRelate.put(aux, new Integer(index));
721
                         * index++; System.out.println("Row " + index + " clave=" + aux); }
722
                         * numReg = index;
723
                         */
724
                        // rs.beforeFirst();
725
                        /*
726
                         * } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) { //
727
                         * TODO Auto-generated catch block e.printStackTrace();
728
                         */
729
                } catch (SQLException e) {
730
                        throw new DBException(e);
731
                }
732
        }
733

    
734
        public String getSqlTotal() {
735
                return sqlTotal;
736
        }
737

    
738
        /**
739
         * @return Returns the completeWhere.
740
         */
741
        public String getCompleteWhere() {
742
                return completeWhere;
743
        }
744

    
745
        /*
746
         * (non-Javadoc)
747
         *
748
         * @see com.iver.cit.gvsig.fmap.drivers.DefaultDBDriver#close()
749
         */
750
        public void close() {
751
                super.close();
752
                /*
753
                 * if (bCursorActivo) { try { // st =
754
                 * conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
755
                 * ResultSet.CONCUR_READ_ONLY); st.execute("CLOSE wkb_cursor_prov"); //
756
                 * st.close(); } catch (SQLException e) { // TODO Auto-generated catch
757
                 * block e.printStackTrace(); } bCursorActivo = false; }
758
                 */
759

    
760
        }
761

    
762
        /*
763
         * (non-Javadoc)
764
         *
765
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialDatabaseDriver#getFeatureIterator(java.awt.geom.Rectangle2D,
766
         *      java.lang.String, java.lang.String[])
767
         */
768
        public IFeatureIterator getFeatureIterator(Rectangle2D r, String strEPSG,
769
                        String[] alphaNumericFieldsNeeded) throws ReadDriverException {
770
                String sqlAux = null;
771
                try {
772
                        if (workingArea != null)
773
                                r = r.createIntersection(workingArea);
774
                        // if (getLyrDef()==null){
775
                        // load();
776
                        // throw new DriverException("Fallo de la conexi?n");
777
                        // }
778
                        String strAux = getGeometryField(getLyrDef().getFieldGeometry());
779

    
780
                        boolean found = false;
781
                        if (alphaNumericFieldsNeeded != null) {
782
                                for (int i = 0; i < alphaNumericFieldsNeeded.length; i++) {
783
                                        strAux = strAux + ", " + alphaNumericFieldsNeeded[i];
784
                                        if (alphaNumericFieldsNeeded[i].equals(getLyrDef()
785
                                                        .getFieldID()))
786
                                                found = true;
787
                                }
788
                        }
789
                        // Nos aseguramos de pedir siempre el campo ID
790
                        if (found == false)
791
                                strAux = strAux + ", " + getLyrDef().getFieldID();
792

    
793
                        String sqlProv = "SELECT " + strAux + " FROM "
794
                                        + getLyrDef().getComposedTableName() + " ";
795
                                        // + getLyrDef().getWhereClause();
796

    
797

    
798
                        if (canReproject(strEPSG)) {
799
                                sqlAux = sqlProv + getCompoundWhere(sqlProv, r, strEPSG);
800
                        } else {
801
                                sqlAux = sqlProv + getCompoundWhere(sqlProv, r, originalEPSG);
802
                        }
803

    
804
                        System.out.println("SqlAux getFeatureIterator = " + sqlAux);
805

    
806
                        return getFeatureIterator(sqlAux);
807
                } catch (Exception e) {
808
//                        e.printStackTrace();
809
//                        SqlDriveExceptionType type = new SqlDriveExceptionType();
810
//            type.setDriverName("PostGIS Driver");
811
//            type.setSql(sqlAux);
812
//            type.setLayerName(getTableName());
813
//            type.setSchema(null);
814
            throw new ReadDriverException("PostGIS Driver",e);
815

    
816
//                        throw new DriverException(e);
817
                }
818
        }
819

    
820
        /* public void preProcess() throws EditionException {
821
                writer.preProcess();
822
        }
823

824
        public void process(IRowEdited row) throws EditionException {
825
                writer.process(row);
826
        }
827

828
        public void postProcess() throws EditionException {
829
                writer.postProcess();
830
        }
831

832
        public String getCapability(String capability) {
833
                return writer.getCapability(capability);
834
        }
835

836
        public void setCapabilities(Properties capabilities) {
837
                writer.setCapabilities(capabilities);
838
        }
839

840
        public boolean canWriteAttribute(int sqlType) {
841
                return writer.canWriteAttribute(sqlType);
842
        }
843

844
        public boolean canWriteGeometry(int gvSIGgeometryType) {
845
                return writer.canWriteGeometry(gvSIGgeometryType);
846
        }
847

848
        public void initialize(ITableDefinition layerDef) throws EditionException {
849
                writer.setCreateTable(false);
850
                writer.setWriteAll(false);
851
                // Obtenemos el DBLayerDefinition a partir del driver
852

853
                DBLayerDefinition dbLyrDef = getLyrDef();
854

855

856
                writer.initialize(dbLyrDef);
857
        }
858
*/
859
        public boolean isWritable() {
860
                return true;
861
        }
862

    
863
        public IWriter getWriter() {
864
                return writer;
865
        }
866

    
867
        public String[] getGeometryFieldsCandidates(IConnection conn, String table_name) throws DBException {
868
                ArrayList list = new ArrayList();
869
                try{
870
                Statement stAux = ((ConnectionJDBC)conn).getConnection().createStatement();
871
                 String[] tokens = table_name.split("\\u002E", 2);
872
        String sql;
873
        if (tokens.length > 1)
874
        {
875
                sql = "select * from GEOMETRY_COLUMNS WHERE F_TABLE_SCHEMA = '"
876
                 + tokens[0] + "' AND F_TABLE_NAME = '" +
877
            tokens[1] + "'";
878
        }
879
        else
880
        {
881
                sql = "select * from GEOMETRY_COLUMNS" +
882
            " where F_TABLE_NAME = " + "'" + table_name + "'";
883

    
884
        }
885

    
886
//                String sql = "SELECT * FROM GEOMETRY_COLUMNS WHERE F_TABLE_NAME = '"
887
//                                + table_name + "'";
888

    
889
                ResultSet rs = stAux.executeQuery(sql);
890
                while (rs.next())
891
                {
892
                        String geomCol = rs.getString("F_GEOMETRY_COLUMN");
893
                        list.add(geomCol);
894
                }
895
                rs.close(); stAux.close();
896
                } catch (SQLException e) {
897
                        throw new DBException(e);
898
                }
899
                return (String[]) list.toArray(new String[0]);
900
        }
901
//        public String[] getTableFields(IConnection conex, String table) throws DBException {
902
//                try{
903
//                Statement st = ((ConnectionJDBC)conex).getConnection().createStatement();
904
//        // ResultSet rs = dbmd.getTables(catalog, null, dbLayerDefinition.getTable(), null);
905
//                ResultSet rs = st.executeQuery("select * from " + table + " LIMIT 1");
906
//                ResultSetMetaData rsmd = rs.getMetaData();
907
//
908
//                String[] ret = new String[rsmd.getColumnCount()];
909
//
910
//                for (int i = 0; i < ret.length; i++) {
911
//                        ret[i] = rsmd.getColumnName(i+1);
912
//                }
913
//
914
//                return ret;
915
//                }catch (SQLException e) {
916
//                        throw new DBException(e);
917
//                }
918
//        }
919

    
920
}