Statistics
| Revision:

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

History | View | Annotate | Download (20.3 KB)

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

    
3
import com.iver.cit.gvsig.fmap.core.FShape;
4
import com.iver.cit.gvsig.fmap.core.GeneralPathX;
5
import com.iver.cit.gvsig.fmap.core.IGeometry;
6
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
7
import com.iver.cit.gvsig.fmap.drivers.BoundedShapes;
8
import com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver;
9
import com.iver.cit.gvsig.fmap.layers.FRecordset;
10

    
11
import java.awt.geom.Point2D;
12
import java.awt.geom.Rectangle2D;
13

    
14
import java.io.File;
15
import java.io.FileInputStream;
16
import java.io.IOException;
17

    
18
import java.nio.ByteBuffer;
19
import java.nio.ByteOrder;
20
import java.nio.channels.FileChannel;
21

    
22

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

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

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

    
60
        if (ret != null) {
61
            throw ret;
62
        }
63
    }
64

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

    
71
        fin = new FileInputStream(f);
72

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

    
76
        long size = channel.size();
77

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

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

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

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

    
252
        ///bb.position(bb.position()+4);
253
        shapeType = bb.getInt();
254

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

    
261
                return ShapeFactory.createPoint2D(p.getX(), p.getY());
262

    
263
            case (SHP.POLYLINE2D):
264

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

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

    
279
                int[] tempParts = new int[numParts];
280

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

    
285
                j = 0;
286

    
287
                for (i = 0; i < numPoints; i++) {
288
                    p = readPoint(bb);
289

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

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

    
301
                return ShapeFactory.createPolyline2D(elShape);
302

    
303
            case (SHP.POLYGON2D):
304

    
305
                //                            BoundingBox = readRectangle(bb);
306
                bb.getDouble();
307
                bb.getDouble();
308
                bb.getDouble();
309
                bb.getDouble();
310

    
311
                numParts = bb.getInt();
312

    
313
                numPoints = bb.getInt();
314

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

    
319
                tempParts = new int[numParts];
320

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

    
325
                j = 0;
326

    
327
                for (i = 0; i < numPoints; i++) {
328
                    p = readPoint(bb);
329

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

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

    
341
                return ShapeFactory.createPolygon2D(elShape);
342

    
343
            case (SHP.POINT3D):
344

    
345
                double x = bb.getDouble();
346
                double y = bb.getDouble();
347
                double z = bb.getDouble();
348

    
349
                return ShapeFactory.createPoint3D(x, y, z);
350

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

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

    
362
                j = 0;
363

    
364
                for (i = 0; i < numPoints; i++) {
365
                    p = readPoint(bb);
366

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

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

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

    
382
                double[] pZ = new double[numPoints];
383

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

    
388
                return ShapeFactory.createPolyline3D(elShape, pZ);
389

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

    
394
                double[] tempX = new double[numPoints];
395
                double[] tempY = new double[numPoints];
396

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

    
402
                return ShapeFactory.createMultipoint2D(tempX, tempY);
403

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

    
408
                double[] temX = new double[numPoints];
409
                double[] temY = new double[numPoints];
410
                double[] temZ = new double[numPoints];
411

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

    
418
                return ShapeFactory.createMultipoint3D(temX, temY, temZ);
419
        }
420

    
421
        return null;
422
    }
423

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

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

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

    
441
                break;
442

    
443
            case (SHP.POLYLINE2D):
444
                auxType = auxType | FShape.LINE;
445

    
446
                break;
447

    
448
            case (SHP.POLYGON2D):
449
                auxType = auxType | FShape.POLYGON;
450

    
451
                break;
452
        }
453

    
454
        return auxType;
455
    }
456

    
457
    /**
458
     * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#initialize()
459
     */
460
    public void initialize() {
461
        try {
462
            // create a new header.
463
            ShapeFileHeader myHeader = new ShapeFileHeader();
464

    
465
            // read the header
466
            myHeader.readHeader(bb);
467

    
468
            extent = new Rectangle2D.Double(myHeader.myXmin, myHeader.myYmin,
469
                    myHeader.myXmax - myHeader.myXmin,
470
                    myHeader.myYmax - myHeader.myYmin);
471

    
472
            type = myHeader.myShapeType;
473

    
474
            double x = myHeader.myXmin;
475
            double y = myHeader.myYmin;
476
            double w = myHeader.myXmax - myHeader.myXmin;
477
            double h = myHeader.myYmax - myHeader.myYmin;
478

    
479
            if (w == 0) {
480
                x -= 0.1;
481
                w = 0.2;
482
            }
483

    
484
            if (h == 0) {
485
                y -= 0.1;
486
                h = 0.2;
487
            }
488

    
489
            // String strFichDbf = m_Path.toLowerCase().replaceAll("\\.shp", ".dbf");
490
            String strFichDbf = file.getAbsolutePath().replaceAll("\\.shp",
491
                    ".dbf");
492
            strFichDbf = strFichDbf.replaceAll("\\.SHP", ".DBF");
493

    
494
            DbaseFileNIO m_FichDbf = new DbaseFileNIO();
495

    
496
            m_FichDbf.open(new File(strFichDbf));
497
            numReg = m_FichDbf.getRecordCount();
498
            m_posShapes = new int[numReg];
499

    
500
            // read the records.
501
            int tempCurrentLength = myHeader.getHeaderLength();
502
            int numReg = 0;
503

    
504
            int pos1;
505

    
506
            while (tempCurrentLength < myHeader.myFileLength) {
507
                // read the record header
508
                // ShapeFileRecord tempRecord = new ShapeFileRecord();
509
                // Bytes 0 to 4 represent the record number in the file, these may be out of order.
510
                bb.order(ByteOrder.BIG_ENDIAN);
511

    
512
                // tempRecord.setIndex(in.readInt());
513
                bb.getInt();
514

    
515
                // read the content length of this record in 16 bit words, excluding the index.
516
                // in.setLittleEndianMode(false);
517
                int tempContentLength = bb.getInt();
518

    
519
                pos1 = bb.position();
520

    
521
                m_posShapes[numReg] = bb.position();
522

    
523
                // Posicionamos
524
                bb.position((pos1 + (2 * tempContentLength)));
525
                numReg = numReg + 1;
526

    
527
                // update the current length the 4 is for the index, and content length.
528
                tempCurrentLength = tempCurrentLength + 4 + tempContentLength;
529
            }
530
        } catch (Exception e) {
531
            e.printStackTrace();
532
        }
533
    }
