Statistics
| Revision:

svn-gvsig-desktop / branches / v10 / libraries / libLidar / src / com / dielmo / lidar / BINHeader.java @ 25423

History | View | Annotate | Download (15.1 KB)

1
/* DielmoOpenLiDAR
2
 *
3
 * Copyright (C) 2008 DIELMO 3D S.L. (DIELMO) and Infrastructures  
4
 * and Transports Department of the Valencian Government (CIT)
5
 * 
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 * 
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 * 
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
19
 * MA  02110-1301, USA.
20
 *
21
 * For more information, contact:
22
 *
23
 * DIELMO 3D S.L.
24
 * Plaza Vicente Andr?s Estell?s 1 Bajo E
25
 * 46950 Xirivella, Valencia
26
 * SPAIN
27
 *   
28
 * +34 963137212
29
 * dielmo@dielmo.com
30
 * www.dielmo.com
31
 * 
32
 * or
33
 * 
34
 * Generalitat Valenciana
35
 * Conselleria d'Infraestructures i Transport
36
 * Av. Blasco Ib??ez, 50
37
 * 46010 VALENCIA
38
 * SPAIN
39
 *
40
 * +34 963862235
41
 * gvsig@gva.es
42
 * www.gvsig.gva.es
43
 */
44

    
45
/*
46
 * AUTHORS (In addition to DIELMO and CIT):
47
 *  
48
 */
