-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #619 from OpenTrafficCam/feature/7185-refactor-use…
…-case-to-add-section-with-its-geometry feature/7185-refactor-use-case-to-add-section-with-its-geometry
- Loading branch information
Showing
6 changed files
with
176 additions
and
101 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
138 changes: 138 additions & 0 deletions
138
OTAnalytics/application/use_cases/editor/section_editor.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
import contextlib | ||
from typing import Callable | ||
|
||
from OTAnalytics.application.application import CancelAddSection | ||
from OTAnalytics.application.use_cases.section_repository import AddSection | ||
from OTAnalytics.domain import geometry | ||
from OTAnalytics.domain.geometry import coordinate_from_tuple | ||
from OTAnalytics.domain.section import ( | ||
ID, | ||
NAME, | ||
RELATIVE_OFFSET_COORDINATES, | ||
Area, | ||
LineSection, | ||
MissingSection, | ||
Section, | ||
SectionId, | ||
SectionRepository, | ||
) | ||
from OTAnalytics.domain.types import EventType | ||
|
||
MetadataProvider = Callable[[], dict] | ||
|
||
|
||
class MissingCoordinate(Exception): | ||
pass | ||
|
||
|
||
def validate_coordinates(coordinates: list[tuple[int, int]]) -> None: | ||
if not coordinates: | ||
raise MissingCoordinate("First coordinate is missing") | ||
elif len(coordinates) == 1: | ||
raise MissingCoordinate("Second coordinate is missing") | ||
|
||
|
||
def validate_section_information( | ||
meta_data: dict, coordinates: list[tuple[int, int]] | ||
) -> None: | ||
validate_coordinates(coordinates) | ||
if not meta_data: | ||
raise ValueError("Metadata of line_section are not defined") | ||
|
||
|
||
class CreateSectionId: | ||
def __init__(self, section_repository: SectionRepository) -> None: | ||
self._section_repository = section_repository | ||
|
||
def create_id(self) -> SectionId: | ||
return self._section_repository.get_id() | ||
|
||
|
||
class AddNewSection: | ||
def __init__(self, create_section_id: CreateSectionId, add_section: AddSection): | ||
self._create_section_id = create_section_id | ||
self._add_section = add_section | ||
|
||
def add_new_section( | ||
self, | ||
coordinates: list[tuple[int, int]], | ||
is_area_section: bool, | ||
get_metadata: MetadataProvider, | ||
) -> Section | None: | ||
validate_coordinates(coordinates) | ||
with contextlib.suppress(CancelAddSection): | ||
return self.__create_section(coordinates, is_area_section, get_metadata) | ||
return None | ||
|
||
def __create_section( | ||
self, | ||
coordinates: list[tuple[int, int]], | ||
is_area_section: bool, | ||
get_metadata: MetadataProvider, | ||
) -> Section: | ||
metadata = self.__get_metadata(get_metadata) | ||
relative_offset_coordinates_enter = metadata[RELATIVE_OFFSET_COORDINATES][ | ||
EventType.SECTION_ENTER.serialize() | ||
] | ||
section: Section | None = None | ||
if is_area_section: | ||
section = Area( | ||
id=self._create_section_id.create_id(), | ||
name=metadata[NAME], | ||
relative_offset_coordinates={ | ||
EventType.SECTION_ENTER: geometry.RelativeOffsetCoordinate( | ||
**relative_offset_coordinates_enter | ||
) | ||
}, | ||
plugin_data={}, | ||
coordinates=[ | ||
coordinate_from_tuple(coordinate) for coordinate in coordinates | ||
], | ||
) | ||
else: | ||
section = LineSection( | ||
id=self._create_section_id.create_id(), | ||
name=metadata[NAME], | ||
relative_offset_coordinates={ | ||
EventType.SECTION_ENTER: geometry.RelativeOffsetCoordinate( | ||
**relative_offset_coordinates_enter | ||
) | ||
}, | ||
plugin_data={}, | ||
coordinates=[ | ||
coordinate_from_tuple(coordinate) for coordinate in coordinates | ||
], | ||
) | ||
if section is None: | ||
raise TypeError("section has to be LineSection or Area, but is None") | ||
self._add_section(section) | ||
return section | ||
|
||
def __get_metadata(self, get_metadata: MetadataProvider) -> dict: | ||
metadata = get_metadata() | ||
while ( | ||
(not metadata) | ||
or (NAME not in metadata) | ||
or (not self._add_section.is_section_name_valid(metadata[NAME])) | ||
or (RELATIVE_OFFSET_COORDINATES not in metadata) | ||
): | ||
metadata = get_metadata() | ||
return metadata | ||
|
||
|
||
class UpdateSectionCoordinates: | ||
def __init__(self, section_repository: SectionRepository) -> None: | ||
self._section_repository = section_repository | ||
|
||
def update(self, meta_data: dict, coordinates: list[tuple[int, int]]) -> SectionId: | ||
validate_section_information(meta_data, coordinates) | ||
section_id = SectionId(meta_data[ID]) | ||
if not (section := self._section_repository.get(section_id)): | ||
raise MissingSection( | ||
f"Could not update section '{section_id.serialize()}' after editing" | ||
) | ||
section.update_coordinates( | ||
[coordinate_from_tuple(coordinate) for coordinate in coordinates] | ||
) | ||
self._section_repository.update(section) | ||
return section_id |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
f2a4780
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possible performance regression was detected for benchmark 'Python Benchmark with pytest-benchmark'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold
2
.tests/benchmark_otanalytics.py::TestBenchmarkTracksIntersectingSections::test_15min
0.11111538318894087
iter/sec (stddev: 0
)157.30079388110306
iter/sec (stddev: 0
)1415.65
tests/benchmark_otanalytics.py::TestBenchmarkTracksIntersectingSections::test_15min_filtered
0.11240283040020586
iter/sec (stddev: 0
)169.7883384610029
iter/sec (stddev: 0
)1510.53
tests/benchmark_otanalytics.py::TestBenchmarkCreateEvents::test_15min
0.09573580424868154
iter/sec (stddev: 0
)1.7481144662555637
iter/sec (stddev: 0
)18.26
tests/benchmark_otanalytics.py::TestBenchmarkCreateEvents::test_15min_filtered
0.09532985206375033
iter/sec (stddev: 0
)1.8067530702358026
iter/sec (stddev: 0
)18.95
tests/benchmark_otanalytics.py::TestBenchmarkExportCounting::test_15min
0.09506526346554196
iter/sec (stddev: 0
)1.679762755011821
iter/sec (stddev: 0
)17.67
tests/benchmark_otanalytics.py::TestBenchmarkExportCounting::test_15min_filtered
0.09520509242000907
iter/sec (stddev: 0
)1.7493861915549835
iter/sec (stddev: 0
)18.37
tests/benchmark_otanalytics.py::TestPipelineBenchmark::test_15min
0.04307626652336649
iter/sec (stddev: 0
)0.21077117859830163
iter/sec (stddev: 0
)4.89
tests/benchmark_otanalytics.py::TestPipelineBenchmark::test_15min_filtered
0.0444422963791822
iter/sec (stddev: 0
)0.210588313015426
iter/sec (stddev: 0
)4.74
This comment was automatically generated by workflow using github-action-benchmark.