Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Copy z into extra bytes attribute

71 views
Skip to first unread message

josevim

unread,
Apr 24, 2025, 4:48:03 AMApr 24
to LAStools - efficient tools for LiDAR processing
Hello colleagues,

I've been trying to copy z coordinate value into a new extra byte attribute:

las2las -i file.las -add_attribute 10 "temp_z" "adding Z to attribute" 0.01 -o file_addAttrib10.las
las2las -file_addAttrib10.las -copy_z_into_attribute 10 -o file_copyZtoAttrib10.las

Not sure if both instructions above should be scripted in one, but nothing happens even in two steps. Z values had also a 0.01 scale. This old post is clear on the solution but I cannot make it work:

My LAS file has up to 9 extra bytes attributes and I'm adding a 10th one. Is that an issue?
The goal is to reserve the z coordinate for a later scaling and translation.
Link for a sample LAS file: 10003_Sample_copyZattrib10.las
Regards

LAStools - efficient tools for LiDAR processing

unread,
Apr 24, 2025, 1:14:57 PMApr 24
to LAStools - efficient tools for LiDAR processing
Hi,
to answer your question about the number of extra bytes: This is easy to test - we did this for you:
las2las -i lake.laz -add_attribute 10 "temp_z1" "adding Z to attribute" 0.01 -o tmp1.laz
las2las -i tmp1.laz -add_attribute 10 "temp_z2" "adding Z to attribute" 0.01 -o tmp2.laz
las2las -i tmp2.laz -add_attribute 10 "temp_z3" "adding Z to attribute" 0.01 -o tmp3.laz
las2las -i tmp3.laz -add_attribute 10 "temp_z4" "adding Z to attribute" 0.01 -o tmp4.laz
las2las -i tmp4.laz -add_attribute 10 "temp_z5" "adding Z to attribute" 0.01 -o tmp5.laz
las2las -i tmp5.laz -add_attribute 10 "temp_z6" "adding Z to attribute" 0.01 -o tmp6.laz
las2las -i tmp6.laz -add_attribute 10 "temp_z7" "adding Z to attribute" 0.01 -o tmp7.laz
las2las -i tmp7.laz -add_attribute 10 "temp_z8" "adding Z to attribute" 0.01 -o tmp8.laz
las2las -i tmp8.laz -add_attribute 10 "temp_z9" "adding Z to attribute" 0.01 -o tmp9.laz
las2las -i tmp9.laz -add_attribute 10 "temp_z10" "adding Z to attribute" 0.01 -o tmp10.laz
las2las -i tmp10.laz -add_attribute 10 "temp_z11" "adding Z to attribute" 0.01 -o tmp11.laz

We see you can add more then 10 arguments, so this is not the issue.
It looks more like your second command is just invalid: You forgot the -i argument (and we use the 64 bit version and LAZ as file format).
Try 
    las2las64 --i file_addAttrib10.laz -copy_z_into_attribute 10 -o file_copyZtoAttrib10.laz -v

It it does not work please report in detail what output the command gives you and we will try to help.

Good luck,

Jochen @rapidlasso

josevim

unread,
Apr 28, 2025, 3:13:42 PMApr 28
to LAStools - efficient tools for LiDAR processing
Hi Jochen,

Yes, I missed the i argument in my initial message. I tried your command(s) example and adding the attribute 10 works fine but then running,

las2las64 -i tmp1.laz -copy_z_into_attribute 10 -o tmp1_copyZ.laz -v

Does not. This is  tmp1_copyZ.laz header:

reporting all LAS header entries:
  file signature:             'LASF'
  file source ID:             10003
  global_encoding:            17
  project ID GUID data 1-4:   00000000-0000-0000-0000-000000000000
  version major.minor:        1.4
  system identifier:          'LAStools (c) by rapidlasso GmbH'
  generating software:        'las2las64 (version 250402)'
  file creation day/year:     93/2025
  header size:                375
  offset to point data:       4143
  number var. length records: 8
  point data format:          6
  point data record length:   69
  number of point records:    0
  number of points by return: 0 0 0 0 0
  scale factor x y z:         0.01 0.01 0.01
  offset x y z:               500000 2800000 0
  min x y z:                  587277.78 2870666.80 -56.55
  max x y z:                  592442.72 2871058.99 308.49
  start of waveform data packet record: 0
  start of first extended variable length record: 0
  number of extended_variable length records: 0
  extended number of point records: 11211016
  extended number of points by return: 5087964 3070747 3052305 0 0 0 0 0 0 0 0 0 0 0 0
