Statistics
| Revision:

root / branches / Mobile_Compatible_Hito_1 / libFMap / src / es / prodevelop / gvsig / mobile / fmap / driver / vect / shp / MemoryShpDriver.java @ 21606

History | View | Annotate | Download (26.9 KB)

1
/* gvSIG. Sistema de Informai?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
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
42
 *
43
 * Copyright (C) 2006 Prodevelop and Generalitat Valenciana.
44
 *
45
 * This program is free software; you can redistribute it and/or
46
 * modify it under the terms of the GNU General Public License
47
 * as published by the Free Software Foundation; either version 2
48
 * of the License, or (at your option) any later version.
49
 *
50
 * This program is distributed in the hope that it will be useful,
51
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
52
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
53
 * GNU General Public License for more details.
54
 *
55
 * You should have received a copy of the GNU General Public License
56
 * along with this program; if not, write to the Free Software
57
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
58
 *
59
 * For more information, contact:
60
 *
61
 *   Generalitat Valenciana
62
 *   Conselleria d'Infraestructures i Transport
63
 *   Av. Blasco Ib??ez, 50
64
 *   46010 VALENCIA
65
 *   SPAIN
66
 *
67
 *   +34 963862235
68
 *   gvsig@gva.es
69
 *   http://www.gvsig.gva.es
70
 *
71
 *    or
72
 *
73
 *   Prodevelop Integraci?n de Tecnolog?as SL
74
 *   Conde Salvatierra de ?lava , 34-10
75
 *   46004 Valencia
76
 *   Spain
77
 *
78
 *   +34 963 510 612
79
 *   +34 963 510 968
80
 *   gis@prodevelop.es
81
 *   http://www.prodevelop.es
82
 *
83
 *    or
84
 *
85
 *   Instituto de Rob?tica
86
 *   Apartado de correos 2085
87
 *   46071 Valencia
88
 *   (Spain)
89
 *   
90
 *   +34 963 543 577
91
 *   jjordan@robotica.uv.es
92
 *   http://robotica.uv.es
93
 *   
94
 */
95

    
96
package es.prodevelop.gvsig.mobile.fmap.driver.vect.shp;
97

    
98
import java.awt.geom.Point2D;
99
import java.awt.geom.Rectangle2D;
100
import java.io.File;
101
import java.io.FileInputStream;
102
import java.io.IOException;
103
import java.nio.ByteOrder;
104
import java.util.ArrayList;
105

    
106
import org.apache.log4j.Logger;
107

    
108
import es.prodevelop.gvsig.mobile.fmap.core.FNullGeometry;
109
import es.prodevelop.gvsig.mobile.fmap.core.FShape;
110
import es.prodevelop.gvsig.mobile.fmap.core.GeneralPathX;
111
import es.prodevelop.gvsig.mobile.fmap.core.IGeometry;
112
import es.prodevelop.gvsig.mobile.fmap.core.ShapeFactory;
113
import es.prodevelop.gvsig.mobile.fmap.driver.BoundedShapes;
114
import es.prodevelop.gvsig.mobile.fmap.driver.ExternalData;
115
import es.prodevelop.gvsig.mobile.fmap.driver.ITableDefinition;
116
import es.prodevelop.gvsig.mobile.fmap.driver.VectorialFileDriver;
117
import es.prodevelop.gvsig.mobile.fmap.driver.vect.dbf.DbfMemoryDataSource;
118
import es.prodevelop.gvsig.mobile.fmap.layer.VectorialFileAdapter;
119
import es.prodevelop.gvsig.mobile.fmap.util.Utils;
120
import es.prodevelop.gvsig.mobile.fmap.util.bytebuffer.FalseByteBuffer;
121

    
122
/**
123
 * SHP driver for a file that is completely loaded into memory.
124
 * 
125
 * @see es.prodevelop.gvsig.mobile.fmap.util.bytebuffer.FalseByteBuffer
126
 * 
127
 * @author jldominguez
128
 */