49

    
50
package com.dielmo.lidar;
51

    
52

    
53
import java.io.File;
54
import java.io.FileInputStream;
55
import java.io.FileNotFoundException;
56
import java.io.IOException;
57
import java.io.InputStream;
58
import java.nio.ByteBuffer;
59
import java.nio.ByteOrder;
60
import java.nio.channels.FileChannel;
61

    
62
import javax.swing.JOptionPane;
63

    
64
import com.iver.utiles.bigfile.BigByteBuffer2;
65

    
66
//The structure of the TerraScan file header is:
67
public class BINHeader implements LidarHeader{
68
        
69
        /**
70
         * path of LAS file 
71
         */
72
        private File m_Fich;
73
        
74
        /**
75
         * Size, in bytes, of the header file 
76
         */
77
        private int hdrSize ; // sizeof(ScanHdr)
78
        
79
        /**
80
         * version number
81
         */
82
        private int hdrVersion ; // Version 20020715, 20010712, 20010129 or 970404
83
        
84
        /**
85
         * RecogVal value, always 970401
86
         */
87
        private int RecogVal ; // Always 970401
88
        
89
        /**
90
         * RecogStr value, always 970401
91
         */
92
        private char[] RecogStr = new char[4]; // CXYZ
93
        
94
        /**
95
         * total number of points records within the file
96
         */
97
        private long PntCnt ; // Number of points stored
98
        
99
        /**
100
         * unit of measure
101
         */
102
        private int Units ; // Units per meter = subpermast * uorpersub
103
        
104
        /**
105
         * X coordinate system origin
106
         */
107
        private double OrgX ; // Coordinate system origin
108
        
109
        /**
110
         * Y coordinate system origin
111
         */
112
        private double OrgY ;
113
        
114
        /**
115
         * Z coordinate system origin
116
         */
117
        private double OrgZ ;
118
        
119
        /**
120
         * time stamps appended to points
121
         */
122
        private int Time ; // 32 bit integer time stamps appended to points
123
        
124
        /**
125
         * color appended to points
126
         */
127
        private int Color ; // Color values appended to points
128
        
129
        /**
130
         * The actual maximum X of coordinate extents of the file
131
         */
132
        private double maxX;
133
        
134
        /**
135
         * The actual minimum X of coordinate extents of the file
136
         */
137
        private double minX;
138
        
139
        /**
140
         * The actual maximum Y of coordinate extents of the file
141
         */
142
        private double maxY;
143
        
144
        /**
145
         * The actual minimum Y of coordinate extents of the file
146
         */
147
        private double minY;
148
        
149
        /**
150
         * The actual maximum Z of coordinate extents of the file
151
         */
152
        private double maxZ;
153
        
154
        /**
155
         * The actual minimum Z of coordinate extents of the file
156
         */
157
        private double minZ;
158
        
159
        /**
160
         * Default constructor, without arguments.
161
         * Initializes all components to zero.
162
         */  
163
        public BINHeader(File file) {
164

    
165
                m_Fich = file;
166

    
167
                hdrSize = 56; // sizeof(ScanHdr)
168
                hdrVersion = 20020715; // Version 20020715, 20010712, 20010129 or 970404
169
                RecogVal = 970401; // Always 970401
170

    
171
                RecogStr[0] = 'C';
172
                RecogStr[1] = 'X';
173
                RecogStr[2] = 'Y';
174
                RecogStr[3] = 'Z';
175
                
176
                PntCnt = 0; // Number of points stored
177
                Units = 0; // Units per meter = subpermast * uorpersub
178
                OrgX = 0; // Coordinate system origin
179
                OrgY = 0;
180
                OrgZ = 0;
181
                Time = 0; // 32 bit integer time stamps appended to points
182
                Color = 0; // Color values appended to points                
183
                
184
                maxX=Double.MIN_VALUE; 
185
                minX=Double.MAX_VALUE;
186
                maxY=Double.MIN_VALUE; 
187
                minY=Double.MAX_VALUE;
188
                maxZ=Double.MIN_VALUE;
189
                minZ=Double.MAX_VALUE;
190
        }
191
        
192
        // GET METHODS
193
        /**
194
         * Return Size, in bytes, of the header file
195
         * 
196
         *  @return header size
197
         */
198
        public int getHdrSize() {
199
                return hdrSize;
200
        }
201
        
202
        /**
203
         * Return BIN version of the file
204
         * 
205
         * @return version
206
         */
207
        public int getHdrVersion() {
208
                return hdrVersion;
209
        }
210

    
211
        /**
212
         * Return value RecogVal
213
         * 
214
         * @return RecogVal
215
         */
216
        public int getRecogVal() {
217
                return RecogVal;
218
        }
219

    
220
        /**
221
         * Return value RecogStr
222
         * 
223
         * @return RecogStr
224
         */
225
        public void getRecogStr(char[] str) {
226
                
227
                str[0] = RecogStr[0];
228
                str[1] = RecogStr[1];
229
                str[2] = RecogStr[2];
230
                str[3] = RecogStr[3];
231
                return;
232
        }
233

    
234
        /**
235
         * Return the total number of points records within the file
236
         * 
237
         * @return number of points of file
238
         */
239
        public long getNumPointsRecord() {
240
                return PntCnt;
241
        }
242

    
243
        /**
244
         * Return the unit of measure
245
         * 
246
         * @return unit of measure
247
         */
248
        public int getUnits() {
249
                return Units;
250
        }
251

    
252
        /**
253
         * Return X coordinate system origin
254
         * 
255
         * @return X coordinate
256
         */
257
        public double getOrgX() {
258
                return OrgX;
259
        }
260

    
261
        /**
262
         * Return Y coordinate system origin
263
         * 
264
         * @return Y coordinate
265
         */
266
        public double getOrgY() {
267
                return OrgY;
268
        }
269

    
270
        /**
271
         * Return Z coordinate system origin
272
         * 
273
         * @return Z coordinate
274
         */
275
        public double getOrgZ() {
276
                return OrgZ;
277
        }
278

    
279
        /**
280
         * Return time stamps appended to points
281
         * 
282
         * @return time stamps
283
         */
284
        public int getTime(){
285
                return Time;
286
        }
287

    
288
        /**
289
         * Return color values appended to points
290
         * 
291
         * @return color
292
         */
293
        public int getColor() {
294
                return Color;
295
        }
296

    
297
        public long getOffsetData() {
298
                return getHdrSize();
299
        }
300

    
301
        public int getVersion() {
302
                
303
                if(getHdrVersion()==20010712)
304
                        return LidarHeader.BIN20010712;
305
                else if(getHdrVersion()==20020715)
306
                        return LidarHeader.BIN20020715;
307
                else 
308
                        return LidarHeader.UNEXPECTED;
309
        }
310

    
311
        public double getXScale() {
312
                return (double)getUnits();
313
        }
314

    
315
        public double getYScale() {
316
                return (double)getUnits();
317
        }
318

    
319
        public double getZScale() {
320
                return (double)getUnits();
321
        }
322
        
323
        public double getXOffset() {
324
                return (double)getOrgX();
325
        }
326

    
327
        public double getYOffset() {
328
                return (double)getOrgY();
329
        }
330

    
331
        public double getZOffset() {
332
                return (double)getOrgZ();
333
        }
334
        
335
        public double getMaxX() {
336
                
337
                return maxX;
338
        }
339

    
340
        public double getMaxY() {
341
                
342
                return maxY;
343
        }
344

    
345
        public double getMaxZ() {
346
                
347
                return maxZ;
348
        }
349

    
350
        public double getMinX() {
351
                
352
                return minX;
353
        }
354

    
355
        public double getMinY() {
356
                
357
                return minY;
358
        }
359

    
360
        public double getMinZ() {
361
                
362
                return minZ;
363
        }
364
        
365
        
366
        
367
        // SET METHODS
368
        /**
369
         * Set Size, in bytes, of the header file
370
         * 
371
         * @param value new value of header file
372
         */
373
        public void setHdrSize(int value) {
374
                hdrSize=value;
375
        }
376
        
377
        /**
378
         * Set BIN version of the file
379
         * 
380
         * @param value new version
381
         */
382
        public void setHdrVersion(int value) {
383
                hdrVersion=value;
384
        }
385

    
386
        /**
387
         * Set value RecogVal
388
         * 
389
         * @param value new RecogVal
390
         */
391
        public void setRecogVal(int value) {
392
                RecogVal=value;
393
        }
394

    
395
        /**
396
         * Set value RecogStr
397
         * 
398
         * @param str new RecogStr
399
         */
400
        public void setRecogStr(char[] str) {
401
                RecogStr[0]=str[0];
402
                RecogStr[1]=str[1];
403
                RecogStr[2]=str[2];
404
                RecogStr[3]=str[3];
405
                return;
406
        }
407

    
408
        /**
409
         * Set point stored
410
         * 
411
         * @param value new point stored
412
         */
413
        public void setNumPointsRecord(long value) {
414
                
415
                try{
416
                        if(value>=0 && value <= UNSIGNED_INT_MAX)
417
                                PntCnt=value;
418
                        else
419
                                throw new OutOfRangeLidarException("Out of range of num points record");
420
                        
421
                } catch(OutOfRangeLidarException e) {
422
                        
423
                        e.printStackTrace();
424
                }
425
        }
426

    
427
        /**
428
         * Set unit of measure
429
         * 
430
         * @param value new unit
431
         */
432
        public void setUnits(int value) {
433
                Units=value;
434
        }
435

    
436
        /**
437
         * Set X coordinate system origin
438
         * 
439
         * @param value new X coordinate
440
         */
441
        public void setOrgX(double value) {
442
                OrgX=value;
443
        }
444

    
445
        /**
446
         * Set Y coordinate system origin
447
         * 
448
         * @param value new Y coordinate
449
         */
450
        public void setOrgY(double value) {
451
                OrgY=value;
452
        }
453

    
454
        /**
455
         * Set Z coordinate system origin
456
         * 
457
         * @param value new Z coordinate
458
         */
459
        public void setOrgZ(double value) {
460
                OrgZ=value;
461
        }
462

    
463
        /**
464
         * Set time stamps appended to points
465
         * 
466
         * @param value new time stamps
467
         */
468
        public void setTime(int value) {
469
                Time=value;
470
        }
471

    
472
        /**
473
         * Set color appended to points
474
         * 
475
         * @param value new color
476
         */
477
        public void setColor(int value) {
478
                Color=value;
479
        }
480
        
481
        public void setMaxX(double newValue) {
482
                maxX = newValue;
483
        }
484

    
485
        public void setMaxY(double newValue) {
486
                maxY = newValue;
487
        }
488

    
489
        public void setMaxZ(double newValue) {
490
                maxZ = newValue;
491
        }
492

    
493
        public void setMinX(double newValue) {
494
                minX = newValue;
495
        }
496

    
497
        public void setMinY(double newValue) {
498
                minY = newValue;
499
        }
500

    
501
        public void setMinZ(double newValue) {
502
                minZ = newValue;
503
        }
504

    
505
        public void setOffsetData(long newValue) {
506
                setHdrSize((int) newValue);
507
        }
508

    
509
        public void setXOffset(double newValue) {
510
                OrgX = newValue;
511
        }
512

    
513
        public void setXScale(double newValue) {
514
                setUnits((int) newValue);
515
        }
516

    
517
        public void setYOffset(double newValue) {
518
                OrgY = newValue;
519
        }
520

    
521
        public void setYScale(double newValue) {
522
                setUnits((int) newValue);
523
        }
524

    
525
        public void setZOffset(double newValue) {
526
                OrgZ = newValue;
527
        }
528

    
529
        public void setZScale(double newValue) {
530
                setUnits((int) newValue);
531
        }
532

    
533
        /**
534
         * Read the header of BIN file
535
         * 
536
         * @param input input file to read
537
         * @return true if success else return false 
538
         */
539
        public boolean readLidarHeader() {                
540
                
541
                int offset = 0,numRead = 0;
542
                byte[] cabecera = new byte[56];
543
                File file = m_Fich;
544
                InputStream input;
545
                
546
                //leemos la cabecera
547
              try {
548
                      
549
                    input = new FileInputStream(file);
550
                        while (offset < 56 && (numRead = input.read(cabecera, offset, cabecera.length-offset) ) >= 0) {
551
                             offset += numRead;
552
                        }
553
                        
554
                    if (offset < cabecera.length) {
555
                            JOptionPane.showMessageDialog(null, "Bad Input Format");
556
                            return false;
557
                        }
558
                    
559
                    input.close();
560
                    
561
                } catch (IOException e) {
562
                        e.printStackTrace();
563
                }
564

    
565
                setHdrSize(ByteUtilities.arr2Int(cabecera, 0));
566
                if (getHdrSize() != 56) {
567
                    JOptionPane.showMessageDialog(null, "Bad input format");
568
                    return false;
569
                }
570

    
571
                setHdrVersion(ByteUtilities.arr2Int(cabecera, 4));
572
                setRecogVal(ByteUtilities.arr2Int(cabecera, 8));
573
                RecogStr[0] = (char)cabecera[12];
574
                RecogStr[1] = (char)cabecera[13];
575
                RecogStr[2] = (char)cabecera[14];
576
                RecogStr[3] = (char)cabecera[15];
577
                setNumPointsRecord(ByteUtilities.arr2UnsignedInt(cabecera, 16));
578
                setUnits(ByteUtilities.arr2Int(cabecera, 20));
579
                setOrgX(ByteUtilities.arr2Double(cabecera, 24));
580
                setOrgY(ByteUtilities.arr2Double(cabecera, 32));
581
                setOrgZ(ByteUtilities.arr2Double(cabecera, 40));
582
                setTime(ByteUtilities.arr2Int(cabecera, 48));
583
                setColor(ByteUtilities.arr2Int(cabecera, 52));
584
                
585
                getMaxMinXYZ();
586

    
587
                return true;
588
        }
589
        
590
        private void getMaxMinXYZ() {
591
                
592
                long auxMaxX=Long.MIN_VALUE, auxMinX=Long.MAX_VALUE, x;
593
                long auxMaxY=Long.MIN_VALUE, auxMinY=Long.MAX_VALUE, y;
594
                long auxMaxZ=Long.MIN_VALUE, auxMinZ=Long.MAX_VALUE, z;
595
                long j;
596
                long inc=1;
597
                BigByteBuffer2 bb;
598
                FileChannel channel;
599
                FileInputStream fin;
600
                
601
                
602
                try {
603
                        fin = new FileInputStream(m_Fich);
604
                
605
                        // Open the file and then get a channel from the stream
606
                        channel = fin.getChannel();
607

    
608
                        // Get the file's size and then map it into memory
609
                        // bb = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
610
                bb = new BigByteBuffer2(channel, FileChannel.MapMode.READ_ONLY);
611
                bb.order(ByteOrder.LITTLE_ENDIAN);
612
                
613
                inc = getNumPointsRecord() / 5000;
614
                        if (inc < 1)
615
                                inc = 1;
616
                        
617
                        if(getVersion()==LidarHeader.BIN20010712) {
618
                                
619
                                for (j=0 ; j<getNumPointsRecord(); j+=inc) {
620
                                
621
                                        BINPoint2001 pointBin2001 = new BINPoint2001(getColor()>0, getTime()>0);
622
                                        pointBin2001.readPoint3D(bb,this,j);
623
                                        x=pointBin2001.getX();
624
                                        y=pointBin2001.getY();
625
                                        z=pointBin2001.getZ();
626
                                        
627
                                        if (auxMinX > x)
628
                                                auxMinX = x;
629
                                        
630
                                        if (auxMaxX < x)
631
                                                auxMaxX = x;
632
                                        
633
                                        if (auxMinY > y)
634
                                                auxMinY = y;
635
                                        
636
                                        if (auxMaxY < y)
637
                                                auxMaxY = y;
638
                                        
639
                                        if (auxMinZ > z)
640
                                                auxMinZ = z;
641
                                        
642
                                        if (auxMaxZ < z)
643
                                                auxMaxZ = z;
644
                                }
645
                                
646
                                setMaxX((auxMaxX - getOrgX())/getUnits());
647
                                setMinX((auxMinX - getOrgX())/getUnits());
648
                                setMaxY((auxMaxY - getOrgY())/getUnits());
649
                                setMinY((auxMinY - getOrgY())/getUnits());
650
                                setMaxZ((auxMaxZ - getOrgZ())/getUnits());
651
                                setMinZ((auxMinZ - getOrgZ())/getUnits());
652
                        } else if(getVersion()==LidarHeader.BIN20020715) {
653
                                
654
                                for (j=0 ; j<getNumPointsRecord(); j+=inc) {
655
                                        
656
                                        BINPoint2002 pointBin2002 = new BINPoint2002(getColor()>0, getTime()>0);
657
                                        pointBin2002.readPoint3D(bb,this,j);
658
                                        x=pointBin2002.getX();
659
                                        y=pointBin2002.getY();
660
                                        z=pointBin2002.getZ();
661
                                        
662
                                        if (auxMinX > x)
663
                                                auxMinX = x;
664
                                        
665
                                        if (auxMaxX < x)
666
                                                auxMaxX = x;
667
                                        
668
                                        if (auxMinY > y)
669
                                                auxMinY = y;
670
                                        
671
                                        if (auxMaxY < y)
672
                                                auxMaxY = y;
673
                                        
674
                                        if (auxMinZ > z)
675
                                                auxMinZ = z;
676
                                        
677
                                        if (auxMaxZ < z)
678
                                                auxMaxZ = z;
679
                                }
680
                                
681
                                setMaxX((auxMaxX - getOrgX())/getUnits());
682
                                setMinX((auxMinX - getOrgX())/getUnits());
683
                                setMaxY((auxMaxY - getOrgY())/getUnits());
684
                                setMinY((auxMinY - getOrgY())/getUnits());
685
                                setMaxZ((auxMaxZ - getOrgZ())/getUnits());
686
                                setMinZ((auxMinZ - getOrgZ())/getUnits());
687
                        }
688
                
689
                } catch (FileNotFoundException e) {
690
                        // TODO Auto-generated catch block
691
                        e.printStackTrace();
692
                } catch (IOException e) {
693
                        // TODO Auto-generated catch block
694
                        e.printStackTrace();
695
                }
696
        }
697

    
698
        public boolean writeLidarHeader(ByteBuffer bb) {
699
                
700
                byte[] hdr = new byte[56];
701
                int i, index;
702
                
703
                // hdrSize bytes 0-4
704
                ByteUtilities.int2Arr(getHdrSize(), hdr, 0);
705
                
706
                // hdrVersion bytes 4-8
707
                ByteUtilities.int2Arr(getHdrVersion(), hdr, 4);
708
                
709
                // RecogVal bytes 8-12
710
                ByteUtilities.int2Arr(getRecogVal(), hdr, 8);
711
                
712
                // RecogStr bytes 12-16
713
                i=0;
714
                for(index=12;index<16;index++){
715
                        hdr[index] = ((byte)(RecogStr[i] & 0XFF));
716
                        i++;
717
                }
718
                
719
                // PntCnt bytes 16-20
720
                ByteUtilities.unsignedInt2Arr(getNumPointsRecord(), hdr, 16);
721
                
722
                // Units bytes 20-24
723
                ByteUtilities.int2Arr(getUnits(), hdr, 20);
724
                
725
                // OrgX bytes 24-32
726
                ByteUtilities.double2Arr(getOrgX(), hdr, 24);
727
                                
728
                // OrgY bytes 32-40
729
                ByteUtilities.double2Arr(getOrgY(), hdr, 32);
730
                
731
                // OrgZ bytes 40-48
732
                ByteUtilities.double2Arr(getOrgZ(), hdr, 40);
733
                
734
                // Time bytes 48-52
735
                ByteUtilities.int2Arr(getTime(), hdr, 48);
736
                
737
                // Color bytes 52-56
738
                ByteUtilities.int2Arr(getColor(), hdr, 52);
739
                
740
                bb.put(hdr);
741
                
742
                return false;
743
        }
744
}