Statistics
| Revision:

root / branches / Mobile_Compatible_Hito_1 / libFMap_mobile_shp_driver / src-file / org / gvsig / data / datastores / vectorial / file / shp_mem / simplify / MemoryShpDriver.java @ 22037

History | View | Annotate | Download (24.4 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 org.gvsig.data.datastores.vectorial.file.shp_mem.simplify;
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
import org.gvsig.data.datastores.vectorial.file.shp_util.FalseByteBuffer;
108
import org.gvsig.data.datastores.vectorial.file.shp_util.SHP;
109
import org.gvsig.data.datastores.vectorial.file.shp_util.Utils;
110
import org.gvsig.fmap.geom.Geometry;
111
import org.gvsig.fmap.geom.GeometryFactory;
112
import org.gvsig.fmap.geom.GeometryManager;
113
import org.gvsig.fmap.geom.primitive.FShape;
114
import org.gvsig.fmap.geom.primitive.GeneralPathX;
115
import org.gvsig.fmap.geom.primitive.NullGeometry;
116

    
117
/**
118
 * SHP driver for a file that is completely loaded into memory.
119
 * 
120
 * @see es.prodevelop.gvsig.mobile.fmap.util.bytebuffer.FalseByteBuffer
121
 * 
122
 * @author jldominguez
123
 */
124
public class MemoryShpDriver {
125

    
126
        private static Logger logger = Logger.getLogger(MemoryShpDriver.class
127
                        .getName());
128

    
129
        private static String tempDirectoryPath = System
130
                        .getProperty("java.io.tmpdir");
131
        
132
        private File fileShp;
133

    
134
        private FalseByteBuffer bb;
135

    
136
        private FileInputStream fin;
137

    
138
        private int type;
139

    
140
        // private long[] m_posShapes;
141
        private int numReg = 0;
142

    
143
        private Rectangle2D extent;
144

    
145
        // private File shxFile;
146
        private FalseByteBuffer bbShx;
147

    
148
        private FileInputStream finShx;
149

    
150
        // point bound box tol:
151
        public static final double POINT_TOL = 0.000001;
152
        
153
        private boolean featInMem = false;
154
        
155
        /**
156
         * @return gets the fiel path
157
         */
158
        public String getFilePath() {
159
                return fileShp.getAbsolutePath();
160
        }
161

    
162
        /**
163
         * Closes the file an dtries to preven memory leaks
164
         * 
165
         * @throws IOException
166
         * 
167
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#close()
168
         */
169
        public void close() throws IOException {
170

    
171
                try {
172
                        fin.close();
173
                } catch (IOException e1) {
174
                        logger.error("While closing file input stream: " + e1.getMessage());
175
                }
176
                bb = null;
177
                bbShx = null;
178
        }
179

    
180
        /**
181
         * Opens the file with using standard Java I/O system and loads it
182
         * completely into memory
183
         * 
184
         * @param f
185
         *            the file to be opened
186
         * 
187
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#open(java.io.File)
188
         */
189
        public void open(File f) throws IOException {
190

    
191
                fileShp = f;
192

    
193
                fin = new FileInputStream(f);
194

    
195
                // Open the file and then get a channel from the stream
196
                // channel = fin.getChannel();
197
                // channel = FileChannelImpl.open(fin.getFD(), true, false, fin);
198

    
199
                // long size = channel.size();
200

    
201
                // Get the file's size and then map it into memory
202
                // bb = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
203
                // bb = ByteBuffer.allocate((int) f.length());
204
                bb = Utils.loadFileInputStream(fin, (int) f.length());
205
                // new BigByteBuffer2(channel, FileChannel.MapMode.READ_ONLY);
206

    
207
                File shxf = getShxFile(f);
208
                finShx = new FileInputStream(shxf);
209

    
210
                // Open the file and then get a channel from the stream
211
                // channelShx = finShx.getChannel();
212
                // channelShx = FileChannelImpl.open(finShx.getFD(), true, false,
213
                // finShx);
214

    
215
                long sizeShx = shxf.length();
216

    
217
                // Get the file's size and then map it into memory
218
                // bb = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
219
                // bbShx = channelShx.map(FileChannel.MapMode.READ_ONLY, 0, sizeShx);
220

    
221
                // bbShx = ByteBuffer.allocate((int) sizeShx); //2(channelShx,
222
                // FileChannel.MapMode.READ_ONLY);
223

    
224
                bbShx = Utils.loadFileInputStream(finShx, (int) shxf.length());
225
                bbShx.setByteOrder(ByteOrder.BIG_ENDIAN);
226

    
227
        }
228

    
229
        /**
230
         * 
231
         * 
232
         * @param index
233
         * 
234
         * @return
235
         * 
236
         * @throws IOException
237
         * 
238
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getShape(int)
239
         */
240

    
241
        /*
242
         * public FShape getShapeByID(int ID) { Point2D.Double p = new
243
         * Point2D.Double(); Point2D.Double pAnt = null; int numParts; int
244
         * numPoints; int i; int j; int numReg; int numeroPuntos; int hasta; int
245
         * desde; Rectangle2D.Double BoundingBox = new Rectangle2D.Double();
246
         * 
247
         * SHPShape shapeShp=null; FShape resulShape = null; try {
248
         * bb.position(m_posShapes[ID]); bb.order(ByteOrder.LITTLE_ENDIAN); int
249
         * tipoShape = bb.getInt(); m_shapeType = tipoShape; // retrieve that shape. //
250
         * tempRecord.setShape(readShape(tempShapeType, tempContentLength, in)); if
251
         * (tipoShape == FConstant.SHAPE_TYPE_POINT) { p = readPoint(bb); resulShape =
252
         * new FShape(new FPoint(p.getX(),p.getY()),FConstant.SHAPE_TYPE_POINT);
253
         * //Comprobaci?n punto. //System.err.println("p.x = "+p.x);
254
         * //System.err.println("p.y = "+p.y);
255
         *  } else if ((tipoShape == FConstant.SHAPE_TYPE_POLYLINE) || (tipoShape ==
256
         * FConstant.SHAPE_TYPE_POLYGON)) { // BoundingBox BoundingBox =
257
         * readRectangle(bb); numParts = bb.getInt(); numPoints = bb.getInt(); //
258
         * part indexes. // Geometry geom = GeometryFactory.toGeometryArray();
259
         * GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
260
         * numPoints); int[] tempParts = new int[numParts]; for (i = 0; i <
261
         * numParts; i++) { tempParts[i] = bb.getInt(); } j = 0; ///Line2D.Double
262
         * line2D; FPoint[] points=new FPoint[numPoints]; for (i = 0; i < numPoints;
263
         * i++) { p=readPoint(bb); points[i] = new FPoint(p.x,p.y); //
264
         * System.out.println("x= " + p.x + " y=" + p.y); // System.out.println("x= " +
265
         * (float) p.x + " y=" + (float) p.y); if (i == tempParts[j]) {
266
         * elShape.moveTo(p.x, p.y); if (j < (numParts - 1)) { j++; } } else {
267
         * elShape.lineTo(p.x, p.y); } } //FGeometry pol=new
268
         * FPolyLine(points,tempParts,BoundingBox);
269
         * 
270
         * resulShape = new FShape(tipoShape,elShape); } else if (tipoShape ==
271
         * FConstant.SHAPE_TYPE_MULTIPOINT) { // BoundingBox BoundingBox =
272
         * readRectangle(bb); numPoints = bb.getInt(); FPoint[] tempPoints = new
273
         * FPoint[numPoints]; for (i = 0; i < numPoints; i++) { Point2D
274
         * p2=readPoint(bb); tempPoints[i] = new FPoint(p2.getX(),p2.getY(),0); }
275
         * FMultiPoint multipoint = new FMultiPoint(tempPoints,BoundingBox);
276
         * resulShape = new FShape(multipoint,tipoShape); } else if (tipoShape ==
277
         * FConstant.SHAPE_TYPE_POINTZ) { FPoint p3d = new FPoint(); p3d.read(bb);
278
         * resulShape = new FShape(p3d,tipoShape); } else if ((tipoShape ==
279
         * FConstant.SHAPE_TYPE_POLYLINEZ) || (tipoShape ==
280
         * FConstant.SHAPE_TYPE_POLYGONZ)) { // BoundingBox BoundingBox =
281
         * readRectangle(bb); numParts = bb.getInt(); numPoints = bb.getInt(); //
282
         * part indexes. // Geometry geom = GeometryFactory.toGeometryArray();
283
         * 
284
         * GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
285
         * numPoints); int[] tempParts = new int[numParts]; for (i = 0; i <
286
         * numParts; i++) { tempParts[i] = bb.getInt(); } j = 0; //Line2D.Double
287
         * line2D; FPoint[] points=new FPoint[numPoints]; for (i = 0; i < numPoints;
288
         * i++) { p = readPoint(bb); points[i]=new FPoint(p.x,p.y);
289
         * 
290
         * if (i == tempParts[j]) { elShape.moveTo(p.x, p.y); if (j < (numParts -
291
         * 1)) { j++; } } else { elShape.lineTo(p.x, p.y); }
292
         *  }
293
         * 
294
         * double[] boxZ = new double[2]; boxZ[0] = bb.getDouble(); boxZ[1] =
295
         * bb.getDouble(); double[] pZ = new double[numPoints]; for (i = 0; i <
296
         * numPoints; i++) { pZ[i] = bb.getDouble(); } //FGeometry pol=new
297
         * FPolyLine(points,tempParts,BoundingBox); resulShape = new
298
         * FShape(tipoShape, elShape, pZ); } else if (tipoShape ==
299
         * FConstant.SHAPE_TYPE_MULTIPOINTZ) { // BoundingBox BoundingBox =
300
         * readRectangle(bb); numPoints = bb.getInt(); FPoint[] tempPoints3D = new
301
         * FPoint[numPoints]; for (i = 0; i < numPoints; i++) { tempPoints3D[i] =
302
         * new FPoint(); tempPoints3D[i].read(bb); } FMultiPoint multipoint3D = new
303
         * FMultiPoint(tempPoints3D,BoundingBox); resulShape = new
304
         * FShape(multipoint3D,tipoShape); } } catch (Exception e) {
305
         * System.err.println("Fallo en getShapeByID. ID=" + ID + "
306
         * m_posShapes[ID]=" + m_posShapes[ID]); System.err.println("getShapeByID: " +
307
         * e.getMessage()); e.printStackTrace(); } return resulShape; }
308
         */
309

    
310
        /**
311
         * Gets the geometry for an index
312
         * 
313
         * @param index
314
         *            index of the geometry of interest
315
         * 
316
         * @return the geometry
317
         * 
318
         * @throws IOException
319
         */
320
        public Geometry getShape(int index) throws IOException {
321

    
322
                Point2D.Double p = new Point2D.Double();
323
                int numParts;
324
                int numPoints;
325
                int i;
326
                int j;
327
                int shapeType;
328
                
329
                GeometryFactory gFactory = GeometryManager.getInstance().getGeometryFactory();
330

    
331
                // Rectangle2D.Double BoundingBox;
332
                // if (m_posShapes[index] == 0)
333

    
334
                // bb.position(m_posShapes[index]);
335
                bb.position(getPositionForRecord(index));
336
                bb.setByteOrder(ByteOrder.LITTLE_ENDIAN);
337

    
338
                // /bb.position(bb.position()+4);
339
                shapeType = bb.getInt();
340
                // el shape tal con tema tal y n?mro tal es null
341
                if (shapeType == SHP.SHPT_NULL) {
342
                        logger.warn("Found a null geometry in file " + fileShp.getName()
343
                                        + " ( shape index: " + index + " )");
344
                        return new NullGeometry();
345
                }
346

    
347
                // retrieve that shape.
348
                // tempRecord.setShape(readShape(tempShapeType, tempContentLength, in));
349
                switch (type) {
350

    
351
                case SHP.SHPT_POINT:
352
                        p = readPoint(bb);
353

    
354
                        return gFactory.createPoint2D(p.getX(), p.getY());
355

    
356
                case SHP.SHPT_ARC:
357

    
358
                        // BoundingBox = readRectangle(bb);
359
                        // bb.getDouble();
360
                        // bb.getDouble();
361
                        // bb.getDouble();
362
                        // bb.getDouble();
363
                        bb.position(bb.getPosition() + 32);
364
                        numParts = bb.getInt();
365
                        numPoints = bb.getInt();
366

    
367
                        // part indexes.
368
                        // Geometry geom = GeometryFactory.toGeometryArray();
369
                        GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
370
                                        numPoints);
371

    
372
                        int[] tempParts = new int[numParts];
373

    
374
                        for (i = 0; i < numParts; i++) {
375
                                tempParts[i] = bb.getInt();
376
                        }
377

    
378
                        j = 0;
379

    
380
                        for (i = 0; i < numPoints; i++) {
381
                                p = readPoint(bb);
382

    
383
                                if (i == tempParts[j]) {
384
                                        elShape.moveTo(p.x, p.y);
385

    
386
                                        if (j < (numParts - 1)) {
387
                                                j++;
388
                                        }
389
                                } else {
390
                                        elShape.lineTo(p.x, p.y);
391
                                }
392
                        }
393

    
394
                        return gFactory.createPolyline2D(elShape);
395

    
396
                case SHP.SHPT_POLYGON:
397

    
398
                        // BoundingBox = readRectangle(bb);
399
                        bb.getDouble();
400
                        bb.getDouble();
401
                        bb.getDouble();
402
                        bb.getDouble();
403

    
404
                        numParts = bb.getInt();
405

    
406
                        numPoints = bb.getInt();
407

    
408
                        // part indexes.
409
                        // Geometry geom = GeometryFactory.toGeometryArray();
410
                        elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
411

    
412
                        tempParts = new int[numParts];
413

    
414
                        for (i = 0; i < numParts; i++) {
415
                                tempParts[i] = bb.getInt();
416
                        }
417

    
418
                        j = 0;
419

    
420
                        for (i = 0; i < numPoints; i++) {
421
                                p = readPoint(bb);
422

    
423
                                if (i == tempParts[j]) {
424
                                        elShape.moveTo(p.x, p.y);
425

    
426
                                        if (j < (numParts - 1)) {
427
                                                j++;
428
                                        }
429
                                } else {
430
                                        elShape.lineTo(p.x, p.y);
431
                                }
432
                        }
433

    
434
                        return gFactory.createPolygon2D(elShape);
435

    
436
                case SHP.SHPT_POINTZ:
437
                case SHP.SHPT_POINTM:
438

    
439
                        double x = bb.getDouble();
440
                        double y = bb.getDouble();
441
                        double z = bb.getDouble();
442

    
443
                        return gFactory.createPoint3D(x, y, z);
444

    
445
                case SHP.SHPT_ARCZ:
446
                case SHP.SHPT_ARCM:
447
                        bb.position(bb.getPosition() + 32);
448
                        numParts = bb.getInt();
449
                        numPoints = bb.getInt();
450
                        elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
451
                        tempParts = new int[numParts];
452

    
453
                        for (i = 0; i < numParts; i++) {
454
                                tempParts[i] = bb.getInt();
455
                        }
456

    
457
                        j = 0;
458

    
459
                        for (i = 0; i < numPoints; i++) {
460
                                p = readPoint(bb);
461

    
462
                                if (i == tempParts[j]) {
463
                                        elShape.moveTo(p.x, p.y);
464

    
465
                                        if (j < (numParts - 1)) {
466
                                                j++;
467
                                        }
468
                                } else {
469
                                        elShape.lineTo(p.x, p.y);
470
                                }
471
                        }
472

    
473
                        double[] boxZ = new double[2];
474
                        boxZ[0] = bb.getDouble();
475
                        boxZ[1] = bb.getDouble();
476

    
477
                        double[] pZ = new double[numPoints];
478

    
479
                        for (i = 0; i < numPoints; i++) {
480
                                pZ[i] = bb.getDouble();
481
                        }
482

    
483
                        return gFactory.createPolyline3D(elShape, pZ);
484

    
485
                case SHP.SHPT_POLYGONZ:
486
                case SHP.SHPT_POLYGONM:
487

    
488
                        bb.position(bb.getPosition() + 32);
489
                        numParts = bb.getInt();
490
                        numPoints = bb.getInt();
491
                        elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
492
                        tempParts = new int[numParts];
493

    
494
                        for (i = 0; i < numParts; i++) {
495
                                tempParts[i] = bb.getInt();
496
                        }
497

    
498
                        j = 0;
499

    
500
                        for (i = 0; i < numPoints; i++) {
501
                                p = readPoint(bb);
502

    
503
                                if (i == tempParts[j]) {
504
                                        elShape.moveTo(p.x, p.y);
505

    
506
                                        if (j < (numParts - 1)) {
507
                                                j++;
508
                                        }
509
                                } else {
510
                                        elShape.lineTo(p.x, p.y);
511
                                }
512
                        }
513

    
514
                        double[] boxpoZ = new double[2];
515
                        boxpoZ[0] = bb.getDouble();
516
                        boxpoZ[1] = bb.getDouble();
517

    
518
                        double[] poZ = new double[numPoints];
519

    
520
                        for (i = 0; i < numPoints; i++) {
521
                                poZ[i] = bb.getDouble();
522
                        }
523

    
524
                        return gFactory.createPolygon3D(elShape, poZ);
525

    
526
                case SHP.SHPT_MULTIPOINT:
527
                        bb.position(bb.getPosition() + 32);
528
                        numPoints = bb.getInt();
529

    
530
                        double[] tempX = new double[numPoints];
531
                        double[] tempY = new double[numPoints];
532

    
533
                        for (i = 0; i < numPoints; i++) {
534
                                tempX[i] = bb.getDouble();
535
                                tempY[i] = bb.getDouble();
536
                        }
537

    
538
                        return gFactory.createMultipoint2D(tempX, tempY);
539

    
540
                case SHP.SHPT_MULTIPOINTZ:
541
                case SHP.SHPT_MULTIPOINTM:
542
                        bb.position(bb.getPosition() + 32);
543
                        numPoints = bb.getInt();
544

    
545
                        double[] temX = new double[numPoints];
546
                        double[] temY = new double[numPoints];
547
                        double[] temZ = new double[numPoints];
548

    
549
                        for (i = 0; i < numPoints; i++) {
550
                                temX[i] = bb.getDouble();
551
                                temY[i] = bb.getDouble();
552
                                // temZ[i] = bb.getDouble();
553
                        }
554

    
555
                        for (i = 0; i < numPoints; i++) {
556
                                temZ[i] = bb.getDouble();
557
                        }
558
                        return gFactory.createMultipoint3D(temX, temY, temZ);
559
                }
560

    
561
                return null;
562
        }
563

    
564
        /**
565
         * @return the number of geometries in this driver
566
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getShapeCount()
567
         */
568
        public int getShapeCount() {
569
                return numReg;
570
        }
571

    
572
        /**
573
         * @return the shape type of the geometries of this driver
574
         * 
575
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialDriver#getShapeType()
576
         */
577
        public int getShapeType() {
578
                int auxType = 0;
579

    
580
                switch (type) {
581
                case SHP.SHPT_POINT:
582
                case SHP.SHPT_POINTZ:
583
                case SHP.SHPT_POINTM:
584
                        auxType = auxType | FShape.POINT;
585

    
586
                        break;
587

    
588
                case SHP.SHPT_ARC:
589
                case SHP.SHPT_ARCZ:
590
                case SHP.SHPT_ARCM:
591
                        auxType = auxType | FShape.LINE;
592

    
593
                        break;
594

    
595
                case SHP.SHPT_POLYGON:
596
                case SHP.SHPT_POLYGONZ:
597
                case SHP.SHPT_POLYGONM:
598
                        auxType = auxType | FShape.POLYGON;
599

    
600
                        break;
601
                case SHP.SHPT_MULTIPOINT:
602
                case SHP.SHPT_MULTIPOINTZ:
603
                case SHP.SHPT_MULTIPOINTM:
604
                        auxType = auxType | FShape.MULTIPOINT;
605

    
606
                        break;
607
                }
608

    
609
                return auxType;
610
        }
611

    
612
        /**
613
         * Initializes the driver
614
         * 
615
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#initialize()
616
         */
617
        public void initialize(long shape_count) throws IOException {
618
                // logger.debug(Utils.time() + "Empieza initialize() del driver shp.");
619

    
620
                ShapeFileHeader myHeader = new ShapeFileHeader();
621
                bb.position(0);
622

    
623
                // read the header
624
                // logger.debug(Utils.time() + "Leer header:");
625
                myHeader.readHeader(bb);
626

    
627
                // logger.debug(Utils.time() + "Leer header, done");
628

    
629
                extent = new Rectangle2D.Double(myHeader.myXmin, myHeader.myYmin,
630
                                myHeader.myXmax - myHeader.myXmin, myHeader.myYmax
631
                                                - myHeader.myYmin);
632

    
633
                type = myHeader.myShapeType;
634

    
635
                double x = myHeader.myXmin;
636
                double y = myHeader.myYmin;
637
                double w = myHeader.myXmax - myHeader.myXmin;
638
                double h = myHeader.myYmax - myHeader.myYmin;
639

    
640
                if (w == 0) {
641
                        x -= 0.1;
642
                        w = 0.2;
643
                }
644

    
645
                if (h == 0) {
646
                        y -= 0.1;
647
                        h = 0.2;
648
                }
649

    
650
                numReg = (int) shape_count;
651

    
652
                /*
653
                 * logger.debug(Utils.time() + "Intentando: ShpReader.openShpFile()");
654
                 * 
655
                 * long aux_handler = ShpReader.openShpFile(fileShp.getAbsolutePath(),
656
                 * false);
657
                 * 
658
                 * logger.debug(Utils.time() + "Intentando: ShpReader.openShpFile(),
659
                 * aux_handler = " + aux_handler);
660
                 * 
661
                 * try { double[] meta = ShpReader.getShpMetadata(aux_handler); numReg =
662
                 * Math.round((float) meta[5]); ShpReader.closeShpFile(aux_handler);
663
                 * done = true; } catch (Throwable th) { logger.error( Utils.time() +
664
                 * "NUMREG, openShpFile(...), getShpMetadata(...) HA FALLADO: " +
665
                 * th.getMessage()); }
666
                 * 
667
                 * if (done) { logger.debug("Se ha obtenido NUMREG = " + numReg);
668
                 * return; }
669
                 * 
670
                 * String dbfpath = getDataFilePath(fileShp);
671
                 * 
672
                 * try { aux_handler = ShpReader.openDbfFile(dbfpath, false); numReg =
673
                 * ShpReader.getDbfFileRowCount(aux_handler);
674
                 * ShpReader.closeDbfFile(aux_handler); done = true; } catch (Throwable
675
                 * th) { logger.error( Utils.time() + "NUMREG, openDbfFile(...), TAMBIEN
676
                 * HA FALLADO: " + th.getMessage()); }
677
                 */
678
        }
679

    
680
        /**
681
         * Reads a Point from the shape file.
682
         * 
683
         * @param in
684
         *            ByteBuffer.
685
         * 
686
         * @return Point2D.
687
         */
688
        private synchronized Point2D.Double readPoint(FalseByteBuffer in) {
689
                // create a new point
690
                Point2D.Double tempPoint = new Point2D.Double();
691

    
692
                // bytes 1 to 4 are the type and have already been read.
693
                // bytes 4 to 12 are the X coordinate
694
                in.setByteOrder(ByteOrder.LITTLE_ENDIAN);
695
                tempPoint.setLocation(in.getDouble(), in.getDouble());
696

    
697
                return tempPoint;
698
        }
699

    
700
        /**
701
         * Lee un rect?ngulo del fichero.
702
         * 
703
         * @param in
704
         *            ByteBuffer.
705
         * 
706
         * @return Rect?ngulo.
707
         * 
708
         * @throws IOException
709
         */
710
        private synchronized Rectangle2D.Double readRectangle(FalseByteBuffer in)
711
                        throws IOException {
712
                Rectangle2D.Double tempRect = new Rectangle2D.Double();
713
                in.setByteOrder(ByteOrder.LITTLE_ENDIAN);
714
                tempRect.x = in.getDouble();
715
                tempRect.y = in.getDouble();
716

    
717
                tempRect.width = in.getDouble() - tempRect.x;
718

    
719
                if (tempRect.width == 0) {
720
                        tempRect.width = 0.2;
721
                        tempRect.x -= 0.1;
722
                }
723

    
724
                tempRect.height = in.getDouble() - tempRect.y;
725

    
726
                if (tempRect.height == 0) {
727
                        tempRect.height = 0.2;
728
                        tempRect.y -= 0.1;
729
                }
730

    
731
                return tempRect;
732
        }
733

    
734
        /**
735
         * Gets the extent of the geometries of this driver
736
         * 
737
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getFullExtent()
738
         */
739
        public Rectangle2D getFullExtent() throws IOException {
740
                return extent;
741
        }
742

    
743
        /**
744
         * Gets the extent of one geometry of this driver.
745
         * 
746
         * @param index
747
         *            the index of the geometry of interest
748
         * @return the bounding box of the geometry
749
         */
750
        public Rectangle2D getShapeBounds(int index) throws IOException {
751
                Point2D p = new Point2D.Double();
752
                Rectangle2D BoundingBox = new Rectangle2D.Double();
753
                bb.position(getPositionForRecord(index));
754
                bb.setByteOrder(ByteOrder.LITTLE_ENDIAN);
755

    
756
                int tipoShape = bb.getInt();
757

    
758
                // AZABALA: si tipoShape viene con valores erroneos deja de funcionar
759
                // el metodo getShape(i)
760
                // if (tipoShape != SHP.NULL) {
761
                // type = tipoShape;
762
                //
763
                // }
764

    
765
                // retrieve that shape.
766
                // tempRecord.setShape(readShape(tempShapeType, tempContentLength, in));
767
                switch (tipoShape) {
768

    
769
                case SHP.SHPT_POINT:
770
                case SHP.SHPT_POINTZ:
771
                case SHP.SHPT_POINTM:
772
                        p = readPoint(bb);
773
                        BoundingBox = new Rectangle2D.Double(p.getX() - POINT_TOL, p.getY()
774
                                        - POINT_TOL, 2 * POINT_TOL, 2 * POINT_TOL);
775

    
776
                        break;
777

    
778
                case SHP.SHPT_ARC:
779
                case SHP.SHPT_ARCZ:
780
                case SHP.SHPT_ARCM:
781
                case SHP.SHPT_MULTIPOINT:
782
                case SHP.SHPT_MULTIPOINTZ:
783
                case SHP.SHPT_MULTIPOINTM:
784
                case SHP.SHPT_POLYGON:
785
                case SHP.SHPT_POLYGONZ:
786
                case SHP.SHPT_POLYGONM:
787
                default:
788
                        // BoundingBox
789
                        try {
790
                                BoundingBox = readRectangle(bb);
791
                        } catch (IOException e) {
792
                                logger.error("Al calcular BB: " + e.getMessage());
793
                                BoundingBox = null;
794
                        }
795

    
796
                        break;
797

    
798
                }
799

    
800
                return BoundingBox;
801
        }
802

    
803
        /**
804
         * Says whether a file is a SHP file.
805
         * 
806
         * @param f
807
         *            the file of interest
808
         * @return whether it is a valid SHP file
809
         */
810
        public boolean accept(File f) {
811
                return (f.getName().toUpperCase().endsWith("SHP"));
812
        }
813

    
814
        /**
815
         * Gets the driver name
816
         */
817
        public String getName() {
818
                return "gvSIG SHP driver";
819
        }
820

    
821
        /**
822
         * Gets the data file (attributes file, in this case a DBF file) that
823
         * corresponds to the given SHP file
824
         */
825
        public File getDataFile(File f) {
826
                String str = f.getAbsolutePath();
827
                return new File(str.substring(0, str.length() - 3) + "dbf");
828
        }
829

    
830
        /**
831
         * Gets the associated SHX file
832
         * 
833
         * @param f
834
         *            a certain SHP file
835
         * @return the associated SHX file
836
         */
837
        public File getShxFile(File f) {
838
                String str = f.getAbsolutePath();
839
                return new File(str.substring(0, str.length() - 3) + "shx");
840
        }
841

    
842
        /**
843
         * Gets the shape type of the geometry of interest. Redirects to
844
         * <code>getShapeType()</code>
845
         * 
846
         * @param index
847
         *            the index of the geometry of interest
848
         * @return the type of the geometry of interest.
849
         * 
850
         */
851
        public int getShapeType(int index) {
852
                // Por ahora todos los fichero .shp contienen
853
                // entidades del mismo tipo. Si trabajamos con
854
                // alguno mixto, tendremos que cambiar esta funci?n.
855
                return getShapeType();
856
        }
857

    
858
        private synchronized int getPositionForRecord(int numRec) {
859
                // shx file has a 100 bytes header, then, records
860
                // 8 bytes length, one for each entity.
861
                // first 4 bytes are the offset
862
                // next 4 bytes are length
863

    
864
                int posIndex = 100 + (numRec * 8);
865
                // bbShx.position(posIndex);
866
                int pos = 8 + 2 * bbShx.getInt(posIndex);
867

    
868
                return pos;
869
        }
870

    
871
        /**
872
         * Gets the main SHP file object.
873
         * 
874
         * @return the main file object
875
         */
876
        public File getFile() {
877
                return fileShp;
878
        }
879

    
880
        /**
881
         * Reloads the driver (reopens file and initializes)
882
         */
883
        public void reload() throws IOException {
884
                open(fileShp);
885
                initialize(numReg);
886
        }
887

    
888
        /**
889
         * @return whether this driver is writable.
890
         */
891
        public boolean isWritable() {
892
                return fileShp.canWrite();
893
        }
894

    
895
        /**
896
         * @return whether this driver's table can be altered
897
         * 
898
         */
899
        public boolean canAlterTable() {
900
                return false;
901
        }
902

    
903
        /**
904
         * Unused.
905
         */
906
        public boolean isWriteAll() {
907
                return true;
908
        }
909

    
910
        /**
911
         * Gets the indices of the geometries intersecting the given rectangle
912
         * 
913
         * @param rect
914
         *            the rectangle of interest
915
         * @param max
916
         *            the maximum number of indices to be returned
917
         */
918
        public int[] getIntersectingIndices(Rectangle2D rect, int max)
919
                        throws IOException {
920

    
921
                ArrayList _resp = new ArrayList();
922
                for (int i = 0; i < numReg; i++) {
923
                        if (Utils.rectanglesItersect(getShapeBounds(i), rect)) {
924
                                Geometry ig = getShape(i);
925
                                if (ig.getType() == FShape.POINT || ig.intersects(rect)) {
926
                                        _resp.add(new Integer(i));
927
                                        // logger.debug("Ha intersectado uno!");
928
                                        if (_resp.size() == max) {
929
                                                break;
930
                                        }
931
                                }
932
                        }
933
                }
934
                int size = _resp.size();
935

    
936
                if (size == 0)
937
                        return null;
938

    
939
                int[] resp = new int[size];
940
                for (int i = 0; i < size; i++)
941
                        resp[i] = ((Integer) _resp.get(i)).intValue();
942
                return resp;
943
        }
944

    
945
}