diff --git a/CHANGELOG.md b/CHANGELOG.md index 266375283..387cde6b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,20 @@ # Changelog +## Current Main + +### Other Changes + +- road-comparison: covered Microsoft Roads are now calculated with tag `highway=* and type:way` ([#791]) +- comparison-indicators: now request metadata from database ([#791]) + + +[#791]: https://github.com/GIScience/ohsome-quality-api/pull/791 + ## Release 1.3.0 ### Breaking Changes -- major-roads-length: rename to `roads` and chnage filter to `highway=* and type:way` ([#786]) +- major-roads-length: rename to `roads` and change filter to `highway=* and type:way` ([#786]) ### New Features diff --git a/ohsome_quality_api/geodatabase/client.py b/ohsome_quality_api/geodatabase/client.py index ac08362a0..647a87de9 100644 --- a/ohsome_quality_api/geodatabase/client.py +++ b/ohsome_quality_api/geodatabase/client.py @@ -70,14 +70,14 @@ async def get_shdi(bpoly: Feature | FeatureCollection) -> list[Record]: # TODO: Check calls of the function -async def get_reference_coverage(table_name: str) -> Feature: +async def get_reference_coverage(table_name: str, coverage_type: str) -> Feature: """Get reference coverage for a bounding polygon.""" file_path = os.path.join(WORKING_DIR, "select_coverage.sql") with open(file_path, "r") as file: - query = file.read() + query = file.read().replace("{coverage_type}", coverage_type) async with get_connection() as conn: - result = await conn.fetch(query.format(table_name=table_name)) - return Feature(geometry=geojson.loads(result[0]["geom"])) + result = await conn.fetchrow(query, table_name) + return Feature(geometry=geojson.loads(result["geom"])) async def get_intersection_area(bpoly: Feature, table_name: str) -> float: @@ -91,7 +91,7 @@ async def get_intersection_area(bpoly: Feature, table_name: str) -> float: query = file.read() geom = str(bpoly.geometry) async with get_connection() as conn: - result = await conn.fetch(query.format(table_name=table_name), geom) + result = await conn.fetch(query, geom, table_name) if result: return result[0]["area_ratio"] else: @@ -105,7 +105,7 @@ async def get_intersection_geom(bpoly: Feature, table_name: str) -> Feature: query = file.read() geom = str(bpoly.geometry) async with get_connection() as conn: - result = await conn.fetch(query.format(table_name=table_name), geom) + result = await conn.fetch(query, geom, table_name) if result: return Feature(geometry=geojson.loads(result[0]["geom"])) else: diff --git a/ohsome_quality_api/geodatabase/select_coverage.sql b/ohsome_quality_api/geodatabase/select_coverage.sql index adb0454ce..6e03bd523 100644 --- a/ohsome_quality_api/geodatabase/select_coverage.sql +++ b/ohsome_quality_api/geodatabase/select_coverage.sql @@ -1,4 +1,8 @@ SELECT - ST_AsGeoJSON (ST_Transform (geom, 4326)) as geom + ST_AsGeoJSON (ST_Transform ({coverage_type}, 4326)) as geom FROM - {table_name}; + comparison_indicators_metadata +WHERE + dataset_name_snake_case like $1; + + diff --git a/ohsome_quality_api/geodatabase/select_intersection.sql b/ohsome_quality_api/geodatabase/select_intersection.sql index cca64f558..377932c71 100644 --- a/ohsome_quality_api/geodatabase/select_intersection.sql +++ b/ohsome_quality_api/geodatabase/select_intersection.sql @@ -1,13 +1,19 @@ WITH bpoly AS ( SELECT - ST_Setsrid (ST_GeomFromGeoJSON ($1), 4326) AS geom + ST_SetSRID(ST_GeomFromGeoJSON($1), 4326) AS geom +), +selected_coverage AS ( + SELECT coverage_simple AS coverage + FROM comparison_indicators_metadata + WHERE dataset_name_snake_case LIKE $2 ) SELECT -- ratio of area within coverage (empty if outside, between 0-1 if intersection) - ST_Area (ST_Intersection (bpoly.geom, coverage.geom)) / ST_Area (bpoly.geom) as area_ratio, - ST_AsGeoJSON (ST_Intersection (bpoly.geom, coverage.geom)) AS geom + ST_Area(ST_Intersection(bpoly.geom, selected_coverage.coverage)) / ST_Area(bpoly.geom) AS area_ratio, + ST_AsGeoJSON(ST_Intersection(bpoly.geom, selected_coverage.coverage)) AS geom FROM bpoly, - {table_name} coverage + selected_coverage WHERE - ST_Intersects (bpoly.geom, coverage.geom) + ST_Intersects(bpoly.geom, selected_coverage.coverage); + diff --git a/ohsome_quality_api/indicators/attribute_completeness/indicator.py b/ohsome_quality_api/indicators/attribute_completeness/indicator.py index cc615e199..137bc6ee7 100644 --- a/ohsome_quality_api/indicators/attribute_completeness/indicator.py +++ b/ohsome_quality_api/indicators/attribute_completeness/indicator.py @@ -41,6 +41,9 @@ def __init__(self, topic: Topic, feature: Feature, attribute_key: str) -> None: self.absolute_value_1 = None self.absolute_value_2 = None + async def init(self) -> None: + pass + async def preprocess(self) -> None: attribute = get_attribute(self.topic.key, self.attribute_key) # Get attribute filter diff --git a/ohsome_quality_api/indicators/base.py b/ohsome_quality_api/indicators/base.py index ee0b02f82..6703bae69 100644 --- a/ohsome_quality_api/indicators/base.py +++ b/ohsome_quality_api/indicators/base.py @@ -123,6 +123,14 @@ async def coverage(cls, inverse=False) -> list[Feature]: else: return [Feature(Polygon(coordinates=[]))] + @abstractmethod + async def init(self) -> None: + """Initialize the indicator. + + This method should be used to initialize data. + """ + pass + @abstractmethod async def preprocess(self) -> None: """Get fetch and preprocess data. diff --git a/ohsome_quality_api/indicators/building_comparison/datasets.yaml b/ohsome_quality_api/indicators/building_comparison/datasets.yaml deleted file mode 100644 index da92d159f..000000000 --- a/ohsome_quality_api/indicators/building_comparison/datasets.yaml +++ /dev/null @@ -1,25 +0,0 @@ -EUBUCCO: - name: EUBUCCO - link: https://docs.eubucco.com/ - date: Nov 3, 2022 - description: >- - EUBUCCO is a dataset of building footprints for Europe. - It is derived from administrative datasets. - color: PURPLE - coverage: - simple: eubucco_coverage_simple - inversed: eubucco_coverage_inversed - table_name: eubucco - -Microsoft Buildings: - name: Microsoft Building Footprints - link: https://planetarycomputer.microsoft.com/dataset/ms-buildings - date: July 5, 2022 - description: >- - Microsoft Building Footprints is a dataset of building footprints for the world. - It is derived from satellite imagery. - color: ORANGE - coverage: - simple: microsoft_buildings_coverage_simple - inversed: microsoft_buildings_coverage_inversed - table_name: microsoft_buildings diff --git a/ohsome_quality_api/indicators/building_comparison/indicator.py b/ohsome_quality_api/indicators/building_comparison/indicator.py index 76b5b33a1..62860969c 100644 --- a/ohsome_quality_api/indicators/building_comparison/indicator.py +++ b/ohsome_quality_api/indicators/building_comparison/indicator.py @@ -5,7 +5,6 @@ import geojson import plotly.graph_objects as pgo import psycopg -import yaml from async_lru import alru_cache from dateutil import parser from geojson import Feature @@ -42,25 +41,23 @@ def __init__( self.area_cov: dict[str, float | None] = {} self.ratio: dict[str, float | None] = {} # self.data_ref: list = load_reference_datasets() # reference datasets - for key, val in load_datasets_metadata().items(): - self.data_ref[key] = val - self.area_osm[key] = None # osm building area - self.area_ref[key] = None # reference building area [sqkm] - self.area_cov[key] = None # covered area [%] - self.ratio[key] = None @classmethod async def coverage(cls, inverse=False) -> list[Feature]: # TODO: could also return a Feature Collection features = [] - datasets = load_datasets_metadata() + datasets = await load_datasets_metadata() for val in datasets.values(): if inverse: - table = val["coverage"]["inversed"] + coverage_type = "coverage_inversed" else: - table = val["coverage"]["simple"] - feature = await db_client.get_reference_coverage(table) - feature.properties.update({"refernce_dataset": val["name"]}) + coverage_type = "coverage_simple" + feature = await db_client.get_reference_coverage( + val["dataset_name_snake_case"], coverage_type + ) + feature.properties.update( + {"refernce_dataset": val["dataset_name_snake_case"]} + ) features.append(feature) return features @@ -68,12 +65,21 @@ async def coverage(cls, inverse=False) -> list[Feature]: def attribution(cls) -> str: return get_attribution(["OSM", "EUBUCCO", "Microsoft Buildings"]) + async def init(self) -> None: + datasets_metadata = await load_datasets_metadata() + for key, val in datasets_metadata.items(): + self.data_ref[key] = val + self.area_osm[key] = None # osm building area + self.area_ref[key] = None # reference building area [sqkm] + self.area_cov[key] = None # covered area [%] + self.ratio[key] = None + async def preprocess(self) -> None: for key, val in self.data_ref.items(): # get coverage [%] self.area_cov[key] = await db_client.get_intersection_area( self.feature, - val["coverage"]["simple"], + val["dataset_name_snake_case"], ) if self.check_major_edge_cases(key) != "": continue @@ -81,12 +87,12 @@ async def preprocess(self) -> None: # clip input geom with coverage of reference dataset feature = await db_client.get_intersection_geom( self.feature, - val["coverage"]["simple"], + val["dataset_name_snake_case"], ) # get reference building area result = await get_reference_building_area( - geojson.dumps(feature), val["table_name"] + geojson.dumps(feature), val["dataset_name_snake_case"] ) self.area_ref[key] = result / (1000 * 1000) @@ -115,7 +121,7 @@ def calculate(self) -> None: description = template.substitute( ratio=round(self.ratio[key] * 100, 2), coverage=round(self.area_cov[key] * 100, 2), - dataset=self.data_ref[key]["name"], + dataset=self.data_ref[key]["dataset_name_snake_case"], ) result_description = " ".join((result_description, edge_case, description)) @@ -169,12 +175,12 @@ def create_figure(self) -> None: for key, dataset in self.data_ref.items(): if None in (self.area_ref[key], self.area_osm[key]): continue - ref_x.append(dataset["name"]) + ref_x.append(dataset["dataset_name_snake_case"]) ref_y.append(round(self.area_ref[key], 2)) ref_data.append(dataset) - osm_x.append(dataset["name"]) + osm_x.append(dataset["dataset_name_snake_case"]) osm_y.append(round(self.area_osm[key], 2)) - ref_hover.append(f"{dataset['name']} ({dataset['date']})") + ref_hover.append(f"{dataset['table_name']} ({dataset['date']})") osm_hover.append(f"OSM ({self.result.timestamp_osm:%b %d, %Y})") ref_color.append(Color[dataset["color"]].value) osm_area.append(round(self.area_osm[key], 2)) @@ -267,11 +273,11 @@ def check_minor_edge_cases(self, dataset: str) -> str: def format_sources(self): sources = [] - for dataset in self.data_ref.values(): - if dataset["link"] is not None: - sources.append(f"" f"{dataset['name']}") + for dataset_key, dataset_value in self.data_ref.items(): + if dataset_value["link"] is not None: + sources.append(f"{dataset_key}") else: - sources.append(f"{dataset}") + sources.append(dataset_key) result = ", ".join(sources) return result @@ -300,7 +306,41 @@ async def get_reference_building_area(feature_str: str, table_name: str) -> floa return res[0] or 0.0 -def load_datasets_metadata() -> dict: - file_path = os.path.join(os.path.dirname(__file__), "datasets.yaml") - with open(file_path, "r") as f: - return yaml.safe_load(f) +async def load_datasets_metadata() -> dict: + """Load dataset metadata from the database.""" + dns = "postgres://{user}:{password}@{host}:{port}/{database}".format( + host=get_config_value("postgres_host"), + port=get_config_value("postgres_port"), + database=get_config_value("postgres_db"), + user=get_config_value("postgres_user"), + password=get_config_value("postgres_password"), + ) + + dataset_metadata = {} + + async with await psycopg.AsyncConnection.connect(dns) as con: + async with con.cursor() as cur: + await cur.execute( + "SELECT * " + "FROM comparison_indicators_metadata " + "WHERE indicator = 'building_comparison';" + ) + async for row in cur: + dataset_name = row[0] + dataset_name_snake_case = row[1] + link = row[2] + date = row[3].strftime("%Y-%m-%d") # Convert date object to string + description = row[4] + color = row[5] + table_name = row[6] + dataset_metadata[dataset_name] = { + "dataset_name": dataset_name, + "dataset_name_snake_case": dataset_name_snake_case, + "link": link, + "date": date, + "description": description, + "color": color, + "table_name": table_name, + } + + return dataset_metadata diff --git a/ohsome_quality_api/indicators/building_completeness/indicator.py b/ohsome_quality_api/indicators/building_completeness/indicator.py index 5ae5b5346..b28742f38 100644 --- a/ohsome_quality_api/indicators/building_completeness/indicator.py +++ b/ohsome_quality_api/indicators/building_completeness/indicator.py @@ -78,6 +78,9 @@ def threshhold_yellow(cls): """Above or equal to this value label should be yellow.""" return 0.2 + async def init(self) -> None: + pass + async def preprocess(self) -> None: # Get hex-cells hex_cells: FeatureCollection = await get_hex_cells(self.feature) diff --git a/ohsome_quality_api/indicators/currentness/indicator.py b/ohsome_quality_api/indicators/currentness/indicator.py index 05dd9b358..8eea92480 100644 --- a/ohsome_quality_api/indicators/currentness/indicator.py +++ b/ohsome_quality_api/indicators/currentness/indicator.py @@ -60,6 +60,9 @@ def __init__( self.bin_in_between: Bin self.bin_out_of_date: Bin + async def init(self) -> None: + pass + async def preprocess(self): """Fetch all latest contributions in monthly buckets since 2008 diff --git a/ohsome_quality_api/indicators/density/indicator.py b/ohsome_quality_api/indicators/density/indicator.py index 116d0ef69..fe9c62dc2 100644 --- a/ohsome_quality_api/indicators/density/indicator.py +++ b/ohsome_quality_api/indicators/density/indicator.py @@ -29,6 +29,9 @@ def green_threshold_function(self, area): def yellow_threshold_function(self, area): return self.threshold_red * area + async def init(self) -> None: + pass + async def preprocess(self) -> None: query_results_count = await ohsome_client.query(self.topic, self.feature) self.area_sqkm = calculate_area(self.feature) / (1000 * 1000) diff --git a/ohsome_quality_api/indicators/mapping_saturation/indicator.py b/ohsome_quality_api/indicators/mapping_saturation/indicator.py index 877710402..f88973f27 100644 --- a/ohsome_quality_api/indicators/mapping_saturation/indicator.py +++ b/ohsome_quality_api/indicators/mapping_saturation/indicator.py @@ -63,6 +63,9 @@ def __init__( self.best_fit: models.BaseStatModel | None = None self.fitted_models: list[models.BaseStatModel] = [] + async def init(self) -> None: + pass + async def preprocess(self) -> None: query_results = await ohsome_client.query( self.topic, diff --git a/ohsome_quality_api/indicators/minimal/indicator.py b/ohsome_quality_api/indicators/minimal/indicator.py index 00bb02022..d7af68ff5 100644 --- a/ohsome_quality_api/indicators/minimal/indicator.py +++ b/ohsome_quality_api/indicators/minimal/indicator.py @@ -14,6 +14,9 @@ def __init__(self, topic: Topic, feature: Feature) -> None: super().__init__(topic=topic, feature=feature) self.count = 0 + async def init(self) -> None: + pass + async def preprocess(self) -> None: query_results = await ohsome_client.query(self.topic, self.feature) self.count = query_results["result"][0]["value"] diff --git a/ohsome_quality_api/indicators/road_comparison/datasets.yaml b/ohsome_quality_api/indicators/road_comparison/datasets.yaml deleted file mode 100644 index d10ddf08e..000000000 --- a/ohsome_quality_api/indicators/road_comparison/datasets.yaml +++ /dev/null @@ -1,13 +0,0 @@ -Microsoft Roads: - name: Microsoft Roads - link: https://github.com/microsoft/RoadDetections - date: February 27, 2023 - description: >- - Microsoft Road Detections is a dataset of road world-wide. - It is derived from satellite imagery. - color: ORANGE - coverage: - simple: microsoft_roads_coverage_simple - inversed: microsoft_roads_coverage_inversed - table_name: microsoft_roads_midpoint - processing_date: 2024-04-05 diff --git a/ohsome_quality_api/indicators/road_comparison/indicator.py b/ohsome_quality_api/indicators/road_comparison/indicator.py index 96243a6df..7d41d4051 100644 --- a/ohsome_quality_api/indicators/road_comparison/indicator.py +++ b/ohsome_quality_api/indicators/road_comparison/indicator.py @@ -4,7 +4,6 @@ import geojson import plotly.graph_objects as pgo import psycopg -import yaml from async_lru import alru_cache from geojson import Feature from numpy import mean @@ -44,27 +43,23 @@ def __init__( self.ratio: dict[str, float | None] = {} self.warnings: dict[str, str | None] = {} # self.data_ref: list = load_reference_datasets() # reference datasets - for key, val in load_datasets_metadata().items(): - self.data_ref[key] = val - self.area_cov[key] = None # covered area [%] - self.length_matched[key] = None - self.length_total[key] = None - self.length_osm[key] = None - self.ratio[key] = None - self.warnings[key] = None @classmethod async def coverage(cls, inverse=False) -> list[Feature]: # TODO: could also return a Feature Collection features = [] - datasets = load_datasets_metadata() + datasets = await load_datasets_metadata() for val in datasets.values(): if inverse: - table = val["coverage"]["inversed"] + coverage_type = "coverage_inversed" else: - table = val["coverage"]["simple"] - feature = await db_client.get_reference_coverage(table) - feature.properties.update({"refernce_dataset": val["name"]}) + coverage_type = "coverage_simple" + feature = await db_client.get_reference_coverage( + val["dataset_name_snake_case"], coverage_type + ) + feature.properties.update( + {"refernce_dataset": val["dataset_name_snake_case"]} + ) features.append(feature) return features @@ -73,12 +68,23 @@ def attribution(cls) -> str: # TODO: add attribution return get_attribution(["OSM"]) + async def init(self) -> None: + dataset_metadata = await load_datasets_metadata() + for key, val in dataset_metadata.items(): + self.data_ref[key] = val + self.area_cov[key] = None # covered area [%] + self.length_matched[key] = None + self.length_total[key] = None + self.length_osm[key] = None + self.ratio[key] = None + self.warnings[key] = None + async def preprocess(self) -> None: for key, val in self.data_ref.items(): # get area covered by reference dataset [%] self.area_cov[key] = await db_client.get_intersection_area( self.feature, - val["coverage"]["simple"], + val["dataset_name_snake_case"], ) self.warnings[key] = self.check_major_edge_cases(key) if self.warnings[key] != "": @@ -87,7 +93,7 @@ async def preprocess(self) -> None: # clip input geom with coverage of reference dataset feature = await db_client.get_intersection_geom( self.feature, - val["coverage"]["simple"], + val["dataset_name_snake_case"], ) # get covered road length @@ -120,7 +126,7 @@ def calculate(self) -> None: self.result.description += self.warnings[key] + "\n" self.result.description += ( - f"{self.data_ref[key]['name']} has a road length of " + f"{self.data_ref[key]['dataset_name']} has a road length of " f"{(self.length_total[key]/1000):.2f} km, of which " f"{(self.length_matched[key]/1000):.2f} km are covered by roads in " f"OSM. " @@ -161,9 +167,9 @@ def create_figure(self) -> None: for key, val in self.ratio.items(): if val is None: continue - ref_name.append(self.data_ref[key]["name"]) + ref_name.append(self.data_ref[key]["dataset_name"]) ref_color.append(Color[self.data_ref[key]["color"]].value) - ref_processingdate.append(self.data_ref[key]["processing_date"]) + ref_processingdate.append(self.data_ref[key]["date"]) ref_ratio.append(val) for i, (name, ratio, date) in enumerate( @@ -253,11 +259,11 @@ def check_minor_edge_cases(self, dataset: str) -> str: def format_sources(self): sources = [] - for dataset in self.data_ref.values(): - if dataset["link"] is not None: - sources.append(f"" f"{dataset['name']}") + for dataset_key, dataset_value in self.data_ref.items(): + if dataset_value["link"] is not None: + sources.append(f"{dataset_key}") else: - sources.append(f"{dataset}") + sources.append(dataset_key) result = ", ".join(sources) return result @@ -293,7 +299,41 @@ async def get_matched_roadlengths( return res[0], res[1] -def load_datasets_metadata() -> dict: - file_path = os.path.join(os.path.dirname(__file__), "datasets.yaml") - with open(file_path, "r") as f: - return yaml.safe_load(f) +async def load_datasets_metadata() -> dict: + """Load dataset metadata from the database.""" + dns = "postgres://{user}:{password}@{host}:{port}/{database}".format( + host=get_config_value("postgres_host"), + port=get_config_value("postgres_port"), + database=get_config_value("postgres_db"), + user=get_config_value("postgres_user"), + password=get_config_value("postgres_password"), + ) + + dataset_metadata = {} + + async with await psycopg.AsyncConnection.connect(dns) as con: + async with con.cursor() as cur: + await cur.execute( + "SELECT * " + "FROM comparison_indicators_metadata " + "WHERE indicator = 'road_comparison';" + ) + async for row in cur: + dataset_name = row[0] + dataset_name_snake_case = row[1] + link = row[2] + date = row[3] # Convert date object to string + description = row[4] + color = row[5] + table_name = row[6] + dataset_metadata[dataset_name] = { + "dataset_name": dataset_name, + "dataset_name_snake_case": dataset_name_snake_case, + "link": link, + "date": date, + "description": description, + "color": color, + "table_name": table_name, + } + + return dataset_metadata diff --git a/ohsome_quality_api/oqt.py b/ohsome_quality_api/oqt.py index b93043da9..c2f62de7a 100644 --- a/ohsome_quality_api/oqt.py +++ b/ohsome_quality_api/oqt.py @@ -77,6 +77,8 @@ async def _create_indicator( indicator_class = get_class_from_key(class_type="indicator", key=key) indicator = indicator_class(topic, feature) + logging.info("Run initialisation") + await indicator.init() logging.info("Run preprocessing") await indicator.preprocess() logging.info("Run calculation") diff --git a/tests/integrationtests/indicators/test_building_comparison.py b/tests/integrationtests/indicators/test_building_comparison.py index 0a2f78798..737b24586 100644 --- a/tests/integrationtests/indicators/test_building_comparison.py +++ b/tests/integrationtests/indicators/test_building_comparison.py @@ -16,7 +16,8 @@ @pytest.fixture def mock_get_building_area(class_mocker): async def side_effect_function(*args, **kwargs): - if args[1] == "EUBUCCO": + if not hasattr(side_effect_function, "called"): + side_effect_function.called = True return 6000000.791645115 else: return 5000000.791645115 @@ -40,7 +41,8 @@ def mock_get_building_area_low(class_mocker): @pytest.fixture def mock_get_building_area_low_some(class_mocker): async def side_effect_function(*args, **kwargs): - if args[1] == "EUBUCCO": + if not hasattr(side_effect_function, "called"): + side_effect_function.called = True return 1 else: return 6000000.791645115 @@ -91,7 +93,8 @@ def mock_get_intersection_area_none(class_mocker): @pytest.fixture def mock_get_intersection_area_some(class_mocker): async def side_effect(*args, **kwargs): - if "eubucco" in args[1]: + if not hasattr(side_effect, "called"): + side_effect.called = True return 0.0 # 0 % else: return 1.0 # 100 % @@ -113,6 +116,7 @@ def test_init(self, topic_building_area, feature_germany_berlin): def test_get_sources(self, topic_building_area, feature_germany_berlin): indicator = BuildingComparison(topic_building_area, feature_germany_berlin) + asyncio.run(indicator.init()) source = indicator.format_sources() assert "EUBUCCO" in source @@ -131,6 +135,7 @@ class TestPreprocess: ) def test_preprocess(self, topic_building_area, feature_germany_berlin): indicator = BuildingComparison(topic_building_area, feature_germany_berlin) + asyncio.run(indicator.init()) asyncio.run(indicator.preprocess()) for area in indicator.area_osm.values(): @@ -148,6 +153,7 @@ def test_preprocess_no_intersection( mock_get_intersection_area_none, ): indicator = BuildingComparison(topic_building_area, feature_germany_berlin) + asyncio.run(indicator.init()) asyncio.run(indicator.preprocess()) for area in indicator.area_cov.values(): @@ -167,6 +173,7 @@ def test_preprocess_some_intersection( feature_germany_berlin, ): indicator = BuildingComparison(topic_building_area, feature_germany_berlin) + asyncio.run(indicator.init()) asyncio.run(indicator.preprocess()) assert 1.0 in list(indicator.area_cov.values()) @@ -188,6 +195,7 @@ def test_calculate( feature_germany_berlin, ): indicator = BuildingComparison(topic_building_area, feature_germany_berlin) + asyncio.run(indicator.init()) asyncio.run(indicator.preprocess()) indicator.calculate() assert indicator.result.value is not None @@ -208,6 +216,7 @@ def test_calculate_reference_area_0( feature_germany_heidelberg, ): indicator = BuildingComparison(topic_building_area, feature_germany_heidelberg) + asyncio.run(indicator.init()) asyncio.run(indicator.preprocess()) indicator.calculate() assert indicator.result.value is None @@ -224,6 +233,7 @@ def test_calculate_above_one_th( feature_germany_heidelberg, ): indicator = BuildingComparison(topic_building_area, feature_germany_heidelberg) + asyncio.run(indicator.init()) asyncio.run(indicator.preprocess()) indicator.calculate() assert indicator.result.value is None @@ -244,6 +254,7 @@ def test_calculate_no_intersection( feature_germany_heidelberg, ): indicator = BuildingComparison(topic_building_area, feature_germany_heidelberg) + asyncio.run(indicator.init()) asyncio.run(indicator.preprocess()) indicator.calculate() assert indicator.result.value is None @@ -264,6 +275,7 @@ def test_calculate_some_intersection( feature_germany_heidelberg, ): indicator = BuildingComparison(topic_building_area, feature_germany_heidelberg) + asyncio.run(indicator.init()) asyncio.run(indicator.preprocess()) indicator.calculate() assert indicator.result.value is not None @@ -287,6 +299,7 @@ def test_calculate_above_one_th_and_expected( feature_germany_heidelberg, ): indicator = BuildingComparison(topic_building_area, feature_germany_heidelberg) + asyncio.run(indicator.init()) asyncio.run(indicator.preprocess()) indicator.calculate() assert indicator.result.value is not None @@ -307,6 +320,7 @@ class TestFigure: ) def test_create_figure(self, topic_building_area, feature_germany_berlin): indicator = BuildingComparison(topic_building_area, feature_germany_berlin) + asyncio.run(indicator.init()) asyncio.run(indicator.preprocess()) indicator.calculate() indicator.create_figure() @@ -322,6 +336,7 @@ def test_create_figure(self, topic_building_area, feature_germany_berlin): ) def test_create_figure_manual(self, topic_building_area, feature_germany_berlin): indicator = BuildingComparison(topic_building_area, feature_germany_berlin) + asyncio.run(indicator.init()) asyncio.run(indicator.preprocess()) indicator.calculate() indicator.create_figure() @@ -339,6 +354,7 @@ def test_create_figure_above_one_th( feature_germany_berlin, ): indicator = BuildingComparison(topic_building_area, feature_germany_berlin) + asyncio.run(indicator.init()) asyncio.run(indicator.preprocess()) indicator.calculate() indicator.create_figure() @@ -358,6 +374,7 @@ def test_create_figure_building_area_zero( feature_germany_berlin, ): indicator = BuildingComparison(topic_building_area, feature_germany_berlin) + asyncio.run(indicator.init()) asyncio.run(indicator.preprocess()) indicator.calculate() indicator.create_figure() diff --git a/tests/integrationtests/indicators/test_road_comparison.py b/tests/integrationtests/indicators/test_road_comparison.py index 5fb7e60a2..f4f7a9548 100644 --- a/tests/integrationtests/indicators/test_road_comparison.py +++ b/tests/integrationtests/indicators/test_road_comparison.py @@ -82,6 +82,7 @@ def test_init(self, topic_major_roads_length, feature_malta): def test_get_sources(self, topic_major_roads_length, feature_malta): indicator = RoadComparison(topic_major_roads_length, feature_malta) + asyncio.run(indicator.init()) source = indicator.format_sources() assert ( "" @@ -103,6 +104,7 @@ class TestPreprocess: ) def test_preprocess(self, topic_major_roads_length, feature_malta): indicator = RoadComparison(topic_major_roads_length, feature_malta) + asyncio.run(indicator.init()) asyncio.run(indicator.preprocess()) for length in indicator.length_total.values(): @@ -117,6 +119,7 @@ def test_preprocess_no_intersection( mock_get_intersection_area_none, ): indicator = RoadComparison(topic_major_roads_length, feature_malta) + asyncio.run(indicator.init()) asyncio.run(indicator.preprocess()) for area in indicator.area_cov.values(): @@ -138,6 +141,7 @@ def test_calculate( feature_malta, ): indicator = RoadComparison(topic_major_roads_length, feature_malta) + asyncio.run(indicator.init()) asyncio.run(indicator.preprocess()) indicator.calculate() assert indicator.result.value is not None @@ -158,6 +162,7 @@ def test_calculate_reference_lenght_0( feature_malta, ): indicator = RoadComparison(topic_major_roads_length, feature_malta) + asyncio.run(indicator.init()) asyncio.run(indicator.preprocess()) indicator.calculate() assert indicator.result.value is None @@ -173,6 +178,7 @@ def test_calculate_no_intersection( feature_malta, ): indicator = RoadComparison(topic_major_roads_length, feature_malta) + asyncio.run(indicator.init()) asyncio.run(indicator.preprocess()) indicator.calculate() assert indicator.result.value is None @@ -191,6 +197,7 @@ class TestFigure: ) def test_create_figure(self, topic_major_roads_length, feature_malta): indicator = RoadComparison(topic_major_roads_length, feature_malta) + asyncio.run(indicator.init()) asyncio.run(indicator.preprocess()) indicator.calculate() indicator.create_figure() @@ -206,6 +213,7 @@ def test_create_figure(self, topic_major_roads_length, feature_malta): ) def test_create_figure_manual(self, topic_major_roads_length, feature_malta): indicator = RoadComparison(topic_major_roads_length, feature_malta) + asyncio.run(indicator.init()) asyncio.run(indicator.preprocess()) indicator.calculate() indicator.create_figure() @@ -221,6 +229,7 @@ def test_create_figure_building_area_zero( self, topic_major_roads_length, feature_malta ): indicator = RoadComparison(topic_major_roads_length, feature_malta) + asyncio.run(indicator.init()) asyncio.run(indicator.preprocess()) indicator.calculate() indicator.create_figure()