Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / drivers / dgn / DGNDriver.java @ 682

History | View | Annotate | Download (20 KB)

1
package com.iver.cit.gvsig.fmap.drivers.dgn;
2

    
3
import java.awt.geom.AffineTransform;
4
import java.awt.geom.Arc2D;
5
import java.awt.geom.Rectangle2D;
6
import java.io.File;
7
import java.io.IOException;
8
import java.util.ArrayList;
9

    
10
import com.hardcode.gdbms.engine.data.DriverException;
11
import com.hardcode.gdbms.engine.data.FileDriver;
12
import com.hardcode.gdbms.engine.values.Value;
13
import com.iver.cit.gvsig.fmap.core.GeneralPathX;
14
import com.iver.cit.gvsig.fmap.core.IGeometry;
15
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
16
import com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver;
17

    
18

    
19
/**
20
 * DOCUMENT ME!
21
 *
22
 * @author Vicente Caballero Navarro
23
 */
24
public class DGNDriver implements VectorialFileDriver, FileDriver {
25

    
26
        DGNReader m_DgnReader;
27
        
28
        private final int ID_FIELD_ID=0;
29
        private final int ID_FIELD_ENTITY=1;
30
        private final int ID_FIELD_LAYER=2;
31
        private final int ID_FIELD_COLOR=3;
32
        private final int ID_FIELD_HEIGHTTEXT=4;
33
        private final int ID_FIELD_ROTATIONTEXT=5;
34
        private final int ID_FIELD_TEXT=6;
35
        
36
        private String path;
37
        private File m_Fich;
38

    
39
    /**
40
     * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#open(java.io.File)
41
     */
42
    public void open(File f) throws IOException {
43
            m_Fich = f;
44
    }
45

    
46
    /**
47
     * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#close()
48
     */
49
    public void close() throws IOException {
50
    }
51

    
52
    /**
53
     * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getShape(int)
54
     */
55
    public IGeometry getShape(int index) throws IOException {
56
                boolean bElementoCompuesto = false, bEsPoligono = false;
57
                boolean bInsideCell = false;
58
                boolean bFirstHoleEntity = false;
59
                boolean bConnect = false; // Se usa para que los pol?gonos cierren bien cuando son formas compuestas
60
                // int contadorSubElementos =0, numSubElementos = 0;
61
                int complex_index_fill_color= -1;
62
                int nClass; // Para filtrar los elementos de construcci?n, etc.
63
                
64
                
65
                // Campos de las MemoryLayer:
66
                Object [] auxRow = new Object[4];
67
                Object [] cellRow = new Object[4];
68
                Object [] complexRow = new Object[4];
69
                ArrayList arrayFields = new ArrayList();
70
                arrayFields.add("ID");
71
                arrayFields.add("Entity");
72
                arrayFields.add("Layer");
73
                arrayFields.add("Color");
74
                
75
                IGeometry aux;
76
                GeneralPathX elementoCompuesto = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD);
77
                
78
                m_DgnReader.DGNGotoElement(index);
79
            
80
        DGNElemCore elemento = m_DgnReader.DGNReadElement();
81
        nClass= 0;
82
        if (elemento.properties != 0)
83
                nClass = elemento.properties & DGNFileHeader.DGNPF_CLASS;
84
        if ((elemento != null) && (elemento.deleted == 0) && (nClass == 0)) //Leer un elemento
85
         {
86
                aux = null;
87
                // if ((elemento.element_id > 3800) && (elemento.element_id < 3850))
88
                //         m_DgnReader.DGNDumpElement(m_DgnReader.getInfo(),elemento,""); 
89
                
90
                if ((elemento.stype == DGNFileHeader.DGNST_MULTIPOINT) || (elemento.stype == DGNFileHeader.DGNST_ARC)
91
                                || (elemento.stype == DGNFileHeader.DGNST_CELL_HEADER)
92
                                        || (elemento.stype == DGNFileHeader.DGNST_SHARED_CELL_DEFN)
93
                                        || (elemento.stype == DGNFileHeader.DGNST_COMPLEX_HEADER))
94
                {
95
                        if (elemento.complex != 0)
96
                        {
97
                                bElementoCompuesto = true;
98
                        }
99
                        else
100
                        {                                
101
                                if (bElementoCompuesto)
102
                                {                                                
103
                                        if (bInsideCell)
104
                                        {
105
                                                auxRow[ID_FIELD_ENTITY] = cellRow[ID_FIELD_ENTITY];
106
                                        }
107
                                        else
108
                                        {
109
                                                auxRow = complexRow;
110
                                        }
111
                                        // System.err.println("Entidad compuesta. bInsideCell = " + bInsideCell + " auxRow = " + auxRow[ID_FIELD_ENTITY]);
112
                                        // TODO: CREACION DE LINEA lyrLines.addShape(new FShape(FConstant.SHAPE_TYPE_POLYLINE, elementoCompuesto), auxRow);
113
                                        if (bEsPoligono)
114
                                        {
115
                                                        if (complex_index_fill_color != -1)
116
                                                                auxRow[ID_FIELD_COLOR] = new Integer(complex_index_fill_color);
117

    
118
                                                // TODO: CREAR POLIGONO lyrPolygons.addShape(new FShape(FConstant.SHAPE_TYPE_POLYGON, elementoCompuesto), auxRow);
119
                                        }
120
                                        elementoCompuesto = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD);
121
                                }
122
                                // System.err.println("Entidad simple");
123
                                bElementoCompuesto = false;
124
                                bEsPoligono = false;
125
                                bConnect = false;
126
                                // elementoCompuesto = new GeneralPathX();
127
                                bInsideCell = false;
128
                        }
129
                }
130
            switch (elemento.stype)
131
                        {
132
                                case DGNFileHeader.DGNST_SHARED_CELL_DEFN:
133
                                        bInsideCell = true;
134
                                        cellRow[ID_FIELD_ID] = new Integer(elemento.element_id);
135
                        cellRow[ID_FIELD_LAYER] = new Integer(elemento.level);
136
                        cellRow[ID_FIELD_COLOR] = new Integer(elemento.color);
137
                        cellRow[ID_FIELD_ENTITY] = new String("Shared Cell");
138
                                        break;
139
                                case DGNFileHeader.DGNST_CELL_HEADER:
140
                                        bInsideCell = true;
141
                                        DGNElemCellHeader psCellHeader = (DGNElemCellHeader) elemento;
142
                                        cellRow[ID_FIELD_ID] = new Integer(elemento.element_id);
143
                        cellRow[ID_FIELD_LAYER] = new Integer(elemento.level);
144
                        cellRow[ID_FIELD_COLOR] = new Integer(elemento.color);
145
                        cellRow[ID_FIELD_ENTITY] = new String("Cell");
146
                        complex_index_fill_color = m_DgnReader.DGNGetShapeFillInfo(elemento);
147
                        // System.err.println("Cell Header " + complex_index_fill_color);
148
                                        break;
149

    
150
                                case DGNFileHeader.DGNST_COMPLEX_HEADER:
151
                                        // bElementoCompuesto = true;
152
                                        // System.err.println("Complex Header");
153
                                        // contadorSubElementos = 0;
154
                                        DGNElemComplexHeader psComplexHeader = (DGNElemComplexHeader) elemento;
155
                                        // numSubElementos = psComplexHeader.numelems;
156
                                        complexRow[ID_FIELD_ID] = new Integer(elemento.element_id);
157
                        complexRow[ID_FIELD_LAYER] = new Integer(elemento.level);
158
                        complexRow[ID_FIELD_COLOR] = new Integer(elemento.color);
159
                        complexRow[ID_FIELD_ENTITY] = new String("Complex");
160
                        
161
                                        
162
                                        if (psComplexHeader.type == DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER)
163
                                        {
164
                                                bEsPoligono = true;
165
                                                // Si es un agujero, no conectamos con el anterior
166
                                                if ((psComplexHeader.properties & 0x8000) != 0)
167
                                                        bFirstHoleEntity = true;
168
                                                else
169
                                                {
170
                                                        // Miramos si tiene color de relleno
171
                                                        // complex_index_fill_color = -1;
172
                                                        // if (elemento.attr_bytes > 0) {
173
                                                                complex_index_fill_color = m_DgnReader.DGNGetShapeFillInfo(elemento);
174
                                                                // System.err.println("complex shape fill color = " + elemento.color);
175
                                                        // }
176
                                                        
177
                                                }
178
                                                bConnect = true;
179
                                        }
180
                                        else
181
                                        {
182
                                                bEsPoligono = false;
183
                                                bConnect = false;
184
                                        }
185
                                        break;
186
                                case DGNFileHeader.DGNST_MULTIPOINT:
187
                                        // OJO: Si lo que viene en este multipoint es un elemento con type=11 (curve), se trata de una "parametric
188
                                        // spline curve". La vamos a tratar como si no fuera curva, pero seg?n la documentaci?n, los 2 primeros puntos
189
                                        // y los 2 ?ltimos puntos definen "endpoint derivatives" y NO se muestran.
190
                                        // TODAV?A HAY UN PEQUE?O FALLO CON EL FICHERO dgn-sample.dgn, pero lo dejo por ahora.
191
                                        // Es posible que tenga que ver con lo de los arcos (arco distorsionado), que
192
                                        // todav?a no est? metido.
193
                       DGNElemMultiPoint psLine = (DGNElemMultiPoint) elemento;                                                                        
194
                        
195
                        auxRow[ID_FIELD_LAYER] = new Integer(elemento.level);
196
                        auxRow[ID_FIELD_COLOR] = new Integer(elemento.color);
197
                        
198
                        if ((psLine.num_vertices == 2) && (psLine.vertices[0].x == psLine.vertices[1].x)
199
                                        && (psLine.vertices[0].y == psLine.vertices[1].y))
200
                        {
201
                                auxRow[ID_FIELD_ENTITY] = new String("Point");
202
                                // TODO: CREAR PUNTO lyrPoints.addShape(new FShape(new FPoint(psLine.vertices[0].x,
203
                                //                 psLine.vertices[0].y,psLine.vertices[0].z),FConstant.SHAPE_TYPE_POINT), auxRow);
204
                                return ShapeFactory.createPoint3D(psLine.vertices[0].x, psLine.vertices[0].y,psLine.vertices[0].z);
205
                        }
206
                        else
207
                        {
208
                               GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD);
209
                               if (psLine.type == DGNFileHeader.DGNT_CURVE)
210
                               {
211
                                               psLine.num_vertices = psLine.num_vertices - 4;
212
                                               for (int aux_n = 0; aux_n < psLine.num_vertices; aux_n++)
213
                                               {
214
                                                       psLine.vertices[aux_n] = psLine.vertices[aux_n+2];
215
                                               }
216
                               }
217
                               if ((psLine.type == DGNFileHeader.DGNT_SHAPE)
218
                                               && ((psLine.properties & 0x8000) != 0))
219
                               {
220
                                               // Invertimos el orden porque es un agujero
221
                                       elShape.moveTo(psLine.vertices[psLine.num_vertices-1].x,
222
                                                       psLine.vertices[psLine.num_vertices-1].y);
223
                                       for (int i = psLine.num_vertices-2; i >= 0; i--)
224
                                                       elShape.lineTo( psLine.vertices[i].x,
225
                                                                       psLine.vertices[i].y);
226
                               }
227
                               else
228
                               {
229
                                       elShape.moveTo(psLine.vertices[0].x, psLine.vertices[0].y);
230
                                       for (int i = 1; i < psLine.num_vertices; i++)
231
                                                       elShape.lineTo( psLine.vertices[i].x,
232
                                                                       psLine.vertices[i].y);
233
                               }
234
                                               
235
                               auxRow[ID_FIELD_ID] = new Integer(elemento.element_id);
236
                                auxRow[ID_FIELD_ENTITY] = new String("Multipoint");
237
                                
238
                                
239
                                if ((psLine.vertices[0].x == psLine.vertices[psLine.num_vertices-1].x)
240
                                                && (psLine.vertices[0].y == psLine.vertices[psLine.num_vertices-1].y))
241
                                {
242
                                        // Lo a?adimos tambi?n como pol?gono
243
                                        bEsPoligono = true;
244
                                                        // Miramos si tiene color de relleno
245
                                                        if (elemento.attr_bytes > 0) {
246
                                                                elemento.color = m_DgnReader.DGNGetShapeFillInfo(elemento);
247
                                                                // System.err.println("fill color = " + elemento.color);
248
                                                                if (elemento.color != -1)
249
                                                                        auxRow[ID_FIELD_COLOR] = new Integer(elemento.color);
250
                                                        }
251
                                        
252
                                        if (elemento.complex == 0)
253
                                        {
254
                                                // TODO: A?adir POLIGONO lyrPolygons.addShape(new FShape(FConstant.SHAPE_TYPE_POLYGON, elShape), auxRow);
255
                                                return ShapeFactory.createPolygon2D(elShape);
256
                                        }
257
                                }
258
                                if (elemento.complex != 0)
259
                                        // Si es un agujero o 
260
                                        // es la primera entidad del agujero, lo a?adimos sin unir al anterior
261
                                        if (bFirstHoleEntity || ((psLine.type == DGNFileHeader.DGNT_SHAPE) && ((psLine.properties & 0x8000) != 0)))
262
                                       {
263
                                                                elementoCompuesto.append(elShape, false);
264
                                                                bFirstHoleEntity = false;
265
                                        }
266
                                        else
267
                                                                elementoCompuesto.append(elShape, bConnect);                                                        
268
                                else
269
                                {                                        
270
                                        // TODO: A?adir LINEA lyrLines.addShape(new FShape(FConstant.SHAPE_TYPE_POLYLINE, elShape), auxRow);
271
                                        return ShapeFactory.createPolyline2D(elShape);
272
                                }
273
                        }                                        
274
                        
275
                        break;
276
                case DGNFileHeader.DGNST_ARC: 
277
                   // m_DgnReader.DGNDumpElement(m_DgnReader.getInfo(), elemento,"");
278
                   DGNElemArc psArc = (DGNElemArc) elemento;
279
                   // La definici?n de arco de MicroStation es distinta a la de Java.
280
                   // En el dgn el origin se entiende que es el centro del arco,
281
                   // y a la hora de crear un Arc2D las 2 primeras coordenadas son
282
                   // la esquina inferior izquierda del rect?ngulo que rodea al arco.
283
                
284
                   // 1.- Creamos la elipse sin rotaci?n.
285
                   // 2.- Creamos el arco
286
                   // 3.- Rotamos el resultado
287
                        /* System.out.println("Arco con primari axis: " + psArc.primary_axis +
288
                                        " start angle: " + psArc.startang + " sweepang = " + psArc.sweepang);
289
                        System.out.println("secondaria axis: " + psArc.secondary_axis +
290
                                                         " rotation = " + psArc.rotation); */ 
291
                
292
                   AffineTransform mT = AffineTransform.getRotateInstance(
293
                                   Math.toRadians(psArc.rotation), psArc.origin.x, psArc.origin.y);
294
                   // mT.preConcatenate(AffineTransform.getScaleInstance(100.0,100.0));
295
                        Arc2D.Double elArco = new Arc2D.Double(
296
                                        psArc.origin.x - psArc.primary_axis, psArc.origin.y - psArc.secondary_axis,                            
297
                        2.0 * psArc.primary_axis, 2.0 * psArc.secondary_axis,
298
                        -psArc.startang, -psArc.sweepang, Arc2D.OPEN);
299
                   // Ellipse2D.Double elArco = new Ellipse2D.Double(psArc.origin.x - psArc.primary_axis,
300
                   //                 psArc.origin.y - psArc.secondary_axis,2.0 * psArc.primary_axis, 2.0 * psArc.secondary_axis);
301
                        GeneralPathX elShapeArc = new GeneralPathX(elArco);
302
                        // Transformamos el GeneralPahtX porque si transformamos elArco nos lo convierte
303
                        // a GeneralPath y nos guarda las coordenadas en float, con la correspondiente p?rdida de precisi?n
304
                        elShapeArc.transform(mT);
305
                       if (m_DgnReader.getInfo().dimension == 3) {
306
                               //Aqu? podr?amos hacer cosas con la coordenada Z
307
                       }
308
                       
309
                       auxRow[ID_FIELD_ID] = new Integer(elemento.element_id);
310
                       auxRow[ID_FIELD_ENTITY] = new String("Arc");
311
                       auxRow[ID_FIELD_LAYER] = new Integer(elemento.level);
312
                       auxRow[ID_FIELD_COLOR] = new Integer(elemento.color);
313
                       
314
                       /* Line2D.Double ejeMayor = new Line2D.Double(psArc.origin.x - psArc.primary_axis, psArc.origin.y, 
315
                                       psArc.origin.x + psArc.primary_axis, psArc.origin.y);
316
                        
317
                       lyrLines.addShape(new FShape(FConstant.SHAPE_TYPE_POLYLINE, new GeneralPathX(ejeMayor)), auxRow); */
318
                        // lyrLines.addShape(new FShape(FConstant.SHAPE_TYPE_POLYLINE, elShapeArc), auxRow);
319
                       if (elemento.complex != 0)
320
                       {
321
                                       // Esto es una posible fuente de fallos si detr?s de una
322
                                   // elipse vienen m?s cosas pegadas. Deber?amos volver
323
                                       // a conectar una vez pasada la elipse.
324
                                  if (elemento.type == DGNFileHeader.DGNT_ELLIPSE)
325
                                                  bConnect = false;
326

    
327
                                  // SI LA ELIPSE ES UN AGUJERO, SE A?ADE SIN PEGAR
328
                                  // Y EL ELEMENTO ES UN POLIGONO                                          
329
                               if (bFirstHoleEntity || ((elemento.type == DGNFileHeader.DGNT_SHAPE)
330
                                               && ((elemento.properties & 0x8000) != 0)))
331
                               {
332
                                                               elementoCompuesto.append(elShapeArc, false);
333
                                                               bFirstHoleEntity = false;
334
                               }
335
                                       else
336
                                                               elementoCompuesto.append(elShapeArc, bConnect);                                                        
337
                       }
338
                            else        
339
                            {
340
                                    // TODO: A?ADIR LINEA lyrLines.addShape(new FShape(FConstant.SHAPE_TYPE_POLYLINE, elShapeArc), auxRow);
341
                                    if (psArc.type == DGNFileHeader.DGNT_ELLIPSE)
342
                                    {
343
                                            // TODO: A?adir POLIGONO lyrPolygons.addShape(new FShape(FConstant.SHAPE_TYPE_POLYGON, elShapeArc), auxRow);
344
                                    }
345
                            }
346
                                                    
347
                            // System.err.println("Entra un Arco");
348
                    break;
349

    
350
                case DGNFileHeader.DGNST_TEXT: 
351
                    DGNElemText psText = (DGNElemText) elemento;
352
                        // TODO: DEVOLVER UN TEXTO??
353
                        /* FPoint2D elShapeTxt = new FPoint2D(
354
                                        psText.origin.x, psText.origin.y,psText.origin.z);
355
                                                        
356
                        auxRow[ID_FIELD_ID] = new Integer(elemento.element_id);
357
                        auxRowTxt[ID_FIELD_ENTITY] = new String("Text");
358
                        auxRowTxt[ID_FIELD_LAYER] = new Integer(elemento.level);
359
                        auxRowTxt[ID_FIELD_COLOR] = new Integer(elemento.color);
360
                        heightText = (float) psText.height_mult;
361
                        auxRowTxt[ID_FIELD_HEIGHTTEXT] = new Double(heightText);
362
                        auxRowTxt[ID_FIELD_ROTATIONTEXT] = new Double(psText.rotation);
363
                        auxRowTxt[ID_FIELD_TEXT] = psText.string; // .trim();
364
                        lyrTexts.addShape(new FShape(elShapeTxt,FConstant.SHAPE_TYPE_POINT), 
365
                                        auxRowTxt);
366
                        */
367
                        break;
368
                        /* default:
369
                                m_DgnReader.DGNDumpElement(m_DgnReader.getInfo(), elemento, "");
370
                                */
371
                        
372
                    } // switch
