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

r.in.pdal: docker support added #16

Merged
merged 1 commit into from
Jul 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
35 changes: 35 additions & 0 deletions grass7/raster/r.in.pdal/r.in.pdal.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ <h2>NOTES</h2>

<h2>EXAMPLES</h2>

<h2>Import LAS file using PDAL</h2>

Import of a LAS file using PDAL into a mapset in the sample NC SPM
location. The sample LAS file is available
<a href="https://www.grassbook.org/wp-content/uploads/ncexternal/lidar_raleigh_nc_spm_height_feet.las">here</a>.
Expand All @@ -49,6 +51,10 @@ <h2>EXAMPLES</h2>

# scan extent (g.region style) and exit
r.in.pdal input=lidar_raleigh_nc_spm_height_feet.las output=lidar_raleigh -s -g
# n=228500 s=215000.01 w=633370.82 e=645000 t=558.87 b=88.5

# set computation region to this extent
g.region n=228500 s=215000.01 w=633370.82 e=645000 -p

# import while aligning pixel geometry to existing "elevation" 10m res. raster map
# specifying EPSG manually because SRS information is missing in this LAS file
Expand Down Expand Up @@ -83,6 +89,35 @@ <h2>EXAMPLES</h2>
<i>Figure: LiDAR cloud footprint</i>
</div>

<h2>Import LAZ file using PDAL docker</h2>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<h2>Import LAZ file using PDAL docker</h2>
<h2>Import of a LAZ file using PDAL in docker</h2>

Import of a LAZ file using PDAL docker into a mapset in the sample NC SPM
location. The sample LAZ file is available
<a href="https://github.com/PDAL/PDAL/raw/master/test/data/laz/simple.laz">here</a>.

<div class="code"><pre>
# pulling official PDAL docker image
docker pull pdal/pdal

# using PDAL docker as command with mounted data volume
# (caution: the LAZ file has to be stored in the mounted folder! (here: $(pwd)))
export pdal_docker="docker run --rm -v $(pwd):/data -t pdal/pdal pdal"

# scan extent and exit
r.in.pdal input=/data/simple.laz output=lidar -s pdal_cmd="$pdal_docker"

# scan extent (g.region style) and exit
r.in.pdal input=/data/simple.laz output=lidar -s -g pdal_cmd="$pdal_docker"
# n=853535.43 s=848899.7 w=635619.85 e=638982.55 t=586.38 b=406.59

# set computation region to this extent
g.region n=853535.43 s=848899.7 w=635619.85 e=638982.55 -p

# import data
r.in.pdal input=/data/simple.laz output=lidar_perc95 method=percentile pth=95 pdal_cmd="$pdal_docker"

r.univar lidar_perc95
</pre></div>


<h2>SEE ALSO</h2>

Expand Down
98 changes: 63 additions & 35 deletions grass7/raster/r.in.pdal/r.in.pdal.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,14 @@
#% required: no
#%end

#%option
#% key: pdal_cmd
#% type: string
#% description: Command for PDAL (e.g. if PDAL runs only in a docker)
#% required: no
#% answer: pdal
#%end

