Statistics
| Revision:

svn-gvsig-desktop / branches / Mobile_Compatible_Hito_1 / libFMap_mobile_shp_driver / src-file / org / gvsig / data / datastores / vectorial / file / shp / SHPStore.java @ 21927

History | View | Annotate | Download (21 KB)

1
package org.gvsig.data.datastores.vectorial.file.shp;
2

    
3
import java.awt.geom.Point2D;
4
import java.io.File;
5
import java.io.FileNotFoundException;
6
import java.io.IOException;
7
import java.lang.ref.WeakReference;
8
import java.nio.ByteOrder;
9
import java.util.Collection;
10
import java.util.Iterator;
11
import java.util.List;
12

    
13
import org.apache.log4j.Logger;
14
import org.gvsig.data.CloseException;
15
import org.gvsig.data.DataCollection;
16
import org.gvsig.data.DataStoreParameters;
17
import org.gvsig.data.InitializeException;
18
import org.gvsig.data.OpenException;
19
import org.gvsig.data.ReadException;
20
import org.gvsig.data.WriteException;
21
import org.gvsig.data.datastores.vectorial.FeaturesWriter;
22
import org.gvsig.data.datastores.vectorial.file.dbf.DBFFeatureID;
23
import org.gvsig.data.datastores.vectorial.file.dbf.DBFStore;
24
import org.gvsig.data.datastores.vectorial.file.shp.utils.SHP;
25
import org.gvsig.data.datastores.vectorial.file.shp.utils.ShapeFileHeader2;
26
import org.gvsig.data.datastores.vectorial.file.shp_util.IGeometricDataStore;
27
import org.gvsig.data.spatialprovisionalold.Extent;
28
import org.gvsig.data.spatialprovisionalold.IExtent;
29
import org.gvsig.data.vectorial.AttributeDescriptor;
30
import org.gvsig.data.vectorial.DefaultFeatureType;
31
import org.gvsig.data.vectorial.Feature;
32
import org.gvsig.data.vectorial.FeatureAttributeDescriptor;
33
import org.gvsig.data.vectorial.FeatureCollection;
34
import org.gvsig.data.vectorial.FeatureID;
35
import org.gvsig.data.vectorial.FeatureType;
36
import org.gvsig.data.vectorial.IsNotAttributeSettingException;
37
import org.gvsig.data.vectorial.IsNotFeatureSettingException;
38
import org.gvsig.datasources.common.IBigByteBuffer;
39
import org.gvsig.datasources.common.IRandomFileChannel;
40
import org.gvsig.datasources.impljme.Impl;
41
import org.gvsig.exceptions.BaseException;
42
import org.gvsig.fmap.geom.Geometry;
43
import org.gvsig.fmap.geom.GeometryFactory;
44
import org.gvsig.fmap.geom.GeometryManager;
45
import org.gvsig.fmap.geom.primitive.DefaultEnvelope;
46
import org.gvsig.fmap.geom.primitive.Envelope;
47
import org.gvsig.fmap.geom.primitive.FShape;
48
import org.gvsig.fmap.geom.primitive.GeneralPathX;
49
import org.gvsig.fmap.geom.primitive.NullGeometry;
50
import org.gvsig.metadata.IMetadata;
51
import org.gvsig.metadata.IMetadataManager;
52
import org.gvsig.metadata.MetadataManager;
53
import org.opengis.filter.Filter;
54
import org.opengis.filter.sort.SortBy;
55

    
56
/**
57
 * This class was created by VCN and modified by jldominguez to make it
58
 * compatible with JME. Some interfaces are used to avoid the use of classes
59
 * that are not available on JME. See <tt>org.gvsig.datasources.common.*</tt>
60
 * for details.
61
 * 
62
 * @see org.gvsig.datasources.common
63
 * 
64
 * @author vcn
65
 * @author jldominguez
66
 * 
67
 */