129
public class MemoryShpDriver implements VectorialFileDriver, BoundedShapes,
130
        ExternalData {
131
        
132
        private static Logger logger = Logger.getLogger(MemoryShpDriver.class.getName());
133
        private static String tempDirectoryPath = System.getProperty("java.io.tmpdir");
134
        private File fileShp;
135
        private FalseByteBuffer bb;
136
        private FileInputStream fin;
137
        private int type;
138
        // private long[] m_posShapes;
139
        private int numReg = 0;
140
        private Rectangle2D extent;
141

    
142
    // private File shxFile;
143
    private FalseByteBuffer bbShx;
144
    private FileInputStream finShx;
145
    
146
    // point bound box tol:
147
    public static final double POINT_TOL = 0.000001;
148
    
149
    /**
150
     * @return gets the fiel path
151
     */
152
    public String getFilePath(){
153
            return fileShp.getAbsolutePath();
154
    }
155
    
156
        /**
157
         * Closes the file an dtries to preven memory leaks
158
         *
159
         * @throws IOException
160
         *
161
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#close()
162
         */
163
        public void close() throws IOException {
164
                
165
                try {
166
                        fin.close();
167
                } catch (IOException e1) {
168
                        logger.error("While closing file input stream: " + e1.getMessage());
169
                }
170
                bb = null;
171
                bbShx = null;
172
        }
173

    
174
        /**
175
         * Opens the file with using standard Java I/O system and loads it completely into memory
176
         * 
177
         * @param f the file to be opened
178
         * 
179
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#open(java.io.File)
180
         */
181
        public void open(File f) throws IOException {
182

    
183
                fileShp = f;
184

    
185
                fin = new FileInputStream(f);
186

    
187
                // Open the file and then get a channel from the stream
188
                // channel = fin.getChannel();
189
                // channel = FileChannelImpl.open(fin.getFD(), true, false, fin);
190

    
191
                // long size = channel.size();
192

    
193
                // Get the file's size and then map it into memory
194
                // bb = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
195
        // bb = ByteBuffer.allocate((int) f.length());
196
        bb = Utils.loadFileInputStream(fin, (int) f.length());
197
        // new BigByteBuffer2(channel, FileChannel.MapMode.READ_ONLY);
198

    
199
        File shxf = getShxFile(f);
200
        finShx = new FileInputStream(shxf);
201

    
202
        // Open the file and then get a channel from the stream
203
        // channelShx = finShx.getChannel();
204
        // channelShx = FileChannelImpl.open(finShx.getFD(), true, false, finShx);
205

    
206
        long sizeShx =  shxf.length();
207

    
208
        // Get the file's size and then map it into memory
209
        // bb = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
210
        // bbShx = channelShx.map(FileChannel.MapMode.READ_ONLY, 0, sizeShx);
211

    
212
        // bbShx = ByteBuffer.allocate((int) sizeShx); //2(channelShx, FileChannel.MapMode.READ_ONLY);
213
        
214
        bbShx = Utils.loadFileInputStream(finShx, (int) shxf.length());
215
        bbShx.setByteOrder(ByteOrder.BIG_ENDIAN);
216
        
217
        }
218

    
219
        /**
220
         * 
221
         *
222
         * @param index 
223
         *
224
         * @return 
225
         *
226
         * @throws IOException
227
         *
228
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getShape(int)
229
         */
230

    
231
        /* public FShape getShapeByID(int ID) {
232
           Point2D.Double p = new Point2D.Double();
233
           Point2D.Double pAnt = null;
234
           int numParts;
235
           int numPoints;
236
           int i;
237
           int j;
238
           int numReg;
239
           int numeroPuntos;
240
           int hasta;
241
           int desde;
242
           Rectangle2D.Double BoundingBox = new Rectangle2D.Double();
243

244
                   SHPShape shapeShp=null;
245
           FShape resulShape = null;
246
           try {
247
               bb.position(m_posShapes[ID]);
248
               bb.order(ByteOrder.LITTLE_ENDIAN);
249
               int tipoShape = bb.getInt();
250
               m_shapeType = tipoShape;
251
               // retrieve that shape.
252
               // tempRecord.setShape(readShape(tempShapeType, tempContentLength, in));
253
               if (tipoShape == FConstant.SHAPE_TYPE_POINT) {
254
                   p = readPoint(bb);
255
                   resulShape = new FShape(new FPoint(p.getX(),p.getY()),FConstant.SHAPE_TYPE_POINT);
256
                   //Comprobaci?n punto.
257
                   //System.err.println("p.x = "+p.x);
258
                   //System.err.println("p.y = "+p.y);
259

260
               } else if ((tipoShape == FConstant.SHAPE_TYPE_POLYLINE) ||
261
                       (tipoShape == FConstant.SHAPE_TYPE_POLYGON)) {
262
                   // BoundingBox
263
                   BoundingBox = readRectangle(bb);
264
                   numParts = bb.getInt();
265
                   numPoints = bb.getInt();
266
                   // part indexes.
267
                   // Geometry geom = GeometryFactory.toGeometryArray();
268
                   GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
269
                           numPoints);
270
                   int[] tempParts = new int[numParts];
271
                   for (i = 0; i < numParts; i++) {
272
                       tempParts[i] = bb.getInt();
273
                   }
274
                   j = 0;
275
                   ///Line2D.Double line2D;
276
                   FPoint[] points=new FPoint[numPoints];
277
                   for (i = 0; i < numPoints; i++) {
278
                           p=readPoint(bb);
279
                       points[i] = new FPoint(p.x,p.y);
280
                       // System.out.println("x= " + p.x + " y=" + p.y);
281
                       // System.out.println("x= " + (float) p.x + " y=" + (float) p.y);
282
                       if (i == tempParts[j]) {
283
                           elShape.moveTo(p.x, p.y);
284
                           if (j < (numParts - 1)) {
285
                               j++;
286
                           }
287
                       } else {
288
                           elShape.lineTo(p.x, p.y);
289
                       }
290
                   }
291
                   //FGeometry pol=new FPolyLine(points,tempParts,BoundingBox);
292

293
                   resulShape = new FShape(tipoShape,elShape);
294
               } else if (tipoShape == FConstant.SHAPE_TYPE_MULTIPOINT) {
295
                   // BoundingBox
296
                   BoundingBox = readRectangle(bb);
297
                   numPoints = bb.getInt();
298
                   FPoint[] tempPoints = new FPoint[numPoints];
299
                   for (i = 0; i < numPoints; i++) {
300
                           Point2D p2=readPoint(bb);
301
                       tempPoints[i] = new FPoint(p2.getX(),p2.getY(),0);
302
                   }
303
                   FMultiPoint multipoint = new FMultiPoint(tempPoints,BoundingBox);
304
                   resulShape = new FShape(multipoint,tipoShape);
305
               } else if (tipoShape == FConstant.SHAPE_TYPE_POINTZ) {
306
                   FPoint p3d = new FPoint();
307
                   p3d.read(bb);
308
                   resulShape = new FShape(p3d,tipoShape);
309
               } else if ((tipoShape == FConstant.SHAPE_TYPE_POLYLINEZ) ||
310
                       (tipoShape == FConstant.SHAPE_TYPE_POLYGONZ)) {
311
                   // BoundingBox
312
                   BoundingBox = readRectangle(bb);
313
                   numParts = bb.getInt();
314
                   numPoints = bb.getInt();
315
                   // part indexes.
316
                   // Geometry geom = GeometryFactory.toGeometryArray();
317

318
                   GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
319
                           numPoints);
320
                   int[] tempParts = new int[numParts];
321
                   for (i = 0; i < numParts; i++) {
322
                       tempParts[i] = bb.getInt();
323
                   }
324
                   j = 0;
325
                  //Line2D.Double line2D;
326
                   FPoint[] points=new FPoint[numPoints];
327
                   for (i = 0; i < numPoints; i++) {
328
                       p = readPoint(bb);
329
                       points[i]=new FPoint(p.x,p.y);
330

331
                       if (i == tempParts[j]) {
332
                           elShape.moveTo(p.x, p.y);
333
                           if (j < (numParts - 1)) {
334
                               j++;
335
                           }
336
                       } else {
337
                           elShape.lineTo(p.x, p.y);
338
                       }
339

340
                   }
341

342
                   double[] boxZ = new double[2];
343
                   boxZ[0] = bb.getDouble();
344
                   boxZ[1] = bb.getDouble();
345
                   double[] pZ = new double[numPoints];
346
                   for (i = 0; i < numPoints; i++) {
347
                       pZ[i] = bb.getDouble();
348
                   }
349
                   //FGeometry pol=new FPolyLine(points,tempParts,BoundingBox);
350
                   resulShape = new FShape(tipoShape, elShape, pZ);
351
               } else if (tipoShape == FConstant.SHAPE_TYPE_MULTIPOINTZ) {
352
                   // BoundingBox
353
                   BoundingBox = readRectangle(bb);
354
                   numPoints = bb.getInt();
355
                   FPoint[] tempPoints3D = new FPoint[numPoints];
356
                   for (i = 0; i < numPoints; i++) {
357
                       tempPoints3D[i] = new FPoint();
358
                       tempPoints3D[i].read(bb);
359
                   }
360
                   FMultiPoint multipoint3D = new FMultiPoint(tempPoints3D,BoundingBox);
361
                   resulShape = new FShape(multipoint3D,tipoShape);
362
               }
363
           } catch (Exception e) {
364
               System.err.println("Fallo en getShapeByID. ID=" + ID +
365
                   " m_posShapes[ID]=" + m_posShapes[ID]);
366
               System.err.println("getShapeByID: " + e.getMessage());
367
               e.printStackTrace();
368
           }
369
           return resulShape;
370
           }
371
         */
372
        
373
        /**
374
         * Gets the geometry for an index
375
         *
376
         * @param index index of the geometry of interest
377
         *
378
         * @return the geometry 
379
         *
380
         * @throws IOException 
381
         */
382
        public IGeometry getShape(int index) throws IOException {
383
                
384
                Point2D.Double p = new Point2D.Double();
385
                int numParts;
386
                int numPoints;
387
                int i;
388
                int j;
389
                int shapeType;
390

    
391
                //Rectangle2D.Double BoundingBox;
392
        // if (m_posShapes[index] == 0)
393

    
394
                // bb.position(m_posShapes[index]);
395
        bb.position(getPositionForRecord(index));
396
                bb.setByteOrder(ByteOrder.LITTLE_ENDIAN);
397

    
398
                ///bb.position(bb.position()+4);
399
                shapeType = bb.getInt();
400
                //el shape tal con tema tal y n?mro tal es null
401
                if (shapeType==SHP.SHPT_NULL){
402
                        logger.warn("Found a null geometry in file " + fileShp.getName() + " (shape index: " + index);
403
                        return new FNullGeometry();
404
                }
405

    
406
                // retrieve that shape.
407
                // tempRecord.setShape(readShape(tempShapeType, tempContentLength, in));
408
                switch (type) {
409
                
410
                case SHP.SHPT_POINT:
411
                                p = readPoint(bb);
412

    
413
                                return ShapeFactory.createPoint2D(p.getX(), p.getY());
414

    
415
                case SHP.SHPT_ARC:
416

    
417
                                //BoundingBox = readRectangle(bb);
418
                                //bb.getDouble();
419
                                //bb.getDouble();
420
                                //bb.getDouble();
421
                                //bb.getDouble();
422
                                bb.position(bb.getPosition() + 32);
423
                                numParts = bb.getInt();
424
                                numPoints = bb.getInt();
425

    
426
                                // part indexes.
427
                                // Geometry geom = GeometryFactory.toGeometryArray();
428
                                GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
429
                                                numPoints);
430

    
431
                                int[] tempParts = new int[numParts];
432

    
433
                                for (i = 0; i < numParts; i++) {
434
                                        tempParts[i] = bb.getInt();
435
                                }
436

    
437
                                j = 0;
438

    
439
                                for (i = 0; i < numPoints; i++) {
440
                                        p = readPoint(bb);
441

    
442
                                        if (i == tempParts[j]) {
443
                                                elShape.moveTo(p.x, p.y);
444

    
445
                                                if (j < (numParts - 1)) {
446
                                                        j++;
447
                                                }
448
                                        } else {
449
                                                elShape.lineTo(p.x, p.y);
450
                                        }
451
                                }
452

    
453
                                return ShapeFactory.createPolyline2D(elShape);
454

    
455
                        case SHP.SHPT_POLYGON:
456

    
457
                                //                            BoundingBox = readRectangle(bb);
458
                                bb.getDouble();
459
                                bb.getDouble();
460
                                bb.getDouble();
461
                                bb.getDouble();
462

    
463
                                numParts = bb.getInt();
464

    
465
                                numPoints = bb.getInt();
466

    
467
                                // part indexes.
468
                                // Geometry geom = GeometryFactory.toGeometryArray();
469
                                elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
470

    
471
                                tempParts = new int[numParts];
472

    
473
                                for (i = 0; i < numParts; i++) {
474
                                        tempParts[i] = bb.getInt();
475
                                }
476

    
477
                                j = 0;
478

    
479
                                for (i = 0; i < numPoints; i++) {
480
                                        p = readPoint(bb);
481

    
482
                                        if (i == tempParts[j]) {
483
                                                elShape.moveTo(p.x, p.y);
484

    
485
                                                if (j < (numParts - 1)) {
486
                                                        j++;
487
                                                }
488
                                        } else {
489
                                                elShape.lineTo(p.x, p.y);
490
                                        }
491
                                }
492

    
493
                                return ShapeFactory.createPolygon2D(elShape);
494

    
495
                        case SHP.SHPT_POINTZ:
496
                        case SHP.SHPT_POINTM:
497

    
498
                                double x = bb.getDouble();
499
                                double y = bb.getDouble();
500
                                double z = bb.getDouble();
501

    
502
                                return ShapeFactory.createPoint3D(x, y, z);
503

    
504
                        case SHP.SHPT_ARCZ:
505
                        case SHP.SHPT_ARCM:
506
                                bb.position(bb.getPosition() + 32);
507
                                numParts = bb.getInt();
508
                                numPoints = bb.getInt();
509
                                elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
510
                                tempParts = new int[numParts];
511

    
512
                                for (i = 0; i < numParts; i++) {
513
                                        tempParts[i] = bb.getInt();
514
                                }
515

    
516
                                j = 0;
517

    
518
                                for (i = 0; i < numPoints; i++) {
519
                                        p = readPoint(bb);
520

    
521
                                        if (i == tempParts[j]) {
522
                                                elShape.moveTo(p.x, p.y);
523

    
524
                                                if (j < (numParts - 1)) {
525
                                                        j++;
526
                                                }
527
                                        } else {
528
                                                elShape.lineTo(p.x, p.y);
529
                                        }
530
                                }
531

    
532
                                double[] boxZ = new double[2];
533
                                boxZ[0] = bb.getDouble();
534
                                boxZ[1] = bb.getDouble();
535

    
536
                                double[] pZ = new double[numPoints];
537

    
538
                                for (i = 0; i < numPoints; i++) {
539
                                        pZ[i] = bb.getDouble();
540
                                }
541

    
542
                                return ShapeFactory.createPolyline3D(elShape, pZ);
543
                                
544
                        case SHP.SHPT_POLYGONZ:
545
                        case SHP.SHPT_POLYGONM:
546
                                
547
                        bb.position(bb.getPosition() + 32);
548
                        numParts = bb.getInt();
549
                        numPoints = bb.getInt();
550
                        elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
551
                        tempParts = new int[numParts];
552

    
553
                        for (i = 0; i < numParts; i++) {
554
                                tempParts[i] = bb.getInt();
555
                        }
556

    
557
                        j = 0;
558

    
559
                        for (i = 0; i < numPoints; i++) {
560
                                p = readPoint(bb);
561

    
562
                                if (i == tempParts[j]) {
563
                                        elShape.moveTo(p.x, p.y);
564

    
565
                                        if (j < (numParts - 1)) {
566
                                                j++;
567
                                        }
568
                                } else {
569
                                        elShape.lineTo(p.x, p.y);
570
                                }
571
                        }
572

    
573
                        double[] boxpoZ = new double[2];
574
                        boxpoZ[0] = bb.getDouble();
575
                        boxpoZ[1] = bb.getDouble();
576

    
577
                        double[] poZ = new double[numPoints];
578

    
579
                        for (i = 0; i < numPoints; i++) {
580
                                poZ[i] = bb.getDouble();
581
                        }
582

    
583
                        return ShapeFactory.createPolygon3D(elShape, poZ);
584

    
585
                        case SHP.SHPT_MULTIPOINT:
586
                                bb.position(bb.getPosition() + 32);
587
                                numPoints = bb.getInt();
588

    
589
                                double[] tempX = new double[numPoints];
590
                                double[] tempY = new double[numPoints];
591

    
592
                                for (i = 0; i < numPoints; i++) {
593
                                        tempX[i] = bb.getDouble();
594
                                        tempY[i] = bb.getDouble();
595
                                }
596

    
597
                                return ShapeFactory.createMultipoint2D(tempX, tempY);
598

    
599
                        case SHP.SHPT_MULTIPOINTZ:
600
                        case SHP.SHPT_MULTIPOINTM:
601
                                bb.position(bb.getPosition() + 32);
602
                                numPoints = bb.getInt();
603

    
604
                                double[] temX = new double[numPoints];
605
                                double[] temY = new double[numPoints];
606
                                double[] temZ = new double[numPoints];
607

    
608
                                for (i = 0; i < numPoints; i++) {
609
                                        temX[i] = bb.getDouble();
610
                                        temY[i] = bb.getDouble();
611
                                        //temZ[i] = bb.getDouble();
612
                                }
613

    
614
                                for (i = 0; i < numPoints; i++) {
615
                                        temZ[i] = bb.getDouble();
616
                                }
617
                                return ShapeFactory.createMultipoint3D(temX, temY, temZ);
618
                }
619

    
620
                return null;
621
        }