variable length header record 1 of 8:
  reserved             0
  user ID              'LASF_Spec'
  record ID            4
  length after header  1920
  description          'by LAStools of rapidlasso GmbH'
    Extra Byte Descriptions
      data type: 4 (short), name "(pseudo-) reflectance", description: "Radiometric calibration output", scale: 0.01, offset: 0 (not set)
      data type: 1 (unsigned char), name "sigma xy", description: "XY coordinate uncertainty", scale: 0.01, offset: 0 (not set)
      data type: 1 (unsigned char), name "sigma z", description: "Z coordinate uncertainty", scale: 0.01, offset: 0 (not set)
      data type: 1 (unsigned char), name "water column optical depth", description: "Water column optical depth", scale: 0.25, offset: 0 (not set)
      data type: 1 (unsigned char), name "figure of merit", description: "FOM for bottom measurement", scale: 1 (not set), offset: 0 (not set)
      data type: 1 (unsigned char), name "Bathymetry flags", description: "Flags", scale: 1 (not set), offset: 0 (not set)
      data type: 10 (double), name "Pitch (radians)", description: "Pitch (radians)", scale: 1 (not set), offset: 0 (not set)
      data type: 10 (double), name "Roll (radians)", description: "Roll (radians)", scale: 1 (not set), offset: 0 (not set)
      data type: 10 (double), name "Heading (radians)", description: "Heading (radians)", scale: 1 (not set), offset: 0 (not set)
      data type: 10 (double), name "temp_z1", description: "adding Z to attribute", scale: 0.01, offset: 0 (not set)
variable length header record 2 of 8:
  reserved             0
  user ID              'LASF_Projection'
  record ID            34735
  length after header  40
  description          'by LAStools of rapidlasso GmbH'
    GeoKeyDirectoryTag version 1.1.0 number of keys 4
      key 1024 tiff_tag_location 0 count 1 value_offset 1 - GTModelTypeGeoKey: ModelTypeProjected
      key 3072 tiff_tag_location 0 count 1 value_offset 6346 - ProjectedCSTypeGeoKey: NAD83(2011) / UTM zone 17N
      key 3076 tiff_tag_location 0 count 1 value_offset 9001 - ProjLinearUnitsGeoKey: Linear_Meter
      key 4099 tiff_tag_location 0 count 1 value_offset 9001 - VerticalUnitsGeoKey: Linear_Meter
variable length header record 3 of 8:
  reserved             0
  user ID              'LASF_Spec'
  record ID            0
  length after header  96
  description          'Classification Lookup'
    40 Seafloor    41 Water Surface    42 Synthetic Surf.    43 Submerged Obj.    44 IHOS57 Object    45 No Bottom Found
variable length header record 4 of 8:
  reserved             0
  user ID              'LASF_Spec'
  record ID            3
  length after header  5
  description          'RPM Version'
    4.1.0
variable length header record 5 of 8:
  reserved             0
  user ID              'LASF_Spec'
  record ID            3
  length after header  559
  description          'RPM CLI Arguments'
    rpm.exe  --boresight -0.3177 0.9502 -0.9763 --depth-bias 0.05625 --glare --show-aircraft --show-derived-water --vertical-shift-tolerance 1 --shift-data --bf 0 --sbet-offset 0
variable length header record 6 of 8:
  reserved             0
  user ID              'LASF_Spec'
  record ID            3
  length after header  16
  description          'Depth Bias Model Coefficients'
    Slope: 0.05625

variable length header record 7 of 8:
  reserved             0
  user ID              'LASF_Spec'
  record ID            3
  length after header  70
  description          'Model information'
    Version: 6.0.0
Description: ramms-mvit-50-triplet-v6-model-rpi-1094