68
public class SHPStore extends DBFStore implements IGeometricDataStore {
69
        
70
        private static Logger logger = Logger.getLogger(SHPStore.class);
71
        
72
        public static String DATASTORE_NAME = "SHPStore";
73

    
74
        static {
75
                Register.selfRegister();
76
        }
77

    
78
        private SHPStoreParameters shpParameters = null;
79

    
80
        private File fileShp;
81

    
82
        // private FileInputStream fin;
83
        private IRandomFileChannel channel;
84

    
85
        private IBigByteBuffer bb;
86

    
87
        private File fileShx;
88

    
89
        // private FileInputStream finShx;
90
        private IRandomFileChannel channelShx;
91

    
92
        private IBigByteBuffer bbShx;
93

    
94
        private Extent extent;
95

    
96
        private int type;
97

    
98
        private boolean onlyGeometry = false;
99

    
100
        public void init(DataStoreParameters parameters) throws InitializeException {
101
                super.init(parameters);
102
                featureType = super.getDefaultFeatureType();
103

    
104
                DefaultFeatureType ft_type = (DefaultFeatureType) featureType;
105
                AttributeDescriptor dad = (AttributeDescriptor) ft_type.createNewAttributeDescriptor();
106
                
107
                dad.loading();
108
                
109
                // DefaultAttributeDescriptor dad = new DefaultAttributeDescriptor();
110
                dad.setOrdinal(featureType.size());
111
                try {
112
                        dad.setName("GEOMETRY");
113
                        dad.setType(FeatureAttributeDescriptor.TYPE_GEOMETRY);
114
                } catch (IsNotAttributeSettingException e1) {
115
                        throw new InitializeException(this.getName(), e1.getMessage());
116
                }
117
                
118
                dad.stopLoading();
119
                
120
                featureType.add(dad);
121
                featureType.setDefaultGeometry("GEOMETRY");
122

    
123
                SHPStoreParameters shpParameters = (SHPStoreParameters) parameters;
124

    
125
                fileShp = shpParameters.getSHPFile();
126

    
127
                try {
128
                        // fin = new FileInputStream(fileShp);
129

    
130
                        // Open the file and then get a channel from the stream
131
                        channel = Impl.getRandomFileChannel(fileShp); // fin.getChannel();
132

    
133
                        // long size = channel.size();
134

    
135
                        // Get the file's size and then map it into memory
136
                        // bb = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
137
                        bb = Impl.getBigByteBuffer(channel,
138
                                        IRandomFileChannel.ACCESS_MODE_READ_ONLY);
139
                        fileShx = shpParameters.getSHXFile();
140
                        // finShx = new FileInputStream(fileShx);
141

    
142
                        // Open the file and then get a channel from the stream
143
                        channelShx = Impl.getRandomFileChannel(fileShx); // finShx.getChannel();
144

    
145
                        // long sizeShx = channelShx.size();
146

    
147
                        // Get the file's size and then map it into memory
148
                        // bb = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
149
                        // bbShx = channelShx.map(FileChannel.MapMode.READ_ONLY, 0,
150
                        // sizeShx);
151
                        // bbShx = new IBigByteBuffer(channelShx,
152
                        // FileChannel.MapMode.READ_ONLY);
153
                        bbShx = Impl.getBigByteBuffer(channelShx,
154
                                        IRandomFileChannel.ACCESS_MODE_READ_ONLY);
155
                        bbShx.order(ByteOrder.BIG_ENDIAN);
156
                } catch (FileNotFoundException e) {
157
                        throw new OpenException(getName(), e);
158
                } catch (IOException e) {
159
                        throw new OpenException(getName(), e);
160
                }
161

    
162
        }
163

    
164
        // private IFeatureAttributeDescriptor createFeatureAttribute(int i) {
165
        // char fieldType = dbf.getFieldType(i);
166
        // DefaultAttributeDescriptor dad=new DefaultAttributeDescriptor();
167
        // dad.setOrdinal(i);
168
        // dad.setName(dbf.getFieldName(i));
169
        // dad.setSize(dbf.getFieldLength(i));
170
        // if (fieldType == 'L') {
171
        // dad.setType(IFeatureAttributeDescriptor.TYPE_BOOLEAN);
172
        //
173
        // } else if ((fieldType == 'F') || (fieldType == 'N')) {
174
        // int precision = dbf.getFieldDecimalLength(i);
175
        // if (precision > 0){
176
        // dad.setType(IFeatureAttributeDescriptor.TYPE_DOUBLE);
177
        // dad.setPrecision(precision);
178
        // } else{
179
        // dad.setType(IFeatureAttributeDescriptor.TYPE_INT);
180
        // }
181
        // } else if (fieldType == 'C') {
182
        // dad.setType(IFeatureAttributeDescriptor.TYPE_STRING);
183
        // } else if (fieldType == 'D') {
184
        // dad.setType(IFeatureAttributeDescriptor.TYPE_DATE);
185
        // } else {
186
        // // throw new
187
        // BadFieldDriverException(getName(),null,String.valueOf(fieldType));
188
        // }
189
        // return dad;
190
        //
191
        // }
192

    
193
        protected void doFinishEdition() throws WriteException, ReadException {
194
                FeaturesWriter writer = getFeaturesWriter();
195
                writer.init(this);
196
                writer.updateFeatureType(featureType);
197
                writer.preProcess();
198
                Collection collection = getDataCollection();
199
                Iterator iterator = collection.iterator();
200
                Feature feature;
201
                while (iterator.hasNext()) {
202
                        feature = (Feature) iterator.next();
203
                        writer.insertFeature(feature);
204
                }
205
                writer.postProcess();
206

    
207
        }
208

    
209
        public DataCollection getDataCollection(FeatureType type, Filter filter,
210
                        SortBy[] order) throws ReadException {
211
                if (type == null) {
212
                        type = getDefaultFeatureType();
213
                }
214
                FeatureCollection coll;
215
                if (order == null) {
216
                        coll = new ShpFeatureCollection(featureManager, this, type, filter);
217
                } else {
218
                        coll = new ShpFeatureCollectionWithFeatureID(featureManager, this,
219
                                        type, filter, order);
220
                }
221

    
222
                this.addObserver(new WeakReference(coll));
223
                return coll;
224
        }
225

    
226
        public Feature getFeatureByID(FeatureID id) throws ReadException {
227

    
228
                if (this.alterMode) {
229
                        if (featureManager.contains(id)) {
230
                                return featureManager.getFeature(id, this, featureType);
231
                        }
232
                }
233
                return getFeatureByPosition(featureType, ((DBFFeatureID) id).getIndex());
234
        }
235

    
236
        public List getFeatureTypes() {
237
                if (featureTypes.size() == 0) {
238
                        featureTypes.add(new Integer(0));
239
                        featureTypes.set(0, getDefaultFeatureType());
240
                }
241
                return featureTypes;
242
        }
243

    
244
        public FeatureType getDefaultFeatureType() {
245
                FeatureType ft = featureType;
246
                if (isEditing()) {
247
                        // Aqu? hay que construir un FeatureType con los cambios que se
248
                        // hayan hecho en la edici?n.
249
                        return attributeManager.getFeatureType();
250
                }
251
                return ft;
252
        }
253

    
254
        public boolean isWithDefaultLegend() {
255
                return false;
256
        }
257

    
258
        public Object getDefaultLegend() {
259
                return null;
260
        }
261

    
262
        public Object getDefaultLabelingStrategy() {
263
                return null;
264
        }
265

    
266
        public boolean canAlterFeatureType() {
267
                return true;
268
        }
269

    
270
        public String getName() {
271
                return DATASTORE_NAME;
272
        }
273

    
274
        public void doOpen() throws OpenException {
275
                // this.observable.notifyObservers(new
276
                // DefaultFeatureStoreNotification(this,
277
                // DefaultFeatureStoreNotification.BEFORE_OPEN));
278
                super.doOpen();
279
                // create a new header.
280
                ShapeFileHeader2 myHeader = new ShapeFileHeader2();
281

    
282
                bb.position(0);
283

    
284
                // read the header
285
                myHeader.readHeader(bb);
286

    
287
                extent = new Extent(myHeader.myXmin, myHeader.myYmin, myHeader.myXmax,
288
                                myHeader.myYmax);
289
                // extent = new Rectangle2D.Double(myHeader.myXmin, myHeader.myYmin,
290
                // myHeader.myXmax - myHeader.myXmin,
291
                // myHeader.myYmax - myHeader.myYmin);
292

    
293
                type = myHeader.myShapeType;
294

    
295
                double x = myHeader.myXmin;
296
                double y = myHeader.myYmin;
297
                double w = myHeader.myXmax - myHeader.myXmin;
298
                double h = myHeader.myYmax - myHeader.myYmin;
299

    
300
                if (w == 0) {
301
                        x -= 0.1;
302
                        w = 0.2;
303
                }
304

    
305
                if (h == 0) {
306
                        y -= 0.1;
307
                        h = 0.2;
308
                }
309
                featureType.setGeometryTypes(new int[] { getGeometryType() });
310
                // String strFichDbf = m_Path.toLowerCase().replaceAll("\\.shp",
311
                // ".dbf");
312
                // String strFichDbf = fileShp.getAbsolutePath().replaceAll("\\.shp",
313
                // ".dbf");
314
                // strFichDbf = strFichDbf.replaceAll("\\.SHP", ".DBF");
315
                //
316
                // DbaseFileNIO m_FichDbf = new DbaseFileNIO();
317
                //
318
                // try {
319
                // m_FichDbf.open(new File(strFichDbf));
320
                // } catch (IOException e) {
321
                // // throw new FileNotFoundDriverException(getName(),e,strFichDbf);
322
                // }
323
                // numReg = m_FichDbf.getRecordCount();
324
                // this.observable.notifyObservers(new
325
                // DefaultFeatureStoreNotification(this,
326
                // DefaultFeatureStoreNotification.AFTER_OPEN));
327

    
328
        }
329

    
330
        public void doClose() throws CloseException {
331
                // this.observable.notifyObservers(new
332
                // DefaultFeatureStoreNotification(this,
333
                // DefaultFeatureStoreNotification.BEFORE_CLOSE));
334
                // super.close();
335
                CloseException ret = null;
336

    
337
                try {
338
                        channel.close();
339
                        channelShx.close();
340
                } catch (IOException e) {
341
                        ret = new CloseException(getName(), e);
342
                } finally {
343
                        // try {
344
                        // fin.close();
345
                        // } catch (IOException e1) {
346
                        // ret = new CloseException(getName(),e1);
347
                        // }
348
                }
349

    
350
                // if (ret != null) {
351
                // throw ret;
352
                // }
353
                bb = null;
354
                bbShx = null;
355
                super.doClose();
356
                // this.observable.notifyObservers(new
357
                // DefaultFeatureStoreNotification(this,
358
                // DefaultFeatureStoreNotification.AFTER_CLOSE));
359

    
360
        }
361

    
362
        public void doDispose() {
363
                // this.observable.notifyObservers(new
364
                // DefaultFeatureStoreNotification(this,
365
                // DefaultFeatureStoreNotification.BEFORE_DISPOSE));
366
                        super.doDispose();
367
                // this.observable.notifyObservers(new
368
                // DefaultFeatureStoreNotification(this,
369
                // DefaultFeatureStoreNotification.AFTER_DISPOSE));
370
        }
371

    
372
        public boolean isEditable() {
373
                if (super.isEditable() && fileShp.canWrite() && fileShx.canWrite())
374
                        return true;
375
                return false;
376
        }
377

    
378
        public IMetadata getMetadata() throws BaseException {
379
                if (metadata == null) {
380
                        IMetadataManager manager = MetadataManager.getManager();
381
                        metadata = manager.create(DATASTORE_NAME);
382
                        IExtent extent = getFullExtent();
383
                        metadata.set("extent", extent);
384
                        String srs = getSRS();
385
                        metadata.set("srs", srs);
386
                }
387
                if (this.alterMode) {
388
                        Envelope extent = (Envelope) metadata.get("extent");
389
                        FeatureCollection featureCollection = (FeatureCollection) getDataCollection();
390
                        if (spatialManager.isFullExtentDirty()) {
391
                                if (!featureCollection.isEmpty()) {
392
                                        Iterator featureIterator = featureCollection.iterator();
393
                                        extent = ((Feature) featureIterator.next()).getExtent();
394
                                        while (featureIterator.hasNext()) {
395
                                                Feature feature = (Feature) featureIterator.next();
396
                                                Envelope boundExtent = feature.getExtent();
397
                                                if (boundExtent != null)
398
                                                        extent.add(boundExtent);
399
                                        }
400
                                }
401
                        }
402
                        metadata.set("extent", extent);
403
                }
404
                return metadata;
405
        }
406

    
407
        protected Feature getFeatureByPosition(FeatureType featureType,
408
                        long position) throws ReadException {
409
                ShpFeature feature = new ShpFeature(featureType, this, position);
410
                // feature.loadOnlyGeometry(getGeometry(position));
411
                try {
412
                        
413
                        if (onlyGeometry) {
414
                                feature.load(getGeometry(position));
415
                        } else {
416
                                feature.load(dbf, getGeometry(position));
417
                        }
418
                } catch (IsNotFeatureSettingException e) {
419
                        logger.error("While loading feature: " + e.getMessage());
420
                }
421
                return feature;
422
        }
423

    
424
        protected FeaturesWriter getFeaturesWriter() {
425
                FeaturesWriter writer = new ShpFeaturesWriter();
426
                // writer.init(this);
427
                return writer;
428
        }
429

    
430
        protected long getFeatureCount() {
431
                return dbf.getRecordCount();
432
        }
433

    
434
        public DataStoreParameters getParameters() {
435
                return parameters;
436
        }
437

    
438
        private synchronized Geometry getGeometry(long position) {
439
                Point2D p = new Point2D.Double();
440
                int numParts;
441
                int numPoints;
442
                int i;
443
                int j;
444
                int shapeType;
445
                
446
                GeometryFactory gFactory = GeometryManager.getInstance().getGeometryFactory();
447

    
448
                bb.position(getPositionForRecord(position));
449
                bb.order(ByteOrder.LITTLE_ENDIAN);
450

    
451
                shapeType = bb.getInt();
452
                // el shape tal con tema tal y n?mro tal es null
453
                if (shapeType == SHP.NULL) {
454
                        return new NullGeometry();
455
                }
456

    
457
                // retrieve that shape.
458
                // tempRecord.setShape(readShape(tempShapeType, tempContentLength, in));
459
                switch (type) {
460
                case (SHP.POINT2D):
461
                        p = readPoint(bb);
462

    
463
                        return gFactory.createPoint2D(p.getX(), p.getY());
464

    
465
                case (SHP.POLYLINE2D):
466

    
467
                        bb.position(bb.position() + 32);
468
                        numParts = bb.getInt();
469
                        numPoints = bb.getInt();
470

    
471
                        // part indexes.
472
                        // Geometry geom = GeometryFactory.toGeometryArray();
473
                        GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
474
                                        numPoints);
475

    
476
                        int[] tempParts = new int[numParts];
477

    
478
                        for (i = 0; i < numParts; i++) {
479
                                tempParts[i] = bb.getInt();
480
                        }
481

    
482
                        j = 0;
483

    
484
                        for (i = 0; i < numPoints; i++) {
485
                                p = readPoint(bb);
486

    
487
                                if (i == tempParts[j]) {
488
                                        elShape.moveTo(p.getX(), p.getY());
489

    
490
                                        if (j < (numParts - 1)) {
491
                                                j++;
492
                                        }
493
                                } else {
494
                                        elShape.lineTo(p.getX(), p.getY());
495
                                }
496
                        }
497

    
498
                        return gFactory.createPolyline2D(elShape);
499

    
500
                case (SHP.POLYGON2D):
501

    
502
                        // BoundingBox = readRectangle(bb);
503
                        // bb.getDouble();
504
                        // bb.getDouble();
505
                        // bb.getDouble();
506
                        // bb.getDouble();
507

    
508
                        long posz = bb.position();
509
                        bb.position(bb.position() + 32);
510
                        numParts = bb.getInt();
511

    
512
                        numPoints = bb.getInt();
513

    
514
                        // part indexes.
515
                        // Geometry geom = GeometryFactory.toGeometryArray();
516
                        elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
517

    
518
                        tempParts = new int[numParts];
519

    
520
                        for (i = 0; i < numParts; i++) {
521
                                tempParts[i] = bb.getInt();
522
                        }
523

    
524
                        j = 0;
525

    
526
                        for (i = 0; i < numPoints; i++) {
527

    
528
                                p = readPoint(bb);
529

    
530
                                if (i == tempParts[j]) {
531
                                        elShape.moveTo(p.getX(), p.getY());
532

    
533
                                        if (j < (numParts - 1)) {
534
                                                j++;
535
                                        }
536
                                } else {
537
                                        if (i == numPoints - 1) {
538
                                                elShape.closePath();
539
                                        } else {
540
                                                elShape.lineTo(p.getX(), p.getY());
541
                                        }
542
                                }
543
                        }
544

    
545
                        return gFactory.createPolygon2D(elShape);
546

    
547
                case (SHP.POINT3D):
548

    
549
                        double x = bb.getDouble();
550
                        double y = bb.getDouble();
551
                        double z = bb.getDouble();
552

    
553
                        return gFactory.createPoint3D(x, y, z);
554

    
555
                case (SHP.POLYLINE3D):
556
                        bb.position(bb.position() + 32);
557
                        numParts = bb.getInt();
558
                        numPoints = bb.getInt();
559
                        elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
560
                        tempParts = new int[numParts];
561

    
562
                        for (i = 0; i < numParts; i++) {
563
                                tempParts[i] = bb.getInt();
564
                        }
565

    
566
                        j = 0;
567

    
568
                        for (i = 0; i < numPoints; i++) {
569
                                p = readPoint(bb);
570

    
571
                                if (i == tempParts[j]) {
572
                                        elShape.moveTo(p.getX(), p.getY());
573

    
574
                                        if (j < (numParts - 1)) {
575
                                                j++;
576
                                        }
577
                                } else {
578
                                        elShape.lineTo(p.getX(), p.getY());
579
                                }
580
                        }
581

    
582
                        double[] boxZ = new double[2];
583
                        boxZ[0] = bb.getDouble();
584
                        boxZ[1] = bb.getDouble();
585

    
586
                        double[] pZ = new double[numPoints];
587

    
588
                        for (i = 0; i < numPoints; i++) {
589
                                pZ[i] = bb.getDouble();
590
                        }
591

    
592
                        return gFactory.createPolyline3D(elShape, pZ);
593
                case (SHP.POLYGON3D):
594
                        bb.position(bb.position() + 32);
595
                        numParts = bb.getInt();
596
                        numPoints = bb.getInt();
597
                        elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
598
                        tempParts = new int[numParts];
599

    
600
                        for (i = 0; i < numParts; i++) {
601
                                tempParts[i] = bb.getInt();
602
                        }
603

    
604
                        j = 0;
605

    
606
                        for (i = 0; i < numPoints; i++) {
607
                                p = readPoint(bb);
608

    
609
                                if (i == tempParts[j]) {
610
                                        elShape.moveTo(p.getX(), p.getY());
611

    
612
                                        if (j < (numParts - 1)) {
613
                                                j++;
614
                                        }
615
                                } else {
616
                                        if (i == numPoints - 1) {
617
                                                elShape.closePath();
618
                                        } else {
619
                                                elShape.lineTo(p.getX(), p.getY());
620
                                        }
621
                                }
622
                        }
623

    
624
                        double[] boxpoZ = new double[2];
625
                        boxpoZ[0] = bb.getDouble();
626
                        boxpoZ[1] = bb.getDouble();
627

    
628
                        double[] poZ = new double[numPoints];
629

    
630
                        for (i = 0; i < numPoints; i++) {
631
                                poZ[i] = bb.getDouble();
632
                        }
633

    
634
                        return gFactory.createPolygon3D(elShape, poZ);
635

    
636
                case (SHP.MULTIPOINT2D):
637
                        bb.position(bb.position() + 32);
638
                        numPoints = bb.getInt();
639

    
640
                        double[] tempX = new double[numPoints];
641
                        double[] tempY = new double[numPoints];
642

    
643
                        for (i = 0; i < numPoints; i++) {
644
                                tempX[i] = bb.getDouble();
645
                                tempY[i] = bb.getDouble();
646
                        }
647

    
648
                        return gFactory.createMultipoint2D(tempX, tempY);
649

    
650
                case (SHP.MULTIPOINT3D):
651
                        bb.position(bb.position() + 32);
652
                        numPoints = bb.getInt();
653

    
654
                        double[] temX = new double[numPoints];
655
                        double[] temY = new double[numPoints];
656
                        double[] temZ = new double[numPoints];
657

    
658
                        for (i = 0; i < numPoints; i++) {
659
                                temX[i] = bb.getDouble();
660
                                temY[i] = bb.getDouble();
661
                                // temZ[i] = bb.getDouble();
662
                        }
663

    
664
                        for (i = 0; i < numPoints; i++) {
665
                                temZ[i] = bb.getDouble();
666
                        }
667
                        return gFactory.createMultipoint3D(temX, temY, temZ);
668
                }
669

    
670
                return null;
671

    
672
        }
