Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libDielmoOpenLiDAR / src / org / gvsig / fmap / dal / store / lidar / LiDARStoreProvider.java @ 29326

History | View | Annotate | Download (13.1 KB)

1
/**
2
 *
3
 */
4
package org.gvsig.fmap.dal.store.lidar;
5

    
6
import java.awt.geom.Point2D;
7
import java.io.File;
8
import java.io.FileInputStream;
9
import java.io.IOException;
10
import java.nio.ByteOrder;
11
import java.nio.channels.FileChannel;
12
import java.util.ArrayList;
13
import java.util.Iterator;
14
import java.util.List;
15

    
16
import org.gvsig.fmap.dal.DataStoreNotification;
17
import org.gvsig.fmap.dal.DataTypes;
18
import org.gvsig.fmap.dal.exception.CloseException;
19
import org.gvsig.fmap.dal.exception.DataException;
20
import org.gvsig.fmap.dal.exception.InitializeException;
21
import org.gvsig.fmap.dal.exception.OpenException;
22
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
23
import org.gvsig.fmap.dal.feature.EditableFeatureType;
24
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
25
import org.gvsig.fmap.dal.feature.FeatureQuery;
26
import org.gvsig.fmap.dal.feature.FeatureStore;
27
import org.gvsig.fmap.dal.feature.FeatureType;
28
import org.gvsig.fmap.dal.feature.spi.AbstractFeatureStoreProvider;
29
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
30
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
31
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
32
import org.gvsig.fmap.dal.resource.exception.ResourceBeginException;
33
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyOpenException;
34
import org.gvsig.fmap.dal.resource.file.FileResource;
35
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
36
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
37
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
38
import org.gvsig.fmap.geom.Geometry;
39
import org.gvsig.fmap.geom.GeometryLocator;
40
import org.gvsig.fmap.geom.GeometryManager;
41
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
42
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
43
import org.gvsig.fmap.geom.exception.CreateGeometryException;
44
import org.gvsig.fmap.geom.primitive.Envelope;
45
import org.gvsig.tools.ToolsLocator;
46
import org.gvsig.tools.dynobject.DynClass;
47
import org.gvsig.tools.dynobject.DynField;
48
import org.gvsig.tools.dynobject.DynObjectManager;
49
import org.slf4j.Logger;
50
import org.slf4j.LoggerFactory;
51

    
52
import com.dielmo.lidar.BigByteBuffer2;
53
import com.dielmo.lidar.InicializeLidar;
54
import com.dielmo.lidar.LidarHeader;
55
import com.dielmo.lidar.LidarPoint;
56
import com.dielmo.lidar.UnexpectedLidarHeaderException;
57
import com.dielmo.lidar.fieldsDescription.fieldsDescription.ColumnDescription;
58
import com.dielmo.lidar.fieldsDescription.fieldsDescription.ContainerColumnDescription;
59

    
60
/**
61
 * @author jmvivo
62
 *
63
 */
