Statistics
| Revision:

svn-gvsig-desktop / branches / v10 / extensions / extJDBC / src / com / iver / cit / gvsig / fmap / drivers / jdbc / postgis / PostGisDriver.java @ 11959

History | View | Annotate | Download (27.3 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.Connection;
50
import java.sql.Date;
51
import java.sql.ResultSet;
52
import java.sql.ResultSetMetaData;
53
import java.sql.SQLException;
54
import java.sql.Statement;
55
import java.sql.Time;
56
import java.sql.Timestamp;
57
import java.sql.Types;
58
import java.util.ArrayList;
59
import java.util.Hashtable;
60

    
61
import org.apache.log4j.Logger;
62
import org.postgis.PGbox2d;
63
import org.postgis.PGbox3d;
64

    
65
import com.hardcode.gdbms.engine.data.edition.DataWare;
66
import com.hardcode.gdbms.engine.values.Value;
67
import com.hardcode.gdbms.engine.values.ValueFactory;
68
import com.iver.andami.messages.NotificationManager;
69
import com.iver.cit.gvsig.fmap.DriverException;
70
import com.iver.cit.gvsig.fmap.SqlDriveExceptionType;
71
import com.iver.cit.gvsig.fmap.core.FShape;
72
import com.iver.cit.gvsig.fmap.core.ICanReproject;
73
import com.iver.cit.gvsig.fmap.core.IGeometry;
74
import com.iver.cit.gvsig.fmap.drivers.ConnectionJDBC;
75
import com.iver.cit.gvsig.fmap.drivers.DBException;
76
import com.iver.cit.gvsig.fmap.drivers.DBLayerDefinition;
77
import com.iver.cit.gvsig.fmap.drivers.DefaultJDBCDriver;
78
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
79
import com.iver.cit.gvsig.fmap.drivers.IConnection;
80
import com.iver.cit.gvsig.fmap.drivers.IFeatureIterator;
81
import com.iver.cit.gvsig.fmap.drivers.WKBParser2;
82
import com.iver.cit.gvsig.fmap.drivers.XTypes;
83
import com.iver.cit.gvsig.fmap.edition.EditionException;
84
import com.iver.cit.gvsig.fmap.edition.IWriteable;
85
import com.iver.cit.gvsig.fmap.edition.IWriter;
86

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

    
97
        private static int FETCH_SIZE = 5000;
98

    
99
        // To avoid problems when using wkb_cursor with same layer.
100
        // I mean, when you add twice or more the same layer using
101
        // the same connection
102

    
103
        private static int CURSOR_ID = 0;
104

    
105
        private int myCursorId;
106

    
107
        private PostGISWriter writer = new PostGISWriter();
108

    
109
        private WKBParser2 parser = new WKBParser2();
110

    
111
        private int fetch_min = -1;
112

    
113
        private int fetch_max = -1;
114

    
115
        private String sqlOrig;
116

    
117
        /**
118
         * Used by setAbsolutePosition
119
         */
120
        private String sqlTotal;
121

    
122
        private String strEPSG = null;
123

    
124
        private String originalEPSG = null;
125

    
126
        private Rectangle2D fullExtent = null;
127

    
128
        private String strAux;
129

    
130
        private String completeWhere;
131

    
132
        private String provCursorName = null;
133

    
134
        int numProvCursors = 0;
135

    
136
        boolean bShapeTypeRevised = false;
137

    
138
        private int actual_position;
139

    
140
        static {
141
                try {
142
                        Class.forName("org.postgresql.Driver");
143
                } catch (ClassNotFoundException e) {
144
                        throw new RuntimeException(e);
145
                }
146
        }
147

    
148
        /**
149
         *
150
         */
151
        public PostGisDriver() {
152
                // To avoid problems when using wkb_cursor with same layer.
153
                // I mean, when you add twice or more the same layer using
154
                // the same connection
155
                CURSOR_ID++;
156
                myCursorId = CURSOR_ID;
157
        }
158

    
159
        /*
160
         * (non-Javadoc)
161
         *
162
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialDriver#getDriverAttributes()
163
         */
164
        public DriverAttributes getDriverAttributes() {
165
                return null;
166
        }
167

    
168
        /*
169
         * (non-Javadoc)
170
         *
171
         * @see com.hardcode.driverManager.Driver#getName()
172
         */
173
        public String getName() {
174
                return "PostGIS JDBC Driver";
175
        }
176

    
177
        /**
178
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShape(int)
179
         */
180
        public IGeometry getShape(int index) {
181
                IGeometry geom = null;
182
                boolean resul;
183
                try {
184
                        setAbsolutePosition(index);
185
                        // strAux = rs.getString(1);
186
                        // geom = parser.read(strAux);
187
                        if (rs != null) {
188
                                byte[] data = rs.getBytes(1);
189
                                if (data == null) // null geometry.
190
                                        return null;
191
                                geom = parser.parse(data);
192
                        }
193
                } catch (SQLException e) {
194
                        e.printStackTrace();
195
                }
196

    
197
                return geom;
198
        }
199

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

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

    
223
                lyrDef.setConnection(conn);
224
                setLyrDef(lyrDef);
225

    
226
                getTableEPSG_and_shapeType();
227

    
228
                getLyrDef().setSRID_EPSG(originalEPSG);
229

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

    
243
                        String sqlAux = sqlOrig + completeWhere + " ORDER BY "
244
                        + getLyrDef().getFieldID();
245

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

    
261
                        writer.setCreateTable(false);
262
                        writer.setWriteAll(false);
263
                        writer.initialize(lyrDef);
264

    
265

    
266
                } catch (SQLException e) {
267
                        e.printStackTrace();
268
                        NotificationManager.addError(
269
                                        "Error al conectar a la base de datos.", e);
270
                } catch (EditionException e) {
271
                        e.printStackTrace();
272
                        NotificationManager.addError(
273
                                        "Error inicializando PosGIS Writer.", e);
274

    
275
                }
