kopia lustrzana https://github.com/OpenDroneMap/ODM
feat: add --compact-overviews config param for slim orthophoto overviews
rodzic
29800652c6
commit
7f3a40c45f
|
|
@ -5,7 +5,7 @@ from opendm.concurrency import get_max_memory
|
|||
from opendm import io
|
||||
from opendm import log
|
||||
|
||||
def convert_to_cogeo(src_path, blocksize=256, max_workers=1, compression="DEFLATE"):
|
||||
def convert_to_cogeo(src_path, blocksize=256, max_workers=1, compression="DEFLATE", compact_overviews=False):
|
||||
"""
|
||||
Guarantee that the .tif passed as an argument is a Cloud Optimized GeoTIFF (cogeo)
|
||||
The file is destructively converted into a cogeo.
|
||||
|
|
@ -15,39 +15,49 @@ def convert_to_cogeo(src_path, blocksize=256, max_workers=1, compression="DEFLAT
|
|||
"""
|
||||
|
||||
if not os.path.isfile(src_path):
|
||||
logger.warning("Cannot convert to cogeo: %s (file does not exist)" % src_path)
|
||||
log.ODM_WARNING("Cannot convert to cogeo: %s (file does not exist)" % src_path)
|
||||
return False
|
||||
|
||||
log.ODM_INFO("Optimizing %s as Cloud Optimized GeoTIFF" % src_path)
|
||||
|
||||
|
||||
tmpfile = io.related_file_path(src_path, postfix='_cogeo')
|
||||
swapfile = io.related_file_path(src_path, postfix='_cogeo_swap')
|
||||
|
||||
kwargs = {
|
||||
'threads': max_workers if max_workers else 'ALL_CPUS',
|
||||
'blocksize': blocksize,
|
||||
'max_memory': get_max_memory(),
|
||||
'src_path': src_path,
|
||||
'tmpfile': tmpfile,
|
||||
'compress': compression,
|
||||
'predictor': '2' if compression in ['LZW', 'DEFLATE'] else '1',
|
||||
}
|
||||
# Configuration params
|
||||
threads = max_workers if max_workers else 'ALL_CPUS'
|
||||
predictor = '2' if compression in ['LZW', 'DEFLATE'] else '1'
|
||||
max_memory = get_max_memory()
|
||||
|
||||
# Build gdal_translate command
|
||||
cmd = [
|
||||
'gdal_translate',
|
||||
'-of', 'COG',
|
||||
'-co', f'NUM_THREADS={threads}',
|
||||
'-co', f'BLOCKSIZE={blocksize}',
|
||||
'-co', f'COMPRESS={compression}',
|
||||
'-co', f'PREDICTOR={predictor}',
|
||||
'-co', 'BIGTIFF=IF_SAFER',
|
||||
'-co', 'RESAMPLING=NEAREST',
|
||||
]
|
||||
|
||||
if compact_overviews:
|
||||
cmd.extend([
|
||||
'-co', 'PHOTOMETRIC_OVERVIEW=YCBCR',
|
||||
'-co', 'INTERLEAVE_OVERVIEW=PIXEL',
|
||||
])
|
||||
|
||||
cmd.extend([
|
||||
'--config', 'GDAL_CACHEMAX', f'{max_memory}%',
|
||||
'--config', 'GDAL_NUM_THREADS', str(threads),
|
||||
src_path,
|
||||
tmpfile,
|
||||
])
|
||||
|
||||
try:
|
||||
system.run("gdal_translate "
|
||||
"-of COG "
|
||||
"-co NUM_THREADS={threads} "
|
||||
"-co BLOCKSIZE={blocksize} "
|
||||
"-co COMPRESS={compress} "
|
||||
"-co PREDICTOR={predictor} "
|
||||
"-co BIGTIFF=IF_SAFER "
|
||||
"-co RESAMPLING=NEAREST "
|
||||
"--config GDAL_CACHEMAX {max_memory}% "
|
||||
"--config GDAL_NUM_THREADS {threads} "
|
||||
"\"{src_path}\" \"{tmpfile}\" ".format(**kwargs))
|
||||
system.run(' '.join(cmd))
|
||||
except Exception as e:
|
||||
log.ODM_WARNING("Cannot create Cloud Optimized GeoTIFF: %s" % str(e))
|
||||
return False
|
||||
|
||||
if os.path.isfile(tmpfile):
|
||||
shutil.move(src_path, swapfile) # Move to swap location
|
||||
|
|
@ -57,6 +67,7 @@ def convert_to_cogeo(src_path, blocksize=256, max_workers=1, compression="DEFLAT
|
|||
except IOError as e:
|
||||
log.ODM_WARNING("Cannot move %s to %s: %s" % (tmpfile, src_path, str(e)))
|
||||
shutil.move(swapfile, src_path) # Attempt to restore
|
||||
return False
|
||||
|
||||
if os.path.isfile(swapfile):
|
||||
os.remove(swapfile)
|
||||
|
|
|
|||
|
|
@ -740,6 +740,12 @@ def config(argv=None, parser=None):
|
|||
default=False,
|
||||
help='Build orthophoto overviews for faster display in programs such as QGIS. Default: %(default)s')
|
||||
|
||||
parser.add_argument('--compact-overviews',
|
||||
action=StoreTrue,
|
||||
nargs=0,
|
||||
default=False,
|
||||
help='Use addtional compression for orthophoto overviews, to improve viewing performance. Default: %(default)s')
|
||||
|
||||
parser.add_argument('--cog',
|
||||
action=StoreTrue,
|
||||
nargs=0,
|
||||
|
|
|
|||
|
|
@ -29,15 +29,31 @@ def get_orthophoto_vars(args):
|
|||
'NUM_THREADS': args.max_concurrency
|
||||
}
|
||||
|
||||
def build_overviews(orthophoto_file):
|
||||
def build_overviews(orthophoto_file, compact_overviews=False):
|
||||
"""
|
||||
Build overviews for an orthophoto file using gdaladdo
|
||||
:param orthophoto_file: path to orthophoto
|
||||
:param compact_overviews: whether to use compact overview settings
|
||||
"""
|
||||
log.ODM_INFO("Building Overviews")
|
||||
kwargs = {'orthophoto': orthophoto_file}
|
||||
|
||||
# Run gdaladdo
|
||||
system.run('gdaladdo -r average '
|
||||
'--config BIGTIFF_OVERVIEW IF_SAFER '
|
||||
'--config COMPRESS_OVERVIEW JPEG '
|
||||
'{orthophoto} 2 4 8 16'.format(**kwargs))
|
||||
# Build gdaladdo command
|
||||
cmd = [
|
||||
'gdaladdo',
|
||||
'-r', 'average',
|
||||
'--config', 'BIGTIFF_OVERVIEW', 'IF_SAFER',
|
||||
'--config', 'COMPRESS_OVERVIEW', 'JPG',
|
||||
]
|
||||
|
||||
if compact_overviews:
|
||||
cmd.extend([
|
||||
'--config', 'PHOTOMETRIC_OVERVIEW', 'YCBCR',
|
||||
'--config', 'INTERLEAVE_OVERVIEW', 'PIXEL',
|
||||
])
|
||||
|
||||
cmd.extend([orthophoto_file, '2', '4', '8', '16'])
|
||||
|
||||
system.run(' '.join(cmd))
|
||||
|
||||
def generate_png(orthophoto_file, output_file=None, outsize=None):
|
||||
if output_file is None:
|
||||
|
|
@ -172,7 +188,7 @@ def post_orthophoto_steps(args, bounds_file_path, orthophoto_file, orthophoto_ti
|
|||
Cropper.crop(bounds_file_path, orthophoto_file, get_orthophoto_vars(args), keep_original=not args.optimize_disk_space, warp_options=['-dstalpha'])
|
||||
|
||||
if args.build_overviews and not args.cog:
|
||||
build_overviews(orthophoto_file)
|
||||
build_overviews(orthophoto_file, compact_overviews=args.compact_overviews)
|
||||
|
||||
if args.orthophoto_png:
|
||||
generate_png(orthophoto_file)
|
||||
|
|
@ -186,7 +202,7 @@ def post_orthophoto_steps(args, bounds_file_path, orthophoto_file, orthophoto_ti
|
|||
generate_orthophoto_tiles(orthophoto_file, orthophoto_tiles_dir, args.max_concurrency, resolution)
|
||||
|
||||
if args.cog:
|
||||
convert_to_cogeo(orthophoto_file, max_workers=args.max_concurrency, compression=args.orthophoto_compression)
|
||||
convert_to_cogeo(orthophoto_file, max_workers=args.max_concurrency, compression=args.orthophoto_compression, compact_overviews=args.compact_overviews)
|
||||
|
||||
generate_extent_polygon(orthophoto_file)
|
||||
generate_tfw(orthophoto_file)
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue