Skip to main content
added 1 character in body
Source Link
JRR
  • 9.7k
  • 1
  • 14
  • 29

grid_metrics is designed in a way that your expression is evaluated within the frame of the data.table that contains the point cloud. Your function is found within the loaded R packages. Thus your code cannot work for two reasons:

  1. f is definedefined within the frame of get_layer_counts
  2. breaks does not exists within the frame of the point cloud

This version works:

# Main package function
get_layer_counts <- function(las, res = 10) 
{
  stats <- lidR::grid_metrics(las, func = layer_count_metrics(Z, breaks = seq(0,20,2)), res = res)
  lidR:::as.raster.lasmetrics(stats)
}

# Metrics function to count points within height intervals
layer_count_metrics <- function(Z, breaks) 
{
  zcat <- findInterval(Z, breaks, left.open = TRUE)
  tcount = as.list(table(factor(zcat, levels = 1:length(breaks))))
  names(tcount) <- paste0("layer", 1:length(breaks))
  tcount
}

library(lidR)

LASfile <- system.file("extdata", "Megaplot.laz", package="lidR")
las = readLAS(LASfile)

stats = get_layer_counts(las)

You can notice one important drawback. You can't propagate the argument breaks through the get_layer_count function because it looks for breaks within the frame of the point cloud. When explicitly passed there is no name to look for and thus it just works. I hope to improve that in future releases.

Also notice that I added factor before table. Indeed the function must returns always the same number of metrics for each pixel. Otherwise the pixel aggregation fails.

grid_metrics is designed in a way that your expression is evaluated within the frame of the data.table that contains the point cloud. Your function is found within the loaded R packages. Thus your code cannot work for two reasons:

  1. f is define within the frame of get_layer_counts
  2. breaks does not exists within the frame of the point cloud

This version works:

# Main package function
get_layer_counts <- function(las, res = 10) 
{
  stats <- lidR::grid_metrics(las, func = layer_count_metrics(Z, breaks = seq(0,20,2)), res = res)
  lidR:::as.raster.lasmetrics(stats)
}

# Metrics function to count points within height intervals
layer_count_metrics <- function(Z, breaks) 
{
  zcat <- findInterval(Z, breaks, left.open = TRUE)
  tcount = as.list(table(factor(zcat, levels = 1:length(breaks))))
  names(tcount) <- paste0("layer", 1:length(breaks))
  tcount
}

library(lidR)

LASfile <- system.file("extdata", "Megaplot.laz", package="lidR")
las = readLAS(LASfile)

stats = get_layer_counts(las)

You can notice one important drawback. You can't propagate the argument breaks through the get_layer_count function because it looks for breaks within the frame of the point cloud. When explicitly passed there is no name to look for and thus it just works. I hope to improve that in future releases.

Also notice that I added factor before table. Indeed the function must returns always the same number of metrics for each pixel. Otherwise the pixel aggregation fails.

grid_metrics is designed in a way that your expression is evaluated within the frame of the data.table that contains the point cloud. Your function is found within the loaded R packages. Thus your code cannot work for two reasons:

  1. f is defined within the frame of get_layer_counts
  2. breaks does not exists within the frame of the point cloud

This version works:

# Main package function
get_layer_counts <- function(las, res = 10) 
{
  stats <- lidR::grid_metrics(las, func = layer_count_metrics(Z, breaks = seq(0,20,2)), res = res)
  lidR:::as.raster.lasmetrics(stats)
}

# Metrics function to count points within height intervals
layer_count_metrics <- function(Z, breaks) 
{
  zcat <- findInterval(Z, breaks, left.open = TRUE)
  tcount = as.list(table(factor(zcat, levels = 1:length(breaks))))
  names(tcount) <- paste0("layer", 1:length(breaks))
  tcount
}

library(lidR)

LASfile <- system.file("extdata", "Megaplot.laz", package="lidR")
las = readLAS(LASfile)

stats = get_layer_counts(las)

You can notice one important drawback. You can't propagate the argument breaks through the get_layer_count function because it looks for breaks within the frame of the point cloud. When explicitly passed there is no name to look for and thus it just works. I hope to improve that in future releases.

Also notice that I added factor before table. Indeed the function must returns always the same number of metrics for each pixel. Otherwise the pixel aggregation fails.

deleted 552 characters in body
Source Link
JRR
  • 9.7k
  • 1
  • 14
  • 29

grid_metrics is designed in a way that your expression is evaluated within the frame of the data.table that contains the point cloud. Your function is found within the loaded R packages. Thus your code cannot work for two reasons:

  1. f is define within the frame of get_layer_counts
  2. breaks does not exists within the frame of the point cloud

This version works:

# Main package function
get_layer_counts <- function(las, res = 10) 
{
  stats <- lidR::grid_metrics(las, func = layer_count_metrics(Z, breaks = seq(0,20,2)), res = res)
  lidR:::as.raster.lasmetrics(stats)
}

