Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 14 additions & 18 deletions mapillary_tools/exif_read.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import abc
import datetime
import io
Expand Down Expand Up @@ -477,9 +479,9 @@ def extract_orientation(self) -> int:

def _extract_alternative_fields(
self,
fields: T.Sequence[str],
field_type: T.Type[_FIELD_TYPE],
) -> T.Optional[_FIELD_TYPE]:
fields: T.Iterable[str],
field_type: type[_FIELD_TYPE],
) -> _FIELD_TYPE | None:
"""
Extract a value for a list of ordered fields.
Return the value of the first existed field in the list
Expand Down Expand Up @@ -736,17 +738,7 @@ def extract_direction(self) -> T.Optional[float]:
"GPS GPSImgDirection",
"GPS GPSTrack",
]
direction = self._extract_alternative_fields(fields, float)
if direction is not None:
if direction > 360:
# fix negative value wrongly parsed in exifread
# -360 degree -> 4294966935 when converting from hex
bearing1 = bin(int(direction))[2:]
bearing2 = "".join([str(int(int(a) == 0)) for a in bearing1])
direction = -float(int(bearing2, 2))
direction %= 360

return direction
return self._extract_alternative_fields(fields, float)

def extract_lon_lat(self) -> T.Optional[T.Tuple[float, float]]:
lat_tag = self.tags.get("GPS GPSLatitude")
Expand Down Expand Up @@ -774,7 +766,9 @@ def extract_make(self) -> T.Optional[str]:
"""
Extract camera make
"""
make = self._extract_alternative_fields(["Image Make", "EXIF LensMake"], str)
make = self._extract_alternative_fields(
["Image Make", "EXIF Make", "EXIF LensMake"], str
)
if make is None:
return None
return make.strip()
Expand All @@ -783,7 +777,9 @@ def extract_model(self) -> T.Optional[str]:
"""
Extract camera model
"""
model = self._extract_alternative_fields(["Image Model", "EXIF LensModel"], str)
model = self._extract_alternative_fields(
["Image Model", "EXIF Model", "EXIF LensModel"], str
)
if model is None:
return None
return model.strip()
Expand Down Expand Up @@ -818,8 +814,8 @@ def extract_orientation(self) -> int:
def _extract_alternative_fields(
self,
fields: T.Sequence[str],
field_type: T.Type[_FIELD_TYPE],
) -> T.Optional[_FIELD_TYPE]:
field_type: type[_FIELD_TYPE],
) -> _FIELD_TYPE | None:
"""
Extract a value for a list of ordered fields.
Return the value of the first existed field in the list
Expand Down
13 changes: 12 additions & 1 deletion mapillary_tools/exiftool_read_video.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ def _aggregate_gps_track(
lon_tag: str,
lat_tag: str,
alt_tag: T.Optional[str] = None,
gps_time_tag: T.Optional[str] = None,
direction_tag: T.Optional[str] = None,
ground_speed_tag: T.Optional[str] = None,
) -> T.List[GPSPoint]:
Expand Down Expand Up @@ -161,6 +162,15 @@ def _aggregate_float_values_same_length(
# aggregate speeds (optional)
ground_speeds = _aggregate_float_values_same_length(ground_speed_tag)

# GPS timestamp (optional)
epoch_time = None
if gps_time_tag is not None:
gps_time_text = _extract_alternative_fields(texts_by_tag, [gps_time_tag], str)
if gps_time_text is not None:
dt = exif_read.parse_gps_datetime(gps_time_text)
if dt is not None:
epoch_time = geo.as_unix_time(dt)

# build track
track = []
for timestamp, lon, lat, alt, direction, ground_speed in zip(
Expand All @@ -180,7 +190,7 @@ def _aggregate_float_values_same_length(
lat=lat,
alt=alt,
angle=direction,
epoch_time=None,
epoch_time=epoch_time,
fix=None,
precision=None,
ground_speed=ground_speed,
Expand Down Expand Up @@ -228,6 +238,7 @@ def _aggregate_gps_track_by_sample_time(
lon_tag: str,
lat_tag: str,
alt_tag: T.Optional[str] = None,
gps_time_tag: T.Optional[str] = None,
direction_tag: T.Optional[str] = None,
ground_speed_tag: T.Optional[str] = None,
gps_fix_tag: T.Optional[str] = None,
Expand Down
Loading