variable length header record 8 of 8:
  reserved             0
  user ID              'LASF_Projection'
  record ID            2112
  length after header  630
  description          'by LAStools of rapidlasso GmbH'
    WKT OGC COORDINATE SYSTEM:
    PROJCS["NAD83(2011) / NAD83(2011) / UTM zone 17N",GEOGCS["NAD83(2011)",DATUM["NAD_1983_2011",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","1116"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","6318"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-81],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","6346"]]
LASzip compression (version 3.4r4 c3 50000): POINT14 3 BYTE14 3
reporting minimum and maximum for all LAS point record entries ...
  X             8727778    9244272
  Y             7066680    7105899
  Z               -5655      30849
  intensity           0      65535
  return_number       1          3
  number_of_returns   1          3
  edge_of_flight_line 0          1
  scan_direction_flag 0          0
  classification      0          7
  scan_angle_rank   -26         26
  user_data           1        100
  point_source_ID 10003      10003
  gps_time 372077587.701670 372077683.749338
  extended_return_number          1      3
  extended_number_of_returns      1      3
  extended_classification         2    100
  extended_scan_angle         -4413   4407
  extended_scanner_channel        0      2
  attribute0          0          0  ('(pseudo-) reflectance')
  attribute1          0          0  ('sigma xy')
  attribute2          0          0  ('sigma z')
  attribute3          0          0  ('water column optical depth')
  attribute4          0          0  ('figure of merit')
  attribute5          0          0  ('Bathymetry flags')
  attribute6  -0.121401 0.00724537  ('Pitch (radians)')
  attribute7 -0.0371566  0.0977106  ('Roll (radians)')
  attribute8          0    1.69472  ('Heading (radians)')
  attribute9          0          0  ('temp_z1') \\----------------------------->Z range expected here!
number of first returns:        5087964
number of intermediate returns: 3052305
number of last returns:         5087707
number of single returns:       2016960
overview over extended number of returns of given pulse: 2016960 37141 9156915 0 0 0 0 0 0 0 0 0 0 0 0
histogram of classification of points:
          934215  ground (2)
           29797  noise (7)
 +-> flagged as synthetic: 5764
  +--->            5764  of those are classification (100)
histogram of extended classification of points:
         3066978  extended classification (40)
         4107284  extended classification (41)
         3066978  extended classification (42)
            5764  extended classification (100)


It still does not appear z is copied over. Would you give it a try yourself. If you want a sample file, a link is posted on the original post.

Best Regards
José

LAStools - efficient tools for LiDAR processing

unread,
Apr 29, 2025, 6:47:39 AMApr 29
to LAStools - efficient tools for LiDAR processing
Hi José,
please always tell the exact commands you are running and give the full verbose output.
Please see this example how we would like to see a problem report.
We tested once again: Is is working, please check again the workflow you are doing.

Starting with the file you supplied:
    lasinfo64 -i 10003_Sample_copyZattrib10.las -v

gives as output:

LAStools lasinfo (by in...@rapidlasso.de) version 250426
reading '10003_Sample_copyZattrib10.las' with 142927 points
lasinfo (250426) report for '10003_Sample_copyZattrib10.las'

reporting all LAS header entries:
... only WE are allowed to suppress some lines :)
variable length header record 1 of 8:
...
reporting minimum and maximum for all LAS point record entries ...
  X             8727778    8843057
  Y             7068579    7103337
  Z               -3220      -2761
...
  extended_scanner_channel        1      2

  attribute0          0          0  ('(pseudo-) reflectance')
  attribute1          0          0  ('sigma xy')
  attribute2          0          0  ('sigma z')
  attribute3          0          0  ('water column optical depth')
  attribute4          0          0  ('figure of merit')
  attribute5          0          0  ('Bathymetry flags')
  attribute6          0          0  ('Pitch (radians)')
  attribute7          0          0  ('Roll (radians)')
  attribute8          0          0  ('Heading (radians)')
  attribute9          0          0  ('temp_z')
number of first returns:        140163
number of intermediate returns: 0
number of last returns:         141975
number of single returns:       139211
overview over extended number of returns of given pulse: 139211 2917 799 0 0 0 0 0 0 0 0 0 0 0 0

histogram of classification of points:
          142927  ground (2)

So your 'temp_z' attribute is already there - just to show it works we add another 10th attribute/extra_byte:
    las2las64 -i  10003_Sample_copyZattrib10.las -o tmp1.laz -add_attribute 10 "temp_zz" "adding Z to attribute" 0.01 -v
We check if the field was added:
    lasinfo64 -i tmp1.laz -v

LAStools lasinfo (by in...@rapidlasso.de) version 250426
....
  attribute8          0          0  ('Heading (radians)')
  attribute9          0          0  ('temp_z')
  attribute10          0          0  ('temp_zz')
number of first returns:        140163
number of intermediate returns: 0
number of last returns:         141975
number of single returns:       139211
overview over extended number of returns of given pulse: 139211 2917 799 0 0 0 0 0 0 0 0 0 0 0 0

histogram of classification of points:
          142927  ground (2)

We see: The extra field was added as attribute10 but has no values set (value range 0...0).
Now we add the z values to this attribute:
    las2las64 -i tmp1.laz -copy_z_into_attribute 10 -o tmp1_copyZ.laz -v

LAStools las2las (by in...@rapidlasso.de) version 250426
reading 142927 and writing all surviving points ...
total time: 0.142 sec. written 142927 surviving points to 'tmp1_copyZ.laz'.

And we check the result again:
   lasinfo64 -i tmp1_copyZ.laz -v

LAStools lasinfo (by in...@rapidlasso.de) version 250426
...
  min x y z:                  587277.78 2870685.79 -32.20
  max x y z:                  588430.57 2871033.37 -27.61
...
  attribute7          0          0  ('Roll (radians)')
  attribute8          0          0  ('Heading (radians)')
  attribute9          0          0  ('temp_z')
  attribute10      -32.2     -27.61  ('temp_zz')
number of first returns:        140163
...

We see: The attribute10 is set with a value range equal to our z-range out of the header.
Everything works correct.

Please check again and report.
Cheers,

Jochen @rapidlasso

josevim

unread,
Apr 29, 2025, 1:18:56 PMApr 29
to LAStools - efficient tools for LiDAR processing
Thanks Jochen for the detailed explanation. I got the instruction working as desired.

I was trying to copy z to attribute "10" but the latter didn't exist. I used:

las2las64 -i 10003_Sample_copyZattrib10.las -add_attribute 10 "temp_z1" "adding Z to attribute" 0.01 -o tmp1.laz -v

But I just noticed attribute "10" was added as "9" because, either numeration starts at 0 or because the next available attribute is "9", not "10"

  attribute0          0          0  ('(pseudo-) reflectance')

  attribute1          0          0  ('sigma xy')
  attribute2          0          0  ('sigma z')
  attribute3          0          0  ('water column optical depth')
  attribute4          0          0  ('figure of merit')
  attribute5          0          0  ('Bathymetry flags')
  attribute6          0          0  ('Pitch (radians)')
  attribute7          0          0  ('Roll (radians)')
  attribute8          0          0  ('Heading (radians)')
  attribute9          0          0  ('temp_z1')

My mistake was I kept trying to add to Attribute10 when Attribute9 was needed. Then of course:

las2las64 -i  tmp1.laz  -copy_z_into_attribute 9 -o  tmp2.laz  -v

Works well:

 attribute0          0          0  ('(pseudo-) reflectance')
  attribute1          0          0  ('sigma xy')
  attribute2          0          0  ('sigma z')
  attribute3          0          0  ('water column optical depth')
  attribute4          0          0  ('figure of merit')
  attribute5          0          0  ('Bathymetry flags')
  attribute6          0          0  ('Pitch (radians)')
  attribute7          0          0  ('Roll (radians)')
  attribute8          0          0  ('Heading (radians)')
  attribute9      -26.7     -25.97  ('temp_z1')

I appreciate the prompt response and helping me to clarify the mix up.

Best Regards
josé

LAStools - efficient tools for LiDAR processing

unread,
Apr 29, 2025, 1:20:36 PMApr 29
to LAStools - efficient tools for LiDAR processing
Hi José,
thanks for the feedback, glad you solved the issue!

Jochen @rapidlasso

Reply all
Reply to author
Forward
0 new messages