Skip to content

Commit ac95130

Browse files
authored
Merge pull request #441 from mapswipe/feature-tutorial-for-footprint-type
add workflow to create footprint project tutorial
2 parents aec66b3 + a1d63c1 commit ac95130

File tree

9 files changed

+233
-7
lines changed

9 files changed

+233
-7
lines changed

mapswipe_workers/mapswipe_workers/definitions.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,9 @@ def constructor(self):
145145
@property
146146
def tutorial(self):
147147
# Imports are first made once this method get called to avoid circular imports.
148+
from mapswipe_workers.project_types.arbitrary_geometry.tutorial import (
149+
Tutorial as ArbitraryGeometriesTutorial,
150+
)
148151
from mapswipe_workers.project_types.tile_map_service_grid.tutorial import (
149152
Tutorial as tmsg_tutorial,
150153
)
@@ -156,7 +159,7 @@ def tutorial(self):
156159

157160
project_type_classes = {
158161
1: tmsg_tutorial,
159-
# 2: ArbitraryGeometriesTutorial,
162+
2: ArbitraryGeometriesTutorial,
160163
3: tmsg_tutorial,
161164
4: tmsg_tutorial,
162165
}

mapswipe_workers/mapswipe_workers/project_types/arbitrary_geometry/group.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@ def __init__(self, project: object, groupId: int) -> None:
99
super().__init__(project, groupId)
1010

1111
def create_tasks(
12-
self, feature_ids: List, feature_geometries: List, center_points: List
12+
self,
13+
feature_ids: List,
14+
feature_geometries: List,
15+
center_points: List,
16+
reference: List,
17+
screen: List,
1318
) -> None:
1419
"""Create tasks for a group
1520
@@ -19,6 +24,13 @@ def create_tasks(
1924
Every coordinate pair is a vertex.
2025
"""
2126
for i in range(0, len(feature_ids)):
22-
task = Task(self, feature_ids[i], feature_geometries[i], center_points[i])
27+
task = Task(
28+
self,
29+
feature_ids[i],
30+
feature_geometries[i],
31+
center_points[i],
32+
reference[i],
33+
screen[i],
34+
)
2335
self.tasks.append(task)
2436
self.numberOfTasks = len(self.tasks)

mapswipe_workers/mapswipe_workers/project_types/arbitrary_geometry/grouping_functions.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ def group_input_geometries(input_geometries_file, group_size):
6666
"feature_ids": [],
6767
"feature_geometries": [],
6868
"center_points": [],
69+
"reference": [],
70+
"screen": [],
6971
}
7072

7173
groups[group_id_string]["feature_ids"].append(feature.GetFID())
@@ -79,6 +81,16 @@ def group_input_geometries(input_geometries_file, group_size):
7981
except: # noqa
8082
groups[group_id_string]["center_points"].append([])
8183

84+
# this is relevant for the tutorial
85+
try:
86+
reference = feature.GetFieldAsDouble("reference")
87+
screen = feature.GetFieldAsDouble("screen")
88+
groups[group_id_string]["reference"].append(reference)
89+
groups[group_id_string]["screen"].append(screen)
90+
except: # noqa
91+
groups[group_id_string]["reference"].append(None)
92+
groups[group_id_string]["screen"].append(None)
93+
8294
return groups
8395

8496

mapswipe_workers/mapswipe_workers/project_types/arbitrary_geometry/project.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,11 @@ def create_groups(self):
145145
for group_id, item in raw_groups.items():
146146
group = Group(self, group_id)
147147
group.create_tasks(
148-
item["feature_ids"], item["feature_geometries"], item["center_points"]
148+
item["feature_ids"],
149+
item["feature_geometries"],
150+
item["center_points"],
151+
item["reference"],
152+
item["screen"],
149153
)
150154

151155
# only append valid groups

mapswipe_workers/mapswipe_workers/project_types/arbitrary_geometry/task.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@
77

