4

I want to export a .las file of segmented trees with the treeID column into ArcGIS Pro, but when I export the file the treeID column is not selectable and I really want the separate colours for the segmented trees.

I have tried changing the name of the treeID row in R and/or copying the data into a recognised header name in ArcGIS Pro, I was trying to rename or copy the column treeID to ReturnNumber but I can not find a way that works and generally receive an error message similar to "no applicable method for rename applied to an object of class c('LAS', 'Spatial').

library(lidR)
library(dplyr)

# Import the las and segment the trees
LASfile <- system.file("extdata", "MixedConifer.laz", package="lidR")
las <- readLAS(LASfile, select = "xyzr", filter = "-drop_z_below 0")
las1 <- segment_trees(las, li2012())
col <- random.colors(200)
plot(las1, color = "treeID", colorPalette = col)
#  trying to rename the columns like you can in a dataframe
select(las1, treeID=ReturnNumber)
# or
temp <- mutate(las1, UserData=ReturnNumber(las1))
# using the pipe function
las1 %>% rename(treeID=ReturnNumber)

colnames(las1) 

# write out .las to file for loading into ArcGIS Pro
writeLAS(las = las1, file = "trees.las", index= TRUE)
1
  • 1
    There is a hard limit of 16 (one nibble) returns in ASPRS LAS 1.4 files and 8 (one octet) in LAS 1.3 and earlier, there is 'user data' but you only get one byte. The specification is available for viewing, have a read it might help give some understanding to the limits. There are other parameters that can be hijacked, intensity or point source id as uint16 should be available to ArcGIS display but you might be overwriting data you care about. Although JRR is correct with respect to extra bytes, which occur after each point record, there is no guarantee that ArcGIS will recognize the extra Commented Aug 4, 2020 at 2:28

2 Answers 2

4

There is no select, mutate or any other dplyr verbs for LAS objects. LAS objects are not data.frame but... LAS objects.

A las file contains a set of core attributes. To save extra attributes such as treeID you must add extra bytes attributes. segment_trees() does it automatically. You can verify that by looking into the header:

library(lidR)
LASfile <- system.file("extdata", "MixedConifer.laz", package="lidR")
las <- readLAS(LASfile)
las1 <- segment_trees(las, li2012())
las1@header
#> File signature:           LASF 
#> File source ID:           0 
#> [...]
#> Variable length records: 
#>    Variable length record 1 of 2 
#>        Description: by LAStools of rapidlasso GmbH 
#>        Tags:
#>           Key 1024 value 1 
#>           Key 3072 value 26912 
#>           Key 3076 value 9001 
#>           Key 4099 value 9001 
#>    Variable length record 2 of 2 
#>        Description: rlas extra bytes 
#>        Extra Bytes Description:
#>           treeID: An ID for each segmented tree

The extra bytes attributes are valid according to LAS specifications. We have already checked that other sofware like python are able to read these data like in this question. However it is not guaranteed that the reader in ArcGIS supports the whole specification of the las format and may not be able to read the extra bytes attributes. Actually I don't know and you should confirm this information from somebody who knows ArcGIS.

You can't store the treeID in UserData because it is a 1 bytes attribute so you can only store numbers between 0 and 255 which is just enough for the very small 0.8 ha example dataset. And ReturnNumber is even worst because it is a 3 bits attribute so between 0 and 7.

2

The Intensity int column has the ability to store all the treeID values. There is a slightly different format for copying rows to another and you can find the locations using str(las1). Additionally, some NA values were discovered from points not allocated, which I have remedied below as this initially failed to enable writing the .las successfully. Once imported into ArcGIS Pro adjust the Symbology to draw using intensity creating a custom Value Source and random Color scheme setting your max number of of identified trees value as highlighted in the screenshot, this gave better visual results showing less adjacent trees being coloured similarly. The data clearly displays individual trees satisfactorily with some adjustment lowering the Symbol scale.

library(lidR)
library(dplyr)

# Import the las and segment the trees
LASfile <- system.file("extdata", "MixedConifer.laz", package="lidR")
las <- readLAS(LASfile)
las1 <- segment_trees(las, li2012())

# remove points that are not assigned to a tree
trees = filter_poi(las1, !is.na(treeID))  # remove NA
col <- random.colors(100)
plot(trees, color = "treeID", colorPalette = col)

# format for copying rows to overwrite 
las1$Intensity = las1$treeID 
head(trees)  # checking first few rows copied

trees = filter_poi(las1, !is.na(Intensity))  # remove all NA values from here too
writeLAS(las = trees, file = "ntrees.las")
max(trees$Intensity, na.rm = TRUE)  # check max number of identified trees 

Screenshot below of my zoomed ArcGIS Pro working with less than 65,535 treeID (Intensity attribute is 16 bits) from the above code but loading a significantly larger.las file than the example, this consisted of 130 Mb or 30 million data points consisting of 4532 trees.

Screenshot of zoomed ArcGIS Pro working with <65,535 treeID from the above code loading a larger .las file

1
  • Be careful not having a treeID bigger than 65535. Anyway writeLAS will throw an error if you have an intensity above 65535: Invalid data: Intensity is not an unsigned integer on 16 bits
    – JRR
    Commented Aug 4, 2020 at 11:00

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.