276
        }
277

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

    
316
                }
317
                return fullExtent;
318
        }
319

    
320
        /*
321
         * (non-Javadoc)
322
         *
323
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialDatabaseDriver#getGeometryIterator(java.lang.String)
324
         */
325
        public IFeatureIterator getFeatureIterator(String sql)
326
                        throws com.iver.cit.gvsig.fmap.DriverException {
327
                PostGisFeatureIterator geomIterator = null;
328
                try {
329
                        // st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
330
                        // ResultSet.CONCUR_READ_ONLY);
331

    
332

    
333
                        if (provCursorName != null) {
334
                                /* st.execute("BEGIN");
335
                                st.execute("CLOSE " + provCursorName);
336
                                bCursorActivo = false;
337
                                st.execute("COMMIT"); */
338
                                numProvCursors++;
339
                        }
340
                        // st.execute("BEGIN");
341
                        provCursorName = getTableName() + myCursorId + "wkb_cursor_prov_" + System.currentTimeMillis() + "" + numProvCursors;
342

    
343
                        // st.execute("BEGIN");
344
                        bCursorActivo = true;
345
                        // ResultSet rs = st.executeQuery(sql);
346
                        geomIterator = new PostGisFeatureIterator(((ConnectionJDBC)conn).getConnection(), provCursorName, sql);
347
                        geomIterator.setLyrDef(getLyrDef());
348
                } catch (SQLException e) {
349
                        e.printStackTrace();
350
                        e.printStackTrace();
351
                        SqlDriveExceptionType type = new SqlDriveExceptionType();
352
            type.setDriverName("PostGIS Driver");
353
            type.setSql(sql);
354
            type.setLayerName(getTableName());
355
            type.setSchema(null);
356
            throw new com.iver.cit.gvsig.fmap.DriverException(e, type);
357
//                        throw new DriverException(e);
358
                        // return null;
359
                }
360

    
361
                return geomIterator;
362
        }
363

    
364
        public IFeatureIterator getFeatureIterator(Rectangle2D r, String strEPSG)
