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()