64
public class LiDARStoreProvider extends AbstractFeatureStoreProvider implements
65
                ResourceConsumer {
66
        private static final GeometryManager geomManager = GeometryLocator.getGeometryManager();
67
        private static final Logger logger = LoggerFactory.getLogger(LiDARStoreProvider.class);
68

    
69
        public static String NAME = "LiDARStore";
70
        public static String DESCRIPTION = "LiDAR file";
71

    
72
        /**
73
         * LiDAR file.
74
         */
75
        private File m_Fich;
76

    
77
        /**
78
         * Temporal LiDAR file for writer. This is used in edition time.
79
         */
80
        private File fTemp;
81

    
82
        /**
83
         * 8 Kbytes buffer
84
         */
85
        private BigByteBuffer2 bb;
86

    
87
        /**
88
         * Channel to read, write and manipulate the LiDAR file
89
         */
90
        private FileChannel channel;
91

    
92
        /**
93
         * management of input read data from LiDAR file.
94
         */
95
        private FileInputStream fin;
96

    
97
        // informacion del LiDAR
98

    
99
        /**
100
         * Definition of one type of LiDAR point.
101
         */
102
        private LidarPoint lp;
103

    
104
        /**
105
         * Definition of one type of LiDAR header.
106
         */
107
        private LidarHeader hdr;
108

    
109
        // Writer
110
        /**
111
         * Writer assigned to LiDAR
112
         */
113
        // private LiDARWriter lidarWriter = new LiDARWriter();
114

    
115
        /**
116
         * Temporal folder to work in edition mode.
117
         */
118
        private static String tempDirectoryPath = System
119
                        .getProperty("java.io.tmpdir");
120

    
121

    
122

    
123

    
124
        private static final String DYNCLASS_NAME = "LiDARStore";
125
        protected static DynClass DYNCLASS = null;
126
        private ResourceProvider liDARResource;
127

    
128

    
129
        private long counterNewsOIDs = -1;
130
        private boolean isOpen = false;
131

    
132

    
133

    
134
        public LiDARStoreProvider(LiDARStoreParameters params,
135
                        DataStoreProviderServices storeServices)
136
                        throws InitializeException {
137
                super(params, storeServices, ToolsLocator.getDynObjectManager()
138
                                .createDynObject(DYNCLASS));
139

    
140
                m_Fich = getLiDARParameters().getFile();
141
                liDARResource = this.createResource(FileResource.NAME,
142
                                new Object[] { m_Fich.getAbsolutePath() });
143
                liDARResource.addConsumer(this);
144
                this.initFeatureType();
145

    
146
        }
147

    
148
        protected static void registerDynClass() {
149
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
150
                DynClass dynClass;
151
                DynField field;
152
                if (DYNCLASS == null) {
153

    
154
                        dynClass = dynman.add(DYNCLASS_NAME);
155

    
156
            // The SHP store parameters extend the DBF store parameters
157
                        dynClass.extend(dynman.get(FeatureStore.DYNCLASS_NAME));
158

    
159
                        DYNCLASS = dynClass;
160
                }
161

    
162
        }
163
        private LiDARStoreParameters getLiDARParameters() {
164
                return (LiDARStoreParameters) getParameters();
165
        }
166

    
167
        protected void initFeatureType() throws InitializeException {
168
                try {
169
                        this.open();
170
                } catch (OpenException e) {
171
                        throw new InitializeException(NAME, e);
172
                }
173
                LiDARStoreParameters liDARParams = getLiDARParameters();
174
                EditableFeatureType fType = this.getStoreServices().createFeatureType();
175
                FeatureType finalFType;
176

    
177
                fType.setHasOID(true);
178

    
179
                getFields(fType);
180

    
181
                EditableFeatureAttributeDescriptor attrGeo = fType.add("GEOMETRY",
182
                                DataTypes.GEOMETRY);
183
                attrGeo.setAllowNull(false);
184
                attrGeo.setGeometryType(Geometry.TYPES.POINT);
185
                attrGeo.setSRS(liDARParams.getSRS());
186
                fType.setDefaultGeometryAttributeName(attrGeo.getName());
187

    
188

    
189
                List types = new ArrayList(1);
190
                finalFType = fType.getNotEditableCopy();
191
                types.add(finalFType);
192
                this.getStoreServices().setFeatureTypes(types, finalFType);
193
        }
194

    
195
        private void getFields(EditableFeatureType fType ){
196

    
197
                ContainerColumnDescription columns = new ContainerColumnDescription();
198
                lp.getColumnsDescription(columns);
199

    
200
                int type;
201
                for(int i=0;i<columns.getColumns().size();i++){
202

    
203
                        type = columns.get(i).getFieldType();
204
                        if(type==ColumnDescription.DOUBLE){
205
                                fType.add(columns.get(i).getFieldName(),DataTypes.DOUBLE, columns.get(i).getFieldSize()).setPrecision(columns.get(i).getFieldPrecision()).setDefaultValue( (columns.get(i).getFieldDefaultValue()) );
206
                        }else if(type==ColumnDescription.INT){
207
                                fType.add(columns.get(i).getFieldName(),DataTypes.INT, columns.get(i).getFieldSize()).setPrecision(columns.get(i).getFieldPrecision()).setDefaultValue( (columns.get(i).getFieldDefaultValue()) );
208
                        }else if(type==ColumnDescription.LONG){
209
                                fType.add(columns.get(i).getFieldName(),DataTypes.LONG, columns.get(i).getFieldSize()).setPrecision(columns.get(i).getFieldPrecision()).setDefaultValue( (columns.get(i).getFieldDefaultValue()) );
210
                        } else if(type==ColumnDescription.BYTE) {
211
                                fType.add(columns.get(i).getFieldName(),DataTypes.BYTE, columns.get(i).getFieldSize()).setPrecision(columns.get(i).getFieldPrecision()).setDefaultValue( (columns.get(i).getFieldDefaultValue()) );
212
                        }
213
                }
214

    
215
        }
216

    
217
        public long getFeatureCount() throws DataException {
218
                this.open();
219
                this.liDARResource.begin();
220
                try {
221
                        return hdr.getNumPointsRecord();
222
                } finally {
223
                        this.liDARResource.end();
224
                }
225
        }
226

    
227
        /**
228
         *
229
         * @param index
230
         * @return
231
         * @throws DataException
232
         */
233
         FeatureProvider getFeatureProviderByIndex(long index, FeatureType fType)
234
                        throws DataException {
235
                 FeatureProvider data = this.createFeatureProvider(fType);
236
                this.loadFeatureProviderByIndex(data, index, fType);
237
                return data;
238
        }
239

    
240

    
241
        /* (non-Javadoc)
242
         * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#createNewOID()
243
         */
244
        public Object createNewOID() {
245
                if (this.counterNewsOIDs < 0) {
246
                        // try {
247
                        // this.counterNewsOIDs = this.getFeatureCount();
248
                        // } catch (DataException e) {
249
                        // e.printStackTrace();
250
                        // }
251

    
252
                } else {
253
                        this.counterNewsOIDs++;
254
                }
255
                return new Long(counterNewsOIDs);
256
        }
257

    
258
        /* (non-Javadoc)
259
         * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#createSet(org.gvsig.fmap.dal.feature.FeatureQuery)
260
         */
261
        public FeatureSetProvider createSet(FeatureQuery query, FeatureType featureType)
262
                        throws DataException {
263
                return new LiDARSetProvider(this, query, featureType);
264
        }
265

    
266
        /*
267
         * (non-Javadoc)
268
         *
269
         * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#getFeatureProviderByReference(org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices)
270
         */
271
        public FeatureProvider getFeatureProviderByReference(
272
                        FeatureReferenceProviderServices reference) throws DataException {
273
                return this.getFeatureProviderByReference(reference, this
274
                                .getFeatureStore()
275
                                .getDefaultFeatureType());
276
        }
277

    
278
        /* (non-Javadoc)
279
         * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#getFeatureProviderByReference(org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices, org.gvsig.fmap.dal.feature.FeatureType)
280
         */
281
        public FeatureProvider getFeatureProviderByReference(
282
                        FeatureReferenceProviderServices reference, FeatureType featureType)
283
                        throws DataException {
284
                return this.getFeatureProviderByIndex((Long) reference.getOID(),
285
                                featureType);
286
        }
287

    
288
        /* (non-Javadoc)
289
         * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#getFeatureReferenceOIDType()
290
         */
291
        public int getOIDType() {
292
                return DataTypes.LONG;
293
        }
294

    
295
        /* (non-Javadoc)
296
         * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#getName()
297
         */
298
        public String getName() {
299
                return NAME;
300
        }
301

    
302

    
303
        /* (non-Javadoc)
304
         * @see org.gvsig.fmap.dal.spi.DataStoreProvider#open()
305
         */
306
        public void open() throws OpenException {
307
                if (isOpen) {
308
                        return;
309
                }
310
                try {
311
                        liDARResource.begin();
312
                } catch (ResourceBeginException e1) {
313
                        throw new OpenException(NAME, e1);
314
                }
315

    
316
                try {
317

    
318
                        hdr = InicializeLidar.InizializeLidarHeader(m_Fich);
319

    
320
                        lp = InicializeLidar.InizializeLidarPoint(m_Fich);
321

    
322
                        fin = new FileInputStream(m_Fich);
323

    
324

    
325
                        // Open the file and then get a channel from the stream
326
                        channel = fin.getChannel();
327

    
328
                        // Get the file's size and then map it into memory
329
                        // bb = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
330
                        bb = new BigByteBuffer2(channel, FileChannel.MapMode.READ_ONLY);
331
                        bb.order(ByteOrder.LITTLE_ENDIAN);
332

    
333
                        isOpen = true;
334
                        liDARResource.notifyOpen();
335

    
336
                        // Cargar Metadatos !!! (Envelope, SRS...)
337
                        Envelope envelope = geomManager.createEnvelope(hdr.getMinX(), hdr
338
                                        .getMinY(), hdr.getMaxX(), hdr.getMaxY(), SUBTYPES.GEOM2D);
339
                        this.setDynValue("Envelope", envelope);
340
                } catch (IOException e) {
341
                        throw new OpenException(NAME, e);
342
                } catch (ResourceNotifyOpenException e) {
343
                        throw new OpenException(NAME, e);
344
                } catch (UnexpectedLidarHeaderException e) {
345
                        throw new OpenException(NAME, e);
346
                } catch (CreateEnvelopeException e) {
347
                        throw new OpenException(NAME, e);
348
                } finally {
349
                        liDARResource.end();
350
                }
351
        }
352

    
353
        public boolean closeResourceRequested(ResourceProvider resource) {
354
                try {
355
                        this.close();
356
                } catch (CloseException e) {
357
                        return false;
358
                }
359
                return true;
360
        }
361

    
362
        public boolean allowWrite() {
363
                // TODO
364
                return false;
365
        }
366

    
367
        public void close() throws CloseException {
368
                if (!isOpen) {
369
                        return;
370
                }
371
                try {
372
                        liDARResource.begin();
373
                } catch (ResourceBeginException e2) {
374
                        throw new CloseException(NAME, e2);
375
                }
376

    
377
                try {
378
                        IOException ret = null;
379
                        try {
380
                                channel.close();
381
                        } catch (IOException e) {
382
                                ret = e;
383
                        } finally {
384
                                try {
385
                                        fin.close();
386
                                } catch (IOException e1) {
387
                                        ret = e1;
388
                                }
389
                        }
390

    
391
                        if (ret != null) {
392
                                throw ret;
393
                        }
394
                        bb = null;
395
                        channel = null;
396
                        fin = null;
397
                        isOpen = false;
398
                } catch (IOException e) {
399
                        throw new CloseException(NAME, e);
400
                } finally {
401
                        liDARResource.end();
402
                }
403

    
404
        }
405

    
406
        @Override
407
        public void dispose() throws CloseException {
408
                this.close();
409
                this.lp = null;
410
                this.hdr = null;
411
                liDARResource.removeConsumer(this);
412
                liDARResource = null;
413
                m_Fich = null;
414
                fTemp = null;
415
                super.dispose();
416
        }
417

    
418
        @Override
419
        public void refresh() throws OpenException {
420
                try {
421
                        this.close();
422
                } catch (CloseException e) {
423
                        throw new OpenException(this.getName(), e);
424
                }
425
                this.open();
426
                try {
427
                        this.initFeatureType();
428
                } catch (InitializeException e) {
429
                        throw new OpenException(this.getName(), e);
430
                }
431

    
432
        }
433

    
434
        public void resourceChanged(ResourceProvider resource) {
435
                this.getStoreServices().notifyChange(
436
                                DataStoreNotification.RESOURCE_CHANGED,
437
                                resource);
438
        }
439

    
440
        public void loadFeatureProviderByIndex(FeatureProvider data, long index,
441
                        FeatureType featureType) throws DataException {
442
                this.open();
443
                liDARResource.begin();
444

    
445
                try {
446

    
447
                        if (index < 0 || hdr.getNumPointsRecord() <= index) {
448
                                // FIXME
449
                                throw new ArrayIndexOutOfBoundsException("" + index);
450
                        }
451

    
452
                        // lp.readPoint(bb, hdr, index);
453

    
454
                        data.setOID(index);
455

    
456
                        FeatureAttributeDescriptor attr;
457
                        Iterator iter = featureType.iterator();
458

    
459
                        Point2D.Double point;
460
                        while (iter.hasNext()) {
461
                                attr = (FeatureAttributeDescriptor) iter.next();
462
                                if (attr.getDataType() != DataTypes.GEOMETRY) {
463
                                        data.set(attr.getIndex(), lp.getFieldValueByName(bb, attr
464
                                                        .getName(), hdr, index));
465
                                } else {
466
                                        point = lp.readPoint2D(bb, hdr, index);
467
                                        try {
468
                                                data.set(attr.getIndex(), geomManager.createPoint(
469
                                                                point.x, point.y, SUBTYPES.GEOM2D));
470
                                        } catch (CreateGeometryException e) {
471
                                                logger.error("Error adding a point", e);
472
                                        }
473
                                }
474
                        }
475

    
476

    
477
                } finally {
478
                        liDARResource.end();
479
                }
480

    
481
        }
482

    
483
        public Object getSourceId() {
484
                return this.getLiDARParameters().getFile().getAbsolutePath();
485
        }
486

    
487
}