365
                        throws DriverException {
366
                if (workingArea != null)
367
                        r = r.createIntersection(workingArea);
368

    
369
                String sqlAux;
370
                if (canReproject(strEPSG)) {
371
                        sqlAux = sqlOrig + getCompoundWhere(sqlOrig, r, strEPSG);
372
                } else {
373
                        sqlAux = sqlOrig + getCompoundWhere(sqlOrig, r, originalEPSG);
374
                }
375

    
376
                System.out.println("SqlAux getFeatureIterator = " + sqlAux);
377

    
378
                return getFeatureIterator(sqlAux);
379
        }
380

    
381
        /**
382
         * Le pasas el rect?ngulo que quieres pedir. La primera vez es el
383
         * workingArea, y las siguientes una interseccion de este rectangulo con el
384
         * workingArea
385
         *
386
         * @param r
387
         * @param strEPSG
388
         * @return
389
         */
390
        private String getCompoundWhere(String sql, Rectangle2D r, String strEPSG) {
391
                if (r == null)
392
                        return getWhereClause();
393

    
394
                double xMin = r.getMinX();
395
                double yMin = r.getMinY();
396
                double xMax = r.getMaxX();
397
                double yMax = r.getMaxY();
398
                String wktBox = "GeometryFromText('LINESTRING(" + xMin + " " + yMin
399
                                + ", " + xMax + " " + yMin + ", " + xMax + " " + yMax + ", "
400
                                + xMin + " " + yMax + ")', " + strEPSG + ")";
401
                String sqlAux;
402
                if (getWhereClause().indexOf("WHERE") != -1)
403
                        sqlAux = getWhereClause() + " AND " + getLyrDef().getFieldGeometry() + " && " + wktBox;
404
                else
405
                        sqlAux = "WHERE " + getLyrDef().getFieldGeometry() + " && "
406
                                        + wktBox;
407
                return sqlAux;
408
        }
409

    
410
        /**
411
         * @see com.iver.cit.gvsig.fmap.drivers.IVectorialDatabaseDriver#getConnectionStringBeginning()
412
         */
413
        public String getConnectionStringBeginning() {
414
                return "jdbc:postgresql:";
415
        }
416

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

    
476
                                if (metaData.getColumnType(fieldId) == Types.NUMERIC) {
477
                                        // System.out.println(metaData.getColumnName(fieldId) + " "
478
                                        // + metaData.getColumnClassName(fieldId));
479
                                        short ndigits = buf.getShort();
480
                                        short weight = buf.getShort();
481
                                        short sign = buf.getShort();
482
                                        short dscale = buf.getShort();
483
                                        String strAux;
484
                                        if (sign == 0)
485
                                                strAux = "+";
486
                                        else
487
                                                strAux = "-";
488

    
489
                                        for (int iDigit = 0; iDigit < ndigits; iDigit++) {
490
                                                short digit = buf.getShort();
491
                                                strAux = strAux + digit;
492
                                                if (iDigit == weight)
493
                                                        strAux = strAux + ".";
494

    
495
                                        }
496
                                        strAux = strAux + "0";
497
                                        BigDecimal dec;
498
                                        dec = new BigDecimal(strAux);
499
                                        // System.out.println(ndigits + "_" + weight + "_" + dscale
500
                                        // + "_" + strAux);
501
                                        // System.out.println(strAux + " Big= " + dec);
502
                                        return ValueFactory.createValue(dec.doubleValue());
503
                                }
504

    
505
                        }
506
                } catch (SQLException e) {
507
                        throw new com.hardcode.gdbms.engine.data.driver.DriverException(e
508
                                        .getMessage());
509
                }
510
                return ValueFactory.createNullValue();
511

    
512
        }
