Skip to content

Commit faaea95

Browse files
committed
feat(locate): add new fields export meta and custom_options
1 parent 048b3d4 commit faaea95

File tree

8 files changed

+132
-6
lines changed

8 files changed

+132
-6
lines changed

apps/project/custom_options.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,31 @@ class CustomOptionDefaults:
9494
},
9595
]
9696

97+
# TODO(susilnem): verify the CustomOptions?
98+
Locate: list[CustomOption] = [
99+
{
100+
"title": "Single Feature",
101+
"icon": IconEnum.CHECKMARK_OUTLINE,
102+
"value": 1,
103+
"description": "the shape outlines a single feature in the image",
104+
"icon_color": "#388E3C",
105+
},
106+
{
107+
"title": "No",
108+
"icon": IconEnum.CLOSE_OUTLINE,
109+
"value": 0,
110+
"description": "the shape does not outline any feature in the image",
111+
"icon_color": "#D32F2F",
112+
},
113+
{
114+
"title": "Multiple Features",
115+
"icon": IconEnum.CHECKMARK_OUTLINE,
116+
"value": 2,
117+
"description": "the shape outlines multiple features in the image",
118+
"icon_color": "#388E3C",
119+
},
120+
]
121+
97122

98123
def get_custom_options(project_type: ProjectTypeEnum) -> list[CustomOption]:
99124
if project_type == ProjectTypeEnum.VALIDATE:
@@ -102,6 +127,8 @@ def get_custom_options(project_type: ProjectTypeEnum) -> list[CustomOption]:
102127
return CustomOptionDefaults.VALIDATE_IMAGE
103128
if project_type == ProjectTypeEnum.STREET:
104129
return CustomOptionDefaults.STREET
130+
if project_type == ProjectTypeEnum.LOCATE:
131+
return CustomOptionDefaults.Locate
105132
return []
106133

107134

@@ -113,13 +140,13 @@ def get_fallback_custom_options_for_export(project_type: ProjectTypeEnum) -> lis
113140
return [item["value"] for item in CustomOptionDefaults.VALIDATE_IMAGE]
114141
if project_type == ProjectTypeEnum.STREET:
115142
return [item["value"] for item in CustomOptionDefaults.STREET]
143+
if project_type == ProjectTypeEnum.LOCATE:
144+
return [item["value"] for item in CustomOptionDefaults.Locate]
116145

