diff --git a/ohsome_quality_api/attributes/definitions.py b/ohsome_quality_api/attributes/definitions.py index c75772c29..090267643 100644 --- a/ohsome_quality_api/attributes/definitions.py +++ b/ohsome_quality_api/attributes/definitions.py @@ -52,7 +52,31 @@ def get_attribute_preset(topic_key: str) -> List[Attribute]: ) from error -def build_attribute_filter(attribute_key: List[str] | str, topic_key: str) -> str: +def build_attribute_filter_ohsomedb( + attribute_key: List[str] | str, topic_key: str +) -> str: + """Build attribute filter for ohsome API query.""" + attributes = get_attributes() + try: + if isinstance(attribute_key, str): + return attribute_key + else: + attribute_filter = "" + for i, key in enumerate(attribute_key): + if i == 0: + attribute_filter = "(" + attributes[topic_key][key].filter + ")" + else: + attribute_filter += ( + " and (" + attributes[topic_key][key].filter + ")" + ) + return attribute_filter + except KeyError as error: + raise KeyError("Invalid topic or attribute key(s).") from error + + +def build_attribute_filter_ohsomeapi( + attribute_key: List[str] | str, topic_key: str +) -> str: """Build attribute filter for ohsome API query.""" attributes = get_attributes() try: diff --git a/ohsome_quality_api/indicators/attribute_completeness/indicator.py b/ohsome_quality_api/indicators/attribute_completeness/indicator.py index a81c97fc1..be802f29d 100644 --- a/ohsome_quality_api/indicators/attribute_completeness/indicator.py +++ b/ohsome_quality_api/indicators/attribute_completeness/indicator.py @@ -1,4 +1,5 @@ import logging +from datetime import datetime, timezone from string import Template import dateutil.parser @@ -7,10 +8,13 @@ from fastapi_i18n import _, get_locale from geojson import Feature +from ohsome_quality_api import ohsomedb from ohsome_quality_api.attributes.definitions import ( - build_attribute_filter, + build_attribute_filter_ohsomeapi, + build_attribute_filter_ohsomedb, get_attribute, ) +from ohsome_quality_api.config import get_config_value from ohsome_quality_api.indicators.base import BaseIndicator from ohsome_quality_api.ohsome import client as ohsome_client from ohsome_quality_api.topics.models import Topic @@ -60,24 +64,63 @@ def __init__( self.absolute_value_1 = None self.absolute_value_2 = None self.description = None - if self.attribute_keys: - self.attribute_filter = build_attribute_filter( - self.attribute_keys, - self.topic.key, - ) - self.attribute_title = ", ".join( - [ - get_attribute(self.topic.key, k).name.lower() - for k in self.attribute_keys - ] - ) + ohsomedb_enabled = get_config_value("ohsomedb_enabled") + if ohsomedb_enabled is True or ohsomedb_enabled in ("True", "true"): + if self.attribute_keys: + self.attribute_filter = build_attribute_filter_ohsomedb( + self.attribute_keys, + self.topic.key, + ) + self.attribute_title = ", ".join( + [ + get_attribute(self.topic.key, k).name.lower() + for k in self.attribute_keys + ] + ) + else: + self.attribute_filter = build_attribute_filter_ohsomedb( + self.attribute_filter, + self.topic.key, + ) else: - self.attribute_filter = build_attribute_filter( - self.attribute_filter, - self.topic.key, - ) + if self.attribute_keys: + self.attribute_filter = build_attribute_filter_ohsomeapi( + self.attribute_keys, + self.topic.key, + ) + self.attribute_title = ", ".join( + [ + get_attribute(self.topic.key, k).name.lower() + for k in self.attribute_keys + ] + ) + else: + self.attribute_filter = build_attribute_filter_ohsomeapi( + self.attribute_filter, + self.topic.key, + ) + + async def preprocess(self): + ohsomedb_enabled = get_config_value("ohsomedb_enabled") + if ohsomedb_enabled is True or ohsomedb_enabled in ("True", "true"): + await self.preprocess_ohsomedb() + else: + await self.preprocess_ohsomeapi() + + async def preprocess_ohsomedb(self) -> None: + # Get attribute filter + result = await ohsomedb.attribute_completeness( + aggregation=self.topic.aggregation_type, + bpolys=self.feature.geometry, + filter_=self.topic.filter, + attribute_filter_=self.attribute_filter, + ) + self.result.timestamp_osm = datetime.now(timezone.utc) + self.result.value = result[0]["attribute_completeness"] + self.absolute_value_1 = result[0]["total_aggregation"] + self.absolute_value_2 = result[0]["aggregation_with_attribute"] - async def preprocess(self) -> None: + async def preprocess_ohsomeapi(self) -> None: # Get attribute filter response = await ohsome_client.query( self.topic, @@ -92,7 +135,7 @@ async def preprocess(self) -> None: def calculate(self) -> None: # result (ratio) can be NaN if no features matching filter1 - if self.result.value == "NaN": + if self.result.value == "NaN" or self.absolute_value_1 == 0: self.result.value = None if self.result.value is None: self.result.description += _(" No features in this region") diff --git a/ohsome_quality_api/indicators/building_comparison/indicator.py b/ohsome_quality_api/indicators/building_comparison/indicator.py index e1572e49f..08ef59e2f 100644 --- a/ohsome_quality_api/indicators/building_comparison/indicator.py +++ b/ohsome_quality_api/indicators/building_comparison/indicator.py @@ -13,6 +13,8 @@ from geojson import Feature from numpy import mean +from ohsome_quality_api import ohsomedb +from ohsome_quality_api.config import get_config_value from ohsome_quality_api.definitions import Color, get_attribution from ohsome_quality_api.geodatabase import client as db_client from ohsome_quality_api.indicators.base import BaseIndicator @@ -71,7 +73,14 @@ async def coverage(cls, inverse=False) -> list[Feature]: def attribution(cls) -> str: return get_attribution(["OSM", "EUBUCCO", "Microsoft Buildings"]) - async def preprocess(self) -> None: + async def preprocess(self): + ohsomedb_enabled = get_config_value("ohsomedb_enabled") + if ohsomedb_enabled is True or ohsomedb_enabled in ("True", "true"): + await self.preprocess_ohsomedb() + else: + await self.preprocess_ohsomeapi() + + async def preprocess_ohsomeapi(self) -> None: for key, val in self.data_ref.items(): # get coverage [%] self.area_cov[key] = await db_client.get_intersection_area( @@ -100,6 +109,38 @@ async def preprocess(self) -> None: timestamp = result["result"][0]["timestamp"] self.result.timestamp_osm = parser.isoparse(timestamp) + async def preprocess_ohsomedb(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"], + ) + if self.check_major_edge_cases(key) != "": + continue + + # clip input geom with coverage of reference dataset + feature = await db_client.get_intersection_geom( + self.feature, + val["coverage"]["simple"], + ) + + # get reference building area + result = await get_reference_building_area( + geojson.dumps(feature), val["table_name"] + ) + self.area_ref[key] = result / (1000 * 1000) + + # get osm building area + result = await ohsomedb.single_snapshot_aggregation( + aggregation=self.topic.aggregation_type, + bpolys=self.feature.geometry, + filter_=self.topic.filter, + ) + value = float(result[0]["value"]) or 0.0 # if None + self.area_osm[key] = value / (1000 * 1000) + self.result.timestamp_osm = result[0]["snapshot_ts"] + def calculate(self) -> None: major_edge_case: bool = False result_description: str = "" diff --git a/ohsome_quality_api/indicators/land_cover_completeness/indicator.py b/ohsome_quality_api/indicators/land_cover_completeness/indicator.py index 10e6f91af..32f87b649 100644 --- a/ohsome_quality_api/indicators/land_cover_completeness/indicator.py +++ b/ohsome_quality_api/indicators/land_cover_completeness/indicator.py @@ -7,6 +7,8 @@ from fastapi_i18n import _, get_locale from geojson import Feature +from ohsome_quality_api import ohsomedb +from ohsome_quality_api.config import get_config_value from ohsome_quality_api.indicators.base import BaseIndicator from ohsome_quality_api.ohsome import client as ohsome_client from ohsome_quality_api.topics.models import Topic @@ -26,15 +28,31 @@ def __init__( self.th_low = 0.50 # Above or equal to this value label should be yellow async def preprocess(self): - # get osm building area + ohsomedb_enabled = get_config_value("ohsomedb_enabled") + if ohsomedb_enabled is True or ohsomedb_enabled in ("True", "true"): + await self.preprocess_ohsomedb() + else: + await self.preprocess_ohsomeapi() + async def preprocess_ohsomeapi(self): result = await ohsome_client.query(self.topic, self.feature, density=True) self.osm_area_ratio = result["result"][0]["value"] or 0.0 # if None timestamp = result["result"][0]["timestamp"] self.result.timestamp_osm = parser.isoparse(timestamp) + async def preprocess_ohsomedb(self): + # get osm building area + + result = await ohsomedb.density( + aggregation=self.topic.aggregation_type, + bpolys=self.feature.geometry, + filter_=self.topic.filter, + ) + self.osm_area_ratio = result[0]["value"] or 0.0 # if None + self.result.timestamp_osm = result[0]["snapshot_ts"] + def calculate(self): - self.osm_area_ratio /= 1000000 + # self.osm_area_ratio /= 1000000 self.result.value = round(self.osm_area_ratio, 2) if self.result.value >= self.th_high: self.result.class_ = 5 diff --git a/ohsome_quality_api/ohsomedb/__init__.py b/ohsome_quality_api/ohsomedb/__init__.py index 02e112eb0..fee3e277f 100644 --- a/ohsome_quality_api/ohsomedb/__init__.py +++ b/ohsome_quality_api/ohsomedb/__init__.py @@ -1,7 +1,17 @@ from .requests import ( + attribute_completeness, contributions, + density, elements, + single_snapshot_aggregation, users, ) -__all__ = ("contributions", "elements", "users") +__all__ = ( + "attribute_completeness", + "contributions", + "density", + "elements", + "single_snapshot_aggregation", + "users", +) diff --git a/ohsome_quality_api/ohsomedb/requests.py b/ohsome_quality_api/ohsomedb/requests.py index 243249e3f..fa362a054 100644 --- a/ohsome_quality_api/ohsomedb/requests.py +++ b/ohsome_quality_api/ohsomedb/requests.py @@ -89,3 +89,84 @@ async def elements( bpolys.model_dump_json(), database="ohsomedb", ) + + +@validate_call +async def attribute_completeness( + *, + aggregation: Literal["count", "length", "area"], + bpolys: Polygon | MultiPolygon, + filter_: OhsomeFilter, + attribute_filter_: OhsomeFilter, +): + sql_filter, sql_filter_args = ohsome_filter_to_sql(filter_) + attribute_sql_filter, attribute_sql_filter_args = ohsome_filter_to_sql( + attribute_filter_, args_shift=len(sql_filter_args) + ) + template = ENV.get_template("attribute_completeness.sql") + query = template.render( + **{ + "aggregation": aggregation, + "contributions": get_config_value("ohsomedb_contributions_table"), + "geom": len(attribute_sql_filter_args) + len(sql_filter_args) + 1, + "filter": sql_filter, + "attribute_filter": attribute_sql_filter, + } + ) + total_sql_filter_args = sql_filter_args + attribute_sql_filter_args + return await client.fetch( + query, + *total_sql_filter_args, + bpolys.model_dump_json(), + database="ohsomedb", + ) + + +@validate_call +async def single_snapshot_aggregation( + *, + aggregation: Literal["count", "length", "area"], + bpolys: Polygon | MultiPolygon, + filter_: OhsomeFilter, +): + sql_filter, sql_filter_args = ohsome_filter_to_sql(filter_) + template = ENV.get_template("single_snapshot_aggregation.sql") + query = template.render( + **{ + "aggregation": aggregation, + "contributions": get_config_value("ohsomedb_contributions_table"), + "geom": len(sql_filter_args) + 1, + "filter": sql_filter, + } + ) + return await client.fetch( + query, + *sql_filter_args, + bpolys.model_dump_json(), + database="ohsomedb", + ) + + +@validate_call +async def density( + *, + aggregation: Literal["area"], + bpolys: Polygon | MultiPolygon, + filter_: OhsomeFilter, +): + sql_filter, sql_filter_args = ohsome_filter_to_sql(filter_) + template = ENV.get_template("density.sql") + query = template.render( + **{ + "aggregation": aggregation, + "contributions": get_config_value("ohsomedb_contributions_table"), + "geom": len(sql_filter_args) + 1, + "filter": sql_filter, + } + ) + return await client.fetch( + query, + *sql_filter_args, + bpolys.model_dump_json(), + database="ohsomedb", + ) diff --git a/ohsome_quality_api/ohsomedb/templates/attribute_completeness.sql b/ohsome_quality_api/ohsomedb/templates/attribute_completeness.sql new file mode 100644 index 000000000..c4e149c9c --- /dev/null +++ b/ohsome_quality_api/ohsomedb/templates/attribute_completeness.sql @@ -0,0 +1,62 @@ +-- Parsing the GeoJSON directly in the WHERE clause instead of +-- in a WITH clause makes the query faster +with stats AS ( + SELECT + {% if aggregation == 'length' %} + 0.001 * SUM( + CASE + WHEN ST_Within( + c.geom, + ST_GeomFromGeoJSON(${{ geom }}) + ) + THEN c.length -- Use precomputed area from ohsome-planet + ELSE ST_Length( + ST_Intersection( + c.geom, + ST_GeomFromGeoJSON(${{ geom }}) + )::geography + ) + END + )::BIGINT + {% elif aggregation == 'area' or aggregation == 'area\density' %} + 0.001 * 0.001 * SUM( + CASE + WHEN ST_Within( + c.geom, + ST_GeomFromGeoJSON(${{ geom }}) + ) + THEN c.area -- Use precomputed area from ohsome-planet + ELSE ST_Area( + ST_Intersection( + c.geom, + ST_GeomFromGeoJSON(${{ geom }}) + )::geography + ) + END + )::BIGINT + {% else %} + COUNT(*) + {% endif %} + AS aggregation, + {{ attribute_filter }} has_attribute + FROM + {{ contributions }} c + WHERE 1=1 + -- TODO: this would be more performant but ohsome-filter-to-sql can not generate this + -- clause because is does not know about "latest" + -- AND status_geom_type = ANY(ARRAY[('latest', 'Polygon'), ('latest', 'MultiPolygon')]::_status_geom_type_type) + AND (status_geom_type).status = 'latest' -- excludes deleted + -- ohsome-filter-to-sql generated clause + AND ({{ filter }}) + AND ST_Intersects(c.geom, ST_GeomFromGeoJSON(${{ geom }})) + GROUP BY has_attribute +) +SELECT + COALESCE(SUM(aggregation), 0) AS total_aggregation, + COALESCE(SUM(aggregation) FILTER (WHERE has_attribute), 0) AS aggregation_with_attribute, + COALESCE( + SUM(aggregation) FILTER (WHERE has_attribute) + / NULLIF(SUM(aggregation), 0)::float, + 0 + ) AS attribute_completeness +FROM stats; diff --git a/ohsome_quality_api/ohsomedb/templates/density.sql b/ohsome_quality_api/ohsomedb/templates/density.sql new file mode 100644 index 000000000..43f0038c6 --- /dev/null +++ b/ohsome_quality_api/ohsomedb/templates/density.sql @@ -0,0 +1,36 @@ +-- WITH poly AS ( +-- SELECT ST_GeomFromGeoJSON(${{ geom }}) AS geom +-- ), +-- intersecting AS ( +-- SELECT c.geom +-- FROM {{ contributions }} c, poly p +-- WHERE +-- (status_geom_type).status = 'latest' +-- AND valid_to >= NOW()::timestamp +-- AND valid_from < NOW()::timestamp +-- AND ({{ filter }}) +-- AND ST_Intersects(c.geom, p.geom) +-- ) +-- SELECT +-- NOW()::timestamp AS snapshot_ts, +-- ST_Area(ST_UnaryUnion(ST_Union(i.geom))::geography) AS non_overlapping_geom +-- FROM intersecting i, poly p; + +WITH poly AS ( + SELECT ST_GeomFromGeoJSON(${{ geom }}) AS geom +) +SELECT + NOW()::timestamp AS snapshot_ts, + ST_Area(ST_UNION( + ST_Intersection(c.geom, p.geom) + )::geography) / ST_Area(p.geom::geography) as value +FROM {{ contributions }} c, poly p +WHERE + (status_geom_type).status = 'latest' + AND valid_to >= NOW()::timestamp + AND valid_from < NOW()::timestamp + AND ({{ filter }}) + AND ST_Intersects(c.geom, p.geom) +GROUP BY p.geom +; + diff --git a/ohsome_quality_api/ohsomedb/templates/saturation.sql b/ohsome_quality_api/ohsomedb/templates/saturation.sql new file mode 100644 index 000000000..1a00bce8e --- /dev/null +++ b/ohsome_quality_api/ohsomedb/templates/saturation.sql @@ -0,0 +1,54 @@ +WITH series AS (SELECT generate_series('2007-10-01'::timestamp, + NOW()::timestamp, 'P1M'::interval) AS ts), +poly AS ( + SELECT ST_GeomFromGeoJSON(${{ geom }}) AS geom +) +SELECT + ts AS timestamp, + {% if aggregation == 'length' %} + SUM( + CASE + WHEN ST_Within( + c.geom, + ST_GeomFromGeoJSON(${{ geom }}) + ) + THEN c.length -- Use precomputed area from ohsome-planet + ELSE ST_Length( + ST_Intersection( + c.geom, + ST_GeomFromGeoJSON(${{ geom }}) + )::geography + ) + END + )::BIGINT + {% elif aggregation == 'area' or aggregation == 'area\density' %} + SUM( + CASE + WHEN ST_Within( + c.geom, + ST_GeomFromGeoJSON(${{ geom }}) + ) + THEN c.area -- Use precomputed area from ohsome-planet + ELSE ST_Area( + ST_Intersection( + c.geom, + ST_GeomFromGeoJSON(${{ geom }}) + )::geography + ) + END + )::BIGINT + {% else %} + COUNT(*) + {% endif %} + AS value +FROM series JOIN {{ contributions }} c ON (valid_from <= ts AND ts < valid_to) CROSS JOIN poly p +WHERE 1=1 + -- TODO: this would be more performant but ohsome-filter-to-sql can not generate this + -- clause because is does not know about "latest" + -- AND status_geom_type = ANY(ARRAY[('history','LineString')::status_geom_type_type, ('latest','LineString')::status_geom_type_type]) + -- ohsome-filter-to-sql generated clause + AND ({{ filter }}) + AND ST_Intersects(c.geom, p.geom) +GROUP BY ts +ORDER BY ts +; diff --git a/ohsome_quality_api/ohsomedb/templates/single_snapshot_aggregation.sql b/ohsome_quality_api/ohsomedb/templates/single_snapshot_aggregation.sql new file mode 100644 index 000000000..6c7900b70 --- /dev/null +++ b/ohsome_quality_api/ohsomedb/templates/single_snapshot_aggregation.sql @@ -0,0 +1,31 @@ +WITH poly AS ( + SELECT ST_GeomFromGeoJSON(${{ geom }}) AS geom +) +SELECT + NOW()::timestamp AS snapshot_ts, + {% if aggregation == 'length' %} + SUM( + CASE + WHEN ST_Within(c.geom, p.geom) + THEN c.length -- Use precomputed length from ohsome-planet + ELSE ST_Length(ST_Intersection(c.geom, p.geom)) + END + )::BIGINT AS value + {% elif aggregation == 'area' or aggregation == 'area\density' %} + SUM( + CASE + WHEN ST_Within(c.geom, p.geom) + THEN c.area -- Use precomputed area from ohsome-planet + ELSE ST_Area(ST_Intersection(c.geom, p.geom)) + END + )::BIGINT AS value + {% else %} + COUNT(*) AS value + {% endif %} +FROM {{ contributions }} c, poly AS p +WHERE 1=1 + AND (status_geom_type).status IN ('latest') + AND valid_to >= NOW()::timestamp + AND valid_from < NOW()::timestamp -- before last snapshot time + AND ({{ filter }}) + AND ST_Intersects(c.geom, p.geom); diff --git a/tests/approvals/integrationtests/indicators/test_attribute_completeness.py--TestCalculation--test_calculate[2791442826].approved.txt b/tests/approvals/integrationtests/indicators/test_attribute_completeness.py--TestCalculation--test_calculate[2791442826].approved.txt index 1710ac172..9c4d10f18 100644 --- a/tests/approvals/integrationtests/indicators/test_attribute_completeness.py--TestCalculation--test_calculate[2791442826].approved.txt +++ b/tests/approvals/integrationtests/indicators/test_attribute_completeness.py--TestCalculation--test_calculate[2791442826].approved.txt @@ -1 +1 @@ -40% of all "Buildings (count)" features (all: 30337 elements) in your area of interest have the selected additional attribute height of buildings (matched: 12083 elements). The attribute completeness is medium (25%-75%). +42% of all "Buildings (count)" features (all: 31336 elements) in your area of interest have the selected additional attribute height of buildings (matched: 13040 elements). The attribute completeness is medium (25%-75%). diff --git a/tests/approvals/integrationtests/indicators/test_attribute_completeness.py--TestCalculation--test_calculate[3513071900].approved.txt b/tests/approvals/integrationtests/indicators/test_attribute_completeness.py--TestCalculation--test_calculate[3513071900].approved.txt index cd1ad1b6b..f061d1892 100644 --- a/tests/approvals/integrationtests/indicators/test_attribute_completeness.py--TestCalculation--test_calculate[3513071900].approved.txt +++ b/tests/approvals/integrationtests/indicators/test_attribute_completeness.py--TestCalculation--test_calculate[3513071900].approved.txt @@ -1 +1 @@ -40% of all "Buildings (count)" features (all: 30337 elements) in your area of interest have the selected additional attribute Height (matched: 12083 elements). The attribute completeness is medium (25%-75%). +42% of all "Buildings (count)" features (all: 31336 elements) in your area of interest have the selected additional attribute Height (matched: 13040 elements). The attribute completeness is medium (25%-75%). diff --git a/tests/approvals/integrationtests/indicators/test_attribute_completeness.py--TestFigure--test_create_figure[2791442826].approved.json b/tests/approvals/integrationtests/indicators/test_attribute_completeness.py--TestFigure--test_create_figure[2791442826].approved.json index 59bbcff6c..cde0d2a72 100644 --- a/tests/approvals/integrationtests/indicators/test_attribute_completeness.py--TestFigure--test_create_figure[2791442826].approved.json +++ b/tests/approvals/integrationtests/indicators/test_attribute_completeness.py--TestFigure--test_create_figure[2791442826].approved.json @@ -1 +1 @@ -{"data":[{"domain":{"x":[0,1],"y":[0,1]},"gauge":{"axis":{"range":[0,100],"tickcolor":"darkblue","tickfont":{"color":"black","size":20},"ticksuffix":"%","tickwidth":1},"bar":{"color":"black"},"steps":[{"color":"tomato","range":[0,25.0]},{"color":"gold","range":[25.0,75.0]},{"color":"darkseagreen","range":[75.0,100]}]},"mode":"gauge+number","number":{"suffix":"%"},"value":39.8293,"type":"indicator"}],"layout":{"autosize":true,"font":{"color":"black","family":"Arial"},"plot_bgcolor":"rgba(0,0,0,0)","xaxis":{"fixedrange":true,"range":[-1,1],"showgrid":false,"visible":false},"yaxis":{"fixedrange":true,"range":[0,1],"showgrid":false,"visible":false},"template":{"data":{"histogram2dcontour":[{"type":"histogram2dcontour","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"choropleth":[{"type":"choropleth","colorbar":{"outlinewidth":0,"ticks":""}}],"histogram2d":[{"type":"histogram2d","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"heatmap":[{"type":"heatmap","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"contourcarpet":[{"type":"contourcarpet","colorbar":{"outlinewidth":0,"ticks":""}}],"contour":[{"type":"contour","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"surface":[{"type":"surface","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"mesh3d":[{"type":"mesh3d","colorbar":{"outlinewidth":0,"ticks":""}}],"scatter":[{"fillpattern":{"fillmode":"overlay","size":10,"solidity":0.2},"type":"scatter"}],"parcoords":[{"type":"parcoords","line":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterpolargl":[{"type":"scatterpolargl","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"bar":[{"error_x":{"color":"#2a3f5f"},"error_y":{"color":"#2a3f5f"},"marker":{"line":{"color":"#E5ECF6","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"bar"}],"scattergeo":[{"type":"scattergeo","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterpolar":[{"type":"scatterpolar","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"histogram":[{"marker":{"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"histogram"}],"scattergl":[{"type":"scattergl","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatter3d":[{"type":"scatter3d","line":{"colorbar":{"outlinewidth":0,"ticks":""}},"marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scattermap":[{"type":"scattermap","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scattermapbox":[{"type":"scattermapbox","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterternary":[{"type":"scatterternary","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scattercarpet":[{"type":"scattercarpet","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"carpet":[{"aaxis":{"endlinecolor":"#2a3f5f","gridcolor":"white","linecolor":"white","minorgridcolor":"white","startlinecolor":"#2a3f5f"},"baxis":{"endlinecolor":"#2a3f5f","gridcolor":"white","linecolor":"white","minorgridcolor":"white","startlinecolor":"#2a3f5f"},"type":"carpet"}],"table":[{"cells":{"fill":{"color":"#EBF0F8"},"line":{"color":"white"}},"header":{"fill":{"color":"#C8D4E3"},"line":{"color":"white"}},"type":"table"}],"barpolar":[{"marker":{"line":{"color":"#E5ECF6","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"barpolar"}],"pie":[{"automargin":true,"type":"pie"}]},"layout":{"autotypenumbers":"strict","colorway":["#636efa","#EF553B","#00cc96","#ab63fa","#FFA15A","#19d3f3","#FF6692","#B6E880","#FF97FF","#FECB52"],"font":{"color":"#2a3f5f"},"hovermode":"closest","hoverlabel":{"align":"left"},"paper_bgcolor":"white","plot_bgcolor":"#E5ECF6","polar":{"bgcolor":"#E5ECF6","angularaxis":{"gridcolor":"white","linecolor":"white","ticks":""},"radialaxis":{"gridcolor":"white","linecolor":"white","ticks":""}},"ternary":{"bgcolor":"#E5ECF6","aaxis":{"gridcolor":"white","linecolor":"white","ticks":""},"baxis":{"gridcolor":"white","linecolor":"white","ticks":""},"caxis":{"gridcolor":"white","linecolor":"white","ticks":""}},"coloraxis":{"colorbar":{"outlinewidth":0,"ticks":""}},"colorscale":{"sequential":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"sequentialminus":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"diverging":[[0,"#8e0152"],[0.1,"#c51b7d"],[0.2,"#de77ae"],[0.3,"#f1b6da"],[0.4,"#fde0ef"],[0.5,"#f7f7f7"],[0.6,"#e6f5d0"],[0.7,"#b8e186"],[0.8,"#7fbc41"],[0.9,"#4d9221"],[1,"#276419"]]},"xaxis":{"gridcolor":"white","linecolor":"white","ticks":"","title":{"standoff":15},"zerolinecolor":"white","automargin":true,"zerolinewidth":2},"yaxis":{"gridcolor":"white","linecolor":"white","ticks":"","title":{"standoff":15},"zerolinecolor":"white","automargin":true,"zerolinewidth":2},"scene":{"xaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2},"yaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2},"zaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2}},"shapedefaults":{"line":{"color":"#2a3f5f"}},"annotationdefaults":{"arrowcolor":"#2a3f5f","arrowhead":0,"arrowwidth":1},"geo":{"bgcolor":"white","landcolor":"#E5ECF6","subunitcolor":"white","showland":true,"showlakes":true,"lakecolor":"white"},"title":{"x":0.05},"mapbox":{"style":"light"}}}}} +{"data":[{"domain":{"x":[0,1],"y":[0,1]},"gauge":{"axis":{"range":[0,100],"tickcolor":"darkblue","tickfont":{"color":"black","size":20},"ticksuffix":"%","tickwidth":1},"bar":{"color":"black"},"steps":[{"color":"tomato","range":[0,25.0]},{"color":"gold","range":[25.0,75.0]},{"color":"darkseagreen","range":[75.0,100]}]},"mode":"gauge+number","number":{"suffix":"%"},"value":41.61347970385499,"type":"indicator"}],"layout":{"autosize":true,"font":{"color":"black","family":"Arial"},"plot_bgcolor":"rgba(0,0,0,0)","xaxis":{"fixedrange":true,"range":[-1,1],"showgrid":false,"visible":false},"yaxis":{"fixedrange":true,"range":[0,1],"showgrid":false,"visible":false},"template":{"data":{"histogram2dcontour":[{"type":"histogram2dcontour","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"choropleth":[{"type":"choropleth","colorbar":{"outlinewidth":0,"ticks":""}}],"histogram2d":[{"type":"histogram2d","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"heatmap":[{"type":"heatmap","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"contourcarpet":[{"type":"contourcarpet","colorbar":{"outlinewidth":0,"ticks":""}}],"contour":[{"type":"contour","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"surface":[{"type":"surface","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"mesh3d":[{"type":"mesh3d","colorbar":{"outlinewidth":0,"ticks":""}}],"scatter":[{"fillpattern":{"fillmode":"overlay","size":10,"solidity":0.2},"type":"scatter"}],"parcoords":[{"type":"parcoords","line":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterpolargl":[{"type":"scatterpolargl","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"bar":[{"error_x":{"color":"#2a3f5f"},"error_y":{"color":"#2a3f5f"},"marker":{"line":{"color":"#E5ECF6","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"bar"}],"scattergeo":[{"type":"scattergeo","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterpolar":[{"type":"scatterpolar","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"histogram":[{"marker":{"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"histogram"}],"scattergl":[{"type":"scattergl","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatter3d":[{"type":"scatter3d","line":{"colorbar":{"outlinewidth":0,"ticks":""}},"marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scattermap":[{"type":"scattermap","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scattermapbox":[{"type":"scattermapbox","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterternary":[{"type":"scatterternary","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scattercarpet":[{"type":"scattercarpet","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"carpet":[{"aaxis":{"endlinecolor":"#2a3f5f","gridcolor":"white","linecolor":"white","minorgridcolor":"white","startlinecolor":"#2a3f5f"},"baxis":{"endlinecolor":"#2a3f5f","gridcolor":"white","linecolor":"white","minorgridcolor":"white","startlinecolor":"#2a3f5f"},"type":"carpet"}],"table":[{"cells":{"fill":{"color":"#EBF0F8"},"line":{"color":"white"}},"header":{"fill":{"color":"#C8D4E3"},"line":{"color":"white"}},"type":"table"}],"barpolar":[{"marker":{"line":{"color":"#E5ECF6","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"barpolar"}],"pie":[{"automargin":true,"type":"pie"}]},"layout":{"autotypenumbers":"strict","colorway":["#636efa","#EF553B","#00cc96","#ab63fa","#FFA15A","#19d3f3","#FF6692","#B6E880","#FF97FF","#FECB52"],"font":{"color":"#2a3f5f"},"hovermode":"closest","hoverlabel":{"align":"left"},"paper_bgcolor":"white","plot_bgcolor":"#E5ECF6","polar":{"bgcolor":"#E5ECF6","angularaxis":{"gridcolor":"white","linecolor":"white","ticks":""},"radialaxis":{"gridcolor":"white","linecolor":"white","ticks":""}},"ternary":{"bgcolor":"#E5ECF6","aaxis":{"gridcolor":"white","linecolor":"white","ticks":""},"baxis":{"gridcolor":"white","linecolor":"white","ticks":""},"caxis":{"gridcolor":"white","linecolor":"white","ticks":""}},"coloraxis":{"colorbar":{"outlinewidth":0,"ticks":""}},"colorscale":{"sequential":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"sequentialminus":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"diverging":[[0,"#8e0152"],[0.1,"#c51b7d"],[0.2,"#de77ae"],[0.3,"#f1b6da"],[0.4,"#fde0ef"],[0.5,"#f7f7f7"],[0.6,"#e6f5d0"],[0.7,"#b8e186"],[0.8,"#7fbc41"],[0.9,"#4d9221"],[1,"#276419"]]},"xaxis":{"gridcolor":"white","linecolor":"white","ticks":"","title":{"standoff":15},"zerolinecolor":"white","automargin":true,"zerolinewidth":2},"yaxis":{"gridcolor":"white","linecolor":"white","ticks":"","title":{"standoff":15},"zerolinecolor":"white","automargin":true,"zerolinewidth":2},"scene":{"xaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2},"yaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2},"zaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2}},"shapedefaults":{"line":{"color":"#2a3f5f"}},"annotationdefaults":{"arrowcolor":"#2a3f5f","arrowhead":0,"arrowwidth":1},"geo":{"bgcolor":"white","landcolor":"#E5ECF6","subunitcolor":"white","showland":true,"showlakes":true,"lakecolor":"white"},"title":{"x":0.05},"mapbox":{"style":"light"}}}}} diff --git a/tests/approvals/integrationtests/indicators/test_attribute_completeness.py--TestFigure--test_create_figure[3513071900].approved.json b/tests/approvals/integrationtests/indicators/test_attribute_completeness.py--TestFigure--test_create_figure[3513071900].approved.json index 59bbcff6c..cde0d2a72 100644 --- a/tests/approvals/integrationtests/indicators/test_attribute_completeness.py--TestFigure--test_create_figure[3513071900].approved.json +++ b/tests/approvals/integrationtests/indicators/test_attribute_completeness.py--TestFigure--test_create_figure[3513071900].approved.json @@ -1 +1 @@ -{"data":[{"domain":{"x":[0,1],"y":[0,1]},"gauge":{"axis":{"range":[0,100],"tickcolor":"darkblue","tickfont":{"color":"black","size":20},"ticksuffix":"%","tickwidth":1},"bar":{"color":"black"},"steps":[{"color":"tomato","range":[0,25.0]},{"color":"gold","range":[25.0,75.0]},{"color":"darkseagreen","range":[75.0,100]}]},"mode":"gauge+number","number":{"suffix":"%"},"value":39.8293,"type":"indicator"}],"layout":{"autosize":true,"font":{"color":"black","family":"Arial"},"plot_bgcolor":"rgba(0,0,0,0)","xaxis":{"fixedrange":true,"range":[-1,1],"showgrid":false,"visible":false},"yaxis":{"fixedrange":true,"range":[0,1],"showgrid":false,"visible":false},"template":{"data":{"histogram2dcontour":[{"type":"histogram2dcontour","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"choropleth":[{"type":"choropleth","colorbar":{"outlinewidth":0,"ticks":""}}],"histogram2d":[{"type":"histogram2d","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"heatmap":[{"type":"heatmap","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"contourcarpet":[{"type":"contourcarpet","colorbar":{"outlinewidth":0,"ticks":""}}],"contour":[{"type":"contour","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"surface":[{"type":"surface","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"mesh3d":[{"type":"mesh3d","colorbar":{"outlinewidth":0,"ticks":""}}],"scatter":[{"fillpattern":{"fillmode":"overlay","size":10,"solidity":0.2},"type":"scatter"}],"parcoords":[{"type":"parcoords","line":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterpolargl":[{"type":"scatterpolargl","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"bar":[{"error_x":{"color":"#2a3f5f"},"error_y":{"color":"#2a3f5f"},"marker":{"line":{"color":"#E5ECF6","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"bar"}],"scattergeo":[{"type":"scattergeo","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterpolar":[{"type":"scatterpolar","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"histogram":[{"marker":{"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"histogram"}],"scattergl":[{"type":"scattergl","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatter3d":[{"type":"scatter3d","line":{"colorbar":{"outlinewidth":0,"ticks":""}},"marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scattermap":[{"type":"scattermap","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scattermapbox":[{"type":"scattermapbox","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterternary":[{"type":"scatterternary","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scattercarpet":[{"type":"scattercarpet","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"carpet":[{"aaxis":{"endlinecolor":"#2a3f5f","gridcolor":"white","linecolor":"white","minorgridcolor":"white","startlinecolor":"#2a3f5f"},"baxis":{"endlinecolor":"#2a3f5f","gridcolor":"white","linecolor":"white","minorgridcolor":"white","startlinecolor":"#2a3f5f"},"type":"carpet"}],"table":[{"cells":{"fill":{"color":"#EBF0F8"},"line":{"color":"white"}},"header":{"fill":{"color":"#C8D4E3"},"line":{"color":"white"}},"type":"table"}],"barpolar":[{"marker":{"line":{"color":"#E5ECF6","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"barpolar"}],"pie":[{"automargin":true,"type":"pie"}]},"layout":{"autotypenumbers":"strict","colorway":["#636efa","#EF553B","#00cc96","#ab63fa","#FFA15A","#19d3f3","#FF6692","#B6E880","#FF97FF","#FECB52"],"font":{"color":"#2a3f5f"},"hovermode":"closest","hoverlabel":{"align":"left"},"paper_bgcolor":"white","plot_bgcolor":"#E5ECF6","polar":{"bgcolor":"#E5ECF6","angularaxis":{"gridcolor":"white","linecolor":"white","ticks":""},"radialaxis":{"gridcolor":"white","linecolor":"white","ticks":""}},"ternary":{"bgcolor":"#E5ECF6","aaxis":{"gridcolor":"white","linecolor":"white","ticks":""},"baxis":{"gridcolor":"white","linecolor":"white","ticks":""},"caxis":{"gridcolor":"white","linecolor":"white","ticks":""}},"coloraxis":{"colorbar":{"outlinewidth":0,"ticks":""}},"colorscale":{"sequential":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"sequentialminus":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"diverging":[[0,"#8e0152"],[0.1,"#c51b7d"],[0.2,"#de77ae"],[0.3,"#f1b6da"],[0.4,"#fde0ef"],[0.5,"#f7f7f7"],[0.6,"#e6f5d0"],[0.7,"#b8e186"],[0.8,"#7fbc41"],[0.9,"#4d9221"],[1,"#276419"]]},"xaxis":{"gridcolor":"white","linecolor":"white","ticks":"","title":{"standoff":15},"zerolinecolor":"white","automargin":true,"zerolinewidth":2},"yaxis":{"gridcolor":"white","linecolor":"white","ticks":"","title":{"standoff":15},"zerolinecolor":"white","automargin":true,"zerolinewidth":2},"scene":{"xaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2},"yaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2},"zaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2}},"shapedefaults":{"line":{"color":"#2a3f5f"}},"annotationdefaults":{"arrowcolor":"#2a3f5f","arrowhead":0,"arrowwidth":1},"geo":{"bgcolor":"white","landcolor":"#E5ECF6","subunitcolor":"white","showland":true,"showlakes":true,"lakecolor":"white"},"title":{"x":0.05},"mapbox":{"style":"light"}}}}} +{"data":[{"domain":{"x":[0,1],"y":[0,1]},"gauge":{"axis":{"range":[0,100],"tickcolor":"darkblue","tickfont":{"color":"black","size":20},"ticksuffix":"%","tickwidth":1},"bar":{"color":"black"},"steps":[{"color":"tomato","range":[0,25.0]},{"color":"gold","range":[25.0,75.0]},{"color":"darkseagreen","range":[75.0,100]}]},"mode":"gauge+number","number":{"suffix":"%"},"value":41.61347970385499,"type":"indicator"}],"layout":{"autosize":true,"font":{"color":"black","family":"Arial"},"plot_bgcolor":"rgba(0,0,0,0)","xaxis":{"fixedrange":true,"range":[-1,1],"showgrid":false,"visible":false},"yaxis":{"fixedrange":true,"range":[0,1],"showgrid":false,"visible":false},"template":{"data":{"histogram2dcontour":[{"type":"histogram2dcontour","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"choropleth":[{"type":"choropleth","colorbar":{"outlinewidth":0,"ticks":""}}],"histogram2d":[{"type":"histogram2d","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"heatmap":[{"type":"heatmap","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"contourcarpet":[{"type":"contourcarpet","colorbar":{"outlinewidth":0,"ticks":""}}],"contour":[{"type":"contour","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"surface":[{"type":"surface","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"mesh3d":[{"type":"mesh3d","colorbar":{"outlinewidth":0,"ticks":""}}],"scatter":[{"fillpattern":{"fillmode":"overlay","size":10,"solidity":0.2},"type":"scatter"}],"parcoords":[{"type":"parcoords","line":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterpolargl":[{"type":"scatterpolargl","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"bar":[{"error_x":{"color":"#2a3f5f"},"error_y":{"color":"#2a3f5f"},"marker":{"line":{"color":"#E5ECF6","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"bar"}],"scattergeo":[{"type":"scattergeo","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterpolar":[{"type":"scatterpolar","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"histogram":[{"marker":{"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"histogram"}],"scattergl":[{"type":"scattergl","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatter3d":[{"type":"scatter3d","line":{"colorbar":{"outlinewidth":0,"ticks":""}},"marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scattermap":[{"type":"scattermap","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scattermapbox":[{"type":"scattermapbox","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterternary":[{"type":"scatterternary","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scattercarpet":[{"type":"scattercarpet","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"carpet":[{"aaxis":{"endlinecolor":"#2a3f5f","gridcolor":"white","linecolor":"white","minorgridcolor":"white","startlinecolor":"#2a3f5f"},"baxis":{"endlinecolor":"#2a3f5f","gridcolor":"white","linecolor":"white","minorgridcolor":"white","startlinecolor":"#2a3f5f"},"type":"carpet"}],"table":[{"cells":{"fill":{"color":"#EBF0F8"},"line":{"color":"white"}},"header":{"fill":{"color":"#C8D4E3"},"line":{"color":"white"}},"type":"table"}],"barpolar":[{"marker":{"line":{"color":"#E5ECF6","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"barpolar"}],"pie":[{"automargin":true,"type":"pie"}]},"layout":{"autotypenumbers":"strict","colorway":["#636efa","#EF553B","#00cc96","#ab63fa","#FFA15A","#19d3f3","#FF6692","#B6E880","#FF97FF","#FECB52"],"font":{"color":"#2a3f5f"},"hovermode":"closest","hoverlabel":{"align":"left"},"paper_bgcolor":"white","plot_bgcolor":"#E5ECF6","polar":{"bgcolor":"#E5ECF6","angularaxis":{"gridcolor":"white","linecolor":"white","ticks":""},"radialaxis":{"gridcolor":"white","linecolor":"white","ticks":""}},"ternary":{"bgcolor":"#E5ECF6","aaxis":{"gridcolor":"white","linecolor":"white","ticks":""},"baxis":{"gridcolor":"white","linecolor":"white","ticks":""},"caxis":{"gridcolor":"white","linecolor":"white","ticks":""}},"coloraxis":{"colorbar":{"outlinewidth":0,"ticks":""}},"colorscale":{"sequential":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"sequentialminus":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"diverging":[[0,"#8e0152"],[0.1,"#c51b7d"],[0.2,"#de77ae"],[0.3,"#f1b6da"],[0.4,"#fde0ef"],[0.5,"#f7f7f7"],[0.6,"#e6f5d0"],[0.7,"#b8e186"],[0.8,"#7fbc41"],[0.9,"#4d9221"],[1,"#276419"]]},"xaxis":{"gridcolor":"white","linecolor":"white","ticks":"","title":{"standoff":15},"zerolinecolor":"white","automargin":true,"zerolinewidth":2},"yaxis":{"gridcolor":"white","linecolor":"white","ticks":"","title":{"standoff":15},"zerolinecolor":"white","automargin":true,"zerolinewidth":2},"scene":{"xaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2},"yaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2},"zaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2}},"shapedefaults":{"line":{"color":"#2a3f5f"}},"annotationdefaults":{"arrowcolor":"#2a3f5f","arrowhead":0,"arrowwidth":1},"geo":{"bgcolor":"white","landcolor":"#E5ECF6","subunitcolor":"white","showland":true,"showlakes":true,"lakecolor":"white"},"title":{"x":0.05},"mapbox":{"style":"light"}}}}} diff --git a/tests/approvals/integrationtests/indicators/test_land_cover_completeness.py--test_create_land_cover_completeness_calculate.2.approved.txt b/tests/approvals/integrationtests/indicators/test_land_cover_completeness.py--test_create_land_cover_completeness_calculate.2.approved.txt index ca6156a7b..b63ba696b 100644 --- a/tests/approvals/integrationtests/indicators/test_land_cover_completeness.py--test_create_land_cover_completeness_calculate.2.approved.txt +++ b/tests/approvals/integrationtests/indicators/test_land_cover_completeness.py--test_create_land_cover_completeness_calculate.2.approved.txt @@ -1 +1 @@ -0.92 +0.9 diff --git a/tests/approvals/integrationtests/indicators/test_land_cover_completeness.py--test_create_land_cover_completeness_calculate.4.approved.txt b/tests/approvals/integrationtests/indicators/test_land_cover_completeness.py--test_create_land_cover_completeness_calculate.4.approved.txt index 1f167181a..229e7a1a5 100644 --- a/tests/approvals/integrationtests/indicators/test_land_cover_completeness.py--test_create_land_cover_completeness_calculate.4.approved.txt +++ b/tests/approvals/integrationtests/indicators/test_land_cover_completeness.py--test_create_land_cover_completeness_calculate.4.approved.txt @@ -1 +1 @@ -In your area-of-interest, the completeness of OSM land cover data is high. 92% of the total area is covered by OSM land cover data. Note that the area of overlapping OSM land cover polygons will be counted multiple times. +In your area-of-interest, the completeness of OSM land cover data is high. 90% of the total area is covered by OSM land cover data. Note that the area of overlapping OSM land cover polygons will be counted multiple times. diff --git a/tests/approvals/integrationtests/indicators/test_land_cover_completeness.py--test_create_land_cover_completeness_calculate.approved.txt b/tests/approvals/integrationtests/indicators/test_land_cover_completeness.py--test_create_land_cover_completeness_calculate.approved.txt index d072768a1..a2a8139b6 100644 --- a/tests/approvals/integrationtests/indicators/test_land_cover_completeness.py--test_create_land_cover_completeness_calculate.approved.txt +++ b/tests/approvals/integrationtests/indicators/test_land_cover_completeness.py--test_create_land_cover_completeness_calculate.approved.txt @@ -1 +1 @@ -0.92310599 +0.9034049357696076 diff --git a/tests/asyncpg_recorder_cassettes/integrationtests/test_main.py--test_create_indicator_private_feature.cassette.pickle b/tests/asyncpg_recorder_cassettes/integrationtests/test_main.py--test_create_indicator_private_feature.cassette.pickle index 61bd982f4..0f874d9ca 100644 Binary files a/tests/asyncpg_recorder_cassettes/integrationtests/test_main.py--test_create_indicator_private_feature.cassette.pickle and b/tests/asyncpg_recorder_cassettes/integrationtests/test_main.py--test_create_indicator_private_feature.cassette.pickle differ diff --git a/tests/asyncpg_recorder_cassettes/integrationtests/test_main.py--test_create_indicator_public_feature_collection_single.cassette.pickle b/tests/asyncpg_recorder_cassettes/integrationtests/test_main.py--test_create_indicator_public_feature_collection_single.cassette.pickle index afa6ff5ef..c04bdc926 100644 Binary files a/tests/asyncpg_recorder_cassettes/integrationtests/test_main.py--test_create_indicator_public_feature_collection_single.cassette.pickle and b/tests/asyncpg_recorder_cassettes/integrationtests/test_main.py--test_create_indicator_public_feature_collection_single.cassette.pickle differ diff --git a/tests/integrationtests/indicators/test_attribute_completeness.py b/tests/integrationtests/indicators/test_attribute_completeness.py index 0b2b62e01..3573738a7 100644 --- a/tests/integrationtests/indicators/test_attribute_completeness.py +++ b/tests/integrationtests/indicators/test_attribute_completeness.py @@ -252,7 +252,7 @@ def test_filters_match(topic_key_building_count, attribute_key_height): attribute_key_height[0] ].filter, ) - + breakpoint() assert ( indicator_attribute_filter.attribute_filter == indicator_attribute_keys.attribute_filter diff --git a/tests/unittests/test_attribute_definitions.py b/tests/unittests/test_attribute_definitions.py index a0d30f6b5..e85f2c6c3 100644 --- a/tests/unittests/test_attribute_definitions.py +++ b/tests/unittests/test_attribute_definitions.py @@ -32,7 +32,7 @@ def test_get_attribute_wrong_key(): def test_build_attribute_filter(attribute_key, topic_key_building_count): - attribute = definitions.build_attribute_filter( + attribute = definitions.build_attribute_filter_ohsomedb( attribute_key, topic_key_building_count ) assert isinstance(attribute, str) @@ -45,7 +45,7 @@ def test_build_attribute_filter(attribute_key, topic_key_building_count): def test_build_attribute_filter_multiple_attributes( attribute_key_multiple, topic_key_building_count ): - attribute = definitions.build_attribute_filter( + attribute = definitions.build_attribute_filter_ohsomedb( attribute_key_multiple, topic_key_building_count ) assert isinstance(attribute, str) @@ -53,7 +53,7 @@ def test_build_attribute_filter_multiple_attributes( def test_build_attribute_filter_wrong_key(): with pytest.raises(KeyError): - definitions.build_attribute_filter("foo", "bar") + definitions.build_attribute_filter_ohsomedb("foo", "bar") def test_get_attribute_preset(topic_key_building_count): diff --git a/tests/unittests/test_ohsome_client.py b/tests/unittests/test_ohsome_client.py index dfd75d286..76cf0ab85 100644 --- a/tests/unittests/test_ohsome_client.py +++ b/tests/unittests/test_ohsome_client.py @@ -9,7 +9,7 @@ from geojson import FeatureCollection from schema import Schema -from ohsome_quality_api.attributes.definitions import build_attribute_filter +from ohsome_quality_api.attributes.definitions import build_attribute_filter_ohsomedb from ohsome_quality_api.ohsome import client as ohsome_client from ohsome_quality_api.topics.models import TopicData from ohsome_quality_api.utils.exceptions import ( @@ -195,7 +195,9 @@ class TestOhsomeClientBuildUrl(TestCase): def setUp(self) -> None: self.ohsome_api = "https://api.ohsome.org/v1" self.topic = get_topic_fixture("building-count") - self.attribute_filter = build_attribute_filter("height", self.topic.key) + self.attribute_filter = build_attribute_filter_ohsomedb( + "height", self.topic.key + ) def test(self) -> None: ohsome_api = self.ohsome_api @@ -228,7 +230,9 @@ def setUp(self) -> None: self.ohsome_api = "https://api.ohsome.org/v1" self.bpolys = get_geojson_fixture("heidelberg-altstadt-feature.geojson") self.topic = get_topic_fixture("building-count") - self.attribute_filter = build_attribute_filter("height", self.topic.key) + self.attribute_filter = build_attribute_filter_ohsomedb( + "height", self.topic.key + ) def test_feature(self) -> None: schema = Schema( @@ -302,7 +306,9 @@ def test_ratio_time(self) -> None: class TestOhsomeClientValidateQuery(TestCase): def setUp(self) -> None: self.ohsome_api = "https://api.ohsome.org/v1/" - self.attribute_filter = build_attribute_filter("height", "building-count") + self.attribute_filter = build_attribute_filter_ohsomedb( + "height", "building-count" + ) def test_valid_1(self): data = {"result": [{"value": 1.0, "timestamp": "2020-03-20T01:30:08.180856"}]}