513

    
514
        public void open() throws com.iver.cit.gvsig.fmap.DriverException {
515
                /*
516
                 * try { st = conn.createStatement(); st.setFetchSize(2000); if
517
                 * (bCursorActivo) close(); st.execute("declare wkb_cursor binary cursor
518
                 * for " + sqlOrig); rs = st.executeQuery("fetch forward all in
519
                 * wkb_cursor"); // st.execute("BEGIN"); bCursorActivo = true; } catch
520
                 * (SQLException e) { e.printStackTrace(); throw new
521
                 * com.iver.cit.gvsig.fmap.DriverException(e); }
522
                 */
523

    
524
        }
525

    
526
        private void setAbsolutePosition(int index) throws SQLException {
527
                // TODO: USAR LIMIT Y ORDER BY, Y HACERLO TAMBI?N PARA
528
                // MYSQL
529

    
530
                // EL ABSOLUTE NO HACE QUE SE VUELVAN A LEER LAS
531
                // FILAS, ASI QUE MONTAMOS ESTA HISTORIA PARA QUE
532
                // LO HAGA
533
                // System.out.println("getShape " + index + " fetchMin=" + fetch_min + "
534
                // fetchMax=" + fetch_max);
535

    
536
                if ((index >= fetch_min) && (index <= fetch_max))
537
                {
538
                        // Est? en el intervalo, as? que lo podemos posicionar
539

    
540
                }
541
                else
542
                {
543
                        // calculamos el intervalo correcto
544
                        fetch_min = (index / FETCH_SIZE) * FETCH_SIZE;
545
                        fetch_max = fetch_min +  FETCH_SIZE;
546
                        // y cogemos ese cacho
547
                        rs.close();
548
                        st.executeQuery("fetch absolute " + fetch_min
549
                                        + " in " + getTableName() + myCursorId + "_wkb_cursor");
550

    
551
                        rs = st.executeQuery("fetch forward " + FETCH_SIZE
552
                                        + " in " + getTableName() + myCursorId + "_wkb_cursor");
553

    
554
                }
555
                rs.absolute(index - fetch_min + 1);
556
                actual_position = index;
557

    
558
        }
559

    
560
        /**
561
         * @see com.iver.cit.gvsig.fmap.drivers.IVectorialDatabaseDriver#getGeometryField(java.lang.String)
562
         */
563
        public String getGeometryField(String fieldName) {
564
                return "ASBINARY(" + fieldName + ", 'XDR')";
565
        }
566

    
567
        /**
568
         * @see com.hardcode.gdbms.engine.data.driver.ObjectDriver#getPrimaryKeys()
569
         */
570
        public int[] getPrimaryKeys()
571
                        throws com.hardcode.gdbms.engine.data.driver.DriverException {
572
                // TODO Auto-generated method stub
573
                return null;
574
        }
575

    
576
        /**
577
         * @see com.iver.cit.gvsig.fmap.drivers.IVectorialJDBCDriver#getDefaultPort()
578
         */
579
        public int getDefaultPort() {
580
                return 5432;
581
        }
582

    
583
        /**
584
         * @see com.hardcode.gdbms.engine.data.driver.ObjectDriver#write(com.hardcode.gdbms.engine.data.edition.DataWare)
585
         */
586
        public void write(DataWare arg0)
587
                        throws com.hardcode.gdbms.engine.data.driver.DriverException {
588
                // TODO Auto-generated method stub
589

    
590
        }
591

    
592
        /*
593
         * (non-Javadoc)
594
         *
595
         * @see com.iver.cit.gvsig.fmap.core.ICanReproject#getSourceProjection()
596
         */
597
        public String getSourceProjection() {
598
                if (originalEPSG == null)
599
                        getTableEPSG_and_shapeType();
600
                return originalEPSG;
601
        }
602

    
603
        /**
604
         * Las tablas con geometr?as est?n en la tabla GEOMETRY_COLUMNS y de
605
         * ah? sacamos en qu? proyecci?n est?n.
606
         * El problema es que si el usuario hace una vista de esa
607
         * tabla, no estar? dada de alta aqu? y entonces gvSIG
608
         * no se entera en qu? proyecci?n est? trabajando (y le
609
         * ponemos un -1 como mal menor). El -1 implica que luego
610
         * no podremos reproyectar al vuelo desde la base de datos.
611
         * OJO: ES SENSIBLE A MAYUSCULAS / MINUSCULAS!!!
612
         */
