Statistics
| Revision:

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

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

    
163
                m_Fich = file;
164

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

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

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

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

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

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

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

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

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

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

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

    
295
        public long getOffsetData() {
296
                return getHdrSize();
297
        }
298

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

    
309
        public double getXScale() {
310
                return (double)getUnits();
311
        }
312

    
313
        public double getYScale() {
314
                return (double)getUnits();
315
        }
316

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

    
325
        public double getYOffset() {
326
                return (double)getOrgY();
327
        }
328

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

    
338
        public double getMaxY() {
339
                
340
                return maxY;
341
        }
342

    
343
        public double getMaxZ() {
344
                
345
                return maxZ;
346
        }
347

    
348
        public double getMinX() {
349
                
350
                return minX;
351
        }
352

    
353
        public double getMinY() {
354
                
355
                return minY;
356
        }
357

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

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

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

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

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

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

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

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

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

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

    
483
        public void setMaxY(double newValue) {
484
                maxY = newValue;
485
        }
486

    
487
        public void setMaxZ(double newValue) {
488
                maxZ = newValue;
489
        }
490

    
491
        public void setMinX(double newValue) {
492
                minX = newValue;
493
        }
494

    
495
        public void setMinY(double newValue) {
496
                minY = newValue;
497
        }
498

    
499
        public void setMinZ(double newValue) {
500
                minZ = newValue;
501
        }
502

    
503
        public void setOffsetData(long newValue) {
504
                setHdrSize((int) newValue);
505
        }
506

    
507
        public void setXOffset(double newValue) {
508
                OrgX = newValue;
509
        }
510

    
511
        public void setXScale(double newValue) {
512
                setUnits((int) newValue);
513
        }
514

    
515
        public void setYOffset(double newValue) {
516
                OrgY = newValue;
517
        }
518

    
519
        public void setYScale(double newValue) {
520
                setUnits((int) newValue);
521
        }
522

    
523
        public void setZOffset(double newValue) {
524
                OrgZ = newValue;
525
        }
526

    
527
        public void setZScale(double newValue) {
528
                setUnits((int) newValue);
529
        }
530

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

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

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

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

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

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