88
class Task(BaseTask):
99
def __init__(
10-
self, group: object, featureId: int, featureGeometry: Dict, center: List
10+
self,
11+
group: object,
12+
featureId: int,
13+
featureGeometry: Dict,
14+
center: List,
15+
reference: int,
16+
screen: int,
1117
):
1218
"""
1319
Parameters
@@ -21,7 +27,13 @@ def __init__(
2127
task_id = f"t{featureId}"
2228
super().__init__(group, taskId=task_id)
2329
self.geojson = featureGeometry
24-
self.center = center
30+
31+
if center is not None:
32+
self.center = center
33+
34+
if screen is not None:
35+
self.screen = screen
36+
self.reference = reference
2537

2638
# Remove projectId and groupId for tasks of Footprint project type
2739
del self.projectId
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import json
2+
3+
from mapswipe_workers.definitions import DATA_PATH, logger
4+
from mapswipe_workers.project_types.arbitrary_geometry import grouping_functions as g
5+
from mapswipe_workers.project_types.arbitrary_geometry.group import Group
6+
from mapswipe_workers.project_types.base.tile_server import BaseTileServer
7+
from mapswipe_workers.project_types.base.tutorial import BaseTutorial
8+
9+
10+
class Tutorial(BaseTutorial):
11+
"""The subclass for an TMS Grid based Tutorial."""
12+
13+
def __init__(self, tutorial_draft):
14+
# this will create the basis attributes
15+
super().__init__(tutorial_draft)
16+
17+
self.projectType = tutorial_draft["projectType"]
18+
self.zoomLevel = int(tutorial_draft.get("zoomLevel", 18))
19+
self.tileServer = vars(BaseTileServer(tutorial_draft["tileServer"]))
20+
self.tutorial_tasks = tutorial_draft["tutorialTasks"]
21+
self.groups = dict()
22+
self.tasks = []
23+
24+
# save tasks as geojson
25+
self.inputGeometries = (
26+
f"{DATA_PATH}/" f"input_geometries/valid_input_{self.projectId}.geojson"
27+
)
28+
29+
with open(self.inputGeometries, "w") as f:
30+
json.dump(self.tutorial_tasks, f)
31+
32+
def create_tutorial_groups(self):
33+
"""Create group for the tutorial based on provided examples in geojson file."""
34+
# load examples/tasks from file
35+
36+
# create the groups dict to be uploaded in Firebase
37+
self.groups = dict()
38+
39+
group = Group(self, groupId=101)
40+
self.groups[101] = vars(group)
41+
42+
logger.info(
43+
f"{self.projectId}"
44+
f" - create_tutorial_groups - "
45+
f"created groups dictionary"
46+
)
47+
48+
def create_tutorial_tasks(self):
49+
"""Create the tasks dict based on provided examples in geojson file."""
50+
51+
raw_groups = g.group_input_geometries(
52+
self.inputGeometries, len(self.tutorial_tasks) + 1
53+
)
54+
for group_id, item in raw_groups.items():
55+
group = Group(self, groupId=101)
56+
group.create_tasks(
57+
item["feature_ids"],
58+
item["feature_geometries"],
59+
item["center_points"],
60+
item["reference"],
61+
item["screen"],
62+
)
63+
64+
for task in group.tasks:
65+
logger.info(task)
66+
self.tasks.append(vars(task))
67+
68+
logger.info(
69+
f"{self.projectId}"
70+
f" - create_tutorial_tasks - "
71+
f"created tasks dictionary"
72+
)

mapswipe_workers/mapswipe_workers/project_types/base/tutorial.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
import base64
2+
import json
13
from abc import ABCMeta, abstractmethod
24

35
from mapswipe_workers import auth
4-
from mapswipe_workers.definitions import CustomError, logger
6+
from mapswipe_workers.definitions import CustomError, ProjectType, logger
7+
from mapswipe_workers.utils import gzip_str
58

69

710
class BaseTutorial(metaclass=ABCMeta):
@@ -46,6 +49,15 @@ def save_tutorial(self):
4649
Project Id is invalid: {self.projectId}"""
4750
)
4851

