Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(building-comparison): add Microsoft Building Footprints dataset #768

Merged
merged 33 commits into from
Feb 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
8b2788f
add datasets.yaml file
Gigaszi Dec 11, 2023
6ba2349
Merge branch 'main' into building-comparison-multiple-datasets
Gigaszi Dec 11, 2023
4d54846
WIP
Gigaszi Dec 14, 2023
b82905e
chore: merge main
Gigaszi Jan 8, 2024
af57908
feat(building-comparison): add functionallity to use multiple coverages
Gigaszi Jan 11, 2024
797799b
changed coverage function to return list of features instead of polyg…
hn437 Jan 11, 2024
8351368
removed geometrycollection as not needed
hn437 Jan 11, 2024
b77e358
coverage function returns list of features with reference data set as…
hn437 Jan 11, 2024
2e4edc0
adapted mock to new structure
hn437 Jan 11, 2024
5722399
adapted coverage test structure to new format
hn437 Jan 11, 2024
2ed9a39
add workflow for showing mulitple datasets
Gigaszi Jan 16, 2024
04c4bca
feat(building-comparison): improve plot for multiple datasets
Gigaszi Jan 18, 2024
b560933
added further tests and removed scope to prevent from ungrounded failing
hn437 Jan 22, 2024
852acf1
adapted result description template to fit multi-references result
hn437 Jan 22, 2024
ee7e844
bugfixing and improving result description
hn437 Jan 22, 2024
43eaddd
add new cassettes for building comparison test
hn437 Jan 22, 2024
168eeac
refactor: small refactors
matthiasschaub Jan 23, 2024
b20e488
Apply suggestions from code review
matthiasschaub Jan 24, 2024
33aa8d4
f
matthiasschaub Jan 24, 2024
73faddb
f
matthiasschaub Jan 24, 2024
a55a6f3
wip
matthiasschaub Jan 24, 2024
4724a36
refactor:
matthiasschaub Jan 29, 2024
2adce70
test(pytest): ignore deprication warnings
matthiasschaub Jan 29, 2024
1f1e545
clean-up
matthiasschaub Jan 30, 2024
4485e32
f
matthiasschaub Jan 30, 2024
77fffbd
docs: update CHANGELOG
matthiasschaub Jan 30, 2024
e48b06e
(geodatabase): do not return None
matthiasschaub Jan 31, 2024
46e720b
feat(building-comparison): add area to legend
Gigaszi Feb 1, 2024
e3e22c3
feat(building-comparison): change color of OSM in plot to grey
Gigaszi Feb 1, 2024
500076a
feat(building-comparison): remove duplicated info from hoverinfo
Gigaszi Feb 1, 2024
3b242a5
fix(building-comparison): coverage function now returns list of features
Gigaszi Feb 1, 2024
0d0e39f
test: add missing vcr cassette decorator
matthiasschaub Feb 3, 2024
d047be3
f
matthiasschaub Feb 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## Current Main

### New Features

