As @HowardButler says, you can also use PDAL for this. The documentation is a little hard to find, but you can do it without any need to call subprocess.
First, we need to load the file as a PDAL pipeline:
import pdal
from shapely.geometry import shape, box
from shapely.ops import transform
from pyproj import Transformer
import fiona
filename = "/path/to/las"
pipeline = pdal.Reader.las(filename=data, count=1).pipeline()
pipeline.execute()
count=1 here makes PDAL load only a single datapoint for speed. I would assume it's possible that some LAS files don't contain this metadata in the header and you need to iterate over all points to find the min/max. For my test dataset it doesn't make a difference, but to be safe, omit count.
Then you can access the metadata property to load the info needed (all returned as dictionaries). I'd recommend exploring the dictionary keys here to figure out what info you need, but for example:
# Get the metadata
meta = pipeline.metadata['metadata']
Bounds
minx = meta['readers.las']['minx']
miny = meta['readers.las']['miny']
maxx = meta['readers.las']['maxx']
maxy = meta['readers.las']['maxy']
las_bbox = box(minx, miny, maxx, maxy)
import pyproj
las_crs = pyproj.crs.CRS(meta['readers.las']['srs']['proj4'])
From here you can do whatever you need - for example, load an arbitrary shapefile and check if any feature intersects the LAS file:
shapefile_path = "/path/to/shapefile"
with fiona.open(shapefile_path, "r") as shapefile:
project = Transformer.from_crs(shapefile.crs, las_crs, always_xy=True).transform
for i, feature in enumerate(shapefile):
geometry = feature["geometry"]
feature_bounds = transform(project, shape(geometry))
print(feature_bounds.within(las_bbox))
liblas. – Kadir Şahbaz May 22 '20 at 21:20