52+
if self.projectType in [ProjectType.FOOTPRINT.value]:
53+
# we compress tasks for footprint project type using gzip
54+
json_string_tasks = json.dumps(tasks).replace(" ", "").replace("\n", "")
55+
compressed_tasks = gzip_str.gzip_str(json_string_tasks)
56+
# we need to decode back, but only when using Python 3.6
57+
# when using Python 3.7 it just works
58+
# Unfortunately the docker image uses Python 3.7
59+
tasks = {"101": base64.b64encode(compressed_tasks).decode("ascii")}
60+
4961
ref.update(
5062
{
5163
f"v2/projects/{self.projectId}": tutorial,
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
{
2+
"1": {
3+
"hint" : {
4+
"description" : "Can you see a building?",
5+
"icon" : "swipe-left",
6+
"title" : "You are looking for buildings."
7+
},
8+
"instructions" : {
9+
"description" : "Tap on the yes button.",
10+
"icon" : "tap",
11+
"title" : "There is a part of a building here."
12+
},
13+
"success" : {
14+
"description" : "Swipe to the next screen to look for more.",
15+
"icon" : "check",
16+
"title" : "You found your first building!"
17+
}
18+
},
19+
"2": {
20+
"hint" : {
21+
"description" : "Check the imagery.",
22+
"icon" : "swipe-left",
23+
"title" : "Still looking for buildings"
24+
},
25+
"instructions" : {
26+
"description" : "Again select 'YES' if you see a building",
27+
"icon" : "tap",
28+
"title" : "Building Building Buildings"
29+
},
30+
"success" : {
31+
"description" : "Swipe to the next screen to learn more.",
32+
"icon" : "check",
33+
"title" : "Nice. You got it know!"
34+
}
35+
},
36+
"3": {
37+
"hint" : {
38+
"description" : "Here we can't find any building",
39+
"icon" : "swipe-left",
40+
"title" : "There is no building?"
41+
},
42+
"instructions" : {
43+
"description" : "Select 'No'.",
44+
"icon" : "tap",
45+
"title" : "Nothing to map here."
46+
},
47+
"success" : {
48+
"description" : "Swipe to keep on going",
49+
"icon" : "check",
50+
"title" : "Great work!"
51+
}
52+
},
53+
"4": {
54+
"hint" : {
55+
"description" : "There's no building in this screen.",
56+
"icon" : "swipe-left",
57+
"title" : "This is easy."
58+
},
59+
"instructions" : {
60+
"description" : "Again select 'No'.",
61+
"icon" : "tap",
62+
"title" : "There’s no building in this image"
63+
},
64+
"success" : {
65+
"description" : "Swipe to keep on going",
66+
"icon" : "check",
67+
"title" : "Great stuff!"
68+
}
69+
},
70+
"5": {
71+
"hint" : {
72+
"description" : "This one was difficult to judge.",
73+
"icon" : "swipe-left",
74+
"title" : "We’ve marked the correct answers"
75+
},
76+
"instructions" : {
77+
"description" : "Select 'Not sure' if you can't say if there is a building.",
78+
"icon" : "tap",
79+
"title" : "This one is difficult to decide."
80+
},
81+
"success" : {
82+
"description" : "Swipe to practice some more.",
83+
"icon" : "check",
84+
"title" : "Well done, you got it right!"
85+
}
86+
}
87+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"type": "FeatureCollection",
3+
"name": "tutorial_tasks",
4+
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
5+
"features": [
6+
{ "type": "Feature", "properties": { "id": 1543, "reference": 1, "screen": 1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 36.952541, -1.196843 ], [ 36.9526309, -1.196843 ], [ 36.9526309, -1.1967531 ], [ 36.952541, -1.1967531 ], [ 36.952541, -1.196843 ] ] ] } },
7+
{ "type": "Feature", "properties": { "id": 1599, "reference": 0, "screen": 3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 36.9537088, -1.1994481 ], [ 36.9537987, -1.1994481 ], [ 36.9537987, -1.1993582 ], [ 36.9537088, -1.1993582 ], [ 36.9537088, -1.1994481 ] ] ] } },
8+
{ "type": "Feature", "properties": { "id": 1621, "reference": 1, "screen": 2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 36.9532597, -1.1998972 ], [ 36.9533495, -1.1998972 ], [ 36.9533495, -1.1998074 ], [ 36.9532597, -1.1998074 ], [ 36.9532597, -1.1998972 ] ] ] } },
9+
{ "type": "Feature", "properties": { "id": 1639, "reference": 0, "screen": 4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 36.9483189, -1.1999871 ], [ 36.9484088, -1.1999871 ], [ 36.9484088, -1.1998972 ], [ 36.9483189, -1.1998972 ], [ 36.9483189, -1.1999871 ] ] ] } },
10+
{ "type": "Feature", "properties": { "id": 1641, "reference": 2, "screen": 5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 36.9483189, -1.2001667 ], [ 36.9484088, -1.2001667 ], [ 36.9484088, -1.2000769 ], [ 36.9483189, -1.2000769 ], [ 36.9483189, -1.2001667 ] ] ] } }
11+
]
12+
}

0 commit comments

Comments
 (0)