Skip to content

Commit 676f19f

Browse files
authored
Safety and read improvements (#43)
* LasIO compat. * Check on iteration. * Much faster reading. * Relax types.
1 parent 80eb5d4 commit 676f19f

File tree

11 files changed

+156
-83
lines changed

11 files changed

+156
-83
lines changed

Project.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ LASzip_jll = "8372b9c3-1e34-5cc3-bfab-1a98e101de11"
1414
LasIO = "570499db-eae3-5eb6-bdd5-a5326f375e68"
1515
Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
1616
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
17+
Setfield = "efcf1570-3423-57d1-acb7-fd33fddbac46"
1718
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
1819
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
1920
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
@@ -36,6 +37,7 @@ GeoInterface = "1"
3637
LasIO = "0.3"
3738
Makie = "0.20, 0.21, 0.22"
3839
RecipesBase = "1.3.4"
40+
Setfield = "1.1.1"
3941
StaticArrays = "1"
4042
Tables = "1.0"
4143
julia = "1.10"

src/LazIO.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ using Libdl
1212
using LinearAlgebra
1313
using StaticArrays
1414
using UUIDs
15+
using Setfield
1516

1617
# Module initialization function
1718
function __init__()

src/dataset.jl

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ struct Dataset{Version}
33
filehandle::Ptr{Cvoid}
44
header::LazHeader # this enables iterating without unsafe_load everytime
55
point::Ptr{RawPoint}
6+
am::CoordinateTransformations.AffineMap{LinearAlgebra.Diagonal{Float64,StaticArraysCore.SVector{3,Float64}},StaticArraysCore.SVector{3,Float64}}
67
end
78

89
function Base.show(io::IO, ds::Dataset{Version}) where {Version}
@@ -36,20 +37,23 @@ function open(f::AbstractString)
3637
point_ptr = Ref{Ptr{RawPoint}}()
3738
@check laszip_reader[] laszip_get_point_pointer(laszip_reader[], point_ptr)
3839

40+
# Get coordinate transformation
41+
am = CoordinateTransformations.AffineMap(Diagonal(SA_F64[header.x_scale_factor 0 0; 0 header.y_scale_factor 0; 0 0 header.z_scale_factor]), SA_F64[header.x_offset, header.y_offset, header.z_offset])
42+
3943
header.point_data_format > 3 && @warn "The LAS 1.4+ format is not fully supported yet."
40-
Dataset{header.point_data_format}(f, laszip_reader[], header, point_ptr[])
44+
Dataset{header.point_data_format}(f, laszip_reader[], header, point_ptr[], am)
4145
end
4246

4347
function CoordinateTransformations.AffineMap(ds::Dataset)
44-
CoordinateTransformations.AffineMap(Diagonal(SA_F64[ds.header.x_scale_factor 0 0; 0 ds.header.y_scale_factor 0; 0 0 ds.header.z_scale_factor]), SA_F64[ds.header.x_offset, ds.header.y_offset, ds.header.z_offset])
48+
ds.am
4549
end
4650

4751
"""Iteration of LAZ file."""
4852
function Base.iterate(ds::Dataset, state::Int)
4953
if state >= length(ds)
5054
return nothing
5155
else
52-
laszip_read_point(ds.filehandle)
56+
@check ds.filehandle laszip_read_point(ds.filehandle)
5357
return eltype(ds)(unsafe_load(ds.point), CoordinateTransformations.AffineMap(ds)), state + 1
5458
end
5559
end
@@ -59,25 +63,26 @@ function Base.iterate(ds::Dataset)
5963
if length(ds) == 0
6064
nothing
6165
else
62-
laszip_seek_point(ds.filehandle, 0)
63-
laszip_read_point(ds.filehandle)
66+
@check ds.filehandle laszip_seek_point(ds.filehandle, 0)
67+
@check ds.filehandle laszip_read_point(ds.filehandle)
6468
eltype(ds)(unsafe_load(ds.point), CoordinateTransformations.AffineMap(ds)), 1
6569
end
6670
end
6771

6872
function Base.getindex(ds::Dataset, i::Integer)
6973
(1 <= i <= length(ds)) || throw(BoundsError(ds, i))
70-
laszip_seek_point(ds.filehandle, i - 1)
71-
laszip_read_point(ds.filehandle)
74+
@check ds.filehandle laszip_seek_point(ds.filehandle, i - 1)
75+
@check ds.filehandle laszip_read_point(ds.filehandle)
7276
eltype(ds)(unsafe_load(ds.point), CoordinateTransformations.AffineMap(ds))
7377
end
7478

7579
function Base.getindex(ds::Dataset, i::UnitRange{<:Integer})
7680
out = Vector{eltype(ds)}(undef, length(i))
81+
isempty(i) && return out
7782
(1 <= i[begin] <= length(ds)) && (1 <= i[end] <= length(ds)) || throw(BoundsError(ds, i))
78-
laszip_seek_point(ds.filehandle, i[begin] - 1)
83+
@check ds.filehandle laszip_seek_point(ds.filehandle, i[begin] - 1)
7984
for I in eachindex(out)
80-
laszip_read_point(ds.filehandle)
85+
@check ds.filehandle laszip_read_point(ds.filehandle)
8186
out[I] = eltype(ds)(unsafe_load(ds.point), CoordinateTransformations.AffineMap(ds))
8287
end
8388
out
@@ -87,8 +92,8 @@ function Base.getindex(ds::Dataset, i::StepRange{<:Integer,<:Integer})
8792
out = Vector{eltype(ds)}(undef, length(i))
8893
(1 <= i[begin] <= length(ds)) && (1 <= i[end] <= length(ds)) || throw(BoundsError(ds, i))
8994
for I in eachindex(out)
90-
laszip_seek_point(ds.filehandle, i[I] - 1)
91-
laszip_read_point(ds.filehandle)
95+
@check ds.filehandle laszip_seek_point(ds.filehandle, i[I] - 1)
96+
@check ds.filehandle laszip_read_point(ds.filehandle)
9297
out[I] = eltype(ds)(unsafe_load(ds.point), CoordinateTransformations.AffineMap(ds))
9398
end
9499
out

src/laszip.jl

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -296,159 +296,159 @@ function laszip_create(pointer::Ref{Ptr{Cvoid}})
296296
ccall((:laszip_create, laszip), Int32, (Ptr{Ptr{Cvoid}},), pointer)
297297
end
298298

299-
function laszip_get_error(pointer::Ptr{Cvoid}, error)
299+
function laszip_get_error(pointer, error)
300300
ccall((:laszip_get_error, laszip), Int32, (Ptr{Cvoid}, Ptr{Cstring}), pointer, error)
301301
end
302302

303-
function laszip_get_warning(pointer::Ptr{Cvoid}, warning)
303+
function laszip_get_warning(pointer, warning)
304304
ccall((:laszip_get_warning, laszip), Int32, (Ptr{Cvoid}, Ptr{Cstring}), pointer, warning)
305305
end
306306

307-
function laszip_clean(pointer::Ptr{Cvoid})
307+
function laszip_clean(pointer)
308308
ccall((:laszip_clean, laszip), Int32, (Ptr{Cvoid},), pointer)
309309
end
310310

311-
function laszip_destroy(pointer::Ptr{Cvoid})
311+
function laszip_destroy(pointer)
312312
ccall((:laszip_destroy, laszip), Int32, (Ptr{Cvoid},), pointer)
313313
end
314314

315-
function laszip_get_header_pointer(pointer::Ptr{Cvoid}, header_pointer)
316-
ccall((:laszip_get_header_pointer, laszip), Int32, (Ptr{Cvoid}, Ref{Ptr{LazHeader}}), pointer, header_pointer)
315+
function laszip_get_header_pointer(pointer, header_pointer)
316+
ccall((:laszip_get_header_pointer, laszip), Int32, (Ptr{Cvoid}, Ptr{Ptr{LazHeader}}), pointer, header_pointer)
317317
end
318318

319-
function laszip_get_point_pointer(pointer::Ptr{Cvoid}, point_pointer)
320-
ccall((:laszip_get_point_pointer, laszip), Int32, (Ptr{Cvoid}, Ref{Ptr{RawPoint}}), pointer, point_pointer)
319+
function laszip_get_point_pointer(pointer, point_pointer)
320+
ccall((:laszip_get_point_pointer, laszip), Int32, (Ptr{Cvoid}, Ptr{Ptr{RawPoint}}), pointer, point_pointer)
321321
end
322322

323-
function laszip_get_point_count(pointer::Ptr{Cvoid}, count)
323+
function laszip_get_point_count(pointer, count)
324324
ccall((:laszip_get_point_count, laszip), Int32, (Ptr{Cvoid}, Ptr{Int64}), pointer, count)
325325
end
326326

327-
function laszip_set_header(pointer::Ptr{Cvoid}, header)
327+
function laszip_set_header(pointer, header)
328328
ccall((:laszip_set_header, laszip), Int32, (Ptr{Cvoid}, Ptr{LazHeader}), pointer, header)
329329
end
330330

331-
# function laszip_set_point_type_and_size(pointer::Ptr{Cvoid}, point_type::UInt8, point_size::UInt16)
331+
# function laszip_set_point_type_and_size(pointer, point_type::UInt8, point_size::UInt16)
332332
# ccall((:laszip_set_point_type_and_size, laszip), Int32, (Ptr{Cvoid}, UInt8, UInt16), pointer, point_type, point_size)
333333
# end
334334

335-
# function laszip_check_for_integer_overflow(pointer::Ptr{Cvoid})
335+
# function laszip_check_for_integer_overflow(pointer)
336336
# ccall((:laszip_check_for_integer_overflow, laszip), Int32, (Ptr{Cvoid},), pointer)
337337
# end
338338

339-
# function laszip_auto_offset(pointer::Ptr{Cvoid})
339+
# function laszip_auto_offset(pointer)
340340
# ccall((:laszip_auto_offset, laszip), Int32, (Ptr{Cvoid},), pointer)
341341
# end
342342

343-
function laszip_set_point(pointer::Ptr{Cvoid}, point)
344-
ccall((:laszip_set_point, laszip), Int32, (Ptr{Cvoid}, Ptr{RawPoint}), pointer, point)
343+
function laszip_set_point(pointer, point::Ref{T}) where T
344+
ccall((:laszip_set_point, laszip), Int32, (Ptr{Cvoid}, Ptr{T}), pointer, point)
345345
end
346346

347-
# function laszip_set_coordinates(pointer::Ptr{Cvoid}, coordinates)
347+
# function laszip_set_coordinates(pointer, coordinates)
348348
# ccall((:laszip_set_coordinates, laszip), Int32, (Ptr{Cvoid}, Ptr{Float64}), pointer, coordinates)
349349
# end
350350

351-
# function laszip_get_coordinates(pointer::Ptr{Cvoid}, coordinates)
351+
# function laszip_get_coordinates(pointer, coordinates)
352352
# ccall((:laszip_get_coordinates, laszip), Int32, (Ptr{Cvoid}, Ptr{Float64}), pointer, coordinates)
353353
# end
354354

355-
# function laszip_set_geokeys(pointer::Ptr{Cvoid}, number::UInt32, key_entries)
355+
# function laszip_set_geokeys(pointer, number::UInt32, key_entries)
356356
# ccall((:laszip_set_geokeys, laszip), Int32, (Ptr{Cvoid}, UInt32, Ptr{Cvoid}), pointer, number, key_entries)
357357
# end
358358

359-
# function laszip_set_geodouble_params(pointer::Ptr{Cvoid}, number::UInt32, geodouble_params)
359+
# function laszip_set_geodouble_params(pointer, number::UInt32, geodouble_params)
360360
# ccall((:laszip_set_geodouble_params, laszip), Int32, (Ptr{Cvoid}, UInt32, Ptr{Float64}), pointer, number, geodouble_params)
361361
# end
362362

363-
# function laszip_set_geoascii_params(pointer::Ptr{Cvoid}, number::UInt32, geoascii_params)
363+
# function laszip_set_geoascii_params(pointer, number::UInt32, geoascii_params)
364364
# ccall((:laszip_set_geoascii_params, laszip), Int32, (Ptr{Cvoid}, UInt32, Ptr{UInt8}), pointer, number, geoascii_params)
365365
# end
366366

367-
# function laszip_add_attribute(pointer::Ptr{Cvoid}, _type::UInt32, name, description, scale::Float64, offset::Float64)
367+
# function laszip_add_attribute(pointer, _type::UInt32, name, description, scale::Float64, offset::Float64)
368368
# ccall((:laszip_add_attribute, laszip), Int32, (Ptr{Cvoid}, UInt32, Ptr{UInt8}, Ptr{UInt8}, Float64, Float64), pointer, _type, name, description, scale, offset)
369369
# end
370370

371-
# function laszip_add_vlr(pointer::Ptr{Cvoid}, user_id, record_id::UInt16, record_length_after_header::UInt16, description, data)
371+
# function laszip_add_vlr(pointer, user_id, record_id::UInt16, record_length_after_header::UInt16, description, data)
372372
# ccall((:laszip_add_vlr, laszip), Int32, (Ptr{Cvoid}, Ptr{UInt8}, UInt16, UInt16, Ptr{UInt8}, Ptr{UInt8}), pointer, user_id, record_id, record_length_after_header, description, data)
373373
# end
374374

375-
# function laszip_remove_vlr(pointer::Ptr{Cvoid}, user_id, record_id::UInt16)
375+
# function laszip_remove_vlr(pointer, user_id, record_id::UInt16)
376376
# ccall((:laszip_remove_vlr, laszip), Int32, (Ptr{Cvoid}, Ptr{UInt8}, UInt16), pointer, user_id, record_id)
377377
# end
378378

379-
# function laszip_create_spatial_index(pointer::Ptr{Cvoid}, create::Cint, append::Cint)
379+
# function laszip_create_spatial_index(pointer, create::Cint, append::Cint)
380380
# ccall((:laszip_create_spatial_index, laszip), Int32, (Ptr{Cvoid}, Cint, Cint), pointer, create, append)
381381
# end
382382

383-
# function laszip_preserve_generating_software(pointer::Ptr{Cvoid}, preserve::Cint)
383+
# function laszip_preserve_generating_software(pointer, preserve::Cint)
384384
# ccall((:laszip_preserve_generating_software, laszip), Int32, (Ptr{Cvoid}, Cint), pointer, preserve)
385385
# end
386386

387-
# function laszip_request_native_extension(pointer::Ptr{Cvoid}, request::Cint)
387+
# function laszip_request_native_extension(pointer, request::Cint)
388388
# ccall((:laszip_request_native_extension, laszip), Int32, (Ptr{Cvoid}, Cint), pointer, request)
389389
# end
390390

391-
# function laszip_request_compatibility_mode(pointer::Ptr{Cvoid}, request::Cint)
391+
# function laszip_request_compatibility_mode(pointer, request::Cint)
392392
# ccall((:laszip_request_compatibility_mode, laszip), Int32, (Ptr{Cvoid}, Cint), pointer, request)
393393
# end
394394

395-
# function laszip_set_chunk_size(pointer::Ptr{Cvoid}, chunk_size::UInt32)
395+
# function laszip_set_chunk_size(pointer, chunk_size::UInt32)
396396
# ccall((:laszip_set_chunk_size, laszip), Int32, (Ptr{Cvoid}, UInt32), pointer, chunk_size)
397397
# end
398398

399-
function laszip_open_writer(pointer::Ptr{Cvoid}, file_name, compress::Cint)
399+
function laszip_open_writer(pointer, file_name, compress::Cint)
400400
ccall((:laszip_open_writer, laszip), Int32, (Ptr{Cvoid}, Ptr{UInt8}, Cint), pointer, file_name, compress)
401401
end
402402

403-
function laszip_write_point(pointer::Ptr{Cvoid})
403+
function laszip_write_point(pointer)
404404
ccall((:laszip_write_point, laszip), Int32, (Ptr{Cvoid},), pointer)
405405
end
406406

407-
# function laszip_write_indexed_point(pointer::Ptr{Cvoid})
407+
# function laszip_write_indexed_point(pointer)
408408
# ccall((:laszip_write_indexed_point, laszip), Int32, (Ptr{Cvoid},), pointer)
409409
# end
410410

411-
function laszip_update_inventory(pointer::Ptr{Cvoid})
411+
function laszip_update_inventory(pointer)
412412
ccall((:laszip_update_inventory, laszip), Int32, (Ptr{Cvoid},), pointer)
413413
end
414414

415-
function laszip_close_writer(pointer::Ptr{Cvoid})
415+
function laszip_close_writer(pointer)
416416
ccall((:laszip_close_writer, laszip), Int32, (Ptr{Cvoid},), pointer)
417417
end
418418

419-
# function laszip_exploit_spatial_index(pointer::Ptr{Cvoid}, exploit::Cint)
419+
# function laszip_exploit_spatial_index(pointer, exploit::Cint)
420420
# ccall((:laszip_exploit_spatial_index, laszip), Int32, (Ptr{Cvoid}, Cint), pointer, exploit)
421421
# end
422422

423-
# function laszip_decompress_selective(pointer::Ptr{Cvoid}, decompress_selective::UInt32)
423+
# function laszip_decompress_selective(pointer, decompress_selective::UInt32)
424424
# ccall((:laszip_decompress_selective, laszip), Int32, (Ptr{Cvoid}, UInt32), pointer, decompress_selective)
425425
# end
426426

427-
function laszip_open_reader(pointer::Ptr{Cvoid}, file_name, is_compressed)
427+
function laszip_open_reader(pointer, file_name, is_compressed)
428428
ccall((:laszip_open_reader, laszip), Int32, (Ptr{Cvoid}, Ptr{UInt8}, Ptr{Cint}), pointer, file_name, is_compressed)
429429
end
430430

431-
# function laszip_has_spatial_index(pointer::Ptr{Cvoid}, is_indexed, is_appended)
431+
# function laszip_has_spatial_index(pointer, is_indexed, is_appended)
432432
# ccall((:laszip_has_spatial_index, laszip), Int32, (Ptr{Cvoid}, Ptr{Cint}, Ptr{Cint}), pointer, is_indexed, is_appended)
433433
# end
434434

435-
# function laszip_inside_rectangle(pointer::Ptr{Cvoid}, min_x::Float64, min_y::Float64, max_x::Float64, max_y::Float64, is_empty)
435+
# function laszip_inside_rectangle(pointer, min_x::Float64, min_y::Float64, max_x::Float64, max_y::Float64, is_empty)
436436
# ccall((:laszip_inside_rectangle, laszip), Int32, (Ptr{Cvoid}, Float64, Float64, Float64, Float64, Ptr{Cint}), pointer, min_x, min_y, max_x, max_y, is_empty)
437437
# end
438438

439-
function laszip_seek_point(pointer::Ptr{Cvoid}, index::Int64)
439+
function laszip_seek_point(pointer, index::Int64)
440440
ccall((:laszip_seek_point, laszip), Int32, (Ptr{Cvoid}, Int64), pointer, index)
441441
end
442-
laszip_seek_point(pointer::Ptr{Cvoid}, index::Int32) = laszip_seek_point(pointer, convert(Int64, index))
442+
laszip_seek_point(pointer, index::Int32) = laszip_seek_point(pointer, convert(Int64, index))
443443

444-
function laszip_read_point(pointer::Ptr{Cvoid})
444+
function laszip_read_point(pointer)
445445
ccall((:laszip_read_point, laszip), Int32, (Ptr{Cvoid},), pointer)
446446
end
447447

448-
# function laszip_read_inside_point(pointer::Ptr{Cvoid}, is_done)
448+
# function laszip_read_inside_point(pointer, is_done)
449449
# ccall((:laszip_read_inside_point, laszip), Int32, (Ptr{Cvoid}, Ptr{Cint}), pointer, is_done)
450450
# end
451451

452-
function laszip_close_reader(pointer::Ptr{Cvoid})
452+
function laszip_close_reader(pointer)
453453
ccall((:laszip_close_reader, laszip), Int32, (Ptr{Cvoid},), pointer)
454454
end

0 commit comments

Comments
 (0)