Statistics
| Revision:

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

History | View | Annotate | Download (17.6 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
import java.awt.geom.Point2D;
53
import java.nio.ByteBuffer;
54

    
55
import com.dielmo.lidar.fieldsDescription.ColumnDescription;
56
import com.dielmo.lidar.fieldsDescription.ContainerColumnDescription;
57

    
58
/**
59
 * BIN point that implement the BIN point data version BIN 20010712
60
 *
61
 * @author Oscar Garcia
62
 */
63
public class BINPoint2001 implements LidarPoint{
64

    
65
        /**
66
         * size of point format
67
         */
68
        private int sizeFormat;
69

    
70
        /**
71
         * indicates if content color.
72
         */
73
        private boolean isColor;
74

    
75
        /**
76
         * indicates if content time GPS.
77
         */
78
        private boolean isTimeGPS;
79

    
80
        /**
81
         * Color RGB
82
         */
83
        private char color[] = new char[4];
84

    
85
        /**
86
         * indicates if content color.
87
         */
88
        private int time;
89

    
90

    
91
        /**
92
         * X value
93
         */
94
        private int x;
95

    
96
        /**
97
         * Y value
98
         */
99
        private int y;
100

    
101
        /**
102
         * Z value
103
         */
104
        private int z;
105

    
106
        /**
107
         * The intensity value is the integer representation of the
108
         * pulse return magnitude.
109
         */
110
        private int intensity;
111

    
112
        /**
113
         * The echo information of BIN is the pulse return number for a given output
114
         * pulse.
115
         *
116
         * 0 Only echo
117
         * 1 First of many echo
118
         * 2 Intermediate echo
119
         * 3 Last if many echo
120
         */
121
        private byte echoInformation;
122

    
123
        /**
124
         * The flight line number.
125
         */
126
        private char flightLine;
127

    
128
        /**
129
         * The classification field is a number to signify a given
130
         * classification during filter processing.
131
         */
132
        private char classification;
133
        
134
        protected long lasIndex;
135

    
136

    
137
        /**
138
         * Default constructor, without arguments.
139
         * Initializes all components to zero.
140
         */
141
        public BINPoint2001(boolean c, boolean t) {
142

    
143
                x = 0;
144
                y = 0;
145
                z = 0;
146
                intensity = 0;
147
                echoInformation = 0;
148
                flightLine = 0;
149
                classification = 0;
150
                isColor = c;
151
                isTimeGPS = t;
152
                color[0] = 0;
153
                color[1] = 0;
154
                color[2] = 0;
155
                color[3] = 0;
156
                time = 0;
157
                sizeFormat = 16;
158
                lasIndex=-1;
159

    
160
                if(c) {
161
                        sizeFormat += 4;
162
                }
163
                if(t) {
164
                        sizeFormat += 4;
165
                }
166
        }
167

    
168
        // GET METHODS
169
        /**
170
         * Get GPS time as long.
171
         */
172
        public int getTime() {
173
                return time;
174
        }
175

    
176
        /**
177
         * Get Color RGB
178
         */
179
        public char[] getcolor() {
180
                return color;
181
        }
182

    
183
        /**
184
         * Get red value of color
185
         */
186
        public char getR() {
187
                return color[0];
188
        }
189

    
190
        /**
191
         * Get green value of color
192
         */
193
        public char getG() {
194
                return color[1];
195
        }
196

    
197
        /**
198
         * Get blue value of color
199
         */
200
        public char getB() {
201
                return color[2];
202
        }
203

    
204
        /**
205
         * Get infrared value of color
206
         */
207
        public char getI() {
208
                return color[3];
209
        }
210

    
211
        /**
212
         * Return X value that is stored as long integer. The corresponding
213
         * X scale from the public header block change this long integer to
214
         * true floating point value. The corresponding offset value can
215
         * also be used for projections with very large numbers.
216
         *
217
         * the coordinate = (X-OrgX)/Units
218
         *
219
         * @return x value
220
         */
221
        public int getX() {
222
                return x;
223
        }
224

    
225
        /**
226
         * Return Y value that is stored as long integer. The corresponding
227
         * Y scale from the public header block change this long integer to
228
         * true floating point value. The corresponding offset value can
229
         * also be used for projections with very large numbers.
230
         *
231
         * the coordinate = (Y-OrgY)/Units
232
         *
233
         * @return y value
234
         */
235
        public int getY() {
236
                return y;
237
        }
238

    
239
        /**
240
         * Return Z value that is stored as long integer. The corresponding
241
         * Z scale from the public header block change this long integer to
242
         * true floating point value. The corresponding offset value can
243
         * also be used for projections with very large numbers.
244
         *
245
         * the coordinate = (Z-OrgZ)/Units
246
         *
247
         * @return z value
248
         */
249
        public int getZ() {
250
                return z;
251
        }
252

    
253
        /**
254
         * Get the intensity value as the integer representation of the pulse
255
         * return magnitude. This value is optional and system specific
256
         *
257
         * @return intensity value
258
         */
259
        public int getIntensity() {
260
                return intensity;
261
        }
262

    
263
        /**
264
         * Get The echo information of BIN is the pulse return number for
265
         * a given output pulse.
266
         *
267
         * 0 Only echo
268
         * 1 First of many echo
269
         * 2 Intermediate echo
270
         * 3 Last if many echo
271
         *
272
         * @return echo information
273
         */
274
        public byte getEchoInformation() {
275
                return echoInformation;
276
        }
277

    
278
        /**
279
         * Get flight line number
280
         *
281
         * @return flight line number
282
         */
283
        public char getFlightLine() {
284
                return flightLine;
285
        }
286

    
287
        /**
288
         * Get a given classification during filter processing.
289
         *
290
         * @return classification
291
         */
292
        public char getClassification() {
293
                return classification;
294
        }
295

    
296
        /**
297
         * Get a bit size of point format
298
         *
299
         * @return sizeFormat
300
         */
301
        public int getSizeFormat() {
302
                return sizeFormat;
303
        }
304

    
305
        // SET METHODS
306

    
307
        /**
308
         * Set GPS time as integer.
309
         */
310
        public void setTime(int t) {
311
                time=t;
312
        }
313

    
314
        /**
315
         * Set Color RGB
316
         *
317
         * @param c this array contains 4 chars for represents the RGBI
318
         */
319
        public void setcolor(char[] c) {
320
                if(c.length == 4) {
321
                        color = c;
322
                }
323
        }
324

    
325
        /**
326
         * set X value that is stored as long integer.
327
         *
328
         * @param newx new value of x
329
         */
330
        public void setX(int newx) {
331
                x = newx;
332
        }
333

    
334
        /**
335
         * set Y value that is stored as long integer.
336
         *
337
         * @param newy new value of y
338
         */
339
        public void setY(int newy) {
340
                y = newy;
341
        }
342

    
343
        /**
344
         * set Z value that is stored as long integer.
345
         *
346
         * @param newz new value of z
347
         */
348
        public void setZ(int newz) {
349
                z = newz;
350
        }
351

    
352
        /**
353
         * Set the intensity value as the integer representation of the pulse
354
         * return magnitude. This value is optional and system specific
355
         *
356
         * @param inten new intensity
357
         */
358
        public void setIntensity(int inten) {
359

    
360
                try{
361
                        // intensity is formed by 14 bits, 16383 represents (2^14)-1
362
                        if(inten >=0 && inten <= 16383) {
363
                                intensity = inten;
364
                        } else {
365
                                throw new OutOfRangeLidarException("Out of range of intensity");
366
                        }
367

    
368
                } catch(OutOfRangeLidarException e) {
369

    
370
                        e.printStackTrace();
371
                }
372
        }
373

    
374
        /**
375
         * Set the echo information of BIN is the pulse return number for
376
         * a given output pulse.
377
         *
378
         * 0 Only echo
379
         * 1 First of many echo
380
         * 2 Intermediate echo
381
         * 3 Last if many echo
382
         *
383
         * @param echo new echo information
384
         */
385
        public void setEchoInformation(byte echo) {
386

    
387
                try{
388
                        if(echo >=0 && echo <= 3) {
389
                                echoInformation = echo;
390
                        } else {
391
                                throw new OutOfRangeLidarException("Out of range of echo information");
392
                        }
393

    
394
                } catch(OutOfRangeLidarException e) {
395

    
396
                        e.printStackTrace();
397
                }
398
        }
399

    
400
        /**
401
         * Get flight line number
402
         *
403
         * @param fl new flight line number
404
         */
405
        public void setFlightLine(char fl) {
406

    
407
                try{
408
                        if(fl>=0 && fl<=255) {
409
                                flightLine = fl;
410
                        } else {
411
                                throw new OutOfRangeLidarException("Out of range of flight line");
412
                        }
413

    
414
                } catch(OutOfRangeLidarException e) {
415

    
416
                        e.printStackTrace();
417
                }
418
        }
419

    
420
        /**
421
         * Set a given classification during filter processing.
422
         *
423
         * @return c new classification
424
         */
425
        public void setClassification(char c) {
426

    
427
                try{
428
                        if(c>=0 && c<=255) {
429
                                classification = c;
430
                        } else {
431
                                throw new OutOfRangeLidarException("Out of range of classification");
432
                        }
433

    
434
                } catch(OutOfRangeLidarException e) {
435

    
436
                        e.printStackTrace();
437
                }
438
        }
439

    
440
        /**
441
         * Read a point of BIN file
442
         *
443
         * @param input input file to read
444
         * @param Offset Offset to data
445
         * @param index index of points to read
446
         * @return true if success else return false
447
         */
448
        public void readPoint(BigByteBuffer2 input, LidarHeader hdr, long index) {
449

    
450
                try{
451
                        if(index>hdr.getNumPointsRecord() || index < 0) {
452
                                throw new UnexpectedPointException("Out of Index");
453
                        }
454
                        
455
                        if(index==lasIndex)
456
                                return;
457
                        else
458
                                lasIndex=index;
459

    
460
                        int auxIndex;
461
                        byte[] punto = new byte[getSizeFormat()];
462
                        byte[] aux = new byte[2];
463

    
464
                        input.position(hdr.getOffsetData()+getSizeFormat()*index);
465
                    input.get(punto);
466

    
467
                    setClassification((char)(punto[0] & 0xFF));
468
                    setFlightLine((char)(punto[1] & 0xFF));
469

    
470
                    aux[0] = punto[2];
471
                    aux[1] = (byte)(punto[3] & 0X3F);
472
                        setIntensity(ByteUtilities.arr2Unsignedshort(aux, 0));  // bits de 0-13
473
                        setEchoInformation((byte)((punto[3] & 0xC0) >> 2)); // bits 14 y 15
474

    
475
                        setX(ByteUtilities.arr2Int(punto, 4));
476
                        setY(ByteUtilities.arr2Int(punto, 8));
477
                        setZ(ByteUtilities.arr2Int(punto, 12));
478

    
479
                        auxIndex = 16;
480

    
481
                        // si hay gps leelo
482
                        if(isTimeGPS) {
483
                                setTime(ByteUtilities.arr2Int(punto, auxIndex));
484
                                auxIndex+=4;
485
                        }
486

    
487
                        // si hay color leelo
488
                        if(isColor) {
489

    
490
                                char[] c = new char[4];
491
                                c[0] = (char)(punto[auxIndex] & 0xFF);
492
                                c[1] = (char)(punto[auxIndex+1] & 0xFF);
493
                                c[2] = (char)(punto[auxIndex+2] & 0xFF);
494
                                c[3] = (char)(punto[auxIndex+3] & 0xFF);
495
                                setcolor(c);
496
                        }
497

    
498
                } catch (UnexpectedPointException e) {
499
                        e.printStackTrace();
500
                }
501
        }
502

    
503
        /**
504
         * Read x and y in point of BIN file
505
         *
506
         * @param input input buffer to read
507
         * @param Offset Offset to data
508
         * @param index index of points to read
509
         * @return true if success else return false
510
         */
511
        public Point2D.Double readPoint2D(BigByteBuffer2 input, LidarHeader hdr,  long index) {
512

    
513
                byte[] punto = new byte[12];
514

    
515
                input.position((hdr.getOffsetData()+getSizeFormat()*index)+4);
516
                input.get(punto);
517

    
518
                setX(ByteUtilities.arr2Int(punto, 4));
519
                setY(ByteUtilities.arr2Int(punto, 8));
520

    
521
                return new Point2D.Double((getX()-hdr.getXOffset())/hdr.getXScale(), (getY()-hdr.getYOffset())/hdr.getYScale());
522
        }
523

    
524
        /**
525
         * Read a x, y and z in point of LAS file
526
         *
527
         * @param input input buffer to read
528
         * @param Offset Offset to data
529
         * @param index index of points to read
530
         * @return true if success else return false
531
         */
532
        public void readPoint3D(BigByteBuffer2 input, LidarHeader hdr, long index) {
533

    
534
                byte[] punto = new byte[16];
535

    
536
            input.position((hdr.getOffsetData()+getSizeFormat()*index)+4);
537
                input.get(punto);
538

    
539
                setX(ByteUtilities.arr2Int(punto, 4));
540
                setY(ByteUtilities.arr2Int(punto, 8));
541
                setZ(ByteUtilities.arr2Int(punto, 12));
542
        }
543

    
544
        /**
545
         * get field value by index:
546
         *
547
         * 0 return X
548
         * 1 return Y
549
         * 2 return Z
550
         * 3 return intensity
551
         * 4 return classification
552
         * 5 return Line
553
         * 6 return echo information
554
         * 7-11 Time and Color RGBI
555
         *
556
         * @param bb byte buffer of data
557
          * @param indexField index of field
558
         * @param hdr LiDAR header
559
         * @param index asked point index. (row)
560
         * @return Value of row and column indicated
561
         */
562
        public Object getFieldValueByIndex(BigByteBuffer2 bb, int indexField,
563
                        LidarHeader hdr, long index) {
564

    
565
                readPoint(bb, hdr, index);
566

    
567
                switch(indexField) {
568

    
569
                        case 0:
570
                                return (getX()-hdr.getXOffset())/hdr.getXScale();
571

    
572
                        case 1:
573
                                return (getY()-hdr.getYOffset())/hdr.getYScale();
574

    
575
                        case 2:
576
                                return (getZ()-hdr.getZOffset())/hdr.getZScale();
577

    
578
                        case 3:
579
                                return getIntensity();
580

    
581
                        case 4:
582
                                return getClassification();
583

    
584
                        case 5:
585
                                return getFlightLine();
586

    
587
                        case 6:
588
                                return getEchoInformation();
589

    
590
                        case 7:
591

    
592
                                if(isTimeGPS) {
593
                                        return getTime();
594
                                } else if(isColor) {
595
                                        return getR();
596
                                }
597

    
598
                        case 8:
599

    
600
                                if(isTimeGPS) {
601
                                        return getR();
602
                                } else if(isColor) {
603
                                        return getG();
604
                                }
605

    
606
                        case 9:
607

    
608
                                if(isTimeGPS) {
609
                                        return getG();
610
                                } else if(isColor) {
611
                                        return getB();
612
                                }
613

    
614
                        case 10:
615

    
616
                                if(isTimeGPS) {
617
                                        return getB();
618
                                } else if(isColor) {
619
                                        return getI();
620
                                }
621

    
622
                        case 11:
623
                                if(isTimeGPS) {
624
                                        return getI();
625
                                }
626
                }
627

    
628
                return null;
629
        }
630

    
631
        public Object getFieldValueByName(BigByteBuffer2 bb, String nameField, LidarHeader hdr,
632
                        long index) {
633

    
634
                readPoint(bb, hdr, index);
635

    
636
                if(nameField.equalsIgnoreCase("X")) {
637
                        return (getX()-hdr.getXOffset())/hdr.getXScale();
638
                } else if(nameField.equalsIgnoreCase("Y")) {
639
                        return (getY()-hdr.getYOffset())/hdr.getYScale();
640
                } else if(nameField.equalsIgnoreCase("Z")) {
641
                        return (getZ()-hdr.getZOffset())/hdr.getZScale();
642
                } else if(nameField.equalsIgnoreCase("Intensity")) {
643
                        return getIntensity();
644
                } else if(nameField.equalsIgnoreCase("Classification")) {
645
                        return getClassification();
646
                } else if(nameField.equalsIgnoreCase("Line")) {
647
                        return getFlightLine();
648
                } else if(nameField.equalsIgnoreCase("Echo")) {
649
                        return getEchoInformation();
650
                } else if(nameField.equalsIgnoreCase("Time")) {
651
                        return getTime();
652
                } else if(nameField.equalsIgnoreCase("R")) {
653
                        return getR();
654
                } else if(nameField.equalsIgnoreCase("G")) {
655
                        return getG();
656
                } else if(nameField.equalsIgnoreCase("B")) {
657
                        return getB();
658
                } else if(nameField.equalsIgnoreCase("I")) {
659
                        return getI();
660
                }
661

    
662
                return null;
663
        }
664

    
665
        public ContainerColumnDescription getColumnsDescription(ContainerColumnDescription fields) {
666

    
667
                int index;
668
                int fieldsAddByColor, fieldsAddByTime;
669

    
670
                if(isColor) {
671
                        fieldsAddByColor = 4;
672
                } else {
673
                        fieldsAddByColor = 0;
674
                }
675

    
676
                if(isTimeGPS) {
677
                        fieldsAddByTime = 1;
678
                } else {
679
                        fieldsAddByTime = 0;
680
                }
681

    
682
                fields.add("X", ColumnDescription.DOUBLE, 20, 3, 0.0);
683
                fields.add("Y", ColumnDescription.DOUBLE, 20, 3, 0.0);
684
                fields.add("Z", ColumnDescription.DOUBLE, 20, 3, 0.0);
685
                fields.add("Intensity", ColumnDescription.INT, 5, 0, 0);
686
                fields.add("Classification", ColumnDescription.BYTE, 1, 0, 0);
687
                fields.add("Line", ColumnDescription.BYTE, 1, 0, 0);
688
                fields.add("Echo", ColumnDescription.BYTE, 1, 0, 0);
689

    
690
                index = 7;
691

    
692
                if(isTimeGPS) {
693

    
694
                        fields.add("Time", ColumnDescription.DOUBLE, 20, 5, 0.0);
695
                        index++;
696
                }
697

    
698
                if(isColor) {
699

    
700
                        fields.add("R", ColumnDescription.INT, 3, 0, 0);
701
                        fields.add("G", ColumnDescription.INT, 3, 0, 0);
702
                        fields.add("B", ColumnDescription.INT, 3, 0, 0);
703
                        fields.add("I", ColumnDescription.INT, 3, 0, 0);
704
                        index+=4;
705
                }
706

    
707
                return fields;
708
        }
709

    
710
        public void WritePoint(ByteBuffer bb) {
711

    
712
                byte[] punto = new byte[getSizeFormat()];
713

    
714
                // byte 1
715
                punto[0] = (byte) (getClassification() & 0xFF);
716

    
717
                // byte 2
718
                punto[1] = (byte) (getFlightLine() & 0xFF);
719

    
720
                // byte 3-4
721
                ByteUtilities.unsignedShort2Arr(getIntensity(), punto, 2);
722

    
723
                // bits 7 y 8 del byte 4
724
                punto[3] >>= 2;
725
                punto[3]+=getEchoInformation();
726

    
727
                // bytes 4-8
728
                ByteUtilities.int2Arr(getX(), punto, 4);
729

    
730

    
731
                // bytes 8-12
732
                ByteUtilities.int2Arr(getY(), punto, 8);
733

    
734
                // bytes 12-16
735
                ByteUtilities.int2Arr(getZ(), punto, 12);
736

    
737
                // si hay gps leelo
738
                if(isTimeGPS) {
739

    
740
                        // bytes 16-20
741
                        ByteUtilities.int2Arr(time, punto, 16);
742

    
743
                        if(isColor) {
744
                                // bytes 20-24
745
                                punto[20]= (byte) (color[0] & 0xFF);
746
                                punto[21] = (byte) (color[1] & 0xFF);
747
                                punto[22] = (byte) (color[2] & 0xFF);
748
                                punto[23] = (byte) (color[3] & 0xFF);
749
                        }
750
                } else {
751

    
752
                        // si hay color leelo
753
                        if(isColor) {
754

    
755
                                // bytes 16-20
756
                                punto[16]= (byte) (color[0] & 0xFF);
757
                                punto[17] = (byte) (color[1] & 0xFF);
758
                                punto[18] = (byte) (color[2] & 0xFF);
759
                                punto[19] = (byte) (color[3] & 0xFF);
760
                        }
761
                }
762

    
763
                bb.put(punto);
764

    
765
                return;
766
        }
767

    
768
        /*
769
         * Set Point from a row
770
         * @see com.dielmo.gvsig.lidar.LidarPoint#setPoint(com.hardcode.gdbms.engine.values.Value[], com.dielmo.gvsig.lidar.LidarHeader)
771
         */
772
        public void setPoint(Object[] row, LidarHeader hdr) {
773

    
774
                double auxX = (Double) row[0];
775
                double auxY = (Double) row[1];
776
                double auxZ = (Double) row[2];
777

    
778
                setX((int) (auxX * (hdr.getXScale()) + hdr.getXOffset()));
779
                setY((int) (auxY * (hdr.getYScale()) + hdr.getYOffset()));
780
                setZ((int) (auxZ * (hdr.getZScale()) + hdr.getZOffset()));
781

    
782
                setIntensity((Integer) row[3]);
783
                setClassification((char) (((Integer) (row[4])).byteValue() & 0xFF));
784
                setFlightLine((char) (((Integer) (row[5])).byteValue() & 0xFF));
785
                setEchoInformation(((Integer) (row[6])).byteValue());
786

    
787
                if(hdr instanceof BINHeader) {
788

    
789
                        BINHeader hdrBin = (BINHeader) hdr;
790
                        if(hdrBin.getTime()>0) {
791

    
792
                                setTime((Integer) row[7]);
793

    
794
                                if(hdrBin.getColor()>0) {
795

    
796
                                        color[0] = (char) (((Integer) (row[8])).byteValue() & 0xFF);
797
                                        color[1] = (char) (((Integer) (row[9])).byteValue() & 0xFF);
798
                                        color[2] = (char) (((Integer) (row[10])).byteValue() & 0xFF);
799
                                        color[3] = (char) (((Integer) (row[11])).byteValue() & 0xFF);
800
                                }
801
                        } else {
802

    
803
                                if(hdrBin.getColor()>0) {
804

    
805
                                        color[0] = (char) (((Integer) (row[7])).byteValue() & 0xFF);
806
                                        color[1] = (char) (((Integer) (row[8])).byteValue() & 0xFF);
807
                                        color[2] = (char) (((Integer) (row[9])).byteValue() & 0xFF);
808
                                        color[3] = (char) (((Integer) (row[10])).byteValue() & 0xFF);
809
                                }
810
                        }
811
                }
812
        }
813

    
814
}