622

    
623
        /**
624
         * @return the number of geometries in this driver
625
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getShapeCount()
626
         */
627
        public int getShapeCount() {
628
                return numReg;
629
        }
630

    
631
        /**
632
         * @return the shape type of the geometries of this driver
633
         * 
634
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialDriver#getShapeType()
635
         */
636
        public int getShapeType() {
637
                int auxType = 0;
638

    
639
                switch (type) {
640
                case SHP.SHPT_POINT:
641
                case SHP.SHPT_POINTZ:
642
                case SHP.SHPT_POINTM:
643
                                auxType = auxType | FShape.POINT;
644

    
645
                                break;
646

    
647
                        case SHP.SHPT_ARC:
648
                        case SHP.SHPT_ARCZ:
649
                        case SHP.SHPT_ARCM:
650
                                auxType = auxType | FShape.LINE;
651

    
652
                                break;
653

    
654
                        case SHP.SHPT_POLYGON:
655
                        case SHP.SHPT_POLYGONZ:
656
                        case SHP.SHPT_POLYGONM:
657
                                auxType = auxType | FShape.POLYGON;
658

    
659
                                break;
660
                        case SHP.SHPT_MULTIPOINT:
661
                        case SHP.SHPT_MULTIPOINTZ:
662
                        case SHP.SHPT_MULTIPOINTM:
663
                                auxType = auxType | FShape.MULTIPOINT;
664

    
665
                                break;
666
                }
667

    
668
                return auxType;
669
        }
