2020-09-14 18:33:39 +00:00
|
|
|
import os
|
2022-06-20 19:57:27 +00:00
|
|
|
import math
|
2020-09-14 18:33:39 +00:00
|
|
|
from opendm import log
|
|
|
|
from opendm import location
|
|
|
|
from pyproj import CRS
|
|
|
|
|
|
|
|
class GeoFile:
|
|
|
|
def __init__(self, geo_path):
|
|
|
|
self.geo_path = geo_path
|
|
|
|
self.entries = {}
|
|
|
|
self.srs = None
|
|
|
|
|
|
|
|
with open(self.geo_path, 'r') as f:
|
|
|
|
contents = f.read().strip()
|
2024-04-02 16:46:20 +00:00
|
|
|
|
|
|
|
# Strip eventual BOM characters
|
|
|
|
contents = contents.replace('\ufeff', '')
|
2020-09-14 18:33:39 +00:00
|
|
|
|
|
|
|
lines = list(map(str.strip, contents.split('\n')))
|
|
|
|
if lines:
|
|
|
|
self.raw_srs = lines[0] # SRS
|
|
|
|
self.srs = location.parse_srs_header(self.raw_srs)
|
|
|
|
longlat = CRS.from_epsg("4326")
|
|
|
|
|
|
|
|
for line in lines[1:]:
|
|
|
|
if line != "" and line[0] != "#":
|
|
|
|
parts = line.split()
|
|
|
|
if len(parts) >= 3:
|
|
|
|
i = 3
|
|
|
|
filename = parts[0]
|
|
|
|
x, y = [float(p) for p in parts[1:3]]
|
|
|
|
z = float(parts[3]) if len(parts) >= 4 else None
|
|
|
|
|
|
|
|
# Always convert coordinates to WGS84
|
|
|
|
if z is not None:
|
|
|
|
x, y, z = location.transform3(self.srs, longlat, x, y, z)
|
|
|
|
else:
|
|
|
|
x, y = location.transform2(self.srs, longlat, x, y)
|
|
|
|
|
2022-06-20 19:57:27 +00:00
|
|
|
yaw = pitch = roll = None
|
2020-09-14 18:33:39 +00:00
|
|
|
|
|
|
|
if len(parts) >= 7:
|
2022-06-20 19:57:27 +00:00
|
|
|
yaw, pitch, roll = [float(p) for p in parts[4:7]]
|
|
|
|
if math.isnan(yaw) or math.isnan(pitch) or math.isnan(roll):
|
|
|
|
yaw = pitch = roll = None
|
2020-09-14 18:33:39 +00:00
|
|
|
i = 7
|
|
|
|
|
|
|
|
horizontal_accuracy = vertical_accuracy = None
|
|
|
|
if len(parts) >= 9:
|
|
|
|
horizontal_accuracy,vertical_accuracy = [float(p) for p in parts[7:9]]
|
|
|
|
i = 9
|
|
|
|
|
|
|
|
extras = " ".join(parts[i:])
|
|
|
|
self.entries[filename] = GeoEntry(filename, x, y, z,
|
2022-06-20 19:57:27 +00:00
|
|
|
yaw, pitch, roll,
|
2020-09-14 18:33:39 +00:00
|
|
|
horizontal_accuracy, vertical_accuracy,
|
|
|
|
extras)
|
|
|
|
else:
|
2020-12-02 22:17:51 +00:00
|
|
|
log.ODM_WARNING("Malformed geo line: %s" % line)
|
2020-09-14 18:33:39 +00:00
|
|
|
|
|
|
|
def get_entry(self, filename):
|
|
|
|
return self.entries.get(filename)
|
|
|
|
|
|
|
|
|
|
|
|
class GeoEntry:
|
2022-06-20 19:57:27 +00:00
|
|
|
def __init__(self, filename, x, y, z, yaw=None, pitch=None, roll=None, horizontal_accuracy=None, vertical_accuracy=None, extras=None):
|
2020-09-14 18:33:39 +00:00
|
|
|
self.filename = filename
|
|
|
|
self.x = x
|
|
|
|
self.y = y
|
|
|
|
self.z = z
|
2022-06-20 19:57:27 +00:00
|
|
|
self.yaw = yaw
|
|
|
|
self.pitch = pitch
|
|
|
|
self.roll = roll
|
2020-09-14 18:33:39 +00:00
|
|
|
self.horizontal_accuracy = horizontal_accuracy
|
|
|
|
self.vertical_accuracy = vertical_accuracy
|
|
|
|
self.extras = extras
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return "{} ({} {} {}) ({} {} {}) ({} {}) {}".format(self.filename,
|
|
|
|
self.x, self.y, self.z,
|
2022-06-20 19:57:27 +00:00
|
|
|
self.yaw, self.pitch, self.roll,
|
2020-09-14 18:33:39 +00:00
|
|
|
self.horizontal_accuracy, self.vertical_accuracy,
|
|
|
|
self.extras).rstrip()
|
|
|
|
|
|
|
|
def position_string(self):
|
|
|
|
return "{} {} {}".format(self.x, self.y, self.z)
|