Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / drivers / shp / DemoSHPDriver.java @ 703

History | View | Annotate | Download (21.1 KB)

1
package com.iver.cit.gvsig.fmap.drivers.shp;
2

    
3
import java.awt.geom.Point2D;
4
import java.awt.geom.Rectangle2D;
5
import java.io.File;
6
import java.io.FileInputStream;
7
import java.io.IOException;
8
import java.nio.ByteBuffer;
9
import java.nio.ByteOrder;
10
import java.nio.channels.FileChannel;
11

    
12
import com.iver.cit.gvsig.fmap.core.FShape;
13
import com.iver.cit.gvsig.fmap.core.GeneralPathX;
14
import com.iver.cit.gvsig.fmap.core.IGeometry;
15
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
16
import com.iver.cit.gvsig.fmap.drivers.BoundedShapes;
17
import com.iver.cit.gvsig.fmap.drivers.ExternalData;
18
import com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver;
19

    
20

    
21
/**
22
 * DOCUMENT ME!
23
 *
24
 * @author $author$
25
 */
26
public class DemoSHPDriver implements VectorialFileDriver, BoundedShapes, ExternalData {
27
    private File file;
28
    private ByteBuffer bb;
29
    private FileChannel channel;
30
    private FileInputStream fin;
31
    private int type;
32
    private int[] m_posShapes;
33
    private int numReg;
34
    private Rectangle2D extent;
35

    
36
    /**
37
     * DOCUMENT ME!
38
     *
39
     * @throws IOException
40
     *
41
     * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#close()
42
     */
43
    public void close() throws IOException {
44
        IOException ret = null;
45

    
46
        try {
47
            channel.close();
48
        } catch (IOException e) {
49
            ret = e;
50
        } finally {
51
            try {
52
                fin.close();
53
            } catch (IOException e1) {
54
                ret = e1;
55
            }
56
        }
57

    
58
        if (ret != null) {
59
            throw ret;
60
        }
61
    }
62

    
63
    /**
64
     * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#open(java.io.File)
65
     */
66
    public void open(File f) throws IOException {
67
        file = f;
68

    
69
        fin = new FileInputStream(f);
70

    
71
        // Open the file and then get a channel from the stream
72
        channel = fin.getChannel();
73

    
74
        long size = channel.size();
75

    
76
        // Get the file's size and then map it into memory
77
        bb = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
78
    }
79

    
80
    /**
81
     * DOCUMENT ME!
82
     *
83
     * @param index DOCUMENT ME!
84
     *
85
     * @return DOCUMENT ME!
86
     *
87
     * @throws IOException
88
     *
89
     * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getShape(int)
90
     */
91

    
92
    /* public FShape getShapeByID(int ID) {
93
       Point2D.Double p = new Point2D.Double();
94
       Point2D.Double pAnt = null;
95
       int numParts;
96
       int numPoints;
97
       int i;
98
       int j;
99
       int numReg;
100
       int numeroPuntos;
101
       int hasta;
102
       int desde;
103
       Rectangle2D.Double BoundingBox = new Rectangle2D.Double();
104
    
105
               SHPShape shapeShp=null;
106
       FShape resulShape = null;
107
       try {
108
           bb.position(m_posShapes[ID]);
109
           bb.order(ByteOrder.LITTLE_ENDIAN);
110
           int tipoShape = bb.getInt();
111
           m_shapeType = tipoShape;
112
           // retrieve that shape.
113
           // tempRecord.setShape(readShape(tempShapeType, tempContentLength, in));
114
           if (tipoShape == FConstant.SHAPE_TYPE_POINT) {
115
               p = readPoint(bb);
116
               resulShape = new FShape(new FPoint(p.getX(),p.getY()),FConstant.SHAPE_TYPE_POINT);
117
               //Comprobaci?n punto.
118
               //System.err.println("p.x = "+p.x);
119
               //System.err.println("p.y = "+p.y);
120
    
121
           } else if ((tipoShape == FConstant.SHAPE_TYPE_POLYLINE) ||
122
                   (tipoShape == FConstant.SHAPE_TYPE_POLYGON)) {
123
               // BoundingBox
124
               BoundingBox = readRectangle(bb);
125
               numParts = bb.getInt();
126
               numPoints = bb.getInt();
127
               // part indexes.
128
               // Geometry geom = GeometryFactory.toGeometryArray();
129
               GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
130
                       numPoints);
131
               int[] tempParts = new int[numParts];
132
               for (i = 0; i < numParts; i++) {
133
                   tempParts[i] = bb.getInt();
134
               }
135
               j = 0;
136
               ///Line2D.Double line2D;
137
               FPoint[] points=new FPoint[numPoints];
138
               for (i = 0; i < numPoints; i++) {
139
                       p=readPoint(bb);
140
                   points[i] = new FPoint(p.x,p.y);
141
                   // System.out.println("x= " + p.x + " y=" + p.y);
142
                   // System.out.println("x= " + (float) p.x + " y=" + (float) p.y);
143
                   if (i == tempParts[j]) {
144
                       elShape.moveTo(p.x, p.y);
145
                       if (j < (numParts - 1)) {
146
                           j++;
147
                       }
148
                   } else {
149
                       elShape.lineTo(p.x, p.y);
150
                   }
151
               }
152
               //FGeometry pol=new FPolyLine(points,tempParts,BoundingBox);
153
    
154
               resulShape = new FShape(tipoShape,elShape);
155
           } else if (tipoShape == FConstant.SHAPE_TYPE_MULTIPOINT) {
156
               // BoundingBox
157
               BoundingBox = readRectangle(bb);
158
               numPoints = bb.getInt();
159
               FPoint[] tempPoints = new FPoint[numPoints];
160
               for (i = 0; i < numPoints; i++) {
161
                       Point2D p2=readPoint(bb);
162
                   tempPoints[i] = new FPoint(p2.getX(),p2.getY(),0);
163
               }
164
               FMultiPoint multipoint = new FMultiPoint(tempPoints,BoundingBox);
165
               resulShape = new FShape(multipoint,tipoShape);
166
           } else if (tipoShape == FConstant.SHAPE_TYPE_POINTZ) {
167
               FPoint p3d = new FPoint();
168
               p3d.read(bb);
169
               resulShape = new FShape(p3d,tipoShape);
170
           } else if ((tipoShape == FConstant.SHAPE_TYPE_POLYLINEZ) ||
171
                   (tipoShape == FConstant.SHAPE_TYPE_POLYGONZ)) {
172
               // BoundingBox
173
               BoundingBox = readRectangle(bb);
174
               numParts = bb.getInt();
175
               numPoints = bb.getInt();
176
               // part indexes.
177
               // Geometry geom = GeometryFactory.toGeometryArray();
178
    
179
               GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
180
                       numPoints);
181
               int[] tempParts = new int[numParts];
182
               for (i = 0; i < numParts; i++) {
183
                   tempParts[i] = bb.getInt();
184
               }
185
               j = 0;
186
              //Line2D.Double line2D;
187
               FPoint[] points=new FPoint[numPoints];
188
               for (i = 0; i < numPoints; i++) {
189
                   p = readPoint(bb);
190
                   points[i]=new FPoint(p.x,p.y);
191
    
192
                   if (i == tempParts[j]) {
193
                       elShape.moveTo(p.x, p.y);
194
                       if (j < (numParts - 1)) {
195
                           j++;
196
                       }
197
                   } else {
198
                       elShape.lineTo(p.x, p.y);
199
                   }
200
    
201
               }
202
    
203
               double[] boxZ = new double[2];
204
               boxZ[0] = bb.getDouble();
205
               boxZ[1] = bb.getDouble();
206
               double[] pZ = new double[numPoints];
207
               for (i = 0; i < numPoints; i++) {
208
                   pZ[i] = bb.getDouble();
209
               }
210
               //FGeometry pol=new FPolyLine(points,tempParts,BoundingBox);
211
               resulShape = new FShape(tipoShape, elShape, pZ);
212
           } else if (tipoShape == FConstant.SHAPE_TYPE_MULTIPOINTZ) {
213
               // BoundingBox
214
               BoundingBox = readRectangle(bb);
215
               numPoints = bb.getInt();
216
               FPoint[] tempPoints3D = new FPoint[numPoints];
217
               for (i = 0; i < numPoints; i++) {
218
                   tempPoints3D[i] = new FPoint();
219
                   tempPoints3D[i].read(bb);
220
               }
221
               FMultiPoint multipoint3D = new FMultiPoint(tempPoints3D,BoundingBox);
222
               resulShape = new FShape(multipoint3D,tipoShape);
223
           }
224
       } catch (Exception e) {
225
           System.err.println("Fallo en getShapeByID. ID=" + ID +
226
               " m_posShapes[ID]=" + m_posShapes[ID]);
227
           System.err.println("getShapeByID: " + e.getMessage());
228
           e.printStackTrace();
229
       }
230
       return resulShape;
231
       }
232
     */
233
    public IGeometry getShape(int index) throws IOException {
234
        Point2D.Double p = new Point2D.Double();
235
        Point2D.Double pAnt = null;
236
        int numParts;
237
        int numPoints;
238
        int i;
239
        int j;
240
        int numReg;
241
        int numeroPuntos;
242
        int hasta;
243
        int desde;
244
        int shapeType;
245

    
246
        //Rectangle2D.Double BoundingBox;
247
        bb.position(m_posShapes[index]);
248
        bb.order(ByteOrder.LITTLE_ENDIAN);
249

    
250
        ///bb.position(bb.position()+4);
251
        shapeType = bb.getInt();
252

    
253
        // retrieve that shape.
254
        // tempRecord.setShape(readShape(tempShapeType, tempContentLength, in));
255
        switch (type) {
256
            case (SHP.POINT2D):
257
                p = readPoint(bb);
258

    
259
                return ShapeFactory.createPoint2D(p.getX(), p.getY());
260

    
261
            case (SHP.POLYLINE2D):
262

    
263
                //BoundingBox = readRectangle(bb);
264
                //bb.getDouble();
265
                //bb.getDouble();
266
                //bb.getDouble();
267
                //bb.getDouble();
268
                bb.position(bb.position() + 32);
269
                numParts = bb.getInt();
270
                numPoints = bb.getInt();
271

    
272
                // part indexes.
273
                // Geometry geom = GeometryFactory.toGeometryArray();
274
                GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
275
                        numPoints);
276

    
277
                int[] tempParts = new int[numParts];
278

    
279
                for (i = 0; i < numParts; i++) {
280
                    tempParts[i] = bb.getInt();
281
                }
282

    
283
                j = 0;
284

    
285
                for (i = 0; i < numPoints; i++) {
286
                    p = readPoint(bb);
287

    
288
                    if (i == tempParts[j]) {
289
                        elShape.moveTo(p.x, p.y);
290

    
291
                        if (j < (numParts - 1)) {
292
                            j++;
293
                        }
294
                    } else {
295
                        elShape.lineTo(p.x, p.y);
296
                    }
297
                }
298

    
299
                return ShapeFactory.createPolyline2D(elShape);
300

    
301
            case (SHP.POLYGON2D):
302

    
303
                //                            BoundingBox = readRectangle(bb);
304
                bb.getDouble();
305
                bb.getDouble();
306
                bb.getDouble();
307
                bb.getDouble();
308

    
309
                numParts = bb.getInt();
310

    
311
                numPoints = bb.getInt();
312

    
313
                // part indexes.
314
                // Geometry geom = GeometryFactory.toGeometryArray();
315
                elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
316

    
317
                tempParts = new int[numParts];
318

    
319
                for (i = 0; i < numParts; i++) {
320
                    tempParts[i] = bb.getInt();
321
                }
322

    
323
                j = 0;
324

    
325
                for (i = 0; i < numPoints; i++) {
326
                    p = readPoint(bb);
327

    
328
                    if (i == tempParts[j]) {
329
                        elShape.moveTo(p.x, p.y);
330

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

    
339
                return ShapeFactory.createPolygon2D(elShape);
340

    
341
            case (SHP.POINT3D):
342

    
343
                double x = bb.getDouble();
344
                double y = bb.getDouble();
345
                double z = bb.getDouble();
346

    
347
                return ShapeFactory.createPoint3D(x, y, z);
348

    
349
            case (SHP.POLYLINE3D):
350
                bb.position(bb.position() + 32);
351
                numParts = bb.getInt();
352
                numPoints = bb.getInt();
353
                elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
354
                tempParts = new int[numParts];
355

    
356
                for (i = 0; i < numParts; i++) {
357
                    tempParts[i] = bb.getInt();
358
                }
359

    
360
                j = 0;
361

    
362
                for (i = 0; i < numPoints; i++) {
363
                    p = readPoint(bb);
364

    
365
                    if (i == tempParts[j]) {
366
                        elShape.moveTo(p.x, p.y);
367

    
368
                        if (j < (numParts - 1)) {
369
                            j++;
370
                        }
371
                    } else {
372
                        elShape.lineTo(p.x, p.y);
373
                    }
374
                }
375

    
376
                double[] boxZ = new double[2];
377
                boxZ[0] = bb.getDouble();
378
                boxZ[1] = bb.getDouble();
379

    
380
                double[] pZ = new double[numPoints];
381

    
382
                for (i = 0; i < numPoints; i++) {
383
                    pZ[i] = bb.getDouble();
384
                }
385

    
386
                return ShapeFactory.createPolyline3D(elShape, pZ);
387

    
388
            case (SHP.MULTIPOINT2D):
389
                bb.position(bb.position() + 32);
390
                numPoints = bb.getInt();
391

    
392
                double[] tempX = new double[numPoints];
393
                double[] tempY = new double[numPoints];
394

    
395
                for (i = 0; i < numPoints; i++) {
396
                    tempX[i] = bb.getDouble();
397
                    tempY[i] = bb.getDouble();
398
                }
399

    
400
                return ShapeFactory.createMultipoint2D(tempX, tempY);
401

    
402
            case (SHP.MULTIPOINT3D):
403
                bb.position(bb.position() + 32);
404
                numPoints = bb.getInt();
405

    
406
                double[] temX = new double[numPoints];
407
                double[] temY = new double[numPoints];
408
                double[] temZ = new double[numPoints];
409

    
410
                for (i = 0; i < numPoints; i++) {
411
                    temX[i] = bb.getDouble();
412
                    temY[i] = bb.getDouble();
413
                    temZ[i] = bb.getDouble();
414
                }
415

    
416
                return ShapeFactory.createMultipoint3D(temX, temY, temZ);
417
        }
418

    
419
        return null;
420
    }
421

    
422
    /**
423
     * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getShapeCount()
424
     */
425
    public int getShapeCount() {
426
        return numReg;
427
    }
428

    
429
    /**
430
     * @see com.iver.cit.gvsig.fmap.drivers.VectorialDriver#getShapeType()
431
     */
432
    public int getShapeType() {
433
        int auxType = 0;
434

    
435
        switch (type) {
436
            case (SHP.POINT2D):
437
                auxType = auxType | FShape.POINT;
438
                break;
439

    
440
            case (SHP.POLYLINE2D):
441
                auxType = auxType | FShape.LINE;
442
                break;
443

    
444
            case (SHP.POLYGON2D):
445
                auxType = auxType | FShape.POLYGON;
446
                break;
447
            case (SHP.POINT3D):
448
                auxType = auxType | FShape.POINT;
449
                    break;
450
            case (SHP.POLYLINE3D):
451
                auxType = auxType | FShape.LINE;
452
                    break;
453

    
454
            case (SHP.MULTIPOINT2D):
455
                auxType = auxType | FShape.MULTI;
456
                    break;
457

    
458
            case (SHP.MULTIPOINT3D):
459
                auxType = auxType | FShape.MULTI;
460
                    break;
461
                
462
        }
463

    
464
        return auxType;
465
    }
466

    
467
    /**
468
     * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#initialize()
469
     */
470
    public void initialize() {
471
        try {
472
            // create a new header.
473
            ShapeFileHeader myHeader = new ShapeFileHeader();
474

    
475
            // read the header
476
            myHeader.readHeader(bb);
477

    
478
            extent = new Rectangle2D.Double(myHeader.myXmin, myHeader.myYmin,
479
                    myHeader.myXmax - myHeader.myXmin,
480
                    myHeader.myYmax - myHeader.myYmin);
481

    
482
            type = myHeader.myShapeType;
483

    
484
            double x = myHeader.myXmin;
485
            double y = myHeader.myYmin;
486
            double w = myHeader.myXmax - myHeader.myXmin;
487
            double h = myHeader.myYmax - myHeader.myYmin;
488

    
489
            if (w == 0) {
490
                x -= 0.1;
491
                w = 0.2;
492
            }
493

    
494
            if (h == 0) {
495
                y -= 0.1;
496
                h = 0.2;
497
            }
498

    
499
            // String strFichDbf = m_Path.toLowerCase().replaceAll("\\.shp", ".dbf");
500
            String strFichDbf = file.getAbsolutePath().replaceAll("\\.shp",
501
                    ".dbf");
502
            strFichDbf = strFichDbf.replaceAll("\\.SHP", ".DBF");
503

    
504
            DbaseFileNIO m_FichDbf = new DbaseFileNIO();
505

    
506
            m_FichDbf.open(new File(strFichDbf));
507
            numReg = m_FichDbf.getRecordCount();
508
            m_posShapes = new int[numReg];
509

    
510
            // read the records.
511
            int tempCurrentLength = myHeader.getHeaderLength();
512
            int numReg = 0;
513

    
514
            int pos1;
515

    
516
            while (tempCurrentLength < myHeader.myFileLength) {
517
                // read the record header
518
                // ShapeFileRecord tempRecord = new ShapeFileRecord();
519
                // Bytes 0 to 4 represent the record number in the file, these may be out of order.
520
                bb.order(ByteOrder.BIG_ENDIAN);
521

    
522
                // tempRecord.setIndex(in.readInt());
523
                bb.getInt();
524

    
525
                // read the content length of this record in 16 bit words, excluding the index.
526
                // in.setLittleEndianMode(false);
527
                int tempContentLength = bb.getInt();
528

    
529
                pos1 = bb.position();
530

    
531
                m_posShapes[numReg] = bb.position();
532

    
533
                // Posicionamos
534
                bb.position((pos1 + (2 * tempContentLength)));
535
                numReg = numReg + 1;
536

    
537
                // update the current length the 4 is for the index, and content length.
538
                tempCurrentLength = tempCurrentLength + 4 + tempContentLength;
539
            }
540
        } catch (Exception e) {
541
            e.printStackTrace();
542
        }
543
    }
544

    
545
    /**
546
     * Reads the Point from the shape file.
547
     *
548
     * @param in DOCUMENT ME!
549
     *
550
     * @return DOCUMENT ME!
551
     */
552
    private Point2D.Double readPoint(ByteBuffer in) {
553
        // create a new point
554
        Point2D.Double tempPoint = new Point2D.Double();
555

    
556
        // bytes 1 to 4 are the type and have already been read.
557
        // bytes 4 to 12 are the X coordinate
558
        in.order(ByteOrder.LITTLE_ENDIAN);
559
        tempPoint.setLocation(in.getDouble(), in.getDouble());
560

    
561
        return tempPoint;
562
    }
563

    
564
    /**
565
     * Lee un rect?ngulo del fichero.
566
     *
567
     * @param in DOCUMENT ME!
568
     *
569
     * @return DOCUMENT ME!
570
     *
571
     * @throws IOException DOCUMENT ME!
572
     */
573
    private Rectangle2D.Double readRectangle(ByteBuffer in)
574
        throws IOException {
575
        Rectangle2D.Double tempRect = new Rectangle2D.Double();
576
        in.order(ByteOrder.LITTLE_ENDIAN);
577
        tempRect.x = in.getDouble();
578
        tempRect.y = in.getDouble();
579

    
580
        tempRect.width = in.getDouble() - tempRect.x;
581

    
582
        if (tempRect.width == 0) {
583
            tempRect.width = 0.2;
584
            tempRect.x -= 0.1;
585
        }
586

    
587
        tempRect.height = in.getDouble() - tempRect.y;
588

    
589
        if (tempRect.height == 0) {
590
            tempRect.height = 0.2;
591
            tempRect.y -= 0.1;
592
        }
593

    
594
        return tempRect;
595
    }
596

    
597
    /**
598
     * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getFullExtent()
599
     */
600
    public Rectangle2D getFullExtent() throws IOException {
601
        return extent;
602
    }
603

    
604
    /**
605
     * DOCUMENT ME!
606
     *
607
     * @param index DOCUMENT ME!
608
     *
609
     * @return DOCUMENT ME!
610
     *
611
     * @throws IOException
612
     *
613
     * @see com.iver.cit.gvsig.fmap.drivers.BoundedShapes#getShapeBounds()
614
     */
615
    public Rectangle2D getShapeBounds(int index) throws IOException {
616
        Point2D p = new Point2D.Double();
617
        Rectangle2D BoundingBox = new Rectangle2D.Double();
618
        bb.position(m_posShapes[index]);
619
        bb.order(ByteOrder.LITTLE_ENDIAN);
620

    
621
        int tipoShape = bb.getInt();
622

    
623
        if (tipoShape != SHP.NULL) {
624
            type = tipoShape;
625
        }
626

    
627
        // retrieve that shape.
628
        // tempRecord.setShape(readShape(tempShapeType, tempContentLength, in));
629
        switch (tipoShape) {
630
            case (SHP.POINT2D):
631
            case (SHP.POINT3D):
632
                p = readPoint(bb);
633
                BoundingBox = new Rectangle2D.Double(p.getX() - 0.1,
634
                        p.getY() - 0.1, 0.2, 0.2);
635

    
636
                break;
637

    
638
            case (SHP.POLYLINE2D):
639
            case (SHP.POLYGON2D):
640
            case (SHP.MULTIPOINT2D):
641
            case (SHP.POLYLINE3D):
642
            case (SHP.POLYGON3D):
643
            case (SHP.MULTIPOINT3D):
644

    
645
                // BoundingBox
646
                BoundingBox = readRectangle(bb);
647

    
648
                break;
649
        }
650

    
651
        return BoundingBox;
652
    }
653

    
654
    /**
655
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#accept(java.io.File)
656
         */
657
        public boolean accept(File f) {
658
                return (f.getName().toUpperCase().endsWith("SHP"));
659
        }
660

    
661
        /**
662
         * @see com.hardcode.driverManager.Driver#getType()
663
         */
664
        public String getName() {
665
                return "gvSIG shp driver";
666
        }
667

    
668
        /**
669
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getDataDriverName()
670
         */
671
        public String getDataDriverName() {
672
                return "gdbms dbf driver";
673
        }
674

    
675
        /**
676
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getDataFile(java.io.File)
677
         */
678
        public File getDataFile(File f) {
679
                String str = f.getAbsolutePath();
680
                
681
                return new File(str.substring(0, str.length() - 3)+ "dbf");
682
        }
683

    
684
        /* (non-Javadoc)
685
         * @see com.iver.cit.gvsig.fmap.drivers.BoundedShapes#getShapeType(int)
686
         */
687
        public int getShapeType(int index) {
688
                // Por ahora todos los fichero .shp contienen
689
                // entidades del mismo tipo. Si trabajamos con
690
                // alguno mixto, tendremos que cambiar esta funci?n.
691
                return getShapeType();
692
        }
693
}