- building-comparison: support comparison with multiple datasets ([#768])

[#768]: https://github.com/GIScience/ohsome-quality-api/pull/768

## Release 1.2.0

### New Features
Expand Down
3 changes: 2 additions & 1 deletion ohsome_quality_api/definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"VNL": "Earth Observation Group Nighttime Light Data",
"EUBUCCO": "European building stock characteristics in a common and open "
+ "database",
"Microsoft Buildings": "Microsoft Building Footprints (ODbL)",
}
)

Expand Down Expand Up @@ -106,6 +107,6 @@ def get_project_keys() -> Iterable[str]:

def get_attribution(data_keys: list) -> str:
"""Return attribution text. Individual attributions are separated by semicolons."""
assert set(data_keys) <= {"OSM", "GHSL", "VNL", "EUBUCCO"}
assert set(data_keys) <= {"OSM", "GHSL", "VNL", "EUBUCCO", "Microsoft Buildings"}
filtered = dict(filter(lambda d: d[0] in data_keys, ATTRIBUTION_TEXTS.items()))
return "; ".join([str(v) for v in filtered.values()])
48 changes: 21 additions & 27 deletions ohsome_quality_api/geodatabase/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import asyncpg
import geojson
from asyncpg import Record
from geojson import Feature, FeatureCollection
from geojson import Feature, FeatureCollection, MultiPolygon

from ohsome_quality_api.config import get_config_value

Expand Down Expand Up @@ -69,50 +69,44 @@ async def get_shdi(bpoly: Feature | FeatureCollection) -> list[Record]:
return await conn.fetch(query, geom)


async def get_building_area(bpoly: Feature) -> list[Record]:
"""Get area of building footprints for a bounding polygon."""
file_path = os.path.join(WORKING_DIR, "select_building_area.sql")
# TODO: Check calls of the function
async def get_reference_coverage(table_name: 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()
geom = str(bpoly.geometry)
async with get_connection() as conn:
return await conn.fetch(query, geom)
result = await conn.fetch(query.format(table_name=table_name))
return Feature(geometry=geojson.loads(result[0]["geom"]))


async def get_eubucco_coverage(inverse: bool) -> list[Record]:
file_path = os.path.join(WORKING_DIR, "select_eubucco_coverage.sql")
with open(file_path, "r") as file:
query = file.read()
if inverse:
table_name = "eubucco_v0_1_coverage_inversed"
else:
table_name = "eubucco_v0_1_coverage_simple"
query = query.format(table_name=table_name)
async with get_connection() as conn:
return await conn.fetch(query)


async def get_eubucco_coverage_intersection_area(bpoly: Feature) -> list[Record]:
async def get_intersection_area(bpoly: Feature, table_name: str) -> float:
"""Get ratio of AOI area to intersection area of AOI and coverage geometry.

The result is the ratio of area within coverage (between 0-1) or an empty list if
AOI lies outside of coverage geometry.
"""
file_path = os.path.join(WORKING_DIR, "select_check_eubucco_coverage.sql")
file_path = os.path.join(WORKING_DIR, "select_intersection.sql")
with open(file_path, "r") as file:
query = file.read()
geom = str(bpoly.geometry)
async with get_connection() as conn:
return await conn.fetch(query, geom)
result = await conn.fetch(query.format(table_name=table_name), geom)
if result:
return result[0]["area_ratio"]
else:
return 0.0


async def get_eubucco_coverage_intersection(bpoly: Feature) -> Feature:
async def get_intersection_geom(bpoly: Feature, table_name: str) -> Feature:
"""Get intersection geometry of AoI and coverage geometry."""
file_path = os.path.join(WORKING_DIR, "get_coverage_intersection.sql")
file_path = os.path.join(WORKING_DIR, "select_intersection.sql")
with open(file_path, "r") as file:
query = file.read()
geom = str(bpoly.geometry)
async with get_connection() as conn:
result = await conn.fetch(query, geom)
bpoly["geometry"] = geojson.loads(result[0]["geom"])
return bpoly
result = await conn.fetch(query.format(table_name=table_name), geom)
if result:
return Feature(geometry=geojson.loads(result[0]["geom"]))
else:
return Feature(geometry=MultiPolygon(coordinates=[]))
11 changes: 0 additions & 11 deletions ohsome_quality_api/geodatabase/get_coverage_intersection.sql

This file was deleted.

7 changes: 3 additions & 4 deletions ohsome_quality_api/geodatabase/select_building_area.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ WITH bpoly AS (
ST_Setsrid (ST_GeomFromGeoJSON (%s), 4326) AS geom
)
SELECT
SUM(eubucco.area) as area
FROM
eubucco,
SUM({table_name}.area) as area
FROM {table_name},
bpoly
WHERE
ST_Intersects (eubucco.centroid, bpoly.geom);
ST_Intersects ({table_name}.centroid, bpoly.geom);
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ WITH bpoly AS (
)
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_Area (ST_Intersection (bpoly.geom, coverage.geom)) / ST_Area (bpoly.geom) as area_ratio,
ST_AsGeoJSON (ST_Intersection (bpoly.geom, coverage.geom)) AS geom
FROM
bpoly,
eubucco_v0_1_coverage_simple coverage
{table_name} coverage
WHERE
ST_Intersects (bpoly.geom, coverage.geom)
34 changes: 19 additions & 15 deletions ohsome_quality_api/indicators/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from abc import ABCMeta, abstractmethod

import plotly.graph_objects as go
from geojson import Feature, MultiPolygon, Polygon
from geojson import Feature, Polygon

from ohsome_quality_api.definitions import get_attribution, get_metadata
from ohsome_quality_api.indicators.models import IndicatorMetadata, Result
Expand Down Expand Up @@ -102,22 +102,26 @@ def attribution(cls) -> str:
return get_attribution(["OSM"])

@classmethod
async def coverage(cls, inverse=False) -> Polygon | MultiPolygon:
"""Return coverage geometry. Default is global coverage."""
async def coverage(cls, inverse=False) -> list[Feature]:
"""Return coverage geometries. Default is global coverage."""
if inverse is False:
return Polygon(
coordinates=[
[
(-180, 90),
(-180, -90),
(180, -90),
(180, 90),
(-180, 90),
]
]
)
return [
Feature(
geometry=Polygon(
coordinates=[
[
(-180, 90),
(-180, -90),
(180, -90),
(180, 90),
(-180, 90),
]
]
)
)
]
else:
return Polygon(coordinates=[])
return [Feature(Polygon(coordinates=[]))]

@abstractmethod
async def preprocess(self) -> None:
Expand Down
23 changes: 23 additions & 0 deletions ohsome_quality_api/indicators/building_comparison/datasets.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
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_v0_1_coverage_simple
inversed: eubucco_v0_1_coverage_inversed

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
Loading