diff --git a/mapillary_tools/process_sequence_properties.py b/mapillary_tools/process_sequence_properties.py index acc801c0..1ddd2b3c 100644 --- a/mapillary_tools/process_sequence_properties.py +++ b/mapillary_tools/process_sequence_properties.py @@ -337,43 +337,28 @@ def _video_name(video_metadata: types.VideoMetadata) -> str: def _check_sequences_by_limits( input_sequences: T.Sequence[PointSequence], - max_sequence_filesize_in_bytes: int | None, max_capture_speed_kmh: float, ) -> tuple[list[PointSequence], list[types.ErrorMetadata]]: output_sequences: list[PointSequence] = [] output_errors: list[types.ErrorMetadata] = [] for sequence in input_sequences: - try: - if max_sequence_filesize_in_bytes is not None: - sequence_filesize = sum( - ( - utils.get_file_size(image.filename) - if image.filesize is None - else image.filesize - ) - for image in sequence - ) - if sequence_filesize > max_sequence_filesize_in_bytes: - raise exceptions.MapillaryFileTooLargeError( - f"Sequence file size {humanize.naturalsize(sequence_filesize)} exceeds max allowed {humanize.naturalsize(max_sequence_filesize_in_bytes)}", - ) + avg_speed_kmh = geo.avg_speed(sequence) * 3.6 # Convert m/s to km/h + too_fast = len(sequence) >= 2 and avg_speed_kmh > max_capture_speed_kmh - avg_speed_kmh = geo.avg_speed(sequence) * 3.6 # Convert m/s to km/h - too_fast = len(sequence) >= 2 and avg_speed_kmh > max_capture_speed_kmh - if too_fast: - raise exceptions.MapillaryCaptureSpeedTooFastError( - f"Capture speed {avg_speed_kmh:.3f} km/h exceeds max allowed {max_capture_speed_kmh:.3f} km/h", - ) - except exceptions.MapillaryDescriptionError as ex: - LOG.error(f"{_sequence_name(sequence)}: {ex}") + if too_fast: + error = exceptions.MapillaryCaptureSpeedTooFastError( + f"Capture speed {avg_speed_kmh:.3f} km/h exceeds max allowed {max_capture_speed_kmh:.3f} km/h", + ) + LOG.error(f"{_sequence_name(sequence)}: {error}") for image in sequence: output_errors.append( types.describe_error_metadata( - exc=ex, filename=image.filename, filetype=types.FileType.IMAGE + exc=error, + filename=image.filename, + filetype=types.FileType.IMAGE, ) ) - else: output_sequences.append(sequence) @@ -864,7 +849,6 @@ def process_sequence_properties( # Check limits for sequences sequences, errors = _check_sequences_by_limits( sequences, - max_sequence_filesize_in_bytes=max_sequence_filesize_in_bytes, max_capture_speed_kmh=max_capture_speed_kmh, ) error_metadatas.extend(errors) diff --git a/tests/unit/test_sequence_processing.py b/tests/unit/test_sequence_processing.py index d84ccf83..7e904fd8 100644 --- a/tests/unit/test_sequence_processing.py +++ b/tests/unit/test_sequence_processing.py @@ -1082,6 +1082,31 @@ def test_zigzag_detection_uturn_not_triggered(tmpdir: py.path.local): assert len(image_metadatas) > 0 +def test_capture_speed_exceeds_limit(tmpdir: py.path.local): + """Test that sequences with speed exceeding the limit are rejected.""" + # Create a sequence that moves very fast (> 400 km/h) + # At the equator: 0.01 degrees ≈ 1.11 km + # Moving 0.01 degrees in 1 second = 1.11 km/s = 4000 km/h (well above 400 km/h limit) + sequence = [ + _make_image_metadata( + Path(tmpdir) / Path("./fast1.jpg"), 1.0, 1.0, 0, filesize=1 + ), + _make_image_metadata( + Path(tmpdir) / Path("./fast2.jpg"), 1.0, 1.01, 1, filesize=1 + ), + ] + + metadatas = psp.process_sequence_properties(sequence) + error_metadatas = [d for d in metadatas if isinstance(d, types.ErrorMetadata)] + + # All images should be rejected due to speed limit + assert len(error_metadatas) == 2 + assert all( + isinstance(d.error, exceptions.MapillaryCaptureSpeedTooFastError) + for d in error_metadatas + ) + + def test_zigzag_backwards_walk_single_deviation(tmpdir: py.path.local): """Test backwards walk with a single deviation point.