2021-07-30 20:07:34 +00:00
|
|
|
import os
|
2024-09-05 08:28:07 +00:00
|
|
|
import rasterio
|
2021-07-30 20:07:34 +00:00
|
|
|
|
2024-09-05 08:28:07 +00:00
|
|
|
from datetime import datetime
|
2021-07-30 20:07:34 +00:00
|
|
|
from osgeo import gdal
|
|
|
|
from opendm import io
|
|
|
|
from opendm import log
|
|
|
|
from opendm import types
|
2024-09-05 18:27:16 +00:00
|
|
|
from opendm import photo
|
2021-07-30 20:07:34 +00:00
|
|
|
from opendm.utils import copy_paths, get_processing_results_paths
|
2022-05-25 16:50:57 +00:00
|
|
|
from opendm.ogctiles import build_3dtiles
|
2021-07-30 20:07:34 +00:00
|
|
|
|
|
|
|
class ODMPostProcess(types.ODM_Stage):
|
|
|
|
def process(self, args, outputs):
|
|
|
|
tree = outputs['tree']
|
|
|
|
reconstruction = outputs['reconstruction']
|
|
|
|
|
|
|
|
log.ODM_INFO("Post Processing")
|
|
|
|
|
2024-09-05 18:27:16 +00:00
|
|
|
rasters = [tree.odm_orthophoto_tif,
|
|
|
|
tree.path("odm_dem", "dsm.tif"),
|
|
|
|
tree.path("odm_dem", "dtm.tif")]
|
2024-09-05 08:28:07 +00:00
|
|
|
|
2024-09-05 18:27:16 +00:00
|
|
|
mean_capture_time = photo.find_mean_utc_time(reconstruction.photos)
|
|
|
|
mean_capture_dt = None
|
|
|
|
if mean_capture_time is not None:
|
|
|
|
mean_capture_dt = datetime.fromtimestamp(mean_capture_time).strftime('%Y:%m:%d %H:%M:%S') + '+00:00'
|
2024-09-05 08:28:07 +00:00
|
|
|
|
2024-09-05 18:27:16 +00:00
|
|
|
# Add TIFF tags
|
|
|
|
for product in rasters:
|
|
|
|
if os.path.isfile(product):
|
|
|
|
log.ODM_INFO("Adding TIFFTAGs to {}".format(product))
|
|
|
|
with rasterio.open(product, 'r+') as rst:
|
|
|
|
if mean_capture_dt is not None:
|
|
|
|
rst.update_tags(TIFFTAG_DATETIME=mean_capture_dt)
|
|
|
|
rst.update_tags(TIFFTAG_SOFTWARE='ODM {}'.format(log.odm_version()))
|
2024-09-05 08:28:07 +00:00
|
|
|
|
2024-09-05 18:27:16 +00:00
|
|
|
# GCP info
|
2021-07-30 20:07:34 +00:00
|
|
|
if not outputs['large']:
|
|
|
|
# TODO: support for split-merge?
|
|
|
|
|
|
|
|
# Embed GCP info in 2D results via
|
|
|
|
# XML metadata fields
|
|
|
|
gcp_gml_export_file = tree.path("odm_georeferencing", "ground_control_points.gml")
|
|
|
|
|
|
|
|
if reconstruction.has_gcp() and io.file_exists(gcp_gml_export_file):
|
|
|
|
skip_embed_gcp = False
|
2021-07-30 20:16:05 +00:00
|
|
|
gcp_xml = ""
|
|
|
|
|
2021-07-30 20:07:34 +00:00
|
|
|
with open(gcp_gml_export_file) as f:
|
|
|
|
gcp_xml = f.read()
|
|
|
|
|
2024-09-05 18:27:16 +00:00
|
|
|
for product in rasters:
|
2021-07-30 20:07:34 +00:00
|
|
|
if os.path.isfile(product):
|
|
|
|
ds = gdal.Open(product)
|
|
|
|
if ds is not None:
|
|
|
|
if ds.GetMetadata('xml:GROUND_CONTROL_POINTS') is None or self.rerun():
|
|
|
|
ds.SetMetadata(gcp_xml, 'xml:GROUND_CONTROL_POINTS')
|
|
|
|
ds = None
|
|
|
|
log.ODM_INFO("Wrote xml:GROUND_CONTROL_POINTS metadata to %s" % product)
|
|
|
|
else:
|
|
|
|
skip_embed_gcp = True
|
2021-07-30 21:03:07 +00:00
|
|
|
log.ODM_WARNING("Already embedded ground control point information")
|
2021-07-30 20:07:34 +00:00
|
|
|
break
|
|
|
|
else:
|
|
|
|
log.ODM_WARNING("Cannot open %s for writing, skipping GCP embedding" % product)
|
2022-05-25 16:50:57 +00:00
|
|
|
|
|
|
|
if getattr(args, '3d_tiles'):
|
|
|
|
build_3dtiles(args, tree, reconstruction, self.rerun())
|
|
|
|
|
2021-07-30 20:07:34 +00:00
|
|
|
if args.copy_to:
|
|
|
|
try:
|
|
|
|
copy_paths([os.path.join(args.project_path, p) for p in get_processing_results_paths()], args.copy_to, self.rerun())
|
|
|
|
except Exception as e:
|
|
|
|
log.ODM_WARNING("Cannot copy to %s: %s" % (args.copy_to, str(e)))
|
2024-09-05 08:28:07 +00:00
|
|
|
|