I am working on releasing a benchmark dataset for trees in RGB + Lidar and I'd like the format to match the most common use cases and packages. I had been intending on proving a tree index using the user_data column. Alot of preprocessing happens in python and i'm writing from laspy. I realized that user_data is clamped 0-255 (there are thousands of trees), meaning that trees do not have a unique index. I'm starting to write an extra dimension function
https://stackoverflow.com/questions/50815580/appending-an-index-to-laspy-file-las
but looking here, it looks like lidR is going to ignore those columns
https://cran.r-project.org/web/packages/lidR/vignettes/lidR-LAS-class.html
and i'll need users to do lasadddata anyways. Perhaps it would be best to just provide a csv lookup table based on x,y,z? With millions of points, will this be the best strategy? I'm worried about precision rounding among platforms. Thoughts welcome on how future users will best interact with extra dim data.
EDIT: The question was deemed too broad. So here is a literal example.
Here is a python pandas dataframe (taken from a laspy-like object) with the x,y,z coordinates of a point and an associated label. What is the best way to write this label information and load it in the R lidR package.
pc.head()
x y z label
272 315547.689 4094399.467 12.288 562.0
287 315541.905 4094400.774 4.151 2233.0
289 315541.279 4094400.842 4.166 2233.0
291 315541.725 4094400.506 8.189 2233.0
292 315540.776 4094400.865 5.199 2233.0
One option is to write to csv and the use lasadddata function add the extra attribute "label" in R separately. However, for a reasonably large point cloud, this would create a 100MB file, which would then be read into R and then joined to ensure the vector order lined up
If you directly write the laspy point cloud, and stick the label data in the user_data column, values above 255 will be clamped by laspy. See link above.
ANSWER:
Because this was flagged, I can't answer my own question. As @JRR noted, the key aspect is to be mindful of the datatype. lidR will read the extra attribute. I hope this helps someone in the future.
So in python
import laspy
def write_label(point_cloud, path):
#Create laspy object
outFile1 = laspy.file.File(path, mode = "w",header = inFile.header)
#First define the new types
outFile1.define_new_dimension(
name="label",
data_type=5, #Data types may matter
description = "Integer Tree Label"
)
# copy fields from laspy object
for dimension in inFile.point_format:
dat = inFile.reader.get_dimension(dimension.name)
outFile1.writer.set_dimension(dimension.name, dat)
outFile1.label = <label column from pandas here>
outFile1.close()
lidR sees a new integer column "label"
> colnames(a@data)
[1] "X" "Y" "Z" "gpstime"
[5] "Intensity" "ReturnNumber" "NumberOfReturns" "ScanDirectionFlag"
[9] "EdgeOfFlightline" "Classification" "Synthetic_flag" "Keypoint_flag"
[13] "Withheld_flag" "ScanAngle" "UserData" "PointSourceID"
[17] "R" "G" "B" "reversible index (lastile)"
[21] "label"
laspy
butlidR
does not recognize those extra attributes. Correct? Can you share a reproducible example as well as an example file (with ten points only for example) + give us at least the file format used.