# Metrics function to count points within height intervals
layer_count_metrics <- function(Z, breaks) 
{
  zcat <- findInterval(Z, breaks, left.open = TRUE)
  tcount = as.list(table(factor(zcat, levels = 1:length(breaks))))
  names(tcount) <- paste0("layer", 1:length(breaks))
  tcount
}

library(lidR)

LASfile <- system.file("extdata", "Megaplot.laz", package="lidR")
las = readLAS(LASfile)

stats = get_layer_counts(las)

You can notice one important drawback. You can't propagate the argument breaks through the get_layer_count function because it looks for breaks within the frame of the point cloud. When explicitly passed there is no name to look for andand thus it just works.

In I hope to improve that in future versions > 2releases.0 these limitations will still exists but developers will be able to bypass it by unquoting the arguments:

get_layer_counts <- function(las, breaks, res = 10) 
{
  lidR::grid_metrics(
     las  = las, 
     func = layer_count_metrics(Z, breaks = lazyeval::uq(breaks)), 
     res  = res)

  # the ouptut is already a RasterLayer in version >= 2.0
}

Also notice that I added factor before table. Indeed the function must returns always the same number of metrics for each pixel. Otherwise the pixel aggregation fails.

grid_metrics is designed in a way that your expression is evaluated within the frame of the data.table that contains the point cloud. Your function is found within the loaded R packages. Thus your code cannot work for two reasons:

  1. f is define within the frame of get_layer_counts
  2. breaks does not exists within the frame of the point cloud

This version works:

# Main package function
get_layer_counts <- function(las, res = 10) 
{
  stats <- lidR::grid_metrics(las, func = layer_count_metrics(Z, breaks = seq(0,20,2)), res = res)
  lidR:::as.raster.lasmetrics(stats)
}

# Metrics function to count points within height intervals
layer_count_metrics <- function(Z, breaks) 
{
  zcat <- findInterval(Z, breaks, left.open = TRUE)
  tcount = as.list(table(factor(zcat, levels = 1:length(breaks))))
  names(tcount) <- paste0("layer", 1:length(breaks))
  tcount
}

library(lidR)

LASfile <- system.file("extdata", "Megaplot.laz", package="lidR")
las = readLAS(LASfile)

stats = get_layer_counts(las)

You can notice one important drawback. You can't propagate the argument breaks through the get_layer_count function because it looks for breaks within the frame of the point cloud. When explicitly passed there is no name to look for and thus it just works.

In future versions > 2.0 these limitations will still exists but developers will be able to bypass it by unquoting the arguments:

get_layer_counts <- function(las, breaks, res = 10) 
{
  lidR::grid_metrics(
     las  = las, 
     func = layer_count_metrics(Z, breaks = lazyeval::uq(breaks)), 
     res  = res)

  # the ouptut is already a RasterLayer in version >= 2.0
}

Also notice that I added factor before table. Indeed the function must returns always the same number of metrics for each pixel. Otherwise the pixel aggregation fails.

grid_metrics is designed in a way that your expression is evaluated within the frame of the data.table that contains the point cloud. Your function is found within the loaded R packages. Thus your code cannot work for two reasons:

  1. f is define within the frame of get_layer_counts
  2. breaks does not exists within the frame of the point cloud

This version works:

# Main package function
get_layer_counts <- function(las, res = 10) 
{
  stats <- lidR::grid_metrics(las, func = layer_count_metrics(Z, breaks = seq(0,20,2)), res = res)
  lidR:::as.raster.lasmetrics(stats)
}

# Metrics function to count points within height intervals
layer_count_metrics <- function(Z, breaks) 
{
  zcat <- findInterval(Z, breaks, left.open = TRUE)
  tcount = as.list(table(factor(zcat, levels = 1:length(breaks))))
  names(tcount) <- paste0("layer", 1:length(breaks))
  tcount
}

library(lidR)

LASfile <- system.file("extdata", "Megaplot.laz", package="lidR")
las = readLAS(LASfile)

stats = get_layer_counts(las)

You can notice one important drawback. You can't propagate the argument breaks through the get_layer_count function because it looks for breaks within the frame of the point cloud. When explicitly passed there is no name to look for and thus it just works. I hope to improve that in future releases.

Also notice that I added factor before table. Indeed the function must returns always the same number of metrics for each pixel. Otherwise the pixel aggregation fails.

added 604 characters in body
Source Link
JRR
  • 9.7k
  • 1
  • 14
  • 29

Unfortunatly you're right. grid_metrics is designed in a way that it looks inyour expression is evaluated within the global environment and suffers of a lackframe of flexibilitythe data.table that contains the point cloud. Your function is found within the loaded R packages. Thus your code cannot work. for two reasons:

  1. f is define within the frame of get_layer_counts
  2. breaks does not exists within the frame of the point cloud

