Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First working version. #1

Merged
merged 17 commits into from
Feb 2, 2018
1 change: 1 addition & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
comment: false
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
*.jl.*.cov
*.jl.mem
deps/deps.jl
*.DS_Store
20 changes: 20 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Documentation: http://docs.travis-ci.com/user/languages/julia/
language: julia
os:
- linux
- osx
julia:
- 0.6
- nightly
matrix:
allow_failures:
- julia: nightly
notifications:
email: false
before_install:
- wget https://github.com/LASzip/LASzip/archive/3.1.1.tar.gz
- tar -xzf 3.1.1.tar.gz
- pushd LASzip-3.1.1 && mkdir build && cd build && cmake .. && make && sudo make install && popd
- if [ $TRAVIS_OS_NAME == osx ]]; then export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib ; fi
- if [ $TRAVIS_OS_NAME == osx ]]; then export DYLD_FALLBACK_LIBRARY_PATH=$DYLD_FALLBACK_LIBRARY_PATH:/usr/local/lib ; fi
- if [ $TRAVIS_OS_NAME = linux ]; then sudo ldconfig ; fi
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [0.1]
- Integrate LasZIP C API
- Export to LasIO
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,14 @@
[![Build Status](https://travis-ci.org/evetion/LazIO.jl.svg?branch=master)](https://travis-ci.org/evetion/LazIO.jl)

# LazIO
Extends LasIO with Laszip integration

Uses the laszip shared library to read compressed las files (*.laz) into the uncompressed format that LasIO reads natively.

At the moment this is read-only.

## TODO
- Write
- Selections and filters

*credits to joa-quim for another, older implementation of the laszip library in Julia*
4 changes: 4 additions & 0 deletions REQUIRE
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
julia 0.6
FileIO
Parameters
LasIO 0.0.1
58 changes: 58 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
environment:
matrix:
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe"
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"

## uncomment the following lines to allow failures on nightly julia
## (tests will run but not make your overall status red)
matrix:
allow_failures:
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"

branches:
only:
- master
- /release-.*/

notifications:
- provider: Email
on_build_success: false
on_build_failure: false
on_build_status_changed: false

install:
- ps: "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12"
# If there's a newer build queued for the same PR, cancel this one
- ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod `
https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | `
Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { `
throw "There are newer queued builds for this pull request, failing early." }
# Download most recent Julia Windows binary
- ps: (new-object net.webclient).DownloadFile(
$env:JULIA_URL,
"C:\projects\julia-binary.exe")
# Run installer silently, output to C:\projects\julia
- C:\projects\julia-binary.exe /S /D=C:\projects\julia

before_build:
- call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat"
- curl -fsS -o 3.1.1.tar.gz https://github.com/LASzip/LASzip/archive/3.1.1.tar.gz
- 7z x 3.1.1.tar.gz
- cd LASzip-3.1.1
- mkdir build
- cd build
- cmake -G "Visual Studio 15 2017 Win64" ..
- cmake --build .
- set PATH=%PATH%;%CD%

build_script:
# Need to convert from shallow to complete for Pkg.clone to work
- IF EXIST .git\shallow (git fetch --unshallow)
- C:\projects\julia\bin\julia -e "versioninfo();
Pkg.clone(pwd(), \"LazIO\"); Pkg.build(\"LazIO\")"

test_script:
- C:\projects\julia\bin\julia -e "Pkg.test(\"LazIO\")"
22 changes: 22 additions & 0 deletions src/LazIO.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
__precompile__()

module LazIO

using FileIO
using LasIO

include("laszip_h.jl")
include("laszip.jl")
include("fileio.jl")
include("convert.jl")


function __init__()
# temporary _ until LasIO defers this key
add_format(format"LAZ_", (), ".laz", [:LazIO])
laszip_load_dll()
atexit(laszip_unload_dll)
end


end # module
105 changes: 105 additions & 0 deletions src/convert.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Here be all conversions from Laszip C Types to LasIO types

import Base.convert

"Conversion to LasIO header"
convert(::Type{LasHeader}, h::laszip_header) =
LasHeader(
h.file_source_ID,
h.global_encoding,
h.project_ID_GUID_data_1,
h.project_ID_GUID_data_2,
h.project_ID_GUID_data_3,
join(convert(NTuple{8, Char}, h.project_ID_GUID_data_4)),
h.version_major,
h.version_minor,
join(convert(NTuple{32, Char}, h.system_identifier)),
join(convert(NTuple{32, Char}, h.generating_software)),
h.file_creation_day,
h.file_creation_year,
h.header_size,
h.offset_to_point_data,
h.number_of_variable_length_records,
h.point_data_format,
h.point_data_record_length,
h.number_of_point_records,
[n for n in h.number_of_points_by_return],
h.x_scale_factor,
h.y_scale_factor,
h.z_scale_factor,
h.x_offset,
h.y_offset,
h.z_offset,
h.max_x,
h.min_x,
h.max_y,
h.min_y,
h.max_z,
h.min_z,
Vector{LasVariableLengthRecord}(),
Vector{UInt8}()
)

"ASPRS LAS point data record format 0"
convert(::Type{LasPoint0}, p::laszip_point) =
LasPoint0(
p.X,
p.Y,
p.Z,
p.intensity,
p.return_number,
p.classification,
p.scan_angle_rank,
p.user_data,
p.point_source_ID
)

"ASPRS LAS point data record format 1"
convert(::Type{LasPoint1}, p::laszip_point) =
LasPoint1(
p.X,
p.Y,
p.Z,
p.intensity,
p.return_number,
p.classification,
p.scan_angle_rank,
p.user_data,
p.point_source_ID,
p.gps_time
)

"ASPRS LAS point data record format 2"
convert(::Type{LasPoint2}, p::laszip_point) =
LasPoint2(
p.X,
p.Y,
p.Z,
p.intensity,
p.return_number,
p.classification,
p.scan_angle_rank,
p.user_data,
p.point_source_ID,
p.rgb[1],
p.rgb[2],
p.rgb[3]
)

"ASPRS LAS point data record format 3"
convert(::Type{LasPoint3}, p::laszip_point) =
LasPoint3(
p.X,
p.Y,
p.Z,
p.intensity,
p.return_number,
p.classification,
p.scan_angle_rank,
p.user_data,
p.point_source_ID,
p.gps_time,
p.rgb[1],
p.rgb[2],
p.rgb[3]
)
98 changes: 98 additions & 0 deletions src/fileio.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# File load

function laszip_error(laszip_obj::Ptr{Void})
errstr = Ref{Ptr{laszip_CHAR}}()
laszip_get_error(laszip_obj, errstr)
error(unsafe_string(errstr[]))
end

macro check(obj, ex)
return :( $(esc(ex)) == 0 ? nothing : laszip_error($(esc(obj))) )
end

load(f::File{format"LAZ_"}) = load(f.filename)
load(f::File{format"LAZ_"}; range::Union{UnitRange{Integer},Integer, Colon, Array{Int64, 1}}=:) = load(f.filename, range=range)
loadheader(f::File{format"LAZ_"}) = loadheader(f.filename)

function loadheader(f::String)
# Setup laszip reader
laszip_reader = Ref{Ptr{Void}}()
@check laszip_reader[] laszip_create(laszip_reader)

# Open lasfile
is_compressed = Ref{Cint}(0)
@check laszip_reader[] laszip_open_reader(laszip_reader[], f, is_compressed)
is_compressed[] == 0 ? nothing : info("File $f is compressed")

# Get header
header_ptr = Ref{Ptr{laszip_header}}()
@check laszip_reader[] laszip_get_header_pointer(laszip_reader[], header_ptr)
header = LasHeader(unsafe_load(header_ptr[]))

# Close the reader
@check laszip_reader[] laszip_close_reader(laszip_reader[])

# Destroy the reader
@check laszip_reader[] laszip_destroy(laszip_reader[])

header
end

function load(f::String; range::Union{UnitRange{Integer},Integer, Colon, Array{Int64, 1}}=:)
version_major = Ref{laszip_U8}(0)
version_minor = Ref{laszip_U8}(0)
version_revision = Ref{laszip_U16}(0)
version_build = Ref{laszip_U32}(0)
pfo = pointer_from_objref
pto = unsafe_pointer_to_objref

laszip_get_version(version_major, version_minor, version_revision, version_build)
info("LASzip DLL $(version_major[]) $(version_minor[]) $(version_revision[]) (build $(version_build[]))")

# Setup laszip reader
laszip_reader = Ref{Ptr{Void}}()
@check laszip_reader[] laszip_create(laszip_reader)

# Open lasfile
is_compressed = Ref{Cint}(0)
@check laszip_reader[] laszip_open_reader(laszip_reader[], f, is_compressed)
is_compressed[] == 0 ? nothing : info("File $f is compressed")

# Get header
header_ptr = Ref{Ptr{laszip_header}}()
@check laszip_reader[] laszip_get_header_pointer(laszip_reader[], header_ptr)
header = LasHeader(unsafe_load(header_ptr[]))

# Get a pointer to the points that will be read
point_ptr = Ref{Ptr{laszip_point}}()
@check laszip_reader[] laszip_get_point_pointer(laszip_reader[], point_ptr)

n = header.records_count
r = collect(1:n)[range]
pointtype = LasIO.pointformat(header)
pointdata = Vector{pointtype}(length(r))

pointerindex = 0 # index for point pointer

info("Reading $(length(r)) point(s).")
for (i, ii) in enumerate(r)
# Requested point not at current pointer
if ii-1 != pointerindex
# Seek it and set pointer
info("Seeking to point $ii")
laszip_seek_point(laszip_reader[], ii-1)
pointerindex = ii
end
laszip_read_point(laszip_reader[])
pointerindex += 1
pointdata[i] = convert(pointtype, unsafe_load(point_ptr[]))
end

# Close the reader
@check laszip_reader[] laszip_close_reader(laszip_reader[])

# Destroy the reader
@check laszip_reader[] laszip_destroy(laszip_reader[])

header, pointdata
end
Loading