373
        
374
                    
375
                        } // if
376
                
377
        // } // for
378

    
379
        if (bElementoCompuesto)
380
        {
381
                if (bInsideCell)
382
                {
383
                        auxRow = cellRow;
384
                }
385
                else
386
                {
387
                        auxRow = complexRow;
388
                }
389
                // System.err.println("Entidad compuesta. bInsideCell = " + bInsideCell + " auxRow = " + auxRow[ID_FIELD_ENTITY]);                        
390
                // TODO: LINEA lyrLines.addShape(new FShape(FConstant.SHAPE_TYPE_POLYLINE, elementoCompuesto), auxRow);
391
                if (bEsPoligono)
392
                {
393
                        if (complex_index_fill_color != -1)
394
                                auxRow[ID_FIELD_COLOR] = new Integer(complex_index_fill_color);
395

    
396
                        // TODO: POLIGONO lyrPolygons.addShape(new FShape(FConstant.SHAPE_TYPE_POLYGON, elementoCompuesto), auxRow);
397
                }
398
        }
399
                return null;
400
    }
401

    
402
    /**
403
     * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getShapeCount()
404
     */
405
    public int getShapeCount() throws IOException {
406
            return m_DgnReader.getNumEntities();
407
    }
408

    
409
    /**
410
     * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getFullExtent()
411
     */
