Hot answers tagged

8

libLAS was developed to provide read/write support for LAS and it was modeled on LAStools which at the time was not released under an open source license. In the subsequent years, many parts of LAStools were released under an open source license which negated the need for a parallel effort in libLAS. The library portion of this is called LASlib. Yes, I agree ...


8

The answer by Howard Butler pretty much sums it up. Some more background. When I created the first LAStools and the LASlib library that the tools are build upon I was a postdoc at UC Berkeley and merely needed to prepare LAS files as input for my research on Streaming Delaunay (or Streaming TIN) processing. Because the code seemed useful on its own I zipped ...


7

Use r.sun as suggested in Command r.sunmask in GRASS. As the input to r.sun build a DSM raster from data (i.e., the trees must be part of the elevation raster, if they are not already). GRASS 7.4 r.sun dsm day=355 time=9 incidout=shadowed_dsm Pixels with NULL are shadowed. GRASS 6.4 r.sun -s dsm day=355 time=9 incidout=shadowed_dsm Pixels with zero ...


4

The header needs to be set with a point format that supports RGB colors, see: https://pythonhosted.org/laspy/tut_background.html. For LAS 1.2, the minimum point format for color is 2: header = laspy.header.Header(point_format=2) # LAS point format 2 supports color with laspy.file.File(output_path, mode="w", header=header) as lasfile: lasfile.header....


4

This brings up an interesting theoretical question regarding slope process in relation to scale. The TWI/CTI is a slope/flow accumulation interaction. However, once must question the exact process that is being represented when deriving slope at very fine grains (eg., <1m) and how it affects this interaction. I would imagine that, without increasing the ...


4

Instead of organizing data where each plot is in a different column, do it as a dataframe with all Z values in one column and an additional index column with the plot ID. For example: plot_id Z 1 10.3 1 11.4 2 12.8 2 7.6 3 24.5 ... ... One will probably have trouble loading all data in R memory, and some options to ...


4

Short answer: No. And more specifically lidR is designed for ALS primarily, if ever I add a function for noise removal it will be for ALS first.


4

Found the answer in the grid_terrain help section "supported processing options": output_files: Return the output in R or write each cluster’s output in a file. Supported templates are ... , ORIGINALFILENAME. This is the solution: opt_output_files(cat) <- paste0(output,"/{ORIGINALFILENAME}")


4

For simplicity (because it was not mentioned in question) I am assuming the XYZ files are ready to be processed (i.e., no classification or filtering is needed) and that the content is suitable for whatever type of raster OP wants (DEM, DSM, etc.). If one really wants/needs to work with ASCII files, one option to grid them is GDAL gdal_grid: Creates ...


3

LiDAR times often come in GPS time or time since the GPS epoch. Here is a stack exchange link with more detail (What is a GPS epoch?) This look like GPS seconds. Your data should also include a column of data that shows the GPS week You can use the week and seconds data to convert the pulse time to human-readable time using a website like GPS Time ...


3

You are trying to read the file "ABCD.las" from the package rLiDAR. The package rLiDAR does not have such file. You probably meant something like: readLAS("D:/Thing/Path/ABCD.las") Also you loaded both lidR and rLiDAR that both have a readLAS function that give two different outputs. You are likely to run into trouble using the two packages simultaneously. ...


3

A convenient way to get point cloud data to Python is to use the PDAL Python extension. PDAL uses the concept of pipelines (much like a GDAL VRT for point clouds instead of rasters) to allow users to orchestrate the processing of point cloud data. With the PDAL Python extension, you can read a LAZ file into a Numpy array and then do whatever you need to ...


3

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: f is defined within the frame of get_layer_counts breaks does not exists within the frame of the point cloud This version works:...


3

Be aware one needs to have the LAStools plugin installed, but also the software per se. The LAStools plugin description says: ... . You also need to download the LAStools software from http://rapidlasso.com/LAStools/ Once plugin and software are installed, make sure to set its path accordingly (as suggested in john's comment):


3

Laspy isn't going to give you convenient access to the SRS in a form you can easily consume. LAS files can have either WKT or GeoTIFF keys as the coordinate system description. For consumption in Esri tools (and elsewhere), you always want the WKT. The most convenient way to get the WKT from an LAS file is to use PDAL. The following script will read a ...


3