673

    
674
        private long getPositionForRecord(long numRec) {
675
                // shx file has a 100 bytes header, then, records
676
                // 8 bytes length, one for each entity.
677
                // first 4 bytes are the offset
678
                // next 4 bytes are length
679

    
680
                int posIndex = 100 + ((int) numRec * 8);
681
                // bbShx.position(posIndex);
682
                long pos = 8 + 2 * bbShx.getInt(posIndex);
683

    
684
                return pos;
685
        }
686

    
687
        /**
688
         * Reads the Point from the shape file.
689
         * 
690
         * @param in
691
         *            ByteBuffer.
692
         * 
693
         * @return Point2D.
694
         */
695
        private synchronized Point2D readPoint(IBigByteBuffer in) {
696
                // create a new point
697
                Point2D.Double tempPoint = new Point2D.Double();
698

    
699
                // bytes 1 to 4 are the type and have already been read.
700
                // bytes 4 to 12 are the X coordinate
701
                in.order(ByteOrder.LITTLE_ENDIAN);
702
                tempPoint.setLocation(in.getDouble(), in.getDouble());
703

    
704
                return tempPoint;
705
        }
706

    
707
        /**
708
         * Lee un rect?ngulo del fichero.
709
         * 
710
         * @param in
711
         *            ByteBuffer.
712
         * 
713
         * @return Rect?ngulo.
714
         * 
715
         * @throws IOException
716
         */
