Skip to content

Commit d8a5833

Browse files
committed
Merge branch 'dev' into improve-ressource-usage
2 parents c6d5141 + 2a458b5 commit d8a5833

File tree

7 files changed

+80
-45
lines changed

7 files changed

+80
-45
lines changed

manager-dashboard/app/views/NewProject/index.tsx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ const defaultProjectFormValue: PartialProjectFormType = {
108108
// maxTasksPerUser: -1,
109109
inputType: PROJECT_INPUT_TYPE_UPLOAD,
110110
filter: FILTER_BUILDINGS,
111-
isPano: false,
111+
randomizeOrder: false,
112+
panoOnly: false,
112113
};
113114

114115
interface Props {
@@ -320,6 +321,7 @@ function NewProject(props: Props) {
320321

321322
valuesToCopy.startTimestamp = valuesToCopy.dateRange?.startDate ?? null;
322323
valuesToCopy.endTimestamp = valuesToCopy.dateRange?.endDate ?? null;
324+
valuesToCopy.isPano = valuesToCopy.panoOnly ? true : null;
323325

324326
const storage = getStorage();
325327
const timestamp = (new Date()).getTime();
@@ -756,12 +758,19 @@ function NewProject(props: Props) {
756758
disabled={submissionPending || projectTypeEmpty}
757759
/>
758760
<Checkbox
759-
name={'isPano' as const}
760-
value={value?.isPano}
761+
name={'panoOnly' as const}
762+
value={value?.panoOnly}
761763
label="Only use 360 degree panorama images."
762764
onChange={setFieldValue}
763765
disabled={submissionPending || projectTypeEmpty}
764766
/>
767+
<Checkbox
768+
name={'randomizeOrder' as const}
769+
value={value?.randomizeOrder}
770+
label="Randomize the order of images in the project."
771+
onChange={setFieldValue}
772+
disabled={submissionPending || projectTypeEmpty}
773+
/>
765774
</div>
766775
</InputSection>
767776
)}

manager-dashboard/app/views/NewProject/utils.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ export interface ProjectFormType {
8383
endTimestamp?: string | null;
8484
organizationId?: number;
8585
creatorId?: number;
86-
isPano?: boolean;
86+
randomizeOrder?: boolean;
87+
panoOnly?: boolean;
88+
isPano?: boolean | null;
8789
samplingThreshold?: number;
8890
}
8991

@@ -305,9 +307,15 @@ export const projectFormSchema: ProjectFormSchema = {
305307
greaterThanCondition(0),
306308
],
307309
},
310+
panoOnly: {
311+
required: false,
312+
},
308313
isPano: {
309314
required: false,
310315
},
316+
randomizeOrder: {
317+
required: false,
318+
},
311319
};
312320

313321
baseSchema = addCondition(

mapswipe_workers/mapswipe_workers/project_types/street/project.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ def __init__(self, project_draft):
5151
start_time=project_draft.get("startTimestamp", None),
5252
end_time=project_draft.get("endTimestamp", None),
5353
organization_id=project_draft.get("organizationId", None),
54+
randomize_order=project_draft.get("randomizeOrder", None),
5455
sampling_threshold=project_draft.get("samplingThreshold", None),
5556
)
5657

mapswipe_workers/mapswipe_workers/utils/process_mapillary.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ def create_tiles(polygon, level):
1919
if isinstance(polygon, Polygon):
2020
polygon = MultiPolygon([polygon])
2121

22-
tiles = []
22+
tiles = set()
2323
for i, poly in enumerate(polygon.geoms):
24-
tiles.extend(list(mercantile.tiles(*poly.bounds, level)))
24+
tiles.update(list(mercantile.tiles(*poly.bounds, level)))
2525