670

    
671

    
672
        /**
673
         * Initializes the driver
674
         * 
675
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#initialize()
676
         */
677
        public void initialize() throws IOException {
678
                // logger.debug(Utils.time() + "Empieza initialize() del driver shp.");
679

    
680
                ShapeFileHeader myHeader = new ShapeFileHeader();
681
                bb.position(0);
682

    
683
                // read the header
684
                // logger.debug(Utils.time() + "Leer header:");
685
                myHeader.readHeader(bb);
686
                
687
                // logger.debug(Utils.time() + "Leer header, done");
688

    
689
                extent = new Rectangle2D.Double(myHeader.myXmin, myHeader.myYmin,
690
                                myHeader.myXmax - myHeader.myXmin,
691
                                myHeader.myYmax - myHeader.myYmin);
692

    
693
                type = myHeader.myShapeType;
694

    
695
                double x = myHeader.myXmin;
696
                double y = myHeader.myYmin;
697
                double w = myHeader.myXmax - myHeader.myXmin;
698
                double h = myHeader.myYmax - myHeader.myYmin;
699

    
700
                if (w == 0) {
701
                        x -= 0.1;
702
                        w = 0.2;
703
                }
704

    
705
                if (h == 0) {
706
                        y -= 0.1;
707
                        h = 0.2;
708
                }
709
                
710
                boolean done = false;
711

    
712
                File dbf_file = getDataFile(fileShp);
713
                DbfMemoryDataSource dbf_ds = new DbfMemoryDataSource(dbf_file);
714
                
715
                try {
716
                        dbf_ds.start();
717
                        numReg = (int) dbf_ds.getRowCount();
718
                        dbf_ds.stop();
719
                        
720
                        done = true;
721
                } catch (Exception ex) {
722
                        logger.error("While getting row count: " + ex.getMessage());
723
                }
724
                
725
                if (done) {
726
                        // logger.debug("NUMREG del DBF: " + numReg);
727
                } else {
728
                        logger.debug("No se ha obtenido NUMREG, vale 0");
729
                        numReg = 0;
730
                }
731

    
732
                /*
733
                logger.debug(Utils.time() + "Intentando: ShpReader.openShpFile()");
734
                
735
                long aux_handler = ShpReader.openShpFile(fileShp.getAbsolutePath(), false);
736
                
737
                logger.debug(Utils.time()
738
                                + "Intentando: ShpReader.openShpFile(), aux_handler = " + aux_handler);
739
                
740
                try {
741
                        double[] meta = ShpReader.getShpMetadata(aux_handler);
742
                        numReg = Math.round((float) meta[5]);
743
                        ShpReader.closeShpFile(aux_handler);
744
                        done = true;
745
                } catch (Throwable th) {
746
                        logger.error(
747
                                        Utils.time()
748
                                        + "NUMREG, openShpFile(...), getShpMetadata(...) HA FALLADO: "
749
                                        + th.getMessage());
750
                }
751
                
752
                if (done) {
753
                        logger.debug("Se ha obtenido NUMREG = " + numReg);
754
                        return;
755
                }
756
                
757
                String dbfpath = getDataFilePath(fileShp);
758
                
759
                try {
760
                        aux_handler = ShpReader.openDbfFile(dbfpath, false);
761
                        numReg = ShpReader.getDbfFileRowCount(aux_handler);
762
                        ShpReader.closeDbfFile(aux_handler);
763
                        done = true;
764
                } catch (Throwable th) {
765
                        logger.error(
766
                                        Utils.time() + "NUMREG, openDbfFile(...), TAMBIEN HA FALLADO: "
767
                                        + th.getMessage());
768
                }
769
                */
770
        }
