Skip to content

Commit 0325e6e

Browse files
authored
refactor: use visitor pattern to parse different CAMM entries (#723)
* support GoPro GPS and CAMM GPS sample entries separately * fix types * type * remove the MLY extension * add back GoProGPSSampleEntry * fix types * use TypeIs * fix types
1 parent 1d7df1e commit 0325e6e

5 files changed

Lines changed: 509 additions & 189 deletions

File tree

mapillary_tools/camm/camm_builder.py

Lines changed: 16 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import io
22
import typing as T
33

4-
from .. import geo, telemetry, types
4+
from .. import geo, types
55
from ..mp4 import (
66
construct_mp4_parser as cparser,
77
mp4_sample_parser as sample_parser,
@@ -11,62 +11,15 @@
1111
from . import camm_parser
1212

1313

14-
TelemetryMeasurement = T.Union[
15-
geo.Point,
16-
telemetry.TelemetryMeasurement,
17-
]
14+
def _build_camm_sample(measurement: camm_parser.TelemetryMeasurement) -> bytes:
15+
if camm_parser.GoProGPSSampleEntry.serializable(measurement):
16+
return camm_parser.GoProGPSSampleEntry.serialize(measurement)
1817

18+
for sample_entry_cls in camm_parser.SAMPLE_ENTRY_CLS_BY_CAMM_TYPE.values():
19+
if sample_entry_cls.serializable(measurement):
20+
return sample_entry_cls.serialize(measurement)
1921

20-
def _build_camm_sample(measurement: TelemetryMeasurement) -> bytes:
21-
if isinstance(measurement, geo.Point):
22-
return camm_parser.CAMMSampleData.build(
23-
{
24-
"type": camm_parser.CAMMType.MIN_GPS.value,
25-
"data": [
26-
measurement.lat,
27-
measurement.lon,
28-
-1.0 if measurement.alt is None else measurement.alt,
29-
],
30-
}
31-
)
32-
elif isinstance(measurement, telemetry.AccelerationData):
33-
# Accelerometer reading in meters/second^2 along XYZ axes of the camera.
34-
return camm_parser.CAMMSampleData.build(
35-
{
36-
"type": camm_parser.CAMMType.ACCELERATION.value,
37-
"data": [
38-
measurement.x,
39-
measurement.y,
40-
measurement.z,
41-
],
42-
}
43-
)
44-
elif isinstance(measurement, telemetry.GyroscopeData):
45-
# Gyroscope signal in radians/seconds around XYZ axes of the camera. Rotation is positive in the counterclockwise direction.
46-
return camm_parser.CAMMSampleData.build(
47-
{
48-
"type": camm_parser.CAMMType.GYRO.value,
49-
"data": [
50-
measurement.x,
51-
measurement.y,
52-
measurement.z,
53-
],
54-
}
55-
)
56-
elif isinstance(measurement, telemetry.MagnetometerData):
57-
# Ambient magnetic field.
58-
return camm_parser.CAMMSampleData.build(
59-
{
60-
"type": camm_parser.CAMMType.MAGNETIC_FIELD.value,
61-
"data": [
62-
measurement.x,
63-
measurement.y,
64-
measurement.z,
65-
],
66-
}
67-
)
68-
else:
69-
raise ValueError(f"unexpected measurement type {type(measurement)}")
22+
raise ValueError(f"Unsupported measurement type {type(measurement)}")
7023

7124

7225
def _create_edit_list_from_points(
@@ -121,16 +74,19 @@ def _create_edit_list_from_points(
12174

12275
def _multiplex(
12376
points: T.Sequence[geo.Point],
124-
measurements: T.Optional[T.List[telemetry.TelemetryMeasurement]] = None,
125-
) -> T.List[TelemetryMeasurement]:
126-
mutiplexed: T.List[TelemetryMeasurement] = [*points, *(measurements or [])]
77+
measurements: T.Optional[T.List[camm_parser.TelemetryMeasurement]] = None,
78+
) -> T.List[camm_parser.TelemetryMeasurement]:
79+
mutiplexed: T.List[camm_parser.TelemetryMeasurement] = [
80+
*points,
81+
*(measurements or []),
82+
]
12783
mutiplexed.sort(key=lambda m: m.time)
12884

12985
return mutiplexed
13086

13187

13288
def convert_telemetry_to_raw_samples(
133-
measurements: T.Sequence[TelemetryMeasurement],
89+
measurements: T.Sequence[camm_parser.TelemetryMeasurement],
13490
timescale: int,
13591
) -> T.Generator[sample_parser.RawSample, None, None]:
13692
for idx, measurement in enumerate(measurements):
@@ -283,7 +239,7 @@ def create_camm_trak(
283239

284240
def camm_sample_generator2(
285241
video_metadata: types.VideoMetadata,
286-
telemetry_measurements: T.Optional[T.List[telemetry.TelemetryMeasurement]] = None,
242+
telemetry_measurements: T.Optional[T.List[camm_parser.TelemetryMeasurement]] = None,
287243
):
288244
def _f(
289245
fp: T.BinaryIO,

0 commit comments

Comments
 (0)