Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / drivers / shp / IndexedShpDriver.java @ 2717

History | View | Annotate | Download (21.6 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package com.iver.cit.gvsig.fmap.drivers.shp;
42

    
43
import java.awt.geom.Point2D;
44
import java.awt.geom.Rectangle2D;
45
import java.io.File;
46
import java.io.FileInputStream;
47
import java.io.IOException;
48
import java.nio.ByteBuffer;
49
import java.nio.ByteOrder;
50
import java.nio.channels.FileChannel;
51

    
52
import org.apache.log4j.Logger;
53

    
54
import com.iver.cit.gvsig.fmap.core.FShape;
55
import com.iver.cit.gvsig.fmap.core.GeneralPathX;
56
import com.iver.cit.gvsig.fmap.core.IGeometry;
57
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
58
import com.iver.cit.gvsig.fmap.drivers.BoundedShapes;
59
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
60
import com.iver.cit.gvsig.fmap.drivers.ExternalData;
61
import com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver;
62
import com.iver.utiles.bigfile.BigByteBuffer;
63

    
64

    
65
/**
66
 * Driver del formato SHP.
67
 *
68
 * @author Francisco Jos? Pe?arrubia
69
 */
70
public class IndexedShpDriver implements VectorialFileDriver, BoundedShapes,
71
        ExternalData {
72
        private static Logger logger = Logger.getLogger(IndexedShpDriver.class.getName());
73
        private File file;
74
        private BigByteBuffer bb;
75
        private FileChannel channel;
76
        private FileInputStream fin;
77
        private int type;
78
        private long[] m_posShapes;
79
        private int numReg;
80
        private Rectangle2D extent;
81
    
82
    private File shxFile;
83
    private ByteBuffer bbShx;
84
    private FileChannel channelShx;
85
    private FileInputStream finShx;
86

    
87
        /**
88
         * Cierra el fichero.
89
         *
90
         * @throws IOException
91
         *
92
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#close()
93
         */
94
        public void close() throws IOException {
95
                IOException ret = null;
96
                
97
                try {
98
                        channel.close();
99
            channelShx.close();
100
                } catch (IOException e) {
101
                        ret = e;
102
                } finally {
103
                        try {
104
                                fin.close();
105
                        } catch (IOException e1) {
106
                                ret = e1;
107
                        }
108
                }
109

    
110
                if (ret != null) {
111
                        throw ret;
112
                }
113
                else // Si todo ha ido bien, preparamos para liberar memoria.
114
        {
115
                    bb = null;
116
            bbShx = null;
117
        }
118
        }
119

    
120
        /**
121
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#open(java.io.File)
122
         */
123
        public void open(File f) throws IOException {
124
                file = f;
125

    
126
                fin = new FileInputStream(f);
127

    
128
                // Open the file and then get a channel from the stream
129
                channel = fin.getChannel();
130

    
131
                long size = channel.size();
132

    
133
                // Get the file's size and then map it into memory
134
                // bb = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
135
        bb = new BigByteBuffer(channel, FileChannel.MapMode.READ_ONLY);
136
        
137
        finShx = new FileInputStream(getShxFile(f));
138

    
139
        // Open the file and then get a channel from the stream
140
        channelShx = finShx.getChannel();
141

    
142
        long sizeShx = channelShx.size();
143

    
144
        // Get the file's size and then map it into memory
145
        // bb = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
146
        bbShx = channelShx.map(FileChannel.MapMode.READ_ONLY, 0, sizeShx);
147
        bbShx.order(ByteOrder.BIG_ENDIAN);
148
        }
149

    
150
        /**
151
         * DOCUMENT ME!
152
         *
153
         * @param index DOCUMENT ME!
154
         *
155
         * @return DOCUMENT ME!
156
         *
157
         * @throws IOException
158
         *
159
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getShape(int)
160
         */
161

    
162
        /* public FShape getShapeByID(int ID) {
163
           Point2D.Double p = new Point2D.Double();
164
           Point2D.Double pAnt = null;
165
           int numParts;
166
           int numPoints;
167
           int i;
168
           int j;
169
           int numReg;
170
           int numeroPuntos;
171
           int hasta;
172
           int desde;
173
           Rectangle2D.Double BoundingBox = new Rectangle2D.Double();
174
        
175
                   SHPShape shapeShp=null;
176
           FShape resulShape = null;
177
           try {
178
               bb.position(m_posShapes[ID]);
179
               bb.order(ByteOrder.LITTLE_ENDIAN);
180
               int tipoShape = bb.getInt();
181
               m_shapeType = tipoShape;
182
               // retrieve that shape.
183
               // tempRecord.setShape(readShape(tempShapeType, tempContentLength, in));
184
               if (tipoShape == FConstant.SHAPE_TYPE_POINT) {
185
                   p = readPoint(bb);
186
                   resulShape = new FShape(new FPoint(p.getX(),p.getY()),FConstant.SHAPE_TYPE_POINT);
187
                   //Comprobaci?n punto.
188
                   //System.err.println("p.x = "+p.x);
189
                   //System.err.println("p.y = "+p.y);
190
        
191
               } else if ((tipoShape == FConstant.SHAPE_TYPE_POLYLINE) ||
192
                       (tipoShape == FConstant.SHAPE_TYPE_POLYGON)) {
193
                   // BoundingBox
194
                   BoundingBox = readRectangle(bb);
195
                   numParts = bb.getInt();
196
                   numPoints = bb.getInt();
197
                   // part indexes.
198
                   // Geometry geom = GeometryFactory.toGeometryArray();
199
                   GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
200
                           numPoints);
201
                   int[] tempParts = new int[numParts];
202
                   for (i = 0; i < numParts; i++) {
203
                       tempParts[i] = bb.getInt();
204
                   }
205
                   j = 0;
206
                   ///Line2D.Double line2D;
207
                   FPoint[] points=new FPoint[numPoints];
208
                   for (i = 0; i < numPoints; i++) {
209
                           p=readPoint(bb);
210
                       points[i] = new FPoint(p.x,p.y);
211
                       // System.out.println("x= " + p.x + " y=" + p.y);
212
                       // System.out.println("x= " + (float) p.x + " y=" + (float) p.y);
213
                       if (i == tempParts[j]) {
214
                           elShape.moveTo(p.x, p.y);
215
                           if (j < (numParts - 1)) {
216
                               j++;
217
                           }
218
                       } else {
219
                           elShape.lineTo(p.x, p.y);
220
                       }
221
                   }
222
                   //FGeometry pol=new FPolyLine(points,tempParts,BoundingBox);
223
        
224
                   resulShape = new FShape(tipoShape,elShape);
225
               } else if (tipoShape == FConstant.SHAPE_TYPE_MULTIPOINT) {
226
                   // BoundingBox
227
                   BoundingBox = readRectangle(bb);
228
                   numPoints = bb.getInt();
229
                   FPoint[] tempPoints = new FPoint[numPoints];
230
                   for (i = 0; i < numPoints; i++) {
231
                           Point2D p2=readPoint(bb);
232
                       tempPoints[i] = new FPoint(p2.getX(),p2.getY(),0);
233
                   }
234
                   FMultiPoint multipoint = new FMultiPoint(tempPoints,BoundingBox);
235
                   resulShape = new FShape(multipoint,tipoShape);
236
               } else if (tipoShape == FConstant.SHAPE_TYPE_POINTZ) {
237
                   FPoint p3d = new FPoint();
238
                   p3d.read(bb);
239
                   resulShape = new FShape(p3d,tipoShape);
240
               } else if ((tipoShape == FConstant.SHAPE_TYPE_POLYLINEZ) ||
241
                       (tipoShape == FConstant.SHAPE_TYPE_POLYGONZ)) {
242
                   // BoundingBox
243
                   BoundingBox = readRectangle(bb);
244
                   numParts = bb.getInt();
245
                   numPoints = bb.getInt();
246
                   // part indexes.
247
                   // Geometry geom = GeometryFactory.toGeometryArray();
248
        
249
                   GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
250
                           numPoints);
251
                   int[] tempParts = new int[numParts];
252
                   for (i = 0; i < numParts; i++) {
253
                       tempParts[i] = bb.getInt();
254
                   }
255
                   j = 0;
256
                  //Line2D.Double line2D;
257
                   FPoint[] points=new FPoint[numPoints];
258
                   for (i = 0; i < numPoints; i++) {
259
                       p = readPoint(bb);
260
                       points[i]=new FPoint(p.x,p.y);
261
        
262
                       if (i == tempParts[j]) {
263
                           elShape.moveTo(p.x, p.y);
264
                           if (j < (numParts - 1)) {
265
                               j++;
266
                           }
267
                       } else {
268
                           elShape.lineTo(p.x, p.y);
269
                       }
270
        
271
                   }
272
        
273
                   double[] boxZ = new double[2];
274
                   boxZ[0] = bb.getDouble();
275
                   boxZ[1] = bb.getDouble();
276
                   double[] pZ = new double[numPoints];
277
                   for (i = 0; i < numPoints; i++) {
278
                       pZ[i] = bb.getDouble();
279
                   }
280
                   //FGeometry pol=new FPolyLine(points,tempParts,BoundingBox);
281
                   resulShape = new FShape(tipoShape, elShape, pZ);
282
               } else if (tipoShape == FConstant.SHAPE_TYPE_MULTIPOINTZ) {
283
                   // BoundingBox
284
                   BoundingBox = readRectangle(bb);
285
                   numPoints = bb.getInt();
286
                   FPoint[] tempPoints3D = new FPoint[numPoints];
287
                   for (i = 0; i < numPoints; i++) {
288
                       tempPoints3D[i] = new FPoint();
289
                       tempPoints3D[i].read(bb);
290
                   }
291
                   FMultiPoint multipoint3D = new FMultiPoint(tempPoints3D,BoundingBox);
292
                   resulShape = new FShape(multipoint3D,tipoShape);
293
               }
294
           } catch (Exception e) {
295
               System.err.println("Fallo en getShapeByID. ID=" + ID +
296
                   " m_posShapes[ID]=" + m_posShapes[ID]);
297
               System.err.println("getShapeByID: " + e.getMessage());
298
               e.printStackTrace();
299
           }
300
           return resulShape;
301
           }
302
         */
303

    
304
        /**
305
         * Devuelve la geometria a partir de un ?ndice.
306
         *
307
         * @param index DOCUMENT ME!
308
         *
309
         * @return DOCUMENT ME!
310
         *
311
         * @throws IOException DOCUMENT ME!
312
         */
313
        public IGeometry getShape(int index) throws IOException {
314
                Point2D.Double p = new Point2D.Double();
315
                Point2D.Double pAnt = null;
316
                int numParts;
317
                int numPoints;
318
                int i;
319
                int j;
320
                int numReg;
321
                int numeroPuntos;
322
                int hasta;
323
                int desde;
324
                int shapeType;
325

    
326
                //Rectangle2D.Double BoundingBox;
327
        // if (m_posShapes[index] == 0)
328
            
329
                // bb.position(m_posShapes[index]);
330
        bb.position(getPositionForRecord(index));
331
                bb.order(ByteOrder.LITTLE_ENDIAN);
332

    
333
                ///bb.position(bb.position()+4);
334
                shapeType = bb.getInt();
335
                //el shape tal con tema tal y n?mro tal es null
336
                if (shapeType==SHP.NULL){
337
                        logger.info("El shape ="+index+ " del tema ="+this.toString()+" es null");
338
                        return null;
339
                }
340
                        
341
                // retrieve that shape.
342
                // tempRecord.setShape(readShape(tempShapeType, tempContentLength, in));
343
                switch (type) {
344
                        case (SHP.POINT2D):
345
                                p = readPoint(bb);
346

    
347
                                return ShapeFactory.createPoint2D(p.getX(), p.getY());
348

    
349
                        case (SHP.POLYLINE2D):
350

    
351
                                //BoundingBox = readRectangle(bb);
352
                                //bb.getDouble();
353
                                //bb.getDouble();
354
                                //bb.getDouble();
355
                                //bb.getDouble();
356
                                bb.position(bb.position() + 32);
357
                                numParts = bb.getInt();
358
                                numPoints = bb.getInt();
359

    
360
                                // part indexes.
361
                                // Geometry geom = GeometryFactory.toGeometryArray();
362
                                GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
363
                                                numPoints);
364

    
365
                                int[] tempParts = new int[numParts];
366

    
367
                                for (i = 0; i < numParts; i++) {
368
                                        tempParts[i] = bb.getInt();
369
                                }
370

    
371
                                j = 0;
372

    
373
                                for (i = 0; i < numPoints; i++) {
374
                                        p = readPoint(bb);
375

    
376
                                        if (i == tempParts[j]) {
377
                                                elShape.moveTo(p.x, p.y);
378

    
379
                                                if (j < (numParts - 1)) {
380
                                                        j++;
381
                                                }
382
                                        } else {
383
                                                elShape.lineTo(p.x, p.y);
384
                                        }
385
                                }
386

    
387
                                return ShapeFactory.createPolyline2D(elShape);
388

    
389
                        case (SHP.POLYGON2D):
390

    
391
                                //                            BoundingBox = readRectangle(bb);
392
                                bb.getDouble();
393
                                bb.getDouble();
394
                                bb.getDouble();
395
                                bb.getDouble();
396

    
397
                                numParts = bb.getInt();
398

    
399
                                numPoints = bb.getInt();
400

    
401
                                // part indexes.
402
                                // Geometry geom = GeometryFactory.toGeometryArray();
403
                                elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
404

    
405
                                tempParts = new int[numParts];
406

    
407
                                for (i = 0; i < numParts; i++) {
408
                                        tempParts[i] = bb.getInt();
409
                                }
410

    
411
                                j = 0;
412

    
413
                                for (i = 0; i < numPoints; i++) {
414
                                        p = readPoint(bb);
415

    
416
                                        if (i == tempParts[j]) {
417
                                                elShape.moveTo(p.x, p.y);
418

    
419
                                                if (j < (numParts - 1)) {
420
                                                        j++;
421
                                                }
422
                                        } else {
423
                                                elShape.lineTo(p.x, p.y);
424
                                        }
425
                                }
426

    
427
                                return ShapeFactory.createPolygon2D(elShape);
428

    
429
                        case (SHP.POINT3D):
430

    
431
                                double x = bb.getDouble();
432
                                double y = bb.getDouble();
433
                                double z = bb.getDouble();
434

    
435
                                return ShapeFactory.createPoint3D(x, y, z);
436

    
437
                        case (SHP.POLYLINE3D):
438
                                bb.position(bb.position() + 32);
439
                                numParts = bb.getInt();
440
                                numPoints = bb.getInt();
441
                                elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
442
                                tempParts = new int[numParts];
443

    
444
                                for (i = 0; i < numParts; i++) {
445
                                        tempParts[i] = bb.getInt();
446
                                }
447

    
448
                                j = 0;
449

    
450
                                for (i = 0; i < numPoints; i++) {
451
                                        p = readPoint(bb);
452

    
453
                                        if (i == tempParts[j]) {
454
                                                elShape.moveTo(p.x, p.y);
455

    
456
                                                if (j < (numParts - 1)) {
457
                                                        j++;
458
                                                }
459
                                        } else {
460
                                                elShape.lineTo(p.x, p.y);
461
                                        }
462
                                }
463

    
464
                                double[] boxZ = new double[2];
465
                                boxZ[0] = bb.getDouble();
466
                                boxZ[1] = bb.getDouble();
467

    
468
                                double[] pZ = new double[numPoints];
469

    
470
                                for (i = 0; i < numPoints; i++) {
471
                                        pZ[i] = bb.getDouble();
472
                                }
473

    
474
                                return ShapeFactory.createPolyline3D(elShape, pZ);
475
                        case (SHP.POLYGON3D):
476
                        bb.position(bb.position() + 32);
477
                        numParts = bb.getInt();
478
                        numPoints = bb.getInt();
479
                        elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
480
                        tempParts = new int[numParts];
481

    
482
                        for (i = 0; i < numParts; i++) {
483
                                tempParts[i] = bb.getInt();
484
                        }
485

    
486
                        j = 0;
487

    
488
                        for (i = 0; i < numPoints; i++) {
489
                                p = readPoint(bb);
490

    
491
                                if (i == tempParts[j]) {
492
                                        elShape.moveTo(p.x, p.y);
493

    
494
                                        if (j < (numParts - 1)) {
495
                                                j++;
496
                                        }
497
                                } else {
498
                                        elShape.lineTo(p.x, p.y);
499
                                }
500
                        }
501

    
502
                        double[] boxpoZ = new double[2];
503
                        boxpoZ[0] = bb.getDouble();
504
                        boxpoZ[1] = bb.getDouble();
505

    
506
                        double[] poZ = new double[numPoints];
507

    
508
                        for (i = 0; i < numPoints; i++) {
509
                                poZ[i] = bb.getDouble();
510
                        }
511

    
512
                        return ShapeFactory.createPolygon3D(elShape, poZ);
513
                        
514
                        case (SHP.MULTIPOINT2D):
515
                                bb.position(bb.position() + 32);
516
                                numPoints = bb.getInt();
517

    
518
                                double[] tempX = new double[numPoints];
519
                                double[] tempY = new double[numPoints];
520

    
521
                                for (i = 0; i < numPoints; i++) {
522
                                        tempX[i] = bb.getDouble();
523
                                        tempY[i] = bb.getDouble();
524
                                }
525

    
526
                                return ShapeFactory.createMultipoint2D(tempX, tempY);
527

    
528
                        case (SHP.MULTIPOINT3D):
529
                                bb.position(bb.position() + 32);
530
                                numPoints = bb.getInt();
531

    
532
                                double[] temX = new double[numPoints];
533
                                double[] temY = new double[numPoints];
534
                                double[] temZ = new double[numPoints];
535

    
536
                                for (i = 0; i < numPoints; i++) {
537
                                        temX[i] = bb.getDouble();
538
                                        temY[i] = bb.getDouble();
539
                                        //temZ[i] = bb.getDouble();
540
                                }
541
                                
542
                                for (i = 0; i < numPoints; i++) {
543
                                        temZ[i] = bb.getDouble();
544
                                }
545
                                return ShapeFactory.createMultipoint3D(temX, temY, temZ);
546
                }
547

    
548
                return null;
549
        }
550

    
551
        /**
552
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getShapeCount()
553
         */
554
        public int getShapeCount() {
555
                return numReg;
556
        }
557

    
558
        /**
559
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialDriver#getShapeType()
560
         */
561
        public int getShapeType() {
562
                int auxType = 0;
563

    
564
                switch (type) {
565
                        case (SHP.POINT2D):
566
                        case (SHP.POINT3D):
567
                                auxType = auxType | FShape.POINT;
568

    
569
                                break;
570

    
571
                        case (SHP.POLYLINE2D):
572
                        case (SHP.POLYLINE3D):
573
                                auxType = auxType | FShape.LINE;
574

    
575
                                break;
576

    
577
                        case (SHP.POLYGON2D):
578
                        case (SHP.POLYGON3D):
579
                                auxType = auxType | FShape.POLYGON;
580

    
581
                                break;
582
                        case (SHP.MULTIPOINT2D):
583
                        case (SHP.MULTIPOINT3D):
584
                                auxType = auxType | FShape.MULTIPOINT;
585

    
586
                                break;
587
                }
588

    
589
                return auxType;
590
        }
591

    
592

    
593
        /**
594
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#initialize()
595
         */
596
        public void initialize() throws IOException {
597
                // create a new header.
598
                ShapeFileHeader myHeader = new ShapeFileHeader();
599

    
600
                // read the header
601
                myHeader.readHeader(bb);
602

    
603
                extent = new Rectangle2D.Double(myHeader.myXmin, myHeader.myYmin,
604
                                myHeader.myXmax - myHeader.myXmin,
605
                                myHeader.myYmax - myHeader.myYmin);
606

    
607
                type = myHeader.myShapeType;
608

    
609
                double x = myHeader.myXmin;
610
                double y = myHeader.myYmin;
611
                double w = myHeader.myXmax - myHeader.myXmin;
612
                double h = myHeader.myYmax - myHeader.myYmin;
613

    
614
                if (w == 0) {
615
                        x -= 0.1;
616
                        w = 0.2;
617
                }
618

    
619
                if (h == 0) {
620
                        y -= 0.1;
621
                        h = 0.2;
622
                }
623

    
624
                // String strFichDbf = m_Path.toLowerCase().replaceAll("\\.shp", ".dbf");
625
                String strFichDbf = file.getAbsolutePath().replaceAll("\\.shp", ".dbf");
626
                strFichDbf = strFichDbf.replaceAll("\\.SHP", ".DBF");
627

    
628
                DbaseFileNIO m_FichDbf = new DbaseFileNIO();
629

    
630
                m_FichDbf.open(new File(strFichDbf));
631
                numReg = m_FichDbf.getRecordCount();
632
                m_posShapes = new long[numReg];
633

    
634
                // read the records.
635
                /* int tempCurrentLength = myHeader.getHeaderLength();
636
                int numReg = 0;
637

638
                long pos1;
639

640
                while (tempCurrentLength < myHeader.myFileLength) {
641
                        // read the record header
642
                        // ShapeFileRecord tempRecord = new ShapeFileRecord();
643
                        // Bytes 0 to 4 represent the record number in the file, these may be out of order.
644
                        bb.order(ByteOrder.BIG_ENDIAN);
645

646
                        // tempRecord.setIndex(in.readInt());
647
                        bb.getInt();
648

649
                        // read the content length of this record in 16 bit words, excluding the index.
650
                        // in.setLittleEndianMode(false);
651
                        int tempContentLength = bb.getInt();
652

653
                        pos1 = bb.position();
654

655
                        m_posShapes[numReg] = bb.position();
656

657
                        // Posicionamos
658
                        bb.position((pos1 + (2 * tempContentLength)));
659
                        numReg = numReg + 1;
660

661
                        // update the current length the 4 is for the index, and content length.
662
                        tempCurrentLength = tempCurrentLength + 4 + tempContentLength;
663
                } */
664
        }
665

    
666
        /**
667
         * Reads the Point from the shape file.
668
         *
669
         * @param in ByteBuffer.
670
         *
671
         * @return Point2D.
672
         */
673
        private Point2D.Double readPoint(BigByteBuffer in) {
674
                // create a new point
675
                Point2D.Double tempPoint = new Point2D.Double();
676

    
677
                // bytes 1 to 4 are the type and have already been read.
678
                // bytes 4 to 12 are the X coordinate
679
                in.order(ByteOrder.LITTLE_ENDIAN);
680
                tempPoint.setLocation(in.getDouble(), in.getDouble());
681

    
682
                return tempPoint;
683
        }
684

    
685
        /**
686
         * Lee un rect?ngulo del fichero.
687
         *
688
         * @param in ByteBuffer.
689
         *
690
         * @return Rect?ngulo.
691
         *
692
         * @throws IOException
693
         */
694
        private Rectangle2D.Double readRectangle(BigByteBuffer in)
695
                throws IOException {
696
                Rectangle2D.Double tempRect = new Rectangle2D.Double();
697
                in.order(ByteOrder.LITTLE_ENDIAN);
698
                tempRect.x = in.getDouble();
699
                tempRect.y = in.getDouble();
700

    
701
                tempRect.width = in.getDouble() - tempRect.x;
702

    
703
                if (tempRect.width == 0) {
704
                        tempRect.width = 0.2;
705
                        tempRect.x -= 0.1;
706
                }
707

    
708
                tempRect.height = in.getDouble() - tempRect.y;
709

    
710
                if (tempRect.height == 0) {
711
                        tempRect.height = 0.2;
712
                        tempRect.y -= 0.1;
713
                }
714

    
715
                return tempRect;
716
        }
717

    
718
        /**
719
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getFullExtent()
720
         */
721
        public Rectangle2D getFullExtent() throws IOException {
722
                return extent;
723
        }
724

    
725
        /**
726
         * Obtiene el extent del shape a partir de un ?ndice.
727
         *
728
         * @param index ?ndice.
729
         *
730
         * @return Rect?ngulo.
731
         *
732
         * @throws IOException
733
         *
734
         * @see com.iver.cit.gvsig.fmap.drivers.BoundedShapes#getShapeBounds()
735
         */
736
        public Rectangle2D getShapeBounds(int index) throws IOException {
737
                Point2D p = new Point2D.Double();
738
                Rectangle2D BoundingBox = new Rectangle2D.Double();
739
                bb.position(getPositionForRecord(index));
740
                bb.order(ByteOrder.LITTLE_ENDIAN);
741

    
742
                int tipoShape = bb.getInt();
743

    
744
                if (tipoShape != SHP.NULL) {
745
                        type = tipoShape;
746
                }
747

    
748
                // retrieve that shape.
749
                // tempRecord.setShape(readShape(tempShapeType, tempContentLength, in));
750
                switch (tipoShape) {
751
                        case (SHP.POINT2D):
752
                        case (SHP.POINT3D):
753
                                p = readPoint(bb);
754
                                BoundingBox = new Rectangle2D.Double(p.getX() - 0.1,
755
                                                p.getY() - 0.1, 0.2, 0.2);
756

    
757
                                break;
758

    
759
                        case (SHP.POLYLINE2D):
760
                        case (SHP.POLYGON2D):
761
                        case (SHP.MULTIPOINT2D):
762
                        case (SHP.POLYLINE3D):
763
                        case (SHP.POLYGON3D):
764
                        case (SHP.MULTIPOINT3D):
765

    
766
                                // BoundingBox
767
                                BoundingBox = readRectangle(bb);
768

    
769
                                break;
770
                }
771

    
772
                return BoundingBox;
773
        }
774

    
775
        /**
776
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#accept(java.io.File)
777
         */
778
        public boolean accept(File f) {
779
                return (f.getName().toUpperCase().endsWith("SHP"));
780
        }
781

    
782
        /**
783
         * @see com.hardcode.driverManager.Driver#getType()
784
         */
785
        public String getName() {
786
                return "gvSIG indexed shp driver";
787
        }
788

    
789
        /**
790
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getDataDriverName()
791
         */
792
        public String getDataDriverName() {
793
                return "gdbms dbf driver";
794
        }
795

    
796
        /**
797
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getDataFile(java.io.File)
798
         */
799
        public File getDataFile(File f) {
800
                String str = f.getAbsolutePath();
801

    
802
                return new File(str.substring(0, str.length() - 3) + "dbf");
803
        }
804

    
805
    public File getShxFile(File f) {
806
        String str = f.getAbsolutePath();
807

    
808
        return new File(str.substring(0, str.length() - 3) + "shx");
809
    }
810
    
811
    
812
        /* (non-Javadoc)
813
         * @see com.iver.cit.gvsig.fmap.drivers.BoundedShapes#getShapeType(int)
814
         */
815
        public int getShapeType(int index) {
816
                // Por ahora todos los fichero .shp contienen
817
                // entidades del mismo tipo. Si trabajamos con
818
                // alguno mixto, tendremos que cambiar esta funci?n.
819
                return getShapeType();
820
        }
821

    
822
    /* (non-Javadoc)
823
     * @see com.iver.cit.gvsig.fmap.drivers.VectorialDriver#getDriverAttributes()
824
     */
825
    public DriverAttributes getDriverAttributes() {
826
        // TODO Auto-generated method stub
827
        return null;
828
    }
829
    
830
    private long getPositionForRecord(int numRec)
831
    {
832
        // shx file has a 100 bytes header, then, records
833
        // 8 bytes length, one for each entity.
834
        // first 4 bytes are the offset
835
        // next 4 bytes are length
836
        
837
        int posIndex = 100 + (numRec * 8);
838
        // bbShx.position(posIndex);
839
        long pos = 8 + 2*bbShx.getInt(posIndex);
840
        
841
        return pos;
842
    }
843
}