613
        private void getTableEPSG_and_shapeType() {
614
                try {
615
                        Statement stAux = ((ConnectionJDBC)conn).getConnection().createStatement();
616

    
617
//                        String sql = "SELECT * FROM GEOMETRY_COLUMNS WHERE F_TABLE_NAME = '"
618
//                                        + getTableName() + "' AND F_GEOMETRY_COLUMN = '" + getLyrDef().getFieldGeometry() + "'";
619
                        String sql;
620
                        if (getLyrDef().getSchema() == null || getLyrDef().getSchema().equals("")){
621
                                sql = "SELECT * FROM GEOMETRY_COLUMNS WHERE F_TABLE_SCHEMA = 'public' AND F_TABLE_NAME = '"
622
                                        + getLyrDef().getTableName() + "' AND F_GEOMETRY_COLUMN = '" + getLyrDef().getFieldGeometry() + "'";                                
623
                        }else{
624
                                sql = "SELECT * FROM GEOMETRY_COLUMNS WHERE F_TABLE_SCHEMA = '"+ getLyrDef().getSchema() + "' AND F_TABLE_NAME = '"
625
                                                + getLyrDef().getTableName() + "' AND F_GEOMETRY_COLUMN = '" + getLyrDef().getFieldGeometry() + "'";
626
                        }
627

    
628
                        ResultSet rs = stAux.executeQuery(sql);
629
                        rs.next();
630
                        originalEPSG = "" + rs.getInt("SRID");
631
                        String geometryType = rs.getString("TYPE");
632
                        int shapeType = FShape.MULTI;
633
                        if (geometryType.compareToIgnoreCase("POINT") == 0)
634
                                shapeType = FShape.POINT;
635
                        if (geometryType.compareToIgnoreCase("LINESTRING") == 0)
636
                                shapeType = FShape.LINE;
637
                        if (geometryType.compareToIgnoreCase("POLYGON") == 0)
638
                                shapeType = FShape.POLYGON;
639
                        if (geometryType.compareToIgnoreCase("MULTIPOINT") == 0)
640
                                shapeType = FShape.POINT;
641
                        if (geometryType.compareToIgnoreCase("MULTILINESTRING") == 0)
642
                                shapeType = FShape.LINE;
643
                        if (geometryType.compareToIgnoreCase("MULTIPOLYGON") == 0)
644
                                shapeType = FShape.POLYGON;
645

    
646
                        getLyrDef().setShapeType(shapeType);
647
                        rs.close();
648
                } catch (SQLException e) {
649
                        // TODO Auto-generated catch block
650
                        originalEPSG = "-1";
651
                        logger.error(e);
652
                        e.printStackTrace();
653
                }
654

    
655
        }
656

    
657
        /*
658
         * (non-Javadoc)
659
         *
660
         * @see com.iver.cit.gvsig.fmap.core.ICanReproject#getDestProjection()
661
         */
662
        public String getDestProjection() {
663
                return strEPSG;
664
        }
665

    
666
        /*
667
         * (non-Javadoc)
668
         *
669
         * @see com.iver.cit.gvsig.fmap.core.ICanReproject#setDestProjection(java.lang.String)
670
         */
671
        public void setDestProjection(String toEPSG) {
672
                this.strEPSG = toEPSG;
673
        }
674

    
675
        /*
676
         * (non-Javadoc)
677
         *
678
         * @see com.iver.cit.gvsig.fmap.core.ICanReproject#canReproject(java.lang.String)
679
         */
680
        public boolean canReproject(String toEPSGdestinyProjection) {
681
                // TODO POR AHORA, REPROYECTA SIEMPRE gvSIG.
682
                return false;
683
        }
684

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

    
722
                        /*
723
                         * for (int index = 0; index < getShapeCount(); index++) { Value aux =
724
                         * getFieldValue(index, idFID_FieldName-2); hashRelate.put(aux, new
725
                         * Integer(index)); // System.out.println("Row " + index + " clave=" +
726
                         * aux); }
727
                         */
