Statistics
| Revision:

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

History | View | Annotate | Download (21.7 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
import com.iver.utiles.bigfile.BigByteBuffer2;
64

    
65

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

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

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

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

    
127
                fin = new FileInputStream(f);
128

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

    
132
                long size = channel.size();
133

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

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

    
143
        long sizeShx = channelShx.size();
144

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

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

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

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

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

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

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

    
350
                        case (SHP.POLYLINE2D):
351

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

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

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

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

    
372
                                j = 0;
373

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

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

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

    
388
                                return ShapeFactory.createPolyline2D(elShape);
389

    
390
                        case (SHP.POLYGON2D):
391

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

    
398
                                numParts = bb.getInt();
399

    
400
                                numPoints = bb.getInt();
401

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

    
406
                                tempParts = new int[numParts];
407

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

    
412
                                j = 0;
413

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

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

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

    
428
                                return ShapeFactory.createPolygon2D(elShape);
429

    
430
                        case (SHP.POINT3D):
431

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

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

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

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

    
449
                                j = 0;
450

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

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

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

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

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

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

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

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

    
487
                        j = 0;
488

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

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

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

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

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

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

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

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

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

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

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

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

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

    
549
                return null;
550
        }
551

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

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

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

    
570
                                break;
571

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

    
576
                                break;
577

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

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

    
587
                                break;
588
                }
589

    
590
                return auxType;
591
        }
592

    
593

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

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

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

    
608
                type = myHeader.myShapeType;
609

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

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

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

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

    
629
                DbaseFileNIO m_FichDbf = new DbaseFileNIO();
630

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

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

639
                long pos1;
640

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

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

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

654
                        pos1 = bb.position();
655

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

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

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

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

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

    
683
                return tempPoint;
684
        }
685

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

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

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

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

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

    
716
                return tempRect;
717
        }
718

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

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

    
743
                int tipoShape = bb.getInt();
744

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

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

    
758
                                break;
759

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

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

    
770
                                break;
771
                }
772

    
773
                return BoundingBox;
774
        }
775

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

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

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

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

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

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

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

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