717
        private synchronized IExtent readRectangle(IBigByteBuffer in) {
718

    
719
                in.order(ByteOrder.LITTLE_ENDIAN);
720
                double x = in.getDouble();
721
                double y = in.getDouble();
722

    
723
                double x2 = in.getDouble();
724

    
725
                if (x2 - x == 0) {
726
                        x2 = 0.2;
727
                        x -= 0.1;
728
                }
729

    
730
                double y2 = in.getDouble();
731

    
732
                if (y2 - y == 0) {
733
                        y2 = 0.2;
734
                        y -= 0.1;
735
                }
736
                IExtent tempRect = new Extent(x, y, x2, y2);
737
                return tempRect;
738
        }
739

    
740
        public org.gvsig.fmap.geom.primitive.Envelope getBoundingBox(
741
                        long featureIndex) {
742
                Point2D p = new Point2D.Double();
743
                IExtent BoundingBox = null;
744
                try {
745
                        bb.position(getPositionForRecord(featureIndex));
746
                } catch (Exception e) {
747
                        e.printStackTrace();
748
                        // logger.error(" Shapefile is corrupted. Drawing aborted. ="+e+ "
749
                        // "+"index = "+index);
750
                }
751
                bb.order(ByteOrder.LITTLE_ENDIAN);
752

    
753
                int tipoShape = bb.getInt();
754

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

    
762
                // retrieve that shape.
763
                // tempRecord.setShape(readShape(tempShapeType, tempContentLength, in));
764
                switch (tipoShape) {
765
                case (SHP.POINT2D):
766
                case (SHP.POINT3D):
767
                        p = readPoint(bb);
768
                        BoundingBox = new Extent(p.getX() - 0.1, p.getY() - 0.1,
769
                                        p.getX() + 0.2, p.getY() + 0.2);
770
                        // new Rectangle2D.Double(p.getX() - 0.1,
771
                        // p.getY() - 0.1, 0.2, 0.2);
772

    
773
                        break;
774

    
775
                case (SHP.POLYLINE2D):
776
                case (SHP.POLYGON2D):
777
                case (SHP.MULTIPOINT2D):
778
                case (SHP.POLYLINE3D):
779
                case (SHP.POLYGON3D):
780
                case (SHP.MULTIPOINT3D):
781

    
782
                        // BoundingBox
783
                        BoundingBox = readRectangle(bb);
784

    
785
                        break;
786
                }
787

    
788
                double[] min = { BoundingBox.getMin(0), BoundingBox.getMin(1) };
789
                double[] max = { BoundingBox.getMax(0), BoundingBox.getMax(1) };
790
                return new DefaultEnvelope(2, min, max);
791
        }