728
                        /*
729
                         * int index = 0;
730
                         *
731
                         * while (rs.next()) { Value aux = getFieldValue(index,
732
                         * idFID_FieldName-2); hashRelate.put(aux, new Integer(index));
733
                         * index++; System.out.println("Row " + index + " clave=" + aux); }
734
                         * numReg = index;
735
                         */
736
                        // rs.beforeFirst();
737
                        /*
738
                         * } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) { //
739
                         * TODO Auto-generated catch block e.printStackTrace();
740
                         */
741
                } catch (SQLException e) {
742
                        // TODO Auto-generated catch block
743
                        e.printStackTrace();
744
                }
745
        }
746

    
747
        public String getSqlTotal() {
748
                return sqlTotal;
749
        }
750

    
751
        /**
752
         * @return Returns the completeWhere.
753
         */
754
        public String getCompleteWhere() {
755
                return completeWhere;
756
        }
757

    
758
        /*
759
         * (non-Javadoc)
760
         *
761
         * @see com.iver.cit.gvsig.fmap.drivers.DefaultDBDriver#close()
762
         */
763
        public void close() {
764
                super.close();
765
                /*
766
                 * if (bCursorActivo) { try { // st =
767
                 * conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
768
                 * ResultSet.CONCUR_READ_ONLY); st.execute("CLOSE wkb_cursor_prov"); //
769
                 * st.close(); } catch (SQLException e) { // TODO Auto-generated catch
770
                 * block e.printStackTrace(); } bCursorActivo = false; }
771
                 */
772

    
773
        }
774

    
775
        /*
776
         * (non-Javadoc)
777
         *
778
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialDatabaseDriver#getFeatureIterator(java.awt.geom.Rectangle2D,
779
         *      java.lang.String, java.lang.String[])
780
         */
781
        public IFeatureIterator getFeatureIterator(Rectangle2D r, String strEPSG,
782
                        String[] alphaNumericFieldsNeeded) throws DriverException {
783
                String sqlAux = null;
784
                try {
785
                        if (workingArea != null)
786
                                r = r.createIntersection(workingArea);
787
                        // if (getLyrDef()==null){
788
                        // load();
789
                        // throw new DriverException("Fallo de la conexi?n");
790
                        // }
791
                        String strAux = getGeometryField(getLyrDef().getFieldGeometry());
792

    
793
                        boolean found = false;
794
                        if (alphaNumericFieldsNeeded != null) {
795
                                for (int i = 0; i < alphaNumericFieldsNeeded.length; i++) {
796
                                        strAux = strAux + ", " + alphaNumericFieldsNeeded[i];
797
                                        if (alphaNumericFieldsNeeded[i].equals(getLyrDef()
798
                                                        .getFieldID()))
799
                                                found = true;
800
                                }
801
                        }
802
                        // Nos aseguramos de pedir siempre el campo ID
803
                        if (found == false)
804
                                strAux = strAux + ", " + getLyrDef().getFieldID();
805

    
806
                        String sqlProv = "SELECT " + strAux + " FROM "
807
                                        + getLyrDef().getComposedTableName() + " ";
808
                                        // + getLyrDef().getWhereClause();
809

    
810

    
811
                        if (canReproject(strEPSG)) {
812
                                sqlAux = sqlProv + getCompoundWhere(sqlProv, r, strEPSG);
813
                        } else {
814
                                sqlAux = sqlProv + getCompoundWhere(sqlProv, r, originalEPSG);
815
                        }
816

    
817
                        System.out.println("SqlAux getFeatureIterator = " + sqlAux);
818

    
819
                        return getFeatureIterator(sqlAux);
820
                } catch (Exception e) {
821
                        e.printStackTrace();
822
                        SqlDriveExceptionType type = new SqlDriveExceptionType();
823
            type.setDriverName("PostGIS Driver");
824
            type.setSql(sqlAux);
825
            type.setLayerName(getTableName());
826
            type.setSchema(null);
827
            throw new com.iver.cit.gvsig.fmap.DriverException(e, type);
828

    
829
//                        throw new DriverException(e);
830
                }
831
        }