117146
if (
118147
project_type == ProjectTypeEnum.FIND
119148
or project_type == ProjectTypeEnum.COMPARE
120149
or project_type == ProjectTypeEnum.COMPLETENESS
121-
# TODO(susilnem): Verify custom options for locate? setting default for now.
122-
or project_type == ProjectTypeEnum.LOCATE
123150
):
124151
return [
125152
0, # No

apps/project/exports/exports.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
from project_types.tile_map_service.compare.project import CompareProjectProperty
2020
from project_types.tile_map_service.completeness.project import CompletenessProjectProperty
2121
from project_types.tile_map_service.find.project import FindProjectProperty
22-
from project_types.tile_map_service.locate.project import LocateProjectProperty
2322
from utils.geo.raster_tile_server.config import RasterTileServerNameEnum
2423

2524
from .mapping_results import generate_mapping_results
@@ -92,8 +91,7 @@ def _export_project_data(project: Project, tmp_directory: Path):
9291
if not isinstance(
9392
project_type_handler.project_type_specifics,
9493
# NOTE: Using negate test to throw type error if new project type is added
95-
# TODO(susilnem): verify Custom options for locate project type?
96-
(CompareProjectProperty | CompletenessProjectProperty | FindProjectProperty | LocateProjectProperty),
94+
(CompareProjectProperty | CompletenessProjectProperty | FindProjectProperty),
9795
):
9896
custom_options_raw = [
9997
{"value": custom_option.value}

apps/project/graphql/inputs/project_types/locate.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,9 @@
33
from project_types.tile_map_service.locate import project as locate_project
44

55

6+
@strawberry.experimental.pydantic.input(model=locate_project.ExportMeta, all_fields=True)
7+
class LocateExportMetaInput: ...
8+
9+
610
@strawberry.experimental.pydantic.input(model=locate_project.LocateProjectProperty, all_fields=True)
711
class LocateProjectPropertyInput: ...

apps/project/graphql/types/project_types/locate.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,9 @@
33
from project_types.tile_map_service.locate import project as locate_project
44

55

6+
@strawberry.experimental.pydantic.type(model=locate_project.ExportMeta, all_fields=True)
7+
class LocateExportMeta: ...
8+
9+
610
@strawberry.experimental.pydantic.type(model=locate_project.LocateProjectProperty, all_fields=True)
711
class LocateProjectPropertyType: ...

apps/project/tests/mutation_test.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1747,6 +1747,25 @@ def test_project_locate(self, mock_requests): # type: ignore[reportMissingParam
17471747
},
17481748
},
17491749
"subGridSize": self.genum(SubGridSizeEnum.SIZE_2X2),
1750+
"exportMeta": {
1751+
"key": "test1",
1752+
"value": "value1",
1753+
},
1754+
"customOptions": {
1755+
"clientId": str(ULID()),
1756+
"description": "Locate project description",
1757+
"icon": self.genum(IconEnum.ADD_OUTLINE),
1758+
"iconColor": "#FF0000",
1759+
"title": "Locate Project Title",
1760+
"value": 1,
1761+
"subOptions": [
1762+
{
1763+
"clientId": str(ULID()),
1764+
"value": 1,
1765+
"description": "Locate sub option description",
1766+
},
1767+
],
1768+
},
17501769
},
17511770
},
17521771
}
@@ -1760,6 +1779,7 @@ def test_project_locate(self, mock_requests): # type: ignore[reportMissingParam
17601779
assert latest_project.image_id == int(image_asset["id"])
17611780
assert latest_project.aoi_geometry_input_asset
17621781
assert latest_project.aoi_geometry_input_asset.id == int(aoi_geometry_asset["id"])
1782+
sub_options = project_data["projectTypeSpecifics"]["locate"]["customOptions"]["subOptions"] # type: ignore[index]
17631783
assert latest_project.project_type_specifics == {
17641784
"aoi_geometry": aoi_geometry_asset["id"],
17651785
"zoom_level": 15,
@@ -1771,6 +1791,27 @@ def test_project_locate(self, mock_requests): # type: ignore[reportMissingParam
17711791
},
17721792
},
17731793
"sub_grid_size": SubGridSizeEnum.SIZE_2X2.value,
1794+
"export_meta": {
1795+
"key": "test1",
1796+
"value": "value1",
1797+
},
1798+
"custom_options": [
1799+
{
1800+
"client_id": project_data["projectTypeSpecifics"]["locate"]["customOptions"]["clientId"], # type: ignore[index]
1801+
"description": "Locate project description",
1802+
"icon": IconEnum.ADD_OUTLINE.value,
1803+
"icon_color": "#FF0000",
1804+
"title": "Locate Project Title",
1805+
"value": 1,
1806+
"sub_options": [
1807+
{
1808+
"client_id": sub_options[0]["clientId"], # type: ignore[index]
1809+
"value": 1,
1810+
"description": "Locate sub option description",
1811+
},
1812+
],
1813+
},
1814+
],
17741815
}
17751816
locate_project.LocateProjectProperty.model_validate(
17761817
latest_project.project_type_specifics,

project_types/tile_map_service/locate/project.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import typing
22

33
from django.db import models
4+
from pydantic import BaseModel
45
from pyfirebase_mapswipe import models as firebase_models
56

67
from apps.project.models import Project, ProjectTypeEnum
78
from project_types.tile_map_service.base import project as tile_map_service_project
9+
from utils.custom_options.models import CustomOption
810

911

1012
class SubGridSizeEnum(models.TextChoices):
@@ -22,8 +24,21 @@ def to_firebase(self) -> firebase_models.FBEnumSubGridSize:
2224
return firebase_models.FBEnumSubGridSize.SIZE_8X8
2325

2426

27+
class ExportMeta(BaseModel):
28+
key: str
29+
value: str
30+
31+
def to_firebase(self) -> firebase_models.FbObjExportMeta:
32+
return firebase_models.FbObjExportMeta(
33+
key=self.key,
34+
value=self.value,
35+
)
36+
37+
2538
class LocateProjectProperty(tile_map_service_project.TileMapServiceProjectProperty):
2639
sub_grid_size: SubGridSizeEnum
40+
custom_options: list[CustomOption] | None = None
41+
export_meta: ExportMeta
2742

2843

2944
class LocateProjectTaskGroupProperty(tile_map_service_project.TileMapServiceProjectTaskGroupProperty): ...
@@ -69,14 +84,37 @@ def get_task_specifics_for_db(self, tile_x: int, tile_y: int) -> LocateProjectTa
6984
@typing.override
7085
def get_project_specifics_for_firebase(self):
7186
tsp = self.project_type_specifics.tile_server_property
87+
custom_opts = self.project_type_specifics.custom_options
7288
return firebase_models.FbProjectLocateCreateOnlyInput(
7389
zoomLevel=self.project_type_specifics.zoom_level,
7490
subGridSize=self.project_type_specifics.sub_grid_size.to_firebase(),
91+
exportMeta=self.project_type_specifics.export_meta.to_firebase(),
7592
tileServer=firebase_models.FbObjRasterTileServer(
7693
name=tsp.name.to_firebase(),
7794
credits=tsp.get_config()["credits"],
7895
url=tsp.get_config()["raw_url"],
7996
apiKey=tsp.get_config()["api_key"],
8097
wmtsLayerName=None,
8198
),
99+
customOptions=[
100+
firebase_models.FbObjCustomOption(
101+
title=opt.title,
102+
description=opt.description,
103+
value=opt.value,
104+
icon=str(opt.icon.label),
105+
iconColor=opt.icon_color,
106+
subOptions=[
107+
firebase_models.FbBaseObjCustomSubOption(
108+
value=sub_opt.value,
109+
description=sub_opt.description,
110+
)
111+
for sub_opt in opt.sub_options
112+
]
113+
if opt.sub_options is not None
114+
else None,
115+
)
116+
for opt in custom_opts
117+
]
118+
if custom_opts is not None
119+
else None,
82120
)

schema.graphql

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,9 +941,21 @@ input IntRangeLookup {
941941
start: Int = null
942942
}
943943

944+
type LocateExportMeta {
945+
key: String!
946+
value: String!
947+
}
948+
949+
input LocateExportMetaInput {
950+
key: String!
951+
value: String!
952+
}
953+
944954
input LocateProjectPropertyInput {
945955
"""Numeric value as string"""
946956
aoiGeometry: String!
957+
customOptions: [CustomOptionInput!] = null
958+
exportMeta: LocateExportMetaInput!
947959
subGridSize: SubGridSizeEnum!
948960
tileServerProperty: ProjectRasterTileServerConfigInput!
949961

@@ -954,6 +966,8 @@ input LocateProjectPropertyInput {
954966
type LocateProjectPropertyType {
955967
"""Numeric value as string"""
956968
aoiGeometry: String!
969+
customOptions: [ProjectCustomOption!]
970+
exportMeta: LocateExportMeta!
957971
subGridSize: SubGridSizeEnum!
958972
tileServerProperty: ProjectRasterTileServerConfig!
959973

0 commit comments

Comments
 (0)