792

    
793
        private int getGeometryType() {
794
                int auxType = 0;
795

    
796
                switch (type) {
797
                case (SHP.POINT2D):
798
                case (SHP.POINT3D):
799
                        auxType = auxType | FShape.POINT;
800

    
801
                        break;
802

    
803
                case (SHP.POLYLINE2D):
804
                case (SHP.POLYLINE3D):
805
                        auxType = auxType | FShape.LINE;
806

    
807
                        break;
808

    
809
                case (SHP.POLYGON2D):
810
                case (SHP.POLYGON3D):
811
                        auxType = auxType | FShape.POLYGON;
812

    
813
                        break;
814
                case (SHP.MULTIPOINT2D):
815
                case (SHP.MULTIPOINT3D):
816
                        auxType = auxType | FShape.MULTIPOINT;
817

    
818
                        break;
819
                }
820

    
821
                return auxType;
822
        }
823

    
824
        /**
825
         * @return
826
         */
827
        public IExtent getFullExtent() {
828
                return extent;
829
        }
830

    
831
        /**
832
         * @deprecated
833
         * @return
834
         */
835
        private String getSRS() {
836
                // TODO Auto-generated method stub
837
                return null;
838
        }
839

    
840
        public void setOnlyGeometry(boolean b) {
841
                onlyGeometry = b;
842
        }
843

    
844
}