771

    
772
        /**
773
         * Reads a Point from the shape file.
774
         *
775
         * @param in ByteBuffer.
776
         *
777
         * @return Point2D.
778
         */
779
        private synchronized Point2D.Double readPoint(FalseByteBuffer in) {
780
                // create a new point
781
                Point2D.Double tempPoint = new Point2D.Double();
782

    
783
                // bytes 1 to 4 are the type and have already been read.
784
                // bytes 4 to 12 are the X coordinate
785
                in.setByteOrder(ByteOrder.LITTLE_ENDIAN);
786
                tempPoint.setLocation(in.getDouble(), in.getDouble());
787

    
788
                return tempPoint;
789
        }
790

    
791
        /**
792
         * Lee un rect?ngulo del fichero.
793
         *
794
         * @param in ByteBuffer.
795
         *
796
         * @return Rect?ngulo.
797
         *
798
         * @throws IOException
799
         */
800
        private synchronized Rectangle2D.Double readRectangle(FalseByteBuffer in)
801
                throws IOException {
802
                Rectangle2D.Double tempRect = new Rectangle2D.Double();
803
                in.setByteOrder(ByteOrder.LITTLE_ENDIAN);
804
                tempRect.x = in.getDouble();
805
                tempRect.y = in.getDouble();
806

    
807
                tempRect.width = in.getDouble() - tempRect.x;
808

    
809
                if (tempRect.width == 0) {
810
                        tempRect.width = 0.2;
811
                        tempRect.x -= 0.1;
812
                }
813

    
814
                tempRect.height = in.getDouble() - tempRect.y;
815

    
816
                if (tempRect.height == 0) {
817
                        tempRect.height = 0.2;
818
                        tempRect.y -= 0.1;
819
                }
820

    
821
                return tempRect;
822
        }
