如何一次读取多个激光雷达文件 (.las) 并将它们合并到 R 中的一个数据帧中
How to read many lidar files (.las) at once and combine them into one dataframe in R
我有一个文件夹,里面有很多激光雷达(.las)文件。看起来像
library(rgdal)
library(raster)
library(tmaptools)
library(tmap)
library(lidR)
library(RStoolbox)
las=readLAS("C:/1/078-638.las")
las1=readLAS("C:/1/082-628.las")
las2=....
所以如果超过100个文件,每一行都很难写。有没有办法一次读取所有这些文件,但格式为 data.frame?
.las 文件有这样的结构
las=payload(las)
las=structure(list(X = c(638238.76, 638238.76, 638239.29, 638235.39,
638233.86, 638233.86, 638235.55, 638231.97, 638231.91, 638228.41
), Y = c(6078001.09, 6078001.09, 6078001.15, 6078001.15, 6078001.07,
6078001.07, 6078001.02, 6078001.08, 6078001.09, 6078001.01),
Z = c(186.64, 186.59, 199.28, 189.37, 186.67, 186.67, 198.04,
200.03, 199.73, 192.14), gpstime = c(319805734.664265, 319805734.664265,
319805734.67875, 319805734.678768, 319805734.678777, 319805734.678777,
319805734.687338, 319805734.701928, 319805734.701928, 319805734.701945
), Intensity = c(13L, 99L, 5L, 2L, 20L, 189L, 2L, 11L, 90L,
1L), ReturnNumber = c(2L, 1L, 1L, 2L, 1L, 1L, 2L, 1L, 1L,
3L), NumberOfReturns = c(2L, 1L, 3L, 2L, 1L, 1L, 3L, 1L,
1L, 4L), ScanDirectionFlag = c(1L, 1L, 0L, 0L, 0L, 0L, 1L,
0L, 0L, 0L), EdgeOfFlightline = c(0L, 0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L), Classification = c(1L, 2L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L), Synthetic_flag = c(FALSE, FALSE, FALSE,
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE), Keypoint_flag = c(FALSE,
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
), Withheld_flag = c(FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
FALSE, FALSE, FALSE, FALSE), ScanAngleRank = c(-12L, -12L,
-12L, -12L, -12L, -12L, -12L, -13L, -13L, -13L), UserData = c(0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), PointSourceID = c(16L,
16L, 16L, 16L, 16L, 16L, 16L, 16L, 16L, 16L), Pulse.width = c(0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L)), class = "data.frame", row.names = c(NA,
-10L))
las1 的结构
las1=structure(list(X = c(628800.68, 628800.75, 628801.43, 628801.47,
628802.13, 628802.19, 628800.19, 628800.24, 628799.57, 628799.58
), Y = c(6082001.07, 6082001.08, 6082001.19, 6082001.2, 6082001.3,
6082001.31, 6082001.21, 6082001.22, 6082001.12, 6082001.12),
Z = c(163.16, 162.96, 163.09, 162.97, 163.12, 162.98, 163.29,
163.16, 163.02, 162.99), gpstime = c(319799021.884921, 319799021.884921,
319799021.884929, 319799021.884929, 319799021.884938, 319799021.884938,
319799021.889375, 319799021.889375, 319799021.889384, 319799021.889384
), Intensity = c(12L, 99L, 14L, 112L, 14L, 121L, 17L, 167L,
20L, 189L), ReturnNumber = c(1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L), NumberOfReturns = c(1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L), ScanDirectionFlag = c(1L, 1L, 1L, 1L, 1L,
1L, 0L, 0L, 0L, 0L), EdgeOfFlightline = c(0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L, 0L, 0L), Classification = c(1L, 2L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 2L), Synthetic_flag = c(FALSE, FALSE,
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE),
Keypoint_flag = c(FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
FALSE, FALSE, FALSE, FALSE), Withheld_flag = c(FALSE, FALSE,
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE),
ScanAngleRank = c(17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L,
17L, 17L), UserData = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,
0L), PointSourceID = c(4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L,
4L), Pulse.width = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,
0L)), class = "data.frame", row.names = c(NA, -10L))
然后在我们读取所有 .las 文件之后,我们将它组合到一个数据集中,并指示这些行属于第一个 las 文件,而这些行属于第二个,类似这样
X Y Z gpstime Intensity ReturnNumber number las
638238.76 6078001.09 186.64 319805734.664265 13 2 1
638238.76 6078001.09 186.59 319805734.664265 99 1 1
638239.29 6078001.15 199.28 319805734.67875 5 1 1
638235.39 6078001.15 189.37 319805734.678768 2 2 1
638233.86 6078001.07 186.67 319805734.678777 20 1 1
638233.86 6078001.07 186.67 319805734.678777 189 1 1
638235.55 6078001.02 198.04 319805734.687338 2 2 1
638231.97 6078001.08 200.03 319805734.701928 11 1 1
638231.91 6078001.09 199.73 319805734.701928 90 1 1
638228.41 6078001.01 192.14 319805734.701945 1 3 1
628800.68 6082001.07 163.16 319799021.884921 12 1 2
628800.75 6082001.08 162.96 319799021.884921 99 1 2
628801.43 6082001.19 163.09 319799021.884929 14 1 2
628801.47 6082001.2 162.97 319799021.884929 112 1 2
628802.13 6082001.3 163.12 319799021.884938 14 1 2
628802.19 6082001.31 162.98 319799021.884938 121 1 2
628800.19 6082001.21 163.29 319799021.889375 17 1 2
628800.24 6082001.22 163.16 319799021.889375 167 1 2
628799.57 6082001.12 163.02 319799021.889384 20 1 2
628799.58 6082001.12 162.99 319799021.889384 189 1 2
那么我如何从文件夹 C:/1 中读取所有 .las 文件,然后为所有这些文件获取我上面提供的结构格式,并将其组合成 1 个具有 las 文件编号的数据集。
感谢您的宝贵帮助。
*编辑
现在下一个错误 list_df <- 文件名 %>%
purrr::map(., ~readLAS(.x) %>% mutate(filenumber = match(.x, filenames)))
UseMethod("mutate") 错误:
'mutate' 没有合适的方法应用于 las 的对象
我认为这是因为 las 格式具有这样的结构
las
class : LAS (v1.2 format 1)
memory : 308.7 Mb
extent : 637999, 638240.5, 6077999, 6079999 (xmin, xmax, ymin, ymax)
coord. ref. : NA
area : 409328 units²
points : 3.68 million points
density : 8.99 points/units²
但是来自 las 的数据帧必须使用我指出的有效载荷功能。
但 list_df <- 文件名 %>%
- purrr::map(., ~readLAS(.x) %>%
payload
(filenumber = match(.x, filenames)))
提供错误。
可能是这样的
filenames <- list.files(path <- "C:/1/", pattern="*.las", full.names=TRUE)
list_df <- filenames %>%
purrr::map(., ~read.LAS(.x) %>% payload() %>% mutate(filenumber = match(.x, filenames)))
# If all data has the same structure, you can easily bind them together, i.e.
list_df %>% bind_rows()
无需循环。 rlas
已经原生支持读取多个文件
rlas::read.las(filenames)
我有一个文件夹,里面有很多激光雷达(.las)文件。看起来像
library(rgdal)
library(raster)
library(tmaptools)
library(tmap)
library(lidR)
library(RStoolbox)
las=readLAS("C:/1/078-638.las")
las1=readLAS("C:/1/082-628.las")
las2=....
所以如果超过100个文件,每一行都很难写。有没有办法一次读取所有这些文件,但格式为 data.frame? .las 文件有这样的结构
las=payload(las)
las=structure(list(X = c(638238.76, 638238.76, 638239.29, 638235.39,
638233.86, 638233.86, 638235.55, 638231.97, 638231.91, 638228.41
), Y = c(6078001.09, 6078001.09, 6078001.15, 6078001.15, 6078001.07,
6078001.07, 6078001.02, 6078001.08, 6078001.09, 6078001.01),
Z = c(186.64, 186.59, 199.28, 189.37, 186.67, 186.67, 198.04,
200.03, 199.73, 192.14), gpstime = c(319805734.664265, 319805734.664265,
319805734.67875, 319805734.678768, 319805734.678777, 319805734.678777,
319805734.687338, 319805734.701928, 319805734.701928, 319805734.701945
), Intensity = c(13L, 99L, 5L, 2L, 20L, 189L, 2L, 11L, 90L,
1L), ReturnNumber = c(2L, 1L, 1L, 2L, 1L, 1L, 2L, 1L, 1L,
3L), NumberOfReturns = c(2L, 1L, 3L, 2L, 1L, 1L, 3L, 1L,
1L, 4L), ScanDirectionFlag = c(1L, 1L, 0L, 0L, 0L, 0L, 1L,
0L, 0L, 0L), EdgeOfFlightline = c(0L, 0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L), Classification = c(1L, 2L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L), Synthetic_flag = c(FALSE, FALSE, FALSE,
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE), Keypoint_flag = c(FALSE,
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
), Withheld_flag = c(FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
FALSE, FALSE, FALSE, FALSE), ScanAngleRank = c(-12L, -12L,
-12L, -12L, -12L, -12L, -12L, -13L, -13L, -13L), UserData = c(0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), PointSourceID = c(16L,
16L, 16L, 16L, 16L, 16L, 16L, 16L, 16L, 16L), Pulse.width = c(0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L)), class = "data.frame", row.names = c(NA,
-10L))
las1 的结构
las1=structure(list(X = c(628800.68, 628800.75, 628801.43, 628801.47,
628802.13, 628802.19, 628800.19, 628800.24, 628799.57, 628799.58
), Y = c(6082001.07, 6082001.08, 6082001.19, 6082001.2, 6082001.3,
6082001.31, 6082001.21, 6082001.22, 6082001.12, 6082001.12),
Z = c(163.16, 162.96, 163.09, 162.97, 163.12, 162.98, 163.29,
163.16, 163.02, 162.99), gpstime = c(319799021.884921, 319799021.884921,
319799021.884929, 319799021.884929, 319799021.884938, 319799021.884938,
319799021.889375, 319799021.889375, 319799021.889384, 319799021.889384
), Intensity = c(12L, 99L, 14L, 112L, 14L, 121L, 17L, 167L,
20L, 189L), ReturnNumber = c(1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L), NumberOfReturns = c(1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L), ScanDirectionFlag = c(1L, 1L, 1L, 1L, 1L,
1L, 0L, 0L, 0L, 0L), EdgeOfFlightline = c(0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L, 0L, 0L), Classification = c(1L, 2L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 2L), Synthetic_flag = c(FALSE, FALSE,
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE),
Keypoint_flag = c(FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
FALSE, FALSE, FALSE, FALSE), Withheld_flag = c(FALSE, FALSE,
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE),
ScanAngleRank = c(17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L,
17L, 17L), UserData = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,
0L), PointSourceID = c(4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L,
4L), Pulse.width = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,
0L)), class = "data.frame", row.names = c(NA, -10L))
然后在我们读取所有 .las 文件之后,我们将它组合到一个数据集中,并指示这些行属于第一个 las 文件,而这些行属于第二个,类似这样
X Y Z gpstime Intensity ReturnNumber number las
638238.76 6078001.09 186.64 319805734.664265 13 2 1
638238.76 6078001.09 186.59 319805734.664265 99 1 1
638239.29 6078001.15 199.28 319805734.67875 5 1 1
638235.39 6078001.15 189.37 319805734.678768 2 2 1
638233.86 6078001.07 186.67 319805734.678777 20 1 1
638233.86 6078001.07 186.67 319805734.678777 189 1 1
638235.55 6078001.02 198.04 319805734.687338 2 2 1
638231.97 6078001.08 200.03 319805734.701928 11 1 1
638231.91 6078001.09 199.73 319805734.701928 90 1 1
638228.41 6078001.01 192.14 319805734.701945 1 3 1
628800.68 6082001.07 163.16 319799021.884921 12 1 2
628800.75 6082001.08 162.96 319799021.884921 99 1 2
628801.43 6082001.19 163.09 319799021.884929 14 1 2
628801.47 6082001.2 162.97 319799021.884929 112 1 2
628802.13 6082001.3 163.12 319799021.884938 14 1 2
628802.19 6082001.31 162.98 319799021.884938 121 1 2
628800.19 6082001.21 163.29 319799021.889375 17 1 2
628800.24 6082001.22 163.16 319799021.889375 167 1 2
628799.57 6082001.12 163.02 319799021.889384 20 1 2
628799.58 6082001.12 162.99 319799021.889384 189 1 2
那么我如何从文件夹 C:/1 中读取所有 .las 文件,然后为所有这些文件获取我上面提供的结构格式,并将其组合成 1 个具有 las 文件编号的数据集。 感谢您的宝贵帮助。
*编辑 现在下一个错误 list_df <- 文件名 %>%
purrr::map(., ~readLAS(.x) %>% mutate(filenumber = match(.x, filenames))) UseMethod("mutate") 错误: 'mutate' 没有合适的方法应用于 las 的对象 我认为这是因为 las 格式具有这样的结构
las class : LAS (v1.2 format 1) memory : 308.7 Mb extent : 637999, 638240.5, 6077999, 6079999 (xmin, xmax, ymin, ymax) coord. ref. : NA area : 409328 units² points : 3.68 million points density : 8.99 points/units²
但是来自 las 的数据帧必须使用我指出的有效载荷功能。
但 list_df <- 文件名 %>%
- purrr::map(., ~readLAS(.x) %>%
payload
(filenumber = match(.x, filenames))) 提供错误。
可能是这样的
filenames <- list.files(path <- "C:/1/", pattern="*.las", full.names=TRUE)
list_df <- filenames %>%
purrr::map(., ~read.LAS(.x) %>% payload() %>% mutate(filenumber = match(.x, filenames)))
# If all data has the same structure, you can easily bind them together, i.e.
list_df %>% bind_rows()
无需循环。 rlas
已经原生支持读取多个文件
rlas::read.las(filenames)