534

    
535
    /**
536
     * Reads the Point from the shape file.
537
     *
538
     * @param in DOCUMENT ME!
539
     *
540
     * @return DOCUMENT ME!
541
     */
542
    private Point2D.Double readPoint(ByteBuffer in) {
543
        // create a new point
544
        Point2D.Double tempPoint = new Point2D.Double();
545

    
546
        // bytes 1 to 4 are the type and have already been read.
547
        // bytes 4 to 12 are the X coordinate
548
        in.order(ByteOrder.LITTLE_ENDIAN);
549
        tempPoint.setLocation(in.getDouble(), in.getDouble());
550

    
551
        return tempPoint;
552
    }
553

    
554
    /**
555
     * Lee un rect?ngulo del fichero.
556
     *
557
     * @param in DOCUMENT ME!
558
     *
559
     * @return DOCUMENT ME!
560
     *
561
     * @throws IOException DOCUMENT ME!
562
     */
563
    private Rectangle2D.Double readRectangle(ByteBuffer in)
564
        throws IOException {
565
        Rectangle2D.Double tempRect = new Rectangle2D.Double();
566
        in.order(ByteOrder.LITTLE_ENDIAN);
567
        tempRect.x = in.getDouble();
568
        tempRect.y = in.getDouble();
569

    
570
        tempRect.width = in.getDouble() - tempRect.x;
571

    
572
        if (tempRect.width == 0) {
573
            tempRect.width = 0.2;
574
            tempRect.x -= 0.1;
575
        }
576

    
577
        tempRect.height = in.getDouble() - tempRect.y;
578

    
579
        if (tempRect.height == 0) {
580
            tempRect.height = 0.2;
581
            tempRect.y -= 0.1;
582
        }
583

    
584
        return tempRect;
585
    }
586

    
587
    /**
588
     * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getFullExtent()
589
     */
590
    public Rectangle2D getFullExtent() throws IOException {
591
        return extent;
592
    }
593

    
594
    /**
595
     * DOCUMENT ME!
596
     *
597
     * @param index DOCUMENT ME!
598
     *
599
     * @return DOCUMENT ME!
600
     *
601
     * @throws IOException
602
     *
603
     * @see com.iver.cit.gvsig.fmap.drivers.BoundedShapes#getShapeBounds()
604
     */
605
    public Rectangle2D getShapeBounds(int index) throws IOException {
606
        Point2D p = new Point2D.Double();
607
        Rectangle2D BoundingBox = new Rectangle2D.Double();
608
        bb.position(m_posShapes[index]);
609
        bb.order(ByteOrder.LITTLE_ENDIAN);
610

    
611
        int tipoShape = bb.getInt();
612

    
613
        if (tipoShape != SHP.NULL) {
614
            type = tipoShape;
615
        }
616

    
617
        // retrieve that shape.
618
        // tempRecord.setShape(readShape(tempShapeType, tempContentLength, in));
619
        switch (tipoShape) {
620
            case (SHP.POINT2D):
621
            case (SHP.POINT3D):
622
                p = readPoint(bb);
623
                BoundingBox = new Rectangle2D.Double(p.getX() - 0.1,
624
                        p.getY() - 0.1, 0.2, 0.2);
625

    
626
                break;
627

    
628
            case (SHP.POLYLINE2D):
629
            case (SHP.POLYGON2D):
630
            case (SHP.MULTIPOINT2D):
631
            case (SHP.POLYLINE3D):
632
            case (SHP.POLYGON3D):
633
            case (SHP.MULTIPOINT3D):
634

    
635
                // BoundingBox
636
                BoundingBox = readRectangle(bb);
637

    
638
                break;
639
        }
640

    
641
        return BoundingBox;
642
    }
643

    
644
    /**
645
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#accept(java.io.File)
646
         */
647
        public boolean accept(File f) {
648
                return (f.getName().toUpperCase().endsWith("SHP"));
649
        }
650

    
651
        /**
652
         * @see com.hardcode.driverManager.Driver#getType()
653
         */
654
        public String getName() {
655
                return "gvSIG shp driver";
656
        }
657

    
658
        /**
659
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getDataDriverName()
660
         */
661
        public String getDataDriverName() {
662
                return "gdbms dbf driver";
663
        }
664

    
665
        /**
666
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver#getDataFile(java.io.File)
667
         */
668
        public File getDataFile(File f) {
669
                String str = f.getAbsolutePath();
670
                
671
                return new File(str.substring(0, str.length() - 3)+ "dbf");
672
        }
673
}