from __future__ import annotations
|
|
import importlib.util
|
import json
|
import sys
|
import tempfile
|
import unittest
|
from pathlib import Path
|
|
|
SCRIPT = Path(__file__).parents[1] / "prepare_odx_reconstruction_inputs.py"
|
SPEC = importlib.util.spec_from_file_location("prepare_odx_reconstruction_inputs", SCRIPT)
|
MODULE = importlib.util.module_from_spec(SPEC)
|
assert SPEC.loader is not None
|
sys.modules[SPEC.name] = MODULE
|
SPEC.loader.exec_module(MODULE)
|
|
|
class OdxInputPreparationTests(unittest.TestCase):
|
def test_dji_orientation_matches_referenced_odx_normalization(self) -> None:
|
self.assertEqual(MODULE.odx_orientation_from_dji(-25.9, -37.7, 0.0), (-25.9, 52.3, 0.0))
|
|
def test_geo_txt_uses_webodm_epsg4326_field_order(self) -> None:
|
record = MODULE.OdxPhoto(
|
image="DJI_0001.JPG", longitude=113.317951157, latitude=25.660699129, altitude_m=1201.372,
|
yaw_deg=-25.9, pitch_deg=52.3, roll_deg=0.0, horizontal_accuracy_m=0.0046, vertical_accuracy_m=0.0112,
|
width=4000, height=3000, sha256="a" * 64, rtk_std_lat_raw=0.0023, rtk_std_lon_raw=0.00201, rtk_std_hgt_raw=0.0056,
|
)
|
with tempfile.TemporaryDirectory() as temporary:
|
path = Path(temporary) / "geo.txt"
|
MODULE.write_geo_txt([record], path)
|
lines = path.read_text(encoding="utf-8").splitlines()
|
self.assertEqual(lines[0], "EPSG:4326")
|
fields = lines[1].split()
|
self.assertEqual(fields[0], "DJI_0001.JPG")
|
self.assertEqual(len(fields), 9)
|
self.assertEqual(float(fields[1]), record.longitude)
|
self.assertEqual(float(fields[2]), record.latitude)
|
self.assertEqual(float(fields[5]), record.pitch_deg)
|
|
def test_camera_positions_are_valid_geojson(self) -> None:
|
record = MODULE.OdxPhoto(
|
image="DJI_0001.JPG", longitude=113.0, latitude=25.0, altitude_m=100.0,
|
yaw_deg=0.0, pitch_deg=90.0, roll_deg=0.0, horizontal_accuracy_m=0.02, vertical_accuracy_m=0.03,
|
width=1, height=1, sha256="b" * 64, rtk_std_lat_raw=0.01, rtk_std_lon_raw=0.01, rtk_std_hgt_raw=0.015,
|
)
|
with tempfile.TemporaryDirectory() as temporary:
|
path = Path(temporary) / "positions.geojson"
|
MODULE.write_camera_positions_geojson([record], path)
|
payload = json.loads(path.read_text(encoding="utf-8"))
|
self.assertEqual(payload["type"], "FeatureCollection")
|
self.assertEqual(payload["features"][0]["geometry"]["coordinates"], [113.0, 25.0, 100.0])
|
|
def test_recommendations_do_not_override_per_photo_accuracy(self) -> None:
|
record = MODULE.OdxPhoto(
|
image="DJI_0001.JPG", longitude=113.0, latitude=25.0, altitude_m=100.0,
|
yaw_deg=0.0, pitch_deg=90.0, roll_deg=0.0, horizontal_accuracy_m=0.02, vertical_accuracy_m=0.03,
|
width=1, height=1, sha256="c" * 64, rtk_std_lat_raw=0.01, rtk_std_lon_raw=0.01, rtk_std_hgt_raw=0.015,
|
)
|
options = MODULE.odx_option_recommendations([record])
|
self.assertNotIn("gps-accuracy-m", options["recommendations"])
|
self.assertIn("Leave unset", options["conditional_options"]["gps-accuracy"])
|
|
|
if __name__ == "__main__":
|
unittest.main()
|