823

    
824
        /**
825
         * Gets the extent of the geometries of this driver
826
         * 
827
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getFullExtent()
828
         */
829
        public Rectangle2D getFullExtent() throws IOException {
830
                return extent;
831
        }
832

    
833
        /**
834
         * Gets the extent of one geometry of this driver.
835
         * 
836
         * @param index the index of the geometry of interest
837
         * @return the bounding box of the geometry
838
         */
839
        public Rectangle2D getShapeBounds(int index) throws IOException {
840
                Point2D p = new Point2D.Double();
841
                Rectangle2D BoundingBox = new Rectangle2D.Double();
842
                bb.position(getPositionForRecord(index));
843
                bb.setByteOrder(ByteOrder.LITTLE_ENDIAN);
844

    
845
                int tipoShape = bb.getInt();
846

    
847
                //AZABALA: si tipoShape viene con valores erroneos deja de funcionar
848
                //el metodo getShape(i)
849
//                if (tipoShape != SHP.NULL) {
850
//                        type = tipoShape;
851
//
852
//                }
853

    
854
                // retrieve that shape.
855
                // tempRecord.setShape(readShape(tempShapeType, tempContentLength, in));
856
                switch (tipoShape) {
857
                
858
                        case SHP.SHPT_POINT:
859
                        case SHP.SHPT_POINTZ:
860
                        case SHP.SHPT_POINTM:
861
                                p = readPoint(bb);
862
                                BoundingBox = new Rectangle2D.Double(p.getX() - POINT_TOL,
863
                                                p.getY() - POINT_TOL, 2 * POINT_TOL, 2 * POINT_TOL);
864

    
865
                                break;
866

    
867
                        case SHP.SHPT_ARC:
868
                        case SHP.SHPT_ARCZ:
869
                        case SHP.SHPT_ARCM:
870
                        case SHP.SHPT_MULTIPOINT:
871
                        case SHP.SHPT_MULTIPOINTZ:
872
                        case SHP.SHPT_MULTIPOINTM:
873
                        case SHP.SHPT_POLYGON:
874
                        case SHP.SHPT_POLYGONZ:
875
                        case SHP.SHPT_POLYGONM:
876
                        default:
877
                                // BoundingBox
878
                                try {
879
                                        BoundingBox = readRectangle(bb);
880
                                } catch (IOException e) {
881
                                        logger.error("Al calcular BB: " + e.getMessage());
882
                                        BoundingBox = null;
883
                                }
884

    
885
                                break;
886
                        
887
                }
888

    
889
                return BoundingBox;
890
        }