832

    
833
        /* public void preProcess() throws EditionException {
834
                writer.preProcess();
835
        }
836

837
        public void process(IRowEdited row) throws EditionException {
838
                writer.process(row);
839
        }
840

841
        public void postProcess() throws EditionException {
842
                writer.postProcess();
843
        }
844

845
        public String getCapability(String capability) {
846
                return writer.getCapability(capability);
847
        }
848

849
        public void setCapabilities(Properties capabilities) {
850
                writer.setCapabilities(capabilities);
851
        }
852

853
        public boolean canWriteAttribute(int sqlType) {
854
                return writer.canWriteAttribute(sqlType);
855
        }
856

857
        public boolean canWriteGeometry(int gvSIGgeometryType) {
858
                return writer.canWriteGeometry(gvSIGgeometryType);
859
        }
860

861
        public void initialize(ITableDefinition layerDef) throws EditionException {
862
                writer.setCreateTable(false);
863
                writer.setWriteAll(false);
864
                // Obtenemos el DBLayerDefinition a partir del driver
865

866
                DBLayerDefinition dbLyrDef = getLyrDef();
867

868

869
                writer.initialize(dbLyrDef);
870
        }
871
*/
872
        public boolean isWritable() {
873
                return true;
874
        }
875

    
876
        public IWriter getWriter() {
877
                return writer;
878
        }
879

    
880
        public String[] getGeometryFieldsCandidates(IConnection conn, String table_name) throws DBException {
881
                ArrayList list = new ArrayList();
882
                try{
883
                Statement stAux = ((ConnectionJDBC)conn).getConnection().createStatement();
884
                 String[] tokens = table_name.split("\\u002E", 2);
885
        String sql;
886
        if (tokens.length > 1)
887
        {
888
                sql = "select * from GEOMETRY_COLUMNS WHERE F_TABLE_SCHEMA = '"
889
                 + tokens[0] + "' AND F_TABLE_NAME = '" +
890
            tokens[1] + "'";
891
        }
892
        else
893
        {
894
                sql = "select * from GEOMETRY_COLUMNS" +
895
            " where F_TABLE_NAME = " + "'" + table_name + "'";
896

    
897
        }
898

    
899
//                String sql = "SELECT * FROM GEOMETRY_COLUMNS WHERE F_TABLE_NAME = '"
900
//                                + table_name + "'";
901

    
902
                ResultSet rs = stAux.executeQuery(sql);
903
                while (rs.next())
904
                {
905
                        String geomCol = rs.getString("F_GEOMETRY_COLUMN");
906
                        list.add(geomCol);
907
                }
908
                rs.close(); stAux.close();
909
                } catch (SQLException e) {
910
                        throw new DBException(e);
911
                }
912
                return (String[]) list.toArray(new String[0]);
913
        }
914
        public String[] getTableFields(IConnection conex, String table) throws DBException {
915
                try{
916
                Statement st = ((ConnectionJDBC)conex).getConnection().createStatement();
917
        // ResultSet rs = dbmd.getTables(catalog, null, dbLayerDefinition.getTable(), null);
918
                ResultSet rs = st.executeQuery("select * from " + table + " LIMIT 1");
919
                ResultSetMetaData rsmd = rs.getMetaData();
920

    
921
                String[] ret = new String[rsmd.getColumnCount()];
922

    
923
                for (int i = 0; i < ret.length; i++) {
924
                        ret[i] = rsmd.getColumnName(i+1);
925
                }
926

    
927
                return ret;
928
                }catch (SQLException e) {
929
                        throw new DBException(e);
930
                }
931
        }
932
        public String[] getTableNames(IConnection conn, String catalog) throws DBException {
933
                // TODO Auto-generated method stub
934
                return super.getTableNames(conn, catalog);
935
        }
936

    
937
}