diff --git a/mapswipe_workers/mapswipe_workers/definitions.py b/mapswipe_workers/mapswipe_workers/definitions.py index aa32d3aac..12a29f9db 100644 --- a/mapswipe_workers/mapswipe_workers/definitions.py +++ b/mapswipe_workers/mapswipe_workers/definitions.py @@ -137,6 +137,7 @@ class ProjectType(Enum): MEDIA_CLASSIFICATION = 5 DIGITIZATION = 6 STREET = 7 + CONFLATION = 8 @property def constructor(self): @@ -145,6 +146,7 @@ def constructor(self): ChangeDetectionProject, ClassificationProject, CompletenessProject, + ConflationProject, DigitizationProject, FootprintProject, MediaClassificationProject, @@ -159,6 +161,7 @@ def constructor(self): 5: MediaClassificationProject, 6: DigitizationProject, 7: StreetProject, + 8: ConflationProject, } return project_type_classes[self.value] diff --git a/mapswipe_workers/mapswipe_workers/project_types/__init__.py b/mapswipe_workers/mapswipe_workers/project_types/__init__.py index 9560c76ef..31282a02f 100644 --- a/mapswipe_workers/mapswipe_workers/project_types/__init__.py +++ b/mapswipe_workers/mapswipe_workers/project_types/__init__.py @@ -1,3 +1,4 @@ +from .arbitrary_geometry.conflation.project import ConflationProject from .arbitrary_geometry.digitization.project import DigitizationProject from .arbitrary_geometry.footprint.project import FootprintProject from .arbitrary_geometry.footprint.tutorial import FootprintTutorial @@ -24,4 +25,5 @@ "DigitizationProject", "StreetProject", "StreetTutorial", + "ConflationProject", ] diff --git a/mapswipe_workers/mapswipe_workers/project_types/arbitrary_geometry/conflation/__init__.py b/mapswipe_workers/mapswipe_workers/project_types/arbitrary_geometry/conflation/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/mapswipe_workers/mapswipe_workers/project_types/arbitrary_geometry/conflation/project.py b/mapswipe_workers/mapswipe_workers/project_types/arbitrary_geometry/conflation/project.py new file mode 100644 index 000000000..586bb24dd --- /dev/null +++ b/mapswipe_workers/mapswipe_workers/project_types/arbitrary_geometry/conflation/project.py @@ -0,0 +1,41 @@ +import urllib + +from mapswipe_workers.firebase.firebase import Firebase +from mapswipe_workers.firebase_to_postgres.transfer_results import ( + results_to_file, + save_results_to_postgres, + truncate_temp_results, +) +from mapswipe_workers.generate_stats.project_stats import ( + get_statistics_for_integer_result_project, +) +from mapswipe_workers.project_types.arbitrary_geometry.project import ( + ArbitraryGeometryProject, +) + + +class ConflationProject(ArbitraryGeometryProject): + def __init__(self, project_draft): + super().__init__(project_draft) + + def handle_input_type(self, raw_input_file: str): + urllib.request.urlretrieve(self.geometry, raw_input_file) + + def save_tasks_to_firebase(self, projectId: str, tasks: dict): + firebase = Firebase() + firebase.save_tasks_to_firebase(projectId, tasks, useCompression=True) + + @staticmethod + def results_to_postgres(results: dict, project_id: str, filter_mode: bool): + """How to move the result data from firebase to postgres.""" + results_file, user_group_results_file = results_to_file(results, project_id) + truncate_temp_results() + save_results_to_postgres(results_file, project_id, filter_mode) + return user_group_results_file + + @staticmethod + def get_per_project_statistics(project_id, project_info): + """How to aggregate the project results.""" + return get_statistics_for_integer_result_project( + project_id, project_info, generate_hot_tm_geometries=False + ) diff --git a/mapswipe_workers/tests/fixtures/projectDrafts/conflation.json b/mapswipe_workers/tests/fixtures/projectDrafts/conflation.json new file mode 100644 index 000000000..1ace4d890 --- /dev/null +++ b/mapswipe_workers/tests/fixtures/projectDrafts/conflation.json @@ -0,0 +1,25 @@ +{ + "createdBy": "atCSosZACaN0qhcVjtMO1tq9d1G3", + "geometry": "https://firebasestorage.googleapis.com/v0/b/dev-mapswipe.appspot.com/o/all_predictions_192.geojson?alt=media&token=b7a85e56-6ab1-4e0d-a734-a772025a88b8", + "filter": "way['building']", + "groupSize": 25, + "image": "https://firebasestorage.googleapis.com/v0/b/dev-mapswipe.appspot.com/o/projectImages%2F1742895229710-project-image-1x1.png?alt=media&token=26cf1956-9ab7-4348-b529-9952f2f8424e", + "lookFor": "Buildings", + "manualUrl": "https://fair-dev.hotosm.org/start-mapping/358", + "name": "Conflate fAIr buildings - Kathmandu (1)\nHOT", + "projectDetails": "This is a test.", + "projectNumber": 1, + "projectRegion": "Kathmandu", + "projectTopic": "Conflate fAIr buildings", + "projectTopicKey": "conflate fair buildings - kathmandu (1) hot", + "projectType": 8, + "requestingOrganisation": "HOT", + "tileServer": { + "credits": "Please add imagery credits here.", + "name": "custom", + "url": "https://2glp8ghj65.execute-api.us-east-1.amazonaws.com/cog/tiles/WebMercatorQuad/{z}/{x}/{y}@1x?url=https%3A%2F%2Foin-hotosm-temp.s3.us-east-1.amazonaws.com%2F62d85d11d8499800053796c1%2F0%2F62d85d11d8499800053796c2.tif", + "wmtsLayerName": "-" + }, + "tutorialId": "tutorial_-MQsj5VWpNcJxCTVTOyH", + "verificationNumber": 3 +} diff --git a/mapswipe_workers/tests/integration/test_create_arbitrary_geometry_conflation_project.py b/mapswipe_workers/tests/integration/test_create_arbitrary_geometry_conflation_project.py new file mode 100644 index 000000000..d6509c7ff --- /dev/null +++ b/mapswipe_workers/tests/integration/test_create_arbitrary_geometry_conflation_project.py @@ -0,0 +1,52 @@ +import unittest + +from click.testing import CliRunner + +from mapswipe_workers import auth, mapswipe_workers +from mapswipe_workers.utils.create_directories import create_directories +from tests.integration import set_up, tear_down + + +class TestCreateConflationProject(unittest.TestCase): + def setUp(self): + self.project_id = set_up.create_test_project_draft("conflation", "conflation") + + create_directories() + + def tearDown(self): + tear_down.delete_test_data(self.project_id) + + def test_create_footprint_project(self): + runner = CliRunner() + result = runner.invoke( + mapswipe_workers.run_create_projects, catch_exceptions=False + ) + if result.exit_code != 0: + raise result.exception + pg_db = auth.postgresDB() + + query = """ + SELECT project_id, project_type_specifics + FROM projects + WHERE project_id = %s + """ + result = pg_db.retr_query(query, [self.project_id])[0] + self.assertEqual(result[0], self.project_id) + + fb_db = auth.firebaseDB() + ref = fb_db.reference(f"/v2/projects/{self.project_id}") + result = ref.get(shallow=True) + self.assertIsNotNone(result) + + ref = fb_db.reference(f"/v2/groups/{self.project_id}") + result = ref.get(shallow=True) + self.assertIsNotNone(result) + + # Footprint projects have tasks in Firebase + ref = fb_db.reference(f"/v2/tasks/{self.project_id}") + result = ref.get(shallow=True) + self.assertIsNotNone(result) + + +if __name__ == "__main__": + unittest.main() diff --git a/mapswipe_workers/tests/unittests/test_project_type_arbitrary_geometry_conflation.py b/mapswipe_workers/tests/unittests/test_project_type_arbitrary_geometry_conflation.py new file mode 100644 index 000000000..75c435c78 --- /dev/null +++ b/mapswipe_workers/tests/unittests/test_project_type_arbitrary_geometry_conflation.py @@ -0,0 +1,38 @@ +import os +import unittest + +from mapswipe_workers.project_types import ConflationProject +from tests import fixtures + + +class TestCreateConflationProject(unittest.TestCase): + def setUp(self) -> None: + project_draft = fixtures.get_fixture( + os.path.join( + "projectDrafts", + "conflation.json", + ) + ) + project_draft["projectDraftId"] = "foo" + self.project = ConflationProject(project_draft) + + def test_init(self): + self.assertIsInstance(self.project.geometry, str) + + def test_create_groups(self): + self.project.validate_geometries() + self.project.create_groups() + # self.assertEqual(len(self.project.groups.keys()), 1) + # self.assertIsInstance(self.project.geometry, str) + + def test_create_tasks(self): + self.project.validate_geometries() + self.project.create_groups() + self.project.create_tasks() + # self.assertEqual(len(self.project.tasks.keys()), 1) + # self.assertEqual(len(self.project.tasks["g100"]), 1) + # self.assertTrue("POLYGON" in self.project.tasks["g100"][0].geometry) + + +if __name__ == "__main__": + unittest.main()