OpenDroneMap-ODM/scripts/odm_dem.py

88 wiersze
4.1 KiB
Python
Czysty Zwykły widok Historia

2019-04-22 19:14:39 +00:00
import os, json
from shutil import copyfile
2017-06-23 15:20:46 +00:00
from opendm import io
from opendm import log
from opendm import system
from opendm import context
from opendm import types
2018-08-08 19:41:08 +00:00
from opendm import gsd
2019-04-29 18:01:55 +00:00
from opendm.dem import commands, utils
from opendm.cropper import Cropper
2017-06-23 15:20:46 +00:00
2019-04-22 19:14:39 +00:00
class ODMDEMStage(types.ODM_Stage):
def process(self, args, outputs):
tree = outputs['tree']
2018-06-18 13:57:20 +00:00
las_model_found = io.file_exists(tree.odm_georeferencing_model_laz)
2017-06-23 19:28:46 +00:00
log.ODM_INFO('Classify: ' + str(args.pc_classify))
2017-06-23 19:28:46 +00:00
log.ODM_INFO('Create DSM: ' + str(args.dsm))
log.ODM_INFO('Create DTM: ' + str(args.dtm))
2018-06-18 13:57:20 +00:00
log.ODM_INFO('DEM input file {0} found: {1}'.format(tree.odm_georeferencing_model_laz, str(las_model_found)))
2017-06-23 19:28:46 +00:00
# define paths and create working directories
odm_dem_root = tree.path('odm_dem')
if not io.dir_exists(odm_dem_root):
system.mkdir_p(odm_dem_root)
if args.pc_classify and las_model_found:
pc_classify_marker = os.path.join(odm_dem_root, 'pc_classify_done.txt')
2019-04-22 19:14:39 +00:00
if not io.file_exists(pc_classify_marker) or self.rerun():
log.ODM_INFO("Classifying {} using Simple Morphological Filter".format(tree.odm_georeferencing_model_laz))
commands.classify(tree.odm_georeferencing_model_laz,
2019-04-20 14:56:42 +00:00
args.smrf_scalar,
args.smrf_slope,
args.smrf_threshold,
args.smrf_window,
verbose=args.verbose
)
with open(pc_classify_marker, 'w') as f:
f.write('Classify: smrf\n')
2019-04-20 14:56:42 +00:00
f.write('Scalar: {}\n'.format(args.smrf_scalar))
f.write('Slope: {}\n'.format(args.smrf_slope))
f.write('Threshold: {}\n'.format(args.smrf_threshold))
f.write('Window: {}\n'.format(args.smrf_window))
2017-06-23 19:28:46 +00:00
# Do we need to process anything here?
if (args.dsm or args.dtm) and las_model_found:
2017-06-27 16:43:36 +00:00
dsm_output_filename = os.path.join(odm_dem_root, 'dsm.tif')
dtm_output_filename = os.path.join(odm_dem_root, 'dtm.tif')
2017-06-23 19:28:46 +00:00
if (args.dtm and not io.file_exists(dtm_output_filename)) or \
(args.dsm and not io.file_exists(dsm_output_filename)) or \
2019-04-22 19:14:39 +00:00
self.rerun():
2017-06-23 19:28:46 +00:00
products = []
if args.dsm: products.append('dsm')
2017-06-23 19:28:46 +00:00
if args.dtm: products.append('dtm')
2018-08-08 19:41:08 +00:00
resolution = gsd.cap_resolution(args.dem_resolution, tree.opensfm_reconstruction, gsd_error_estimate=-3, ignore_gsd=args.ignore_gsd)
2018-08-08 19:41:08 +00:00
radius_steps = [(resolution / 100.0) / 2.0]
2017-06-23 19:28:46 +00:00
for _ in range(args.dem_gapfill_steps - 1):
radius_steps.append(radius_steps[-1] * 2) # 2 is arbitrary, maybe there's a better value?
2017-06-23 19:28:46 +00:00
for product in products:
2019-04-11 20:29:53 +00:00
commands.create_dem(
tree.odm_georeferencing_model_laz,
product,
output_type='idw' if product == 'dtm' else 'max',
2019-04-11 20:29:53 +00:00
radiuses=map(str, radius_steps),
gapfill=args.dem_gapfill_steps > 0,
outdir=odm_dem_root,
2018-08-08 19:41:08 +00:00
resolution=resolution / 100.0,
decimation=args.dem_decimation,
2018-07-03 17:01:18 +00:00
verbose=args.verbose,
max_workers=args.max_concurrency
)
if args.crop > 0:
bounds_file_path = os.path.join(tree.odm_georeferencing, 'odm_georeferenced_model.bounds.gpkg')
if os.path.exists(bounds_file_path):
2019-04-29 18:01:55 +00:00
Cropper.crop(bounds_file_path, os.path.join(odm_dem_root, "{}.tif".format(product)), utils.get_dem_vars(args))
2017-06-23 19:28:46 +00:00
else:
log.ODM_WARNING('Found existing outputs in: %s' % odm_dem_root)
2017-06-23 15:20:46 +00:00
else:
2017-06-23 19:28:46 +00:00
log.ODM_WARNING('DEM will not be generated')