1

I would like to create a tiled index for extents of processed (e.g. normalized) LAS files that include date and time of processing. This is because we sometimes receive replacement tiles, and I need to have an easy way to show on a map where areas have been updated. The header of a LAS file holds a date (d/y) - the year stays the same after normalization (although day is set to 0 which maybe is a bug?), so I assume the file creation date refers to original creation and shouldn't change. I could extract the date/time afterwards and join it back to lidR output of the catalog via the name, but I was wondering if the file date/time could be read into the catalog itself?

library(lidR)

LASfile <- system.file("extdata", "Topography.laz", package="lidR")
ctg <- readLAScatalog(LASfile)
opt_chunk_size(ctg) <- 300
opt_chunk_alignment(ctg) <- c(200, 50)
opt_output_files(ctg) = "{tempdir()}/{ID}_normalized"

nctg = normalize_height(ctg, tin())

# Year of file creation is not updated
ctg$File.Creation.Year
#> [1] 2018
nctg$File.Creation.Year
#> [1] 2018 2018

1 Answer 1

1

Interesting question. No, the File.Creation.Year is not updated. I'd argue that this information should refer to the date of acquisition of the data and thus should be preserved but the LAS specification states:

The year, expressed as a four digit number, in which the file was created

So, your interpretation and your expectation are valid. Currently the header is not updated and there is no simple way to do it using built in function. The simplest option might be to happen the date to the filename

opt_output_files(ctg) = "{tempdir()}/{ID}_normalized_{Sys.Date()}"

The other complex option would be to rewrite a normalize_height function that updates the header.

library(lidR)

LASfile <- system.file("extdata", "Topography.laz", package="lidR")
ctg = readLAScatalog(LASfile)
opt_chunk_size(ctg) = 300
opt_chunk_alignment(ctg) = c(200, 50)
opt_output_files(ctg) = "{tempdir()}/{ID}_normalized"

normalize_height_with_date = function(las, algorithm, na.rm = FALSE, use_class = c(2L,9L), ..., add_lasattribute = FALSE, Wdegenerated = TRUE)
{
  x <- readLAS(las)
  if (is.empty(x)) return(NULL)
  x <- normalize_height(x, algorithm, na.rm, use_class, ..., add_lasattribute = add_lasattribute, Wdegenerated = Wdegenerated)
  x <- filter_poi(x, buffer == 0)
  x@header@PHB[["File Creation Year"]] <- as.numeric(format(Sys.time(), "%Y"))
  x@header@PHB[["File Creation Day of Year"]] <- as.numeric(format(Sys.time(), "%j"))
  return(x)
}

options <- list(need_buffer = TRUE, drop_null = TRUE, need_output_file = TRUE, automerge = TRUE)
nctg  <- catalog_apply(ctg, normalize_height_with_date, algorithm = tin(), .options = options)

# Year of file is updated
ctg$File.Creation.Year
#> [1] 2018
nctg$File.Creation.Year
#> [1] 2021 2021

But File.Creation.Day.of.Year is zeroed and it is indeed a bug in rlas < 1.4 reported here

I guess you could also use the information recorded by your file system but this is not reliable through time I guess

format(file.info(nctg$filename)$mtime, "%Y")
#> [1] "2021" "2021"
2
  • Yes, this works very well thank you. I'm going to use both solutions so that the date is easily seen both on the file and in the index. Once the creation.day.of.year is fixed this will be exported out to a shapefile to keep track of updates. (I can understand the reluctance to change the creation date on principle, but this is more important in our case I think.)
    – Ray J
    Mar 10, 2021 at 16:45
  • 1
    Bug in rlas is fixed. And you can use as.spatial to transform a LAScatalog into SpatialPolygonDataFrame and save it into shapefile
    – JRR
    Mar 10, 2021 at 16:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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