From 403a902f4eb540d118ca3853626bc6d51061dd25 Mon Sep 17 00:00:00 2001 From: Tao Peng Date: Tue, 25 Mar 2025 11:37:19 -0700 Subject: [PATCH 1/4] fix types --- mapillary_tools/exif_read.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/mapillary_tools/exif_read.py b/mapillary_tools/exif_read.py index 284d59377..d1c5d57ce 100644 --- a/mapillary_tools/exif_read.py +++ b/mapillary_tools/exif_read.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import abc import datetime import io @@ -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 @@ -818,8 +820,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 From 7175d1e71cd7ae045eb17b0c40476d38a69e32ec Mon Sep 17 00:00:00 2001 From: Tao Peng Date: Tue, 25 Mar 2025 11:37:53 -0700 Subject: [PATCH 2/4] remoev the hack in direction interpolation --- mapillary_tools/exif_read.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/mapillary_tools/exif_read.py b/mapillary_tools/exif_read.py index d1c5d57ce..2d75a5f1e 100644 --- a/mapillary_tools/exif_read.py +++ b/mapillary_tools/exif_read.py @@ -738,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") From 7563f977f19d06ec801a768fcf284387a86b6b29 Mon Sep 17 00:00:00 2001 From: Tao Peng Date: Tue, 25 Mar 2025 11:38:26 -0700 Subject: [PATCH 3/4] update the make/model extraction order --- mapillary_tools/exif_read.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/mapillary_tools/exif_read.py b/mapillary_tools/exif_read.py index 2d75a5f1e..8a025d255 100644 --- a/mapillary_tools/exif_read.py +++ b/mapillary_tools/exif_read.py @@ -766,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() @@ -775,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() From f206c1b3652d58f28f45fc8c4bbf0baaba8cd005 Mon Sep 17 00:00:00 2001 From: Tao Peng Date: Tue, 25 Mar 2025 11:39:13 -0700 Subject: [PATCH 4/4] extract GPS timestamps from EXIFTOOL --- mapillary_tools/exiftool_read_video.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/mapillary_tools/exiftool_read_video.py b/mapillary_tools/exiftool_read_video.py index a8ee18423..25be9e5b4 100644 --- a/mapillary_tools/exiftool_read_video.py +++ b/mapillary_tools/exiftool_read_video.py @@ -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]: @@ -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( @@ -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, @@ -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,