2626
bbox_list = [mercantile.bounds(tile.x, tile.y, tile.z) for tile in tiles]
2727
bbox_polygons = [box(*bbox) for bbox in bbox_list]
@@ -212,6 +212,7 @@ def get_image_metadata(
212212
organization_id: str = None,
213213
start_time: str = None,
214214
end_time: str = None,
215+
randomize_order=False,
215216
sampling_threshold=None,
216217
):
217218
kwargs = {
@@ -231,6 +232,9 @@ def get_image_metadata(
231232
if sampling_threshold is not None:
232233
downloaded_metadata = spatial_sampling(downloaded_metadata, sampling_threshold)
233234

235+
if randomize_order is True:
236+
downloaded_metadata = downloaded_metadata.sample(frac=1).reset_index(drop=True)
237+
234238
total_images = len(downloaded_metadata)
235239
if total_images > 100000:
236240
raise ValueError(

mapswipe_workers/mapswipe_workers/utils/spatial_sampling.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,11 @@ def spatial_sampling(df, interval_length):
141141
for sequence in sorted_df["sequence_id"].unique():
142142
sequence_df = sorted_df[sorted_df["sequence_id"] == sequence]
143143

144-
filtered_sorted_sub_df = filter_points(sequence_df, interval_length)
145-
sampled_sequence_df = pd.concat(
146-
[sampled_sequence_df, filtered_sorted_sub_df], axis=0
147-
)
144+
if interval_length:
145+
sequence_df = filter_points(sequence_df, interval_length)
146+
sampled_sequence_df = pd.concat([sampled_sequence_df, sequence_df], axis=0)
147+
148+
# reverse order such that sequence are in direction of travel
149+
sampled_sequence_df = sampled_sequence_df.iloc[::-1]
148150

149151
return sampled_sequence_df

mapswipe_workers/tests/unittests/test_process_mapillary.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,6 @@ def setUpClass(cls):
4848
def setUp(self):
4949
self.level = 14
5050
self.test_polygon = Polygon([(0, 0), (1, 0), (1, 1), (0, 1)])
51-
self.test_multipolygon = MultiPolygon(
52-
[self.test_polygon, Polygon([(2, 2), (3, 2), (3, 3), (2, 3)])]
53-
)
5451
self.empty_polygon = Polygon()
5552
self.empty_geometry = GeometryCollection()
5653
self.row = pd.Series({"x": 1, "y": 1, "z": self.level})
@@ -61,9 +58,19 @@ def test_create_tiles_with_valid_polygon(self):
6158
self.assertFalse(tiles.empty)
6259

6360
def test_create_tiles_with_multipolygon(self):
64-
tiles = create_tiles(self.test_multipolygon, self.level)
61+
polygon = Polygon(
62+
[
63+
(0.00000000, 0.00000000),
64+
(0.000000001, 0.00000000),
65+
(0.00000000, 0.000000001),
66+
(0.00000000, 0.000000001),
67+
]
68+
)
69+
multipolygon = MultiPolygon([polygon, polygon])
70+
tiles = create_tiles(multipolygon, self.level)
6571
self.assertIsInstance(tiles, pd.DataFrame)
6672
self.assertFalse(tiles.empty)
73+
self.assertEqual(len(tiles), 1)
6774

6875
def test_create_tiles_with_empty_polygon(self):
6976
tiles = create_tiles(self.empty_polygon, self.level)
@@ -312,12 +319,13 @@ def test_get_image_metadata_empty_response(self, mock_coordinate_download):
312319
with self.assertRaises(ValueError):
313320
get_image_metadata(self.fixture_data)
314321

322+
@patch("mapswipe_workers.utils.process_mapillary.filter_results")
315323
@patch("mapswipe_workers.utils.process_mapillary.coordinate_download")
316-
def test_get_image_metadata_size_restriction(self, mock_coordinate_download):
317-
mock_coordinate_download.return_value = pd.DataFrame(
318-
{"geometry": range(1, 100002)}
319-
)
320-
324+
def test_get_image_metadata_size_restriction(
325+
self, mock_coordinate_download, mock_filter_results
326+
):
327+
mock_df = pd.DataFrame({"id": range(1, 100002), "geometry": range(1, 100002)})
328+
mock_coordinate_download.return_value = mock_df
321329
with self.assertRaises(ValueError):
322330
get_image_metadata(self.fixture_data)
323331

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,32 @@
11
import os
2-
32
import unittest
3+
44
import numpy as np
55
import pandas as pd
66
from shapely import wkt
77
from shapely.geometry import Point
88

9-
from mapswipe_workers.utils.spatial_sampling import distance_on_sphere, filter_points, spatial_sampling
9+
from mapswipe_workers.utils.spatial_sampling import (
10+
distance_on_sphere,
11+
filter_points,
12+
spatial_sampling,
13+
)
1014

1115

1216
class TestDistanceCalculations(unittest.TestCase):
13-
1417
@classmethod
1518
def setUpClass(cls):
1619
with open(
17-
os.path.join(
18-
os.path.dirname(os.path.abspath(__file__)),
19-
"..",
20-
"fixtures",
21-
"mapillary_sequence.csv",
22-
),
23-
"r",
20+
os.path.join(
21+
os.path.dirname(os.path.abspath(__file__)),
22+
"..",
23+
"fixtures",
24+
"mapillary_sequence.csv",
25+
),
26+
"r",
2427
) as file:
2528
df = pd.read_csv(file)
26-
df['geometry'] = df['geometry'].apply(wkt.loads)
29+
df["geometry"] = df["geometry"].apply(wkt.loads)
2730

2831
cls.fixture_df = df
2932

@@ -42,41 +45,43 @@ def test_filter_points(self):
4245
"POINT (-74.006 40.7128)",
4346
"POINT (-75.006 41.7128)",
4447
"POINT (-76.006 42.7128)",
45-
"POINT (-77.006 43.7128)"
48+
"POINT (-77.006 43.7128)",
4649
]
4750
}
4851
df = pd.DataFrame(data)
4952

50-
df['geometry'] = df['geometry'].apply(wkt.loads)
53+
df["geometry"] = df["geometry"].apply(wkt.loads)
5154

52-
df['long'] = df['geometry'].apply(lambda geom: geom.x if geom.geom_type == 'Point' else None)
53-
df['lat'] = df['geometry'].apply(lambda geom: geom.y if geom.geom_type == 'Point' else None)
55+
df["long"] = df["geometry"].apply(
56+
lambda geom: geom.x if geom.geom_type == "Point" else None
57+
)
58+
df["lat"] = df["geometry"].apply(
59+
lambda geom: geom.y if geom.geom_type == "Point" else None
60+
)
5461
threshold_distance = 100
5562
filtered_df = filter_points(df, threshold_distance)
5663

5764
self.assertIsInstance(filtered_df, pd.DataFrame)
5865
self.assertLessEqual(len(filtered_df), len(df))
5966

60-
6167
def test_spatial_sampling_ordering(self):
6268
data = {
6369
"geometry": [
6470
"POINT (-74.006 40.7128)",
6571
"POINT (-75.006 41.7128)",
6672
"POINT (-76.006 42.7128)",
67-
"POINT (-77.006 43.7128)"
73+
"POINT (-77.006 43.7128)",
6874
],
69-
'captured_at': [1, 2, 3, 4],
70-
'sequence_id': ['1', '1', '1', '1']
75+
"captured_at": [1, 2, 3, 4],
76+
"sequence_id": ["1", "1", "1", "1"],
7177
}
7278
df = pd.DataFrame(data)
73-
df['geometry'] = df['geometry'].apply(wkt.loads)
79+
df["geometry"] = df["geometry"].apply(wkt.loads)
7480

7581
interval_length = 0.1
7682
filtered_gdf = spatial_sampling(df, interval_length)
7783

78-
self.assertTrue(filtered_gdf['captured_at'].is_monotonic_increasing)
79-
84+
self.assertTrue(filtered_gdf["captured_at"].is_monotonic_decreasing)
8085

8186
def test_spatial_sampling_with_sequence(self):
8287
threshold_distance = 0.01
@@ -86,15 +91,13 @@ def test_spatial_sampling_with_sequence(self):
8691

8792
filtered_df.reset_index(drop=True, inplace=True)
8893
for i in range(len(filtered_df) - 1):
89-
geom1 = filtered_df.loc[i, 'geometry']
90-
geom2 = filtered_df.loc[i + 1, 'geometry']
94+
geom1 = filtered_df.loc[i, "geometry"]
95+
geom2 = filtered_df.loc[i + 1, "geometry"]
9196

9297
distance = geom1.distance(geom2)
9398

9499
self.assertLess(distance, threshold_distance)
95100

96101

97-
98-
99102
if __name__ == "__main__":
100103
unittest.main()

0 commit comments

Comments
 (0)