There is no streaming equivalent of ReturnNumber <= NumberOfReturns I can see some options: I'm pretty sure that the warnings comes from points that have a NumberOfReturns = 0. Thus I would try filter = "-drop_number_of_returns 0". Go to the github repo of the rlas package and open an issue with a feature request. This is not hard to add such filter. ...


3

This example is directly from the documentation @JRR provided. You can use writeOGR() from the rgdal package to write the convex hull polygons representing tree canopies to shapefile. library(lidR) library(rgdal) las = readLAS("/path/to/your/points.las") plot(las) # Classify ground points las = lasground(las, csf()) plot(las, color = "Classification") # ...


3

The lidR package relies on the rlas package to read and write las file. The rlas package has a recent support of LAS 1.4 files (v1.3.0 release date: 2019-02-03). Moreover the point record formats >6 are a bit different than former point formats. Your code is correct and you actually found a bug in function write.las from rlas that occurs with point format 6 (...


3

lasfilter will only directly take objects of class LAS (and not LAScatalog) as per the package documentation. One way to go is with catalog_apply: This function gives users access to the LAScatalog processing engine. It allows the application of a user-defined routine over an entire catalog. So, embed lasfilter within a user-defined function and pass it ...


3

In your case the filter you are using is a simple one: Classification != 2. And you don't need the ground points at all. You are better to use a streaming filter and a streamed processing. ctg <- catalog("/...2015TestGroup") opt_chunk_size(ctg) <- 0 opt_chunk_buffer(ctg) <- 0 opt_output_files(ctg) <- ".../Outputs/2015nonground/{XLEFT}_{YBOTTOM}...


3

You were almost there. You missed to compute the pulseID with laspulse() and you missed that the scan angle is stored in ScanAngleRank Since lidR 2.0.0 pulseID is no longer computed at read time. And since rlas 1.3.0 that introduced support of LAS 1.4 format the attribute ScanAngle is now ScanAngleRank. The name ScanAngle is reserved for angle stored in LAS ...


3

This question has been discussed here. For an unknown reason the payload of the file is offseted to 375 bytes instead of 235 for a LAS 1.3. las0@header@PHB$`Header Size` #> 375 In theory it could be written properly but in practice rlas generates a corrupted file. You must manually fix the header. las0@header@PHB$`Header Size` <- 235


3

It's perfectly valid (although not usual) for the LAS header to contain additional bytes. It seems Trimble always writes 375, no matter if it's LAS 1.2 (227 bytes), LAS 1.3 (235 bytes), or LAS 1.4 (375 bytes). One advantage of this is that the LAS file could be upgraded to LAS 1.4 in place (assuming the point type is kept). However, those additional 140 ...


3

There are several questions here: Why do you have NAs in the DTM? NAs in the DTM are usually not a big deal. lidR interpolates within the convex hull of the point cloud to ensure to have a DTM in accordance with the point cloud especially with circular plots for example. A raster being rectangular you can have NAs in pixels with no points Why do you have -3....


2

This is a working solution with laspy: import numpy as np import laspy from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt # reading las file and copy points input_las = laspy.file.File("test.las", mode="r") point_records = input_las.points.copy() # getting scaling and offset parameters las_scaleX = input_las.header.scale[0] ...


2

Found the reference below that some LiDAR instruments can record up to six returns depending on the discretization settings: Modern instruments can process the energy-backscatter pertaining to a single beam and identify up to six returns, but the majority support only up to four. A Guide to LIDAR Data Acquisition and Processing for the Forests of the ...


2

There is a maximum of 5 and it depends on the software. There can be 3–5 returns possible per laser pulse. Discrete return lidar can record multiple measurements within a single laser pulse. If the reflected signal strength exceeds a given threshold, then the sensor will record another measurement, up to the maximum number allowed by the sensor (...


2

https://github.com/hobu/laz-perf contains an alternative implementation of LASzip that can be compiled to WASM and JavaScript using Emscripten. It is used by Potree and PlasioJS to provide LAZ support in JavaScript.


2

Starting to play around with tools found here. Its been quite useful. https://github.com/brycefrank/pyfor


2

According to the LAS specification a las file contains a set of core attributes including X Y Z obviously but also the 'intensity' or the 'classification' and other data for each point. Among the core attributes one of them is the 'return number' that stores the position of the point in the return sequence (see also What are LiDAR returns?). A point with a ...


Only top voted, non community-wiki answers of a minimum length are eligible