1

I'm trying to use lidR to range correct the intensity values in my point cloud. I'm running into some trouble with running lasrangecorrection due to producing an unrealistic range value.

The mean sensor altitude as provided in the las tile metadata is 2260 meters.

The sensor_tracking() function indicates that the point cloud might be "wrongly populated" - in what way might it be wrongly populated?

The lasrangecorrection() function suggests checking correctness of sensor position and gps times, but what is considered incorrect?

Warnings and error messages:

lastile <- readLAS("/tmp/u_5370088700_2015.las")
lastile
#> class        : LAS (LASF v1.4)
#> point format : 6
#> memory       : 594.3 Mb 
#> extent       :537000, 538500, 4887000, 4888500 (xmin, xmax, ymin, ymax)
#> coord. ref.  : +proj=utm +zone=18 +datum=NAD83 +units=m +no_defs +ellps=GRS80 +towgs84=0,0,0 
#> area         : 2.05 km²
#> points       : 6.77 million points
#> density      : 3.3 points/m²
#> names        : X Y Z gpstime Intensity ReturnNumber NumberOfReturns ScanDirectionFlag EdgeOfFlightline Classification ScannerChannel Synthetic_flag Keypoint_flag Withheld_flag Overlap_flag ScanAngle UserData PointSourceID 
sensor <- sensor_tracking(lastile)
#> Warning message:
#> 7991 pulses with multiple returns were not actually paired. The point cloud is likely to be wrongly populated. These pulses were removed 
range_corrected <- lasrangecorrection(lastile, sensor, 2000)
#> An high range R has been computed relatively to the expected average range Rm = 2106
#> Point number 851196 at (x,y,z,t) = (538442.61, 4888494.26, 548.58, 115043523.41)
#> Matched with sensor between (538020.25, 4888520.48, 2601.76, 115044213.00) and (538020.03, 4888486.40, 2598.99, 115044213.50)
#> The range computed was R = 47387.71
#> Check the correctness of the sensor positions and the correctness of the gpstime either in the point cloud or in the sensor positions.
#> Error: Unrealistic range: see message above

Visualization of sensor positions overlayed with bounding box of las tile: enter image description here

Bounding boxes for sensor positions and lastile:

bbox(sensor)
#>         min       max
#> X  536890.6  539228.8
#> Y 4886784.4 4888531.6
lastile@bbox
#>       min     max
#> x  537000  538500
#> y 4887000 4888500

lascheck() output:

> lascheck(lastile)

#> Checking the data
#>  - Checking coordinates... ✓
#>  - Checking coordinates type... ✓
#>  - Checking attributes type... ✓
#>  - Checking ReturnNumber validity... ✓
#>  - Checking NumberOfReturns validity... ✓
#>  - Checking ReturnNumber vs. NumberOfReturns... ✓
#>  - Checking RGB validity... ✓
#>  - Checking absence of NAs... ✓
#>  - Checking duplicated points...
#>   ⚠ 1474 points are duplicated and share XYZ coordinates with other points
#>  - Checking degenerated ground points...
#>   ⚠ There were 4 degenerated ground points. Some X Y Z coordinates were repeated.
#>  - Checking attribute population... ✓
#>  - Checking flag attributes... ✓
#> Checking the header
#>  - Checking header completeness... ✓
#>  - Checking scale factor validity... ✓
#>  - Checking point data format ID validity... ✓
#>  - Checking extra bytes attributes validity... ✓
#>  - Checking coordinate reference sytem... ✓
#> Checking header vs data adequacy
#>  - Checking attributes vs. point format... ✓
#>  - Checking header bbox vs. actual content... ✓
#>  - Checking header number of points vs. actual content... ✓
#>  - Checking header return number vs. actual content... ✓
#> Checking preprocessing already done 
#>  - Checking ground classification... yes
#>  - Checking normalization... no
#>  - Checking negative outliers... ✓
#>  - Checking flightline classification... yes

1 Answer 1

1

Edit: after investigation in a bug report it appeared that the dataset contained very weird data. The solution was deeply specific to this dataset and is not relevant to explain the problem here.

Orginal anwser

Sensor tracking and range correction are new functions in lidR. To be computed properly they require a dataset with attributes return number, number of returns, gpstime and point source ID perfectly populated. There are so many way for dataset to be incorrectly populated that it is impossible to tell you with certitude why the algorithm failed.

To tell the truth I (the developer) am waiting for people like you to report bugs because I was not able to guess all the possible way for a dataset to be invalid and thus I cannot handle every error properly. First you should check your point cloud with lascheck(). Then please report the bug in the lidR repo.

7991 pulses with multiple returns were not actually paired. The point cloud is likely to be wrongly populated. These pulses were removed

In the source code you can read:

# Does this really happen?
if (any(unpaired_pulse))
   warning(glue::glue("{sum(unpaired_pulse)} pulses with multiple returns were not actually paired. The point cloud is likely to be wrongly populated. These pulses were removed"), call. = FALSE) # nocov

It means that there is a test to handle the case of unpaired pulse but the comment shows that I (the developer) was not sure if this case can really happen. Now I know it can and that I was right to handle it. But I'm still unable to tell you why without seeing the dataset. My guess is: corrupted gpstime or corrupted return number attributes.

An high range R has been computed relatively to the expected average range Rm = 2106 Point number 851196 at (x,y,z,t) = (538442.61, 4888494.26, 548.58, 115043523.41) Matched with sensor between (538020.25, 4888520.48, 2601.76, 115044213.00) and (538020.03, 4888486.40, 2598.99, 115044213.50) The range computed was R = 47387.71 Check the correctness of the sensor positions and the correctness of the gpstime either in the point cloud or in the sensor positions.

The algorithm has some tests to do not return weird data silently. Again I can't answer without seeing the dataset. We can see that the current point was sampled at t = 115043523.4 but the the range was computed with the sensor positions at t = 115044213 and t = 115044213.5 which is incorrect.

4
  • thank you for the response and explanation. I have added the lascheck output. Everything seems to be in place. Github issue posted: github.com/Jean-Romain/lidR/issues/327
    – Lucas
    Commented Mar 19, 2020 at 21:45
  • I'm pretty sure duplicated point may be involved in the troubleshooting
    – JRR
    Commented Mar 19, 2020 at 21:50
  • After seeing your investigations here: github.com/Jean-Romain/lidR/issues/327, and doing some more digging myself, my hunch is that this problem is due to a multiple beam sensor. Lastools mentions the potential problems that multiple-beam sensors can create (rapidlasso.com/2019/12/09/…) and the file in question is indeed from a multiple beam sensor - Leica ALS70-HP. My guess is that the UserData field indicates the beam for each return. Do you have any experience with this kind of data?
    – Lucas
    Commented Mar 22, 2020 at 15:31
  • ^ question continued here: gis.stackexchange.com/questions/354769/…
    – Lucas
    Commented Mar 22, 2020 at 16:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.