Statistics
| Revision:

svn-gvsig-desktop / branches / org.gvsig.desktop-2018a / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.file / org.gvsig.fmap.dal.file.bsq / src / main / java / org / gvsig / fmap / dal / fileutils / impl / DefaultHDRFile.java @ 43867

History | View | Annotate | Download (16.6 KB)

1
package org.gvsig.fmap.dal.fileutils.impl;
2

    
3
import org.gvsig.fmap.dal.fileutils.HDRFile;
4
import java.io.File;
5
import java.nio.ByteOrder;
6
import java.util.List;
7
import java.util.logging.Level;
8
import org.apache.commons.io.FileUtils;
9
import org.apache.commons.io.FilenameUtils;
10
import org.apache.commons.lang3.StringUtils;
11
import org.gvsig.fmap.geom.Geometry;
12
import org.gvsig.fmap.geom.GeometryLocator;
13
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
14
import org.gvsig.fmap.geom.primitive.Envelope;
15
import org.gvsig.raster.lib.buffer.api.BufferManager;
16
import org.slf4j.Logger;
17
import org.slf4j.LoggerFactory;
18

    
19
public class DefaultHDRFile implements HDRFile {
20

    
21
    // http://resources.esri.com/help/9.3/arcgisdesktop/com/gp_toolref/spatial_analyst_tools/esri_ascii_raster_format.htm
22
    private static final Logger logger = LoggerFactory.getLogger(DefaultHDRFile.class);
23

    
24
    private File source;
25
    private String comments;
26

    
27
    private int nrows = NONE;
28
    private int ncols = NONE;
29
    private int nbands = 1;
30
    private int nbits = 8;
31
    private String pixeltype;
32
    private String byteorder_word;
33
    private ByteOrder byteorder = ByteOrder.nativeOrder();
34
    private String layout = LAYOUT_BIL;
35
    private int skipbytes = 0;
36
    private double ulxmax = Double.NaN;
37
    private double ulymax = Double.NaN;
38
    private double xdim = Double.NaN;
39
    private double ydim = Double.NaN;
40
    private int bandrowbytes = NONE;
41
    private int totalrowbytes = NONE;
42
    private int bandgapbytes = 0;
43
    private boolean valid = false;
44
    private double nodata_value = Double.NaN;
45

    
46
    // X coordinate of the origin (by center or lower left corner of the cell).
47
    private double xllcorner = Double.NaN;
48

    
49
    // Y coordinate of the origin (by center or lower left corner of the cell).
50
    private double yllcorner = Double.NaN;
51

    
52
    private int cellsize = NONE;
53

    
54
    public DefaultHDRFile() {
55
        this.source = null;
56
    }
57

    
58
    @SuppressWarnings("OverridableMethodCallInConstructor")
59
    public DefaultHDRFile(File file) {
60
        this();
61
        this.read(file);
62
    }
63

    
64
    @Override
65
    public File getFile(File file) {
66
        File f = new File(FilenameUtils.removeExtension(file.getAbsolutePath()) + "." + FILE_EXTENSION);
67
        return f;
68
    }
69

    
70
    @Override
71
    public File getFile() {
72
        return source;
73
    }
74

    
75
    @Override
76
    public void read(File file) {
77
        File f = this.getFile(file);
78
        if (f.exists()) {
79
            try {
80
                List<String> lines = FileUtils.readLines(f);
81
                if (lines != null) {
82
                    this.source = f.getAbsoluteFile();
83
                    int lineno = 1;
84
                    for (String line : lines) {
85
                        String[] words = StringUtils.split(line.trim().toLowerCase());
86
                        try {
87
                            switch (words[0]) {
88
                                case "nrows":
89
                                    this.nrows = Integer.parseUnsignedInt(words[1]);
90
                                    break;
91
                                case "ncols":
92
                                    this.ncols = Integer.parseUnsignedInt(words[1]);
93
                                    break;
94
                                case "nbands":
95
                                    this.nbands = Integer.parseUnsignedInt(words[1]);
96
                                    break;
97
                                case "nbits":
98
                                    this.nbits = Integer.parseUnsignedInt(words[1]);
99
                                    break;
100
                                case "pixeltype":
101
                                    this.pixeltype = words[1];
102
                                    break;
103
                                case "byteorder":
104
                                    this.byteorder_word = words[1];
105
                                    break;
106
                                case "layout":
107
                                    this.layout = words[1];
108
                                    break;
109
                                case "skipbytes":
110
                                    this.skipbytes = Integer.parseUnsignedInt(words[1]);
111
                                    break;
112
                                case "nodata_value":
113
                                    this.nodata_value = Double.parseDouble(words[1]);
114
                                    break;
115
                                case "cellsize":
116
                                    this.cellsize = Integer.parseUnsignedInt(words[1]);
117
                                    break;
118
                                case "xllcorner":
119
                                case "xllcenter":
120
                                    this.xllcorner = Double.parseDouble(words[1]);
121
                                    break;
122
                                case "yllcorner":
123
                                case "yllcenter":
124
                                    this.yllcorner = Double.parseDouble(words[1]);
125
                                    break;
126
                                case "ulxmax":
127
                                    this.ulxmax = Double.parseDouble(words[1]);
128
                                    break;
129
                                case "ulymax":
130
                                    this.ulymax = Double.parseDouble(words[1]);
131
                                    break;
132
                                case "xdim":
133
                                    this.xdim = Double.parseDouble(words[1]);
134
                                    break;
135
                                case "ydim":
136
                                    this.ydim = Double.parseDouble(words[1]);
137
                                    break;
138
                                case "bandrowbytes":
139
                                    this.bandrowbytes = Integer.parseUnsignedInt(words[1]);
140
                                    break;
141
                                case "totalrowbytes":
142
                                    this.totalrowbytes = Integer.parseUnsignedInt(words[1]);
143
                                    break;
144
                                case "bandgapbytes":
145
                                    this.bandgapbytes = Integer.parseUnsignedInt(words[1]);
146
                                    break;
147
                            }
148
                        } catch (NumberFormatException e) {
149
                            logger.warn("Can't parse keyword '" + words[0]
150
                                    + "' (value='" + words[1]
151
                                    + "', lineno=+" + lineno
152
                                    + ", file=" + f.getAbsoluteFile()
153
                                    + ").", e);
154
                        }
155
                        lineno++;
156
                    }
157
                    this.fixValues();
158
                }
159

    
160
            } catch (Exception e) {
161
                logger.warn("Couldn't read " + FILE_EXTENSION + " file (" + f.getAbsoluteFile() + ")", e);
162
            }
163
        }
164
    }
165

    
166
    private void fixValues() {
167
        @SuppressWarnings("LocalVariableHidesMemberVariable")
168
        boolean valid = true;
169

    
170
        if (this.pixeltype != null) {
171
            switch (this.pixeltype) {
172
                case "signedint":
173
                    this.nbits = 32;
174
                    break;
175
                case "byte_unsigned":
176
                    this.nbits = 8;
177
                    break;
178
            }
179
        }
180

    
181
        switch (this.getNbits()) {
182
            case 1:
183
            case 4:
184
                logger.warn("nbits keyword has a non supported value of " + this.getNbits() + " (" + this.source.getAbsolutePath() + ").");
185
                valid = false;
186
                break;
187
            case 8:
188
            case 16:
189
            case 32:
190
            case 64:
191
                break;
192
            default:
193
                logger.warn("nbits keyword has an invalid value of " + this.getNbits() + " (" + this.source.getAbsolutePath() + ").");
194
                this.nbits = 1;
195
                valid = false;
196
                break;
197
        }
198

    
199
        switch (this.getLayout()) {
200
            case LAYOUT_BIL:
201
            case LAYOUT_BIP:
202
            case LAYOUT_BSQ:
203
                break;
204
            default:
205
                logger.warn("layout keyword has an invalid value of '" + this.getLayout() + "' (" + this.source.getAbsolutePath() + ").");
206
                this.layout = LAYOUT_BIL;
207
                valid = false;
208
                break;
209
        }
210

    
211
        if( StringUtils.isEmpty(this.byteorder_word) ) {
212
            this.byteorder = ByteOrder.nativeOrder();
213
            if( this.byteorder == ByteOrder.BIG_ENDIAN ) {
214
                this.byteorder_word = "msbfirst";
215
            } else {
216
                this.byteorder_word = "lsbfirst";
217
            }
218
        } else {
219
            switch(this.byteorder_word) {
220
                case "lsbfirst":
221
                case "little_endian":
222
                case "littleendian":
223
                case "intel":
224
                case "i":
225
                    this.byteorder = ByteOrder.LITTLE_ENDIAN;
226
                    break;
227
                case "motorola":
228
                case "m":
229
                case "msbfirst":
230
                case "big_endian":
231
                case "bigendian":
232
                    this.byteorder = ByteOrder.BIG_ENDIAN;
233
                    break;
234
                default:
235
                    logger.warn("byteorder keyword has an invalid value of '" + this.byteorder_word + "' (" + this.source.getAbsolutePath() + ").");
236
                    this.byteorder = ByteOrder.nativeOrder();
237
            }
238
        }
239
        if (this.getNrows() == NONE || this.getNcols() == NONE) {
240
            logger.warn("nrows/ncols keywords has an invalid value of '" + this.getNrows() + "/" + this.getNcols() + "' (" + this.source.getAbsolutePath() + ").");
241
            valid = false;
242
        }
243
        if (this.getUlymax() == NONE) {
244
            this.ulymax = this.getNrows() - 1;
245
        }
246
        if (this.getBandrowbytes() == NONE) {
247
            this.bandrowbytes = (this.getNcols() * this.getNbits()) / 8;
248
        }
249
        switch (this.getLayout()) {
250
            case LAYOUT_BIL:
251
                if (this.getTotalrowbytes() == NONE) {
252
                    this.totalrowbytes = this.getNbands() * this.getBandrowbytes();
253
                }
254
                this.bandgapbytes = 0;
255
                break;
256
            case LAYOUT_BIP:
257
                if (this.getTotalrowbytes() == NONE) {
258
                    this.totalrowbytes = (this.getNcols() * this.getNbands() * this.getNbits()) / 8;
259
                }
260
                this.bandgapbytes = 0;
261
                break;
262
            case LAYOUT_BSQ:
263
                if (this.getTotalrowbytes() == NONE) {
264
                    this.totalrowbytes = 0;
265
                }
266
                if (this.getBandgapbytes() == NONE) {
267
                    this.bandgapbytes = 0;
268
                }
269
                break;
270
        }
271
        this.valid = valid;
272
    }
273

    
274
    @Override
275
    public int getDataType() {
276
        if (this.pixeltype != null) {
277
            switch (this.pixeltype) {
278
                case "signedint":
279
                    return BufferManager.TYPE_INT;
280
                case "byte_unsigned":
281
                    return BufferManager.TYPE_BYTE;
282
            }
283
        }
284
        switch (this.getNbits()) {
285
            case 1:
286
            case 4:
287
            default:
288
                return BufferManager.TYPE_UNDEFINED;
289
            case 8:
290
                return BufferManager.TYPE_BYTE;
291
            case 16:
292
                return BufferManager.TYPE_USHORT;
293
            case 32:
294
                return BufferManager.TYPE_INT;
295
            case 64:
296
                return BufferManager.TYPE_DOUBLE;
297
        }
298
    }
299

    
300
    @Override
301
    public void write(File file) {
302
        // TODO: falta implementar el write del hdr
303
        File f = this.getFile(file);
304
    }
305

    
306
    @Override
307
    public Envelope getEnvelope() {
308
        Envelope envelope = null;
309
        try {
310
            if (!Double.isNaN(this.xllcorner)
311
                    && !Double.isNaN(this.yllcorner)
312
                    && this.cellsize > 0) {
313
                envelope = GeometryLocator.getGeometryManager().createEnvelope(
314
                        this.xllcorner,
315
                        this.yllcorner,
316
                        this.xllcorner + (this.ncols * this.cellsize),
317
                        this.yllcorner + (this.nrows * this.cellsize),
318
                        Geometry.SUBTYPES.GEOM2D);
319
            }
320
            if (envelope == null && !Double.isNaN(this.ulxmax)
321
                    && !Double.isNaN(this.ulymax)
322
                    && !Double.isNaN(this.xdim)
323
                    && !Double.isNaN(this.ydim)) {
324
                envelope = GeometryLocator.getGeometryManager().createEnvelope(
325
                        this.ulxmax,
326
                        this.ulymax - (this.nrows * this.ydim),
327
                        this.ulxmax + (this.ncols * this.xdim),
328
                        this.ulymax,
329
                        Geometry.SUBTYPES.GEOM2D);
330
            }
331
            if (envelope == null && !Double.isNaN(this.xdim)
332
                    && !Double.isNaN(this.ydim)) {
333
                envelope = GeometryLocator.getGeometryManager().createEnvelope(
334
                        0,
335
                        0,
336
                        this.ncols * this.xdim,
337
                        this.nrows * this.ydim,
338
                        Geometry.SUBTYPES.GEOM2D);
339
            }
340
            if (envelope == null && this.cellsize > 0) {
341
                envelope = GeometryLocator.getGeometryManager().createEnvelope(
342
                        0,
343
                        0,
344
                        this.ncols * this.cellsize,
345
                        this.nrows * this.cellsize,
346
                        Geometry.SUBTYPES.GEOM2D);
347
            }
348
            if (envelope == null) {
349
                envelope = GeometryLocator.getGeometryManager().createEnvelope(
350
                        0,
351
                        0,
352
                        this.ncols,
353
                        this.nrows,
354
                        Geometry.SUBTYPES.GEOM2D);
355
            }
356
        } catch (Exception ex) {
357
            logger.debug("Can't calculate envelope.", ex);
358
        }
359
        return envelope;
360
    }
361

    
362
    /**
363
     * @return the nrows
364
     */
365
    @Override
366
    public int getNrows() {
367
        return nrows;
368
    }
369

    
370
    /**
371
     * @return the ncols
372
     */
373
    @Override
374
    public int getNcols() {
375
        return ncols;
376
    }
377

    
378
    /**
379
     * @return the nbands
380
     */
381
    @Override
382
    public int getNbands() {
383
        return nbands;
384
    }
385

    
386
    /**
387
     * @return the nbits
388
     */
389
    @Override
390
    public int getNbits() {
391
        return nbits;
392
    }
393

    
394
    /**
395
     * @return the byteorder
396
     */
397
    @Override
398
    public ByteOrder getByteorder() {
399
        return byteorder;
400
    }
401

    
402
    /**
403
     * @return the layout
404
     */
405
    @Override
406
    public String getLayout() {
407
        return layout;
408
    }
409

    
410
    /**
411
     * @return the skipbytes
412
     */
413
    @Override
414
    public int getSkipbytes() {
415
        return skipbytes;
416
    }
417

    
418
    /**
419
     * @return the ulxmax
420
     */
421
    @Override
422
    public double getUlxmax() {
423
        return ulxmax;
424
    }
425

    
426
    /**
427
     * @return the ulymax
428
     */
429
    @Override
430
    public double getUlymax() {
431
        return ulymax;
432
    }
433

    
434
    /**
435
     * @return the xdim
436
     */
437
    @Override
438
    public double getXdim() {
439
        return xdim;
440
    }
441

    
442
    /**
443
     * @return the ydim
444
     */
445
    @Override
446
    public double getYdim() {
447
        return ydim;
448
    }
449

    
450
    /**
451
     * @return the bandrowbytes
452
     */
453
    @Override
454
    public int getBandrowbytes() {
455
        return bandrowbytes;
456
    }
457

    
458
    /**
459
     * @return the totalrowbytes
460
     */
461
    @Override
462
    public int getTotalrowbytes() {
463
        return totalrowbytes;
464
    }
465

    
466
    /**
467
     * @return the bandgapbytes
468
     */
469
    @Override
470
    public int getBandgapbytes() {
471
        return bandgapbytes;
472
    }
473

    
474
    /**
475
     * @return the isValid
476
     */
477
    @Override
478
    public boolean isValid() {
479
        return valid;
480
    }
481

    
482
    /**
483
     * @return the comments
484
     */
485
    @Override
486
    public String getComments() {
487
        return comments;
488
    }
489

    
490
    /**
491
     * @param comments the comments to set
492
     */
493
    @Override
494
    public void setComments(String comments) {
495
        this.comments = comments;
496
    }
497

    
498
    /**
499
     * @return the nodata_value
500
     */
501
    @Override
502
    public double getNodata_value() {
503
        return nodata_value;
504
    }
505

    
506
    /**
507
     * @return the xllcorner
508
     */
509
    @Override
510
    public double getXllcorner() {
511
        return xllcorner;
512
    }
513

    
514
    /**
515
     * @return the yllcorner
516
     */
517
    @Override
518
    public double getYllcorner() {
519
        return yllcorner;
520
    }
521

    
522
    /**
523
     * @return the cellsize
524
     */
525
    @Override
526
    public int getCellsize() {
527
        return cellsize;
528
    }
529

    
530
    @Override
531
    public int getBandSize() {
532
        return (this.nrows * this.ncols * this.nbits) + this.bandgapbytes;
533
    }
534

    
535
}