This version works:

# Main package function
get_layer_counts <- function(las, res = 10) 
{
  stats <- lidR::grid_metrics(las, func = layer_count_metrics(Z, breaks = seq(0,20,2)), res = res)
  lidR:::as.raster.lasmetrics(stats)
}

# Metrics function to count points within height intervals
layer_count_metrics <- function(Z, breaks) 
{
  zcat <- findInterval(Z, breaks, left.open = TRUE)
  tcount = as.list(table(factor(zcat, levels = 1:length(breaks))))
  names(tcount) <- paste0("layer", 1:length(breaks))
  tcount
}

library(lidR)

LASfile <- system.file("extdata", "Megaplot.laz", package="lidR")
las = readLAS(LASfile)

stats = get_layer_counts(las)

But youYou can notice one important drawback. You can't propagate the argument breaks through the get_layer_count function because it looks for breaks within the frame of the point cloud. I hopeWhen explicitly passed there is no name to fix that in the next releaselook for and thus it just works.

In future versions > 2.0 these limitations will still exists but developers will be able to bypass it by unquoting the arguments:

get_layer_counts <- function(las, breaks, res = 10) 
{
  lidR::grid_metrics(
     las  = las, 
     func = layer_count_metrics(Z, breaks = lazyeval::uq(breaks)), 
     res  = res)

  # the ouptut is already a RasterLayer in version >= 2.0
}

Also notice that I added factor before table. Indeed the function must returns always the same number of metrics for each pixel. Otherwise the pixel aggregation fails.

Unfortunatly you're right. grid_metrics is designed in a way that it looks in the global environment and suffers of a lack of flexibility. Thus your code cannot work. This version works:

# Main package function
get_layer_counts <- function(las, res = 10) 
{
  stats <- lidR::grid_metrics(las, func = layer_count_metrics(Z, breaks = seq(0,20,2)), res = res)
  lidR:::as.raster.lasmetrics(stats)
}

# Metrics function to count points within height intervals
layer_count_metrics <- function(Z, breaks) 
{
  zcat <- findInterval(Z, breaks, left.open = TRUE)
  tcount = as.list(table(factor(zcat, levels = 1:length(breaks))))
  names(tcount) <- paste0("layer", 1:length(breaks))
  tcount
}

library(lidR)

LASfile <- system.file("extdata", "Megaplot.laz", package="lidR")
las = readLAS(LASfile)

stats = get_layer_counts(las)

But you can notice one important drawback. You can't propagate the argument breaks through the get_layer_count function. I hope to fix that in the next release.

Also notice that I added factor before table. Indeed the function must returns always the same number of metrics for each pixel. Otherwise the pixel aggregation fails.

grid_metrics is designed in a way that your expression is evaluated within the frame of the data.table that contains the point cloud. Your function is found within the loaded R packages. Thus your code cannot work for two reasons:

  1. f is define within the frame of get_layer_counts
  2. breaks does not exists within the frame of the point cloud

This version works:

# Main package function
get_layer_counts <- function(las, res = 10) 
{
  stats <- lidR::grid_metrics(las, func = layer_count_metrics(Z, breaks = seq(0,20,2)), res = res)
  lidR:::as.raster.lasmetrics(stats)
}

# Metrics function to count points within height intervals
layer_count_metrics <- function(Z, breaks) 
{
  zcat <- findInterval(Z, breaks, left.open = TRUE)
  tcount = as.list(table(factor(zcat, levels = 1:length(breaks))))
  names(tcount) <- paste0("layer", 1:length(breaks))
  tcount
}

library(lidR)

LASfile <- system.file("extdata", "Megaplot.laz", package="lidR")
las = readLAS(LASfile)

stats = get_layer_counts(las)

You can notice one important drawback. You can't propagate the argument breaks through the get_layer_count function because it looks for breaks within the frame of the point cloud. When explicitly passed there is no name to look for and thus it just works.

In future versions > 2.0 these limitations will still exists but developers will be able to bypass it by unquoting the arguments:

get_layer_counts <- function(las, breaks, res = 10) 
{
  lidR::grid_metrics(
     las  = las, 
     func = layer_count_metrics(Z, breaks = lazyeval::uq(breaks)), 
     res  = res)

  # the ouptut is already a RasterLayer in version >= 2.0
}

Also notice that I added factor before table. Indeed the function must returns always the same number of metrics for each pixel. Otherwise the pixel aggregation fails.

added 8 characters in body
Source Link
JRR
  • 9.7k
  • 1
  • 14
  • 29
Loading
added 15 characters in body
Source Link
JRR
  • 9.7k
  • 1
  • 14
  • 29
Loading
added 81 characters in body
Source Link
JRR
  • 9.7k
  • 1
  • 14
  • 29
Loading
Source Link
JRR
  • 9.7k
  • 1
  • 14
  • 29
Loading