891

    
892
        /**
893
         * Says whether a file is a SHP file.
894
         * 
895
         * @param f the file of interest
896
         * @return whether it is a valid SHP file
897
         */
898
        public boolean accept(File f) {
899
                return (f.getName().toUpperCase().endsWith("SHP"));
900
        }
901

    
902
        /**
903
         * Gets the driver name
904
         */
905
        public String getName() {
906
                return "gvSIG SHP driver";
907
        }
908

    
909
        /**
910
         * @return the name of the associated data driver (DBF in this case)
911
         */
912
        public String getDataDriverName() {
913
                return VectorialFileAdapter.DBF_FILE_DATASOURCE;
914
        }
915

    
916
        /**
917
         * Gets the data file (attributes file, in this case a DBF file)
918
         * that corresponds to the given SHP file
919
         */
920
        public File getDataFile(File f) {
921
                String str = f.getAbsolutePath();
922
                return new File(str.substring(0, str.length() - 3) + "dbf");
923
        }
924

    
925
        /**
926
         * Gets the associated SHX file
927
         * 
928
         * @param f a certain SHP file
929
         * @return the associated SHX file
930
         */
931
    public File getShxFile(File f) {
932
        String str = f.getAbsolutePath();
933
        return new File(str.substring(0, str.length() - 3) + "shx");
934
    }