412
    public Rectangle2D getFullExtent() throws IOException {
413
        return m_DgnReader.getBoundingBox();
414
    }
415

    
416
    /**
417
     * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#initialize()
418
     */
419
    public void initialize() throws IOException {
420
            m_DgnReader = new DGNReader(m_Fich.getAbsolutePath());
421
    }
422

    
423
    /**
424
     * @see com.iver.cit.gvsig.fmap.drivers.VectorialDriver#getShapeType()
425
     */
426
    public int getShapeType() {
427
        return 15;
428
    }
429

    
430
    /**
431
         * @see com.hardcode.driverManager.Driver#getType()
432
         */
433
        public String getName() {
434
                return "gvSIG DGN Driver";
435
        }
436

    
437
        /**
438
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#accept(java.io.File)
439
         */
440
        public boolean accept(File f) {
441
                return f.getName().toUpperCase().endsWith("DGN");
442
        }
443

    
444
        /**
445
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getDataDriverName()
446
         */
447
        public String getDataDriverName() {
448
                //TODO implementar bien
449
                return null;
450
        }
451

    
452
        /**
453
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getDataFile(java.io.File)
454
         */
455
        public File getDataFile(File f) {
456
                //TODO implementar bien
457
                return null;
458
        }
459

    
460
        /* (non-Javadoc)
461
         * @see com.hardcode.gdbms.engine.data.FileDriver#fileAccepted(java.io.File)
462
         */