#%flag
#% key: s
#% description: Scan data file for extent then exit
Expand Down Expand Up @@ -158,22 +166,26 @@ def footprint_to_vectormap(infile, footprint):
infile(string): Name of LAS input file
footprint(string): Footprint of the data as vector map
"""
if not grass.find_program('pdal', 'info --boundary'):
if not grass.find_program(
options['pdal_cmd'].split(' ')[0], ' '.join(options['pdal_cmd'].split(' ')[1:])
+ ' info --boundary'
):
grass.fatal(_(
"The pdal executable is not available."
" Install PDAL or put the pdal executable on path."))
command_fp = ['pdal', 'info', '--boundary', infile]
"The pdal executable is not available."
" Install PDAL or put the pdal executable on path."))
command_fp = options['pdal_cmd'].split(' ')
command_fp.extend(['info', '--boundary', infile])
tmp_fp = grass.tempfile()
if tmp_fp is None:
grass.fatal("Unable to create temporary files")
fh = open(tmp_fp, 'wb')
p = grass.call(command_fp, stdout=fh)
fh.close()
if p != 0:
if grass.call(command_fp, stdout=fh) != 0:
fh.close()
# check to see if pdal info executed properly
os.remove(tmp_fp)
grass.fatal(_("pdal info broken..."))

else:
fh.close()
data = json.load(open(tmp_fp))
xy_in = ''
str1 = u'boundary'
Expand All @@ -186,10 +198,9 @@ def footprint_to_vectormap(infile, footprint):
except Exception:
coord_str = str(data[str1][str1])
coord = coord_str[coord_str.find('((') + 2:coord_str.find('))')]
x_y = coord.split(', ')
x_y = coord.split(',')
for xy in x_y:
xy_in += xy.replace(' ', ',') + '\n'

xy_in += xy.rstrip().replace(' ', ',') + '\n'
tmp_xy = grass.tempfile()
if tmp_xy is None:
grass.fatal("Unable to create temporary files")
Expand Down Expand Up @@ -285,31 +296,39 @@ def main():

# scan -s or shell_script_style -g:
if scan:
if not grass.find_program('pdal', 'info --summary'):
if not grass.find_program(
options['pdal_cmd'].split(' ')[0], ' '.join(options['pdal_cmd'].split(' ')[1:])
+ ' info --summary'
):
grass.fatal(_(
"The pdal program is not in the path " +
"and executable. Please install first"))
command_scan = ['pdal', 'info', '--summary', infile]
command_scan = options['pdal_cmd'].split(' ')
command_scan.extend(['info', '--summary', infile])

tmp_scan = grass.tempfile()
if tmp_scan is None:
grass.fatal("Unable to create temporary files")
fh = open(tmp_scan, 'wb')
p = grass.call(command_scan, stdout=fh)
fh.close()
summary = True
if p != 0:
command_scan = ['pdal', 'info', infile]
fh = open(tmp_scan, 'wb')
p = grass.call(command_scan, stdout=fh)
if grass.call(command_scan, stdout=fh) != 0:
fh.close()
command_scan = options['pdal_cmd'].split(' ')
command_scan.extend(['info', infile])
fh2 = open(tmp_scan, 'wb')
if grass.call(command_scan, stdout=fh2) != 0:
os.remove(tmp_scan)
grass.fatal(_(
"pdal cannot determine metadata " +
"for unsupported format of <%s>")
% infile)
fh2.close()
else:
fh2.close()
summary = False
if p != 0:
# check to see if pdal executed properly
os.remove(tmp_scan)
grass.fatal(_(
"pdal cannot determine metadata " +
"for unsupported format of <%s>")
% infile)
else:
fh.close()

data = json.load(open(tmp_scan))
if summary:
str1 = u'summary'
Expand Down Expand Up @@ -414,9 +433,8 @@ def main():
quiet=True
)
grass.fatal(_("Format .%s is not supported.." % infile_format))
tmp_file_json = grass.tempfile()
if tmp_file_json is None:
grass.fatal("Unable to create temporary files")
tmp_file_json = 'tmp_file_json_' + str(os.getpid())

data = {}
data['pipeline'] = []
data['pipeline'].append({'type': format_reader, 'filename': infile})
Expand All @@ -433,7 +451,17 @@ def main():
tmp_xyz = grass.tempfile()
if tmp_xyz is None:
grass.fatal("Unable to create temporary files")
command_pdal1 = ['pdal', 'pipeline', '--input', tmp_file_json]
command_pdal1 = options['pdal_cmd'].split(' ')
if options['pdal_cmd'] != 'pdal':
v_index = None
cmd_entries = options['pdal_cmd'].split(' ')
for cmd_entry, num in zip(cmd_entries, range(len(cmd_entries))):
if cmd_entry == '-v':
v_index = num
break
mnt_vol = cmd_entries[v_index+1].split(':')[1]
tmp_file_json2 = os.path.join(mnt_vol, tmp_file_json)
command_pdal1.extend(['pipeline', '--input', tmp_file_json2])
command_pdal2 = ['r.in.xyz',
'input=' + tmp_xyz, 'output=' + outfile,
'skip=1', 'separator=comma', 'method=' + method]
Expand All @@ -452,14 +480,14 @@ def main():
command_pdal2.append('trim=' + trim)

fh = open(tmp_xyz, 'wb')
p2 = grass.call(command_pdal1, stdout=fh)
fh.close()
if p2 != 0:
if grass.call(command_pdal1, stdout=fh) != 0:
fh.close()
# check to see if pdal pipeline executed properly
grass.fatal(_("pdal pipeline is broken..."))
else:
fh.close()

p3 = grass.call(command_pdal2, stdout=outdev)
if p3 != 0:
if grass.call(command_pdal2, stdout=outdev) != 0:
# check to see if r.in.xyz executed properly
os.remove(tmp_xyz)
grass.fatal(_("r.in.xyz is broken..."))
Expand Down