TreeLS icon indicating copy to clipboard operation
TreeLS copied to clipboard

tlsNormalize failing to normalize TLS data

Open munachau opened this issue 1 year ago • 11 comments

I used the TLS data available in package pine_plot.laz. but it is unable to normalize as it is related with function raster

tls = tlsNormalize(tls, keep_ground = T) no ground points found, performing ground segmentation Error in h(simpleError(msg, call)) : error in evaluating the argument 'x' in selecting a method for function 'raster': unable to find an inherited method for function ‘extent’ for signature ‘"LAS"’

munachau avatar Mar 01 '24 09:03 munachau

I am also having this issue.

ashlynolah avatar Apr 22 '24 18:04 ashlynolah

Me too

green512 avatar Apr 26 '24 09:04 green512

It's line 545 of methods.R - grid = las %>% extent %>% raster which is trying to apply extent to an object of class LAS and instead lidR uses ext from terra since lidR no longer uses raster (as no one should, since the "package has been superseded by the "terra" package")

In short, I'd be careful even using this package at all as it's no longer supported, but if you do I suggest rewriting functions (like tlsNormalize) to use them locally (or fork the repo and make your on version of the package) where objects like rasters produced from function in lidR are converted to raste::raster prior to being used. That or undertake the epic task of reworking the entire package to use terra instead of raster.

For example:

tlsNormalize = function(las, min_res=.25, keep_ground=TRUE){
  
  isLAS(las)
  
  if(min_res <= 0)
    stop('res must be a positive number')
  
  if(!any(las$Classification == 2)){
    message('no ground points found, performing ground segmentation')
    las = classify_ground(las, csf(class_threshold = 0.05, cloth_resolution = 0.05), last_returns = F)
  }
  
  res = lidR::st_area(las) / length(las@data[Classification == 2])
  res = ifelse(res < min_res, min_res, res)
  
  ext = lidR::ext(las)
  grid = terra::rast(ext, res=res)
  
  dtm = grid_terrain(las, res = grid, algorithm = knnidw(), full_raster=TRUE)
  las = normalize_height(las, dtm, na.rm=TRUE, Wdegenerated = TRUE)
  
  if(!keep_ground) las = filter_poi(las, Classification != 2)
  
  return(las)
}

bi0m3trics avatar Apr 27 '24 16:04 bi0m3trics

thank you @bi0m3trics for the helpful response. I tried using your updated tlsNormalize() function as you've written it out above, but I get this error: could not find function "isLAS". Is this function in a different package that I should load or is this just example code that I should adjust myself for my own needs?

Estrada-Gene avatar May 01 '24 01:05 Estrada-Gene

@Estrada-Gene isLAS is part of TreeLS, so if you know it's a las you can delete it...

bi0m3trics avatar May 01 '24 02:05 bi0m3trics

@bi0m3trics I forked the project and moved sp/raster functions to sf/terra...it still may need some proof-check but it runs the examples pretty smoothly :) If any of you can test it a bit against the previous version, I can then push a pull request to the main repo and let TreeLS roll again

spono avatar Jun 10 '24 21:06 spono

Thanks @spono and @bi0m3trics.

radt0005 avatar Aug 13 '24 01:08 radt0005

Same problem, and I´m too neophyte to try the suggested fixes. Is this library current?

crespelp avatar Aug 24 '24 15:08 crespelp

@crespelp It was current to R 4.3 about a year ago. @spono has a fork that was current a few months ago (correct me if I'm wrong, Nic) and my fork was current to somewhere in between (but definitely pre-4.4)... so this repo - maybe no, other forks - maybe yes. Not a great answer, but the truth.

I suggest installing Nic's fork, and seeing if it works... remotes::install_github('spono/TreeLS')

bi0m3trics avatar Aug 24 '24 15:08 bi0m3trics