463
        public boolean fileAccepted(File f) {
464
                return f.getName().toUpperCase().endsWith("DGN");
465
        }
466

    
467
        /* (non-Javadoc)
468
         * @see com.hardcode.gdbms.engine.data.ReadDriver#getFieldValue(long, int)
469
         */
470
        public Value getFieldValue(long rowIndex, int fieldId) throws DriverException {
471
                // TODO Auto-generated method stub
472
                return null;
473
        }
474

    
475
        /* (non-Javadoc)
476
         * @see com.hardcode.gdbms.engine.data.ReadDriver#getFieldCount()
477
         */
478
        public int getFieldCount() throws DriverException {
479
                // TODO Auto-generated method stub
480
                return 0;
481
        }
482

    
483
        /* (non-Javadoc)
484
         * @see com.hardcode.gdbms.engine.data.ReadDriver#getFieldName(int)
485
         */
486
        public String getFieldName(int fieldId) throws DriverException {
487
                // TODO Auto-generated method stub
488
                return null;
489
        }
490

    
491
        /* (non-Javadoc)
492
         * @see com.hardcode.gdbms.engine.data.ReadDriver#getRowCount()
493
         */
494
        public long getRowCount() throws DriverException {
495
                try {
496
                        return getShapeCount();
497
                } catch (IOException e) {
498
                        e.printStackTrace();
499
                }
500
                return -1;
501
        }
502
}