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 | 43867 | jjdelcerro | 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 | } |