Statistics
| Revision:

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

History | View | Annotate | Download (25.9 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.FileNotFoundException;
48
import java.io.FileOutputStream;
49
import java.io.IOException;
50
import java.nio.ByteOrder;
51
import java.nio.channels.FileChannel;
52
import java.util.Properties;
53

    
54
import org.apache.log4j.Logger;
55

    
56
import com.hardcode.gdbms.driver.DriverUtilities;
57
import com.iver.cit.gvsig.fmap.core.FShape;
58
import com.iver.cit.gvsig.fmap.core.GeneralPathX;
59
import com.iver.cit.gvsig.fmap.core.IGeometry;
60
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
61
import com.iver.cit.gvsig.fmap.drivers.BoundedShapes;
62
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
63
import com.iver.cit.gvsig.fmap.drivers.ExternalData;
64
import com.iver.cit.gvsig.fmap.drivers.ITableDefinition;
65
import com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver;
66
import com.iver.cit.gvsig.fmap.edition.EditionException;
67
import com.iver.cit.gvsig.fmap.edition.IRowEdited;
68
import com.iver.cit.gvsig.fmap.edition.ISpatialWriter;
69
import com.iver.cit.gvsig.fmap.edition.IWriteable;
70
import com.iver.cit.gvsig.fmap.edition.IWriter;
71
import com.iver.cit.gvsig.fmap.edition.writers.shp.ShpWriter;
72
import com.iver.utiles.bigfile.BigByteBuffer2;
73

    
74

    
75
/**
76
 * Driver del formato SHP. Usa ByteBuffer2, que no consume
77
 * memoria (bueno, 8KBytes... !) y no le importa que le pidan
78
 * entidades desordenadas del fichero, lo cual es indispensable
79
 * para trabajar con ?ndices espaciales.
80
 * Adem?s, el tiempo de espera para abrir un fichero y empezar a pintar es
81
 * pr?cticamente nulo, tanto desde disco duro como por red.
82
 * La ?nica pega es que en ficheros grandes puede ser unos
83
 * milisegundos un poco m?s lento que el otro, pero muy poco.
84
 *
85
 * @author Francisco Jos? Pe?arrubia
86
 */
87
public class IndexedShpDriver implements VectorialFileDriver, BoundedShapes,
88
        ExternalData, IWriteable, ISpatialWriter {
89
        private static Logger logger = Logger.getLogger(IndexedShpDriver.class.getName());
90
        private static String tempDirectoryPath = System.getProperty("java.io.tmpdir");
91
        private File fileShp;
92
        private File fTemp;
93
        private BigByteBuffer2 bb;
94
        private FileChannel channel;
95
        private FileInputStream fin;
96
        private int type;
97
        // private long[] m_posShapes;
98
        private int numReg;
99
        private Rectangle2D extent;
100

    
101
    // private File shxFile;
102
    private BigByteBuffer2 bbShx;
103
    private FileChannel channelShx;
104
    private FileInputStream finShx;
105

    
106
    private ShpWriter shpWriter = new ShpWriter();
107

    
108

    
109
        /**
110
         * Cierra el fichero.
111
         *
112
         * @throws IOException
113
         *
114
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#close()
115
         */
116
        public void close() throws IOException {
117
                IOException ret = null;
118

    
119
                try {
120
                        channel.close();
121
            channelShx.close();
122
                } catch (IOException e) {
123
                        ret = e;
124
                } finally {
125
                        try {
126
                                fin.close();
127
                        } catch (IOException e1) {
128
                                ret = e1;
129
                        }
130
                }
131

    
132
                if (ret != null) {
133
                        throw ret;
134
                }
135
                else // Si todo ha ido bien, preparamos para liberar memoria.
136
        {
137
                    bb = null;
138
            bbShx = null;
139
        }
140
        }
141

    
142
        /**
143
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#open(java.io.File)
144
         */
145
        public void open(File f) throws IOException {
146
                fileShp = f;
147

    
148
                fin = new FileInputStream(f);
149

    
150
                // Open the file and then get a channel from the stream
151
                channel = fin.getChannel();
152

    
153
                // long size = channel.size();
154

    
155
                // Get the file's size and then map it into memory
156
                // bb = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
157
        bb = new BigByteBuffer2(channel, FileChannel.MapMode.READ_ONLY);
158

    
159
        finShx = new FileInputStream(getShxFile(f));
160

    
161
        // Open the file and then get a channel from the stream
162
        channelShx = finShx.getChannel();
163

    
164
        long sizeShx = channelShx.size();
165

    
166
        // Get the file's size and then map it into memory
167
        // bb = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
168
        // bbShx = channelShx.map(FileChannel.MapMode.READ_ONLY, 0, sizeShx);
169
        bbShx = new BigByteBuffer2(channelShx, FileChannel.MapMode.READ_ONLY);
170
        bbShx.order(ByteOrder.BIG_ENDIAN);
171
        }
172

    
173
        /**
174
         * DOCUMENT ME!
175
         *
176
         * @param index DOCUMENT ME!
177
         *
178
         * @return DOCUMENT ME!
179
         *
180
         * @throws IOException
181
         *
182
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getShape(int)
183
         */
184

    
185
        /* public FShape getShapeByID(int ID) {
186
           Point2D.Double p = new Point2D.Double();
187
           Point2D.Double pAnt = null;
188
           int numParts;
189
           int numPoints;
190
           int i;
191
           int j;
192
           int numReg;
193
           int numeroPuntos;
194
           int hasta;
195
           int desde;
196
           Rectangle2D.Double BoundingBox = new Rectangle2D.Double();
197

198
                   SHPShape shapeShp=null;
199
           FShape resulShape = null;
200
           try {
201
               bb.position(m_posShapes[ID]);
202
               bb.order(ByteOrder.LITTLE_ENDIAN);
203
               int tipoShape = bb.getInt();
204
               m_shapeType = tipoShape;
205
               // retrieve that shape.
206
               // tempRecord.setShape(readShape(tempShapeType, tempContentLength, in));
207
               if (tipoShape == FConstant.SHAPE_TYPE_POINT) {
208
                   p = readPoint(bb);
209
                   resulShape = new FShape(new FPoint(p.getX(),p.getY()),FConstant.SHAPE_TYPE_POINT);
210
                   //Comprobaci?n punto.
211
                   //System.err.println("p.x = "+p.x);
212
                   //System.err.println("p.y = "+p.y);
213

214
               } else if ((tipoShape == FConstant.SHAPE_TYPE_POLYLINE) ||
215
                       (tipoShape == FConstant.SHAPE_TYPE_POLYGON)) {
216
                   // BoundingBox
217
                   BoundingBox = readRectangle(bb);
218
                   numParts = bb.getInt();
219
                   numPoints = bb.getInt();
220
                   // part indexes.
221
                   // Geometry geom = GeometryFactory.toGeometryArray();
222
                   GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
223
                           numPoints);
224
                   int[] tempParts = new int[numParts];
225
                   for (i = 0; i < numParts; i++) {
226
                       tempParts[i] = bb.getInt();
227
                   }
228
                   j = 0;
229
                   ///Line2D.Double line2D;
230
                   FPoint[] points=new FPoint[numPoints];
231
                   for (i = 0; i < numPoints; i++) {
232
                           p=readPoint(bb);
233
                       points[i] = new FPoint(p.x,p.y);
234
                       // System.out.println("x= " + p.x + " y=" + p.y);
235
                       // System.out.println("x= " + (float) p.x + " y=" + (float) p.y);
236
                       if (i == tempParts[j]) {
237
                           elShape.moveTo(p.x, p.y);
238
                           if (j < (numParts - 1)) {
239
                               j++;
240
                           }
241
                       } else {
242
                           elShape.lineTo(p.x, p.y);
243
                       }
244
                   }
245
                   //FGeometry pol=new FPolyLine(points,tempParts,BoundingBox);
246

247
                   resulShape = new FShape(tipoShape,elShape);
248
               } else if (tipoShape == FConstant.SHAPE_TYPE_MULTIPOINT) {
249
                   // BoundingBox
250
                   BoundingBox = readRectangle(bb);
251
                   numPoints = bb.getInt();
252
                   FPoint[] tempPoints = new FPoint[numPoints];
253
                   for (i = 0; i < numPoints; i++) {
254
                           Point2D p2=readPoint(bb);
255
                       tempPoints[i] = new FPoint(p2.getX(),p2.getY(),0);
256
                   }
257
                   FMultiPoint multipoint = new FMultiPoint(tempPoints,BoundingBox);
258
                   resulShape = new FShape(multipoint,tipoShape);
259
               } else if (tipoShape == FConstant.SHAPE_TYPE_POINTZ) {
260
                   FPoint p3d = new FPoint();
261
                   p3d.read(bb);
262
                   resulShape = new FShape(p3d,tipoShape);
263
               } else if ((tipoShape == FConstant.SHAPE_TYPE_POLYLINEZ) ||
264
                       (tipoShape == FConstant.SHAPE_TYPE_POLYGONZ)) {
265
                   // BoundingBox
266
                   BoundingBox = readRectangle(bb);
267
                   numParts = bb.getInt();
268
                   numPoints = bb.getInt();
269
                   // part indexes.
270
                   // Geometry geom = GeometryFactory.toGeometryArray();
271

272
                   GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
273
                           numPoints);
274
                   int[] tempParts = new int[numParts];
275
                   for (i = 0; i < numParts; i++) {
276
                       tempParts[i] = bb.getInt();
277
                   }
278
                   j = 0;
279
                  //Line2D.Double line2D;
280
                   FPoint[] points=new FPoint[numPoints];
281
                   for (i = 0; i < numPoints; i++) {
282
                       p = readPoint(bb);
283
                       points[i]=new FPoint(p.x,p.y);
284

285
                       if (i == tempParts[j]) {
286
                           elShape.moveTo(p.x, p.y);
287
                           if (j < (numParts - 1)) {
288
                               j++;
289
                           }
290
                       } else {
291
                           elShape.lineTo(p.x, p.y);
292
                       }
293

294
                   }
295

296
                   double[] boxZ = new double[2];
297
                   boxZ[0] = bb.getDouble();
298
                   boxZ[1] = bb.getDouble();
299
                   double[] pZ = new double[numPoints];
300
                   for (i = 0; i < numPoints; i++) {
301
                       pZ[i] = bb.getDouble();
302
                   }
303
                   //FGeometry pol=new FPolyLine(points,tempParts,BoundingBox);
304
                   resulShape = new FShape(tipoShape, elShape, pZ);
305
               } else if (tipoShape == FConstant.SHAPE_TYPE_MULTIPOINTZ) {
306
                   // BoundingBox
307
                   BoundingBox = readRectangle(bb);
308
                   numPoints = bb.getInt();
309
                   FPoint[] tempPoints3D = new FPoint[numPoints];
310
                   for (i = 0; i < numPoints; i++) {
311
                       tempPoints3D[i] = new FPoint();
312
                       tempPoints3D[i].read(bb);
313
                   }
314
                   FMultiPoint multipoint3D = new FMultiPoint(tempPoints3D,BoundingBox);
315
                   resulShape = new FShape(multipoint3D,tipoShape);
316
               }
317
           } catch (Exception e) {
318
               System.err.println("Fallo en getShapeByID. ID=" + ID +
319
                   " m_posShapes[ID]=" + m_posShapes[ID]);
320
               System.err.println("getShapeByID: " + e.getMessage());
321
               e.printStackTrace();
322
           }
323
           return resulShape;
324
           }
325
         */
326

    
327
        /**
328
         * Devuelve la geometria a partir de un ?ndice.
329
         *
330
         * @param index DOCUMENT ME!
331
         *
332
         * @return DOCUMENT ME!
333
         *
334
         * @throws IOException DOCUMENT ME!
335
         */
336
        public synchronized IGeometry getShape(int index) throws IOException {
337
                IGeometry geom=null;
338
                Point2D.Double p = new Point2D.Double();
339
                int numParts;
340
                int numPoints;
341
                int i;
342
                int j;
343
                /* int numReg;
344
                int numeroPuntos;
345
                int hasta;
346
                int desde; */
347
                int shapeType;
348

    
349
                //Rectangle2D.Double BoundingBox;
350
        // if (m_posShapes[index] == 0)
351

    
352
                // bb.position(m_posShapes[index]);
353
        bb.position(getPositionForRecord(index));
354
                bb.order(ByteOrder.LITTLE_ENDIAN);
355

    
356
                ///bb.position(bb.position()+4);
357
                shapeType = bb.getInt();
358
                //el shape tal con tema tal y n?mro tal es null
359
                if (shapeType==SHP.NULL){
360
                        logger.info("El shape ="+index+ " de la capa ="+this.toString()+" es null");
361
                        return null;
362
                }
363

    
364
                // retrieve that shape.
365
                // tempRecord.setShape(readShape(tempShapeType, tempContentLength, in));
366
                switch (type) {
367
                        case (SHP.POINT2D):
368
                                p = readPoint(bb);
369
                        geom=ShapeFactory.createPoint2D(p.getX(), p.getY());
370
                        geom.setGeometryType(FShape.POINT);
371
                        return geom;
372

    
373
                        case (SHP.POLYLINE2D):
374

    
375
                                bb.position(bb.position() + 32);
376
                                numParts = bb.getInt();
377
                                numPoints = bb.getInt();
378

    
379
                                // part indexes.
380
                                // Geometry geom = GeometryFactory.toGeometryArray();
381
                                GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
382
                                                numPoints);
383

    
384
                                int[] tempParts = new int[numParts];
385

    
386
                                for (i = 0; i < numParts; i++) {
387
                                        tempParts[i] = bb.getInt();
388
                                }
389

    
390
                                j = 0;
391

    
392
                                for (i = 0; i < numPoints; i++) {
393
                                        p = readPoint(bb);
394

    
395
                                        if (i == tempParts[j]) {
396
                                                elShape.moveTo(p.x, p.y);
397

    
398
                                                if (j < (numParts - 1)) {
399
                                                        j++;
400
                                                }
401
                                        } else {
402
                                                elShape.lineTo(p.x, p.y);
403
                                        }
404
                                }
405
                                geom = ShapeFactory.createPolyline2D(elShape);
406
                                geom.setGeometryType(FShape.LINE);
407
                                return geom;
408
                        case (SHP.POLYGON2D):
409

    
410
                                //                            BoundingBox = readRectangle(bb);
411
                                bb.getDouble();
412
                                bb.getDouble();
413
                                bb.getDouble();
414
                                bb.getDouble();
415

    
416
                                numParts = bb.getInt();
417

    
418
                                numPoints = bb.getInt();
419

    
420
                                // part indexes.
421
                                // Geometry geom = GeometryFactory.toGeometryArray();
422
                                elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
423

    
424
                                tempParts = new int[numParts];
425

    
426
                                for (i = 0; i < numParts; i++) {
427
                                        tempParts[i] = bb.getInt();
428
                                }
429

    
430
                                j = 0;
431

    
432
                                for (i = 0; i < numPoints; i++) {
433
                                        p = readPoint(bb);
434

    
435
                                        if (i == tempParts[j]) {
436
                                                elShape.moveTo(p.x, p.y);
437

    
438
                                                if (j < (numParts - 1)) {
439
                                                        j++;
440
                                                }
441
                                        } else {
442
                                                elShape.lineTo(p.x, p.y);
443
                                        }
444
                                }
445
                                geom = ShapeFactory.createPolygon2D(elShape);
446
                                geom.setGeometryType(FShape.POLYGON);
447
                                return geom;
448

    
449
                        case (SHP.POINT3D):
450

    
451
                                double x = bb.getDouble();
452
                                double y = bb.getDouble();
453
                                double z = bb.getDouble();
454
                                geom = ShapeFactory.createPoint3D(x, y, z);
455
                                geom.setGeometryType(FShape.POINT);
456
                                return geom;
457

    
458
                        case (SHP.POLYLINE3D):
459
                                bb.position(bb.position() + 32);
460
                                numParts = bb.getInt();
461
                                numPoints = bb.getInt();
462
                                elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
463
                                tempParts = new int[numParts];
464

    
465
                                for (i = 0; i < numParts; i++) {
466
                                        tempParts[i] = bb.getInt();
467
                                }
468

    
469
                                j = 0;
470

    
471
                                for (i = 0; i < numPoints; i++) {
472
                                        p = readPoint(bb);
473

    
474
                                        if (i == tempParts[j]) {
475
                                                elShape.moveTo(p.x, p.y);
476

    
477
                                                if (j < (numParts - 1)) {
478
                                                        j++;
479
                                                }
480
                                        } else {
481
                                                elShape.lineTo(p.x, p.y);
482
                                        }
483
                                }
484

    
485
                                double[] boxZ = new double[2];
486
                                boxZ[0] = bb.getDouble();
487
                                boxZ[1] = bb.getDouble();
488

    
489
                                double[] pZ = new double[numPoints];
490

    
491
                                for (i = 0; i < numPoints; i++) {
492
                                        pZ[i] = bb.getDouble();
493
                                }
494
                                geom = ShapeFactory.createPolyline3D(elShape, pZ);
495
                                geom.setGeometryType(FShape.LINE);
496
                                return geom;
497
                        case (SHP.POLYGON3D):
498
                        bb.position(bb.position() + 32);
499
                        numParts = bb.getInt();
500
                        numPoints = bb.getInt();
501
                        elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
502
                        tempParts = new int[numParts];
503

    
504
                        for (i = 0; i < numParts; i++) {
505
                                tempParts[i] = bb.getInt();
506
                        }
507

    
508
                        j = 0;
509

    
510
                        for (i = 0; i < numPoints; i++) {
511
                                p = readPoint(bb);
512

    
513
                                if (i == tempParts[j]) {
514
                                        elShape.moveTo(p.x, p.y);
515

    
516
                                        if (j < (numParts - 1)) {
517
                                                j++;
518
                                        }
519
                                } else {
520
                                        elShape.lineTo(p.x, p.y);
521
                                }
522
                        }
523

    
524
                        double[] boxpoZ = new double[2];
525
                        boxpoZ[0] = bb.getDouble();
526
                        boxpoZ[1] = bb.getDouble();
527

    
528
                        double[] poZ = new double[numPoints];
529

    
530
                        for (i = 0; i < numPoints; i++) {
531
                                poZ[i] = bb.getDouble();
532
                        }
533
                        geom = ShapeFactory.createPolygon3D(elShape, poZ);
534
                        geom.setGeometryType(FShape.POLYGON);
535
                        return geom;
536

    
537
                        case (SHP.MULTIPOINT2D):
538
                                bb.position(bb.position() + 32);
539
                                numPoints = bb.getInt();
540

    
541
                                double[] tempX = new double[numPoints];
542
                                double[] tempY = new double[numPoints];
543

    
544
                                for (i = 0; i < numPoints; i++) {
545
                                        tempX[i] = bb.getDouble();
546
                                        tempY[i] = bb.getDouble();
547
                                }
548
                                geom = ShapeFactory.createMultipoint2D(tempX, tempY);
549
                                geom.setGeometryType(FShape.POINT);
550
                                return geom;
551

    
552
                        case (SHP.MULTIPOINT3D):
553
                                bb.position(bb.position() + 32);
554
                                numPoints = bb.getInt();
555

    
556
                                double[] temX = new double[numPoints];
557
                                double[] temY = new double[numPoints];
558
                                double[] temZ = new double[numPoints];
559

    
560
                                for (i = 0; i < numPoints; i++) {
561
                                        temX[i] = bb.getDouble();
562
                                        temY[i] = bb.getDouble();
563
                                        //temZ[i] = bb.getDouble();
564
                                }
565

    
566
                                for (i = 0; i < numPoints; i++) {
567
                                        temZ[i] = bb.getDouble();
568
                                }
569
                                geom = ShapeFactory.createMultipoint3D(temX, temY, temZ);
570
                                geom.setGeometryType(FShape.POINT);
571
                                return geom;
572
                }
573

    
574
                return geom;
575
        }
576

    
577
        /**
578
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getShapeCount()
579
         */
580
        public int getShapeCount() {
581
                return numReg;
582
        }
583

    
584
        /**
585
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialDriver#getShapeType()
586
         */
587
        public int getShapeType() {
588
                int auxType = 0;
589

    
590
                switch (type) {
591
                        case (SHP.POINT2D):
592
                        case (SHP.POINT3D):
593
                                auxType = auxType | FShape.POINT;
594

    
595
                                break;
596

    
597
                        case (SHP.POLYLINE2D):
598
                        case (SHP.POLYLINE3D):
599
                                auxType = auxType | FShape.LINE;
600

    
601
                                break;
602

    
603
                        case (SHP.POLYGON2D):
604
                        case (SHP.POLYGON3D):
605
                                auxType = auxType | FShape.POLYGON;
606

    
607
                                break;
608
                        case (SHP.MULTIPOINT2D):
609
                        case (SHP.MULTIPOINT3D):
610
                                auxType = auxType | FShape.MULTIPOINT;
611

    
612
                                break;
613
                }
614

    
615
                return auxType;
616
        }
617

    
618

    
619
        /**
620
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#initialize()
621
         */
622
        public void initialize() throws IOException {
623
                // create a new header.
624
                ShapeFileHeader2 myHeader = new ShapeFileHeader2();
625

    
626
                bb.position(0);
627

    
628
                // read the header
629
                myHeader.readHeader(bb);
630

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

    
635
                type = myHeader.myShapeType;
636

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

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

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

    
652
                // String strFichDbf = m_Path.toLowerCase().replaceAll("\\.shp", ".dbf");
653
                String strFichDbf = fileShp.getAbsolutePath().replaceAll("\\.shp", ".dbf");
654
                strFichDbf = strFichDbf.replaceAll("\\.SHP", ".DBF");
655

    
656
                DbaseFileNIO m_FichDbf = new DbaseFileNIO();
657

    
658
                m_FichDbf.open(new File(strFichDbf));
659
                numReg = m_FichDbf.getRecordCount();
660

    
661
                // shpWriter.initialize(file);
662
                // m_posShapes = new long[numReg];
663

    
664
                // read the records.
665
                /* int tempCurrentLength = myHeader.getHeaderLength();
666
                int numReg = 0;
667

668
                long pos1;
669

670
                while (tempCurrentLength < myHeader.myFileLength) {
671
                        // read the record header
672
                        // ShapeFileRecord tempRecord = new ShapeFileRecord();
673
                        // Bytes 0 to 4 represent the record number in the file, these may be out of order.
674
                        bb.order(ByteOrder.BIG_ENDIAN);
675

676
                        // tempRecord.setIndex(in.readInt());
677
                        bb.getInt();
678

679
                        // read the content length of this record in 16 bit words, excluding the index.
680
                        // in.setLittleEndianMode(false);
681
                        int tempContentLength = bb.getInt();
682

683
                        pos1 = bb.position();
684

685
                        m_posShapes[numReg] = bb.position();
686

687
                        // Posicionamos
688
                        bb.position((pos1 + (2 * tempContentLength)));
689
                        numReg = numReg + 1;
690

691
                        // update the current length the 4 is for the index, and content length.
692
                        tempCurrentLength = tempCurrentLength + 4 + tempContentLength;
693
                } */
694
        }
695

    
696
        /**
697
         * Reads the Point from the shape file.
698
         *
699
         * @param in ByteBuffer.
700
         *
701
         * @return Point2D.
702
         */
703
        private synchronized Point2D.Double readPoint(BigByteBuffer2 in) {
704
                // create a new point
705
                Point2D.Double tempPoint = new Point2D.Double();
706

    
707
                // bytes 1 to 4 are the type and have already been read.
708
                // bytes 4 to 12 are the X coordinate
709
                in.order(ByteOrder.LITTLE_ENDIAN);
710
                tempPoint.setLocation(in.getDouble(), in.getDouble());
711

    
712
                return tempPoint;
713
        }
714

    
715
        /**
716
         * Lee un rect?ngulo del fichero.
717
         *
718
         * @param in ByteBuffer.
719
         *
720
         * @return Rect?ngulo.
721
         *
722
         * @throws IOException
723
         */
724
        private synchronized Rectangle2D.Double readRectangle(BigByteBuffer2 in)
725
                throws IOException {
726
                Rectangle2D.Double tempRect = new Rectangle2D.Double();
727
                in.order(ByteOrder.LITTLE_ENDIAN);
728
                tempRect.x = in.getDouble();
729
                tempRect.y = in.getDouble();
730

    
731
                tempRect.width = in.getDouble() - tempRect.x;
732

    
733
                if (tempRect.width == 0) {
734
                        tempRect.width = 0.2;
735
                        tempRect.x -= 0.1;
736
                }
737

    
738
                tempRect.height = in.getDouble() - tempRect.y;
739

    
740
                if (tempRect.height == 0) {
741
                        tempRect.height = 0.2;
742
                        tempRect.y -= 0.1;
743
                }
744

    
745
                return tempRect;
746
        }
747

    
748
        /**
749
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getFullExtent()
750
         */
751
        public Rectangle2D getFullExtent() throws IOException {
752
                return extent;
753
        }
754

    
755
        /**
756
         * Obtiene el extent del shape a partir de un ?ndice.
757
         *
758
         * @param index ?ndice.
759
         *
760
         * @return Rect?ngulo.
761
         *
762
         * @throws IOException
763
         *
764
         * @see com.iver.cit.gvsig.fmap.drivers.BoundedShapes#getShapeBounds()
765
         */
766
        public synchronized Rectangle2D getShapeBounds(int index) throws IOException {
767
                Point2D p = new Point2D.Double();
768
                Rectangle2D BoundingBox = new Rectangle2D.Double();
769
                bb.position(getPositionForRecord(index));
770
                bb.order(ByteOrder.LITTLE_ENDIAN);
771

    
772
                int tipoShape = bb.getInt();
773

    
774
                //AZABALA: si tipoShape viene con valores erroneos deja de funcionar
775
                //el metodo getShape(i)
776
//                if (tipoShape != SHP.NULL) {
777
//                        type = tipoShape;
778
//
779
//                }
780

    
781
                // retrieve that shape.
782
                // tempRecord.setShape(readShape(tempShapeType, tempContentLength, in));
783
                switch (tipoShape) {
784
                        case (SHP.POINT2D):
785
                        case (SHP.POINT3D):
786
                                p = readPoint(bb);
787
                                BoundingBox = new Rectangle2D.Double(p.getX() - 0.1,
788
                                                p.getY() - 0.1, 0.2, 0.2);
789

    
790
                                break;
791

    
792
                        case (SHP.POLYLINE2D):
793
                        case (SHP.POLYGON2D):
794
                        case (SHP.MULTIPOINT2D):
795
                        case (SHP.POLYLINE3D):
796
                        case (SHP.POLYGON3D):
797
                        case (SHP.MULTIPOINT3D):
798

    
799
                                // BoundingBox
800
                                BoundingBox = readRectangle(bb);
801

    
802
                                break;
803
                }
804

    
805
                return BoundingBox;
806
        }
807

    
808
        /**
809
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#accept(java.io.File)
810
         */
811
        public boolean accept(File f) {
812
                return (f.getName().toUpperCase().endsWith("SHP"));
813
        }
814

    
815
        /**
816
         * @see com.hardcode.driverManager.Driver#getType()
817
         */
818
        public String getName() {
819
                // Para que se use este driver en lugar del viejo DemoShpDriver.
820

    
821
                // return "gvSIG indexed shp driver";
822
                return "gvSIG shp driver";
823
        }
824

    
825
        /**
826
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getDataDriverName()
827
         */
828
        public String getDataDriverName() {
829
                return "gdbms dbf driver";
830
        }
831

    
832
        /**
833
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getDataFile(java.io.File)
834
         */
835
        public File getDataFile(File f) {
836
                String str = f.getAbsolutePath();
837

    
838
                return new File(str.substring(0, str.length() - 3) + "dbf");
839
        }
840

    
841
    public File getShxFile(File f) {
842
        String str = f.getAbsolutePath();
843

    
844
        return new File(str.substring(0, str.length() - 3) + "shx");
845
    }
846

    
847

    
848
        /* (non-Javadoc)
849
         * @see com.iver.cit.gvsig.fmap.drivers.BoundedShapes#getShapeType(int)
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
    /* (non-Javadoc)
859
     * @see com.iver.cit.gvsig.fmap.drivers.VectorialDriver#getDriverAttributes()
860
     */
861
    public DriverAttributes getDriverAttributes() {
862
        return null;
863
    }
864

    
865
    private synchronized long getPositionForRecord(int numRec)
866
    {
867
        // shx file has a 100 bytes header, then, records
868
        // 8 bytes length, one for each entity.
869
        // first 4 bytes are the offset
870
        // next 4 bytes are length
871

    
872
        int posIndex = 100 + (numRec * 8);
873
        // bbShx.position(posIndex);
874
        long pos = 8 + 2*bbShx.getInt(posIndex);
875

    
876
        return pos;
877
    }
878

    
879
        public File getFile() {
880
                return fileShp;
881
        }
882

    
883
        public void reLoad() throws IOException {
884
                open(fileShp);
885
                initialize();
886
        }
887

    
888
        public boolean canWriteGeometry(int gvSIGgeometryType) {
889
                return shpWriter.canWriteGeometry(gvSIGgeometryType);
890
        }
891

    
892
        /* (non-Javadoc)
893
         * @see com.iver.cit.gvsig.fmap.edition.IWriter#preProcess()
894
         */
895
        public void preProcess() throws EditionException {
896
                // Necesitamos crear un fichero temporal porque a la vez que esic
897
                // La cabecera ya existe, as? que no la sobreescribimos.
898
                // shpWriter.setWriteHeaders(false);
899
                shpWriter.preProcess();
900

    
901
        }
902

    
903
        public void process(IRowEdited row) throws EditionException {
904
                shpWriter.process(row);
905

    
906
        }
907

    
908
        public void postProcess() throws EditionException {
909
                shpWriter.postProcess();
910

    
911
                try {
912

    
913
                        // close();
914

    
915
                        // Shp
916
                        FileChannel fcinShp = new FileInputStream(fTemp).getChannel();
917
                        FileChannel fcoutShp = new FileOutputStream(fileShp).getChannel();
918
                        DriverUtilities.copy(fcinShp, fcoutShp);
919

    
920
                        // Shx
921
                        File shxFile = getShxFile(fTemp);
922
                        FileChannel fcinShx = new FileInputStream(shxFile).getChannel();
923
                        FileChannel fcoutShx = new FileOutputStream(getShxFile(fileShp)).getChannel();
924
                        DriverUtilities.copy(fcinShx, fcoutShx);
925

    
926
                        // Dbf
927
                        File dbfFile = getDataFile(fTemp);
928
                        FileChannel fcinDbf = new FileInputStream(dbfFile).getChannel();
929
                        FileChannel fcoutDbf = new FileOutputStream(getDataFile(fileShp)).getChannel();
930
                        DriverUtilities.copy(fcinDbf, fcoutDbf);
931

    
932
                        // Borramos los temporales
933
                        fTemp.delete();
934
                        shxFile.delete();
935
                        dbfFile.delete();
936
                        reLoad();
937

    
938

    
939

    
940
                } catch (FileNotFoundException e) {
941
                        throw new EditionException(e);
942
                } catch (IOException e) {
943
                        throw new EditionException(e);
944
                }
945

    
946

    
947
        }
948

    
949
        public String getCapability(String capability) {
950
                return shpWriter.getCapability(capability);
951
        }
952

    
953
        public void setCapabilities(Properties capabilities) {
954
                shpWriter.setCapabilities(capabilities);
955

    
956
        }
957

    
958
        public boolean canWriteAttribute(int sqlType) {
959
                return shpWriter.canWriteAttribute(sqlType);
960
        }
961

    
962
        public ShpWriter getShpWriter() {
963
                return shpWriter;
964
        }
965

    
966
        public void setShpWriter(ShpWriter shpWriter) {
967
                this.shpWriter = shpWriter;
968
        }
969

    
970
        public void initialize(ITableDefinition layerDef) throws EditionException {
971
                int aux = (int)(Math.random() * 1000);
972
                fTemp = new File(tempDirectoryPath + "/tmpShp" + aux + ".shp");
973
                shpWriter.setFile(fTemp);
974
                shpWriter.initialize(layerDef);
975

    
976
        }
977

    
978
        public void setFlatness(double flatness) {
979
                shpWriter.setFlatness(flatness);
980
        }
981

    
982
        public boolean isWritable() {
983
                return fileShp.canWrite();
984
        }
985

    
986
        public IWriter getWriter()
987
        {
988
                return this;
989
        }
990
}