935

    
936

    
937
    /**
938
     * Gets the shape type of the geometry of interest. Redirects to
939
     * <code>getShapeType()</code> 
940
     * 
941
     * @param index the index of the geometry of interest
942
     * @return the type of the geometry of interest.
943
     * 
944
     */
945
        public int getShapeType(int index) {
946
                // Por ahora todos los fichero .shp contienen
947
                // entidades del mismo tipo. Si trabajamos con
948
                // alguno mixto, tendremos que cambiar esta funci?n.
949
                return getShapeType();
950
        }
951

    
952
    private synchronized int getPositionForRecord(int numRec)
953
    {
954
        // shx file has a 100 bytes header, then, records
955
        // 8 bytes length, one for each entity.
956
        // first 4 bytes are the offset
957
        // next 4 bytes are length
958

    
959
        int posIndex = 100 + (numRec * 8);
960
        // bbShx.position(posIndex);
961
        int pos = 8 + 2*bbShx.getInt(posIndex);
962

    
963
        return pos;
964
    }
965

    
966
    /**
967
     * Gets the main SHP file object.
968
     * @return the main file object
969
     */
970
        public File getFile() {
971
                return fileShp;
972
        }
973

    
974
        /**
975
         * Reloads the driver (reopens file and initializes)
976
         */
977
        public void reload() throws IOException {
978
                open(fileShp);
979
                initialize();
980
        }
981

    
982
        /**
983
         * Initializes the driver 
984
         * 
985
         * @param layerDef the table definition to initialize the driver
986
         * 
987
         */
988
        public void initialize(ITableDefinition layerDef) {
989
        }
990

    
991

    
992
        /**
993
         * @return whether this driver is writable.
994
         */
995
        public boolean isWritable() {
996
                return fileShp.canWrite();
997
        }
998

    
999
        /**
1000
         * @return whether this driver's table can be altered 
1001
         *
1002
         */
1003
        public boolean canAlterTable() {
1004
                return false;
1005
        }
1006

    
1007
        
1008

    
1009
        /**
1010
         * Unused.
1011
         */
1012
        public boolean isWriteAll() {
1013
                return true;
1014
        }
1015

    
1016
        
1017
        /**
1018
         * Gets the indices of the geometries intersecting the given rectangle
1019
         * 
1020
         * @param rect the rectangle of interest
1021
         * @param max the maximum number of indices to be returned
1022
         */
1023
        public int[] getIntersectingIndices(Rectangle2D rect, int max) throws IOException {
1024
                
1025
                ArrayList _resp = new ArrayList();
1026
                for (int i=0; i<numReg; i++) {
1027
                        if (Utils.rectanglesItersect(getShapeBounds(i), rect)) {
1028
                                IGeometry ig = getShape(i);
1029
                                if (ig.getGeometryType() == FShape.POINT || ig.intersects(rect)) {
1030
                                        _resp.add(new Integer(i));
1031
                                        // logger.debug("Ha intersectado uno!");
1032
                                        if (_resp.size() == max) {
1033
                                                break;
1034
                                        }
1035
                                }
1036
                        }
1037
                }
1038
                int size = _resp.size();
1039
                
1040
                if (size == 0) return null;
1041

    
1042
                int[] resp = new int[size];
1043
                for (int i=0; i<size; i++) resp[i] = ((Integer) _resp.get(i)).intValue();
1044
                return resp;
1045
        }
1046

    
1047
}