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

Google Floods Part 3: Adding Inundation Maps; COUNTRY=mozambique #1332

Open
wants to merge 108 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
c5c1215
Adding Google Floods Backend
Aug 8, 2024
b9722d3
Viewing the gauges on the frontend, adding error handling to backend
gislawill Aug 12, 2024
bc92d38
Update comment
gislawill Aug 12, 2024
08a4499
Updates to support tooltip content
gislawill Aug 12, 2024
0653f1e
copy update
gislawill Aug 12, 2024
7cd866d
Refactor title state management
gislawill Aug 12, 2024
94e1588
Fixing and adding server tests
gislawill Aug 12, 2024
6ac3aad
update set_env
ericboucher Aug 13, 2024
eb29b6e
Merge branch 'master' into feature/google-floods/1317
ericboucher Aug 13, 2024
6be26d7
update snapshots
ericboucher Aug 13, 2024
2fe481a
Merge branch 'master' into feature/google-floods/1317
gislawill Aug 15, 2024
7efaf78
Adding graph for google flood data
gislawill Aug 19, 2024
8e84cbb
Adding support for multi country deployments and adding google flood …
gislawill Aug 21, 2024
efdf2c9
Use interpolation for popup titles
gislawill Aug 21, 2024
8fa327c
Adding pytest-recording
gislawill Aug 21, 2024
f5ffbf6
Merge branch 'master' into feature/google-floods/1317
ericboucher Aug 21, 2024
438ee04
Update test_google_floods_api.py
ericboucher Aug 21, 2024
e369704
Merge branch 'feature/google-floods/1317' of https://github.com/WFP-V…
ericboucher Aug 21, 2024
6547f3b
Fixing river template
gislawill Aug 22, 2024
ac58dca
More selective with pytest recording
gislawill Aug 22, 2024
2e4bf07
Adding Google Floods Inundation API
Aug 22, 2024
65af7e7
Merge branch 'master' into feature/google-floods/1317
ericboucher Aug 22, 2024
0adb49d
Update API URL
ericboucher Aug 22, 2024
d358674
Updating inundations to call with same signature as gauges
Aug 23, 2024
6415863
Merge branch 'feature/google-floods/1317' into feature/google-floods-…
gislawill Aug 30, 2024
b206a6e
Merge conflict resolution and units
gislawill Aug 30, 2024
1842c4f
Updating tests
gislawill Aug 31, 2024
3a0b0fd
formatting
gislawill Aug 31, 2024
b0d1828
Using superscript
gislawill Sep 2, 2024
105b7d2
Adding Google Floods Inundation API
Aug 22, 2024
bb77ff7
Updating inundations to call with same signature as gauges
Aug 23, 2024
d397a70
Update tests, fix merge conflicts
gislawill Sep 3, 2024
c8b9be0
Speed up server, update tests
gislawill Sep 3, 2024
98cdc63
Supporting rbd
gislawill Sep 11, 2024
62d47df
Merge branch 'feature/google-floods-forecast-chart/1317' into feature…
ericboucher Sep 25, 2024
dc94f60
Merge branch 'master' into feature/google-floods/1317
ericboucher Sep 25, 2024
850cc51
Displaying inundation maps as geojson polygon layer
gislawill Oct 7, 2024
b0780fa
Merge branch 'master' into feature/google-floods/1317
gislawill Oct 7, 2024
9832dc4
Merge branch 'feature/google-floods/1317' into feature/google-floods-…
gislawill Oct 7, 2024
b3c066a
Merge branch 'feature/google-floods-forecast-chart/1317' into feature…
gislawill Oct 7, 2024
412b0b5
fixing test and ordering
gislawill Oct 7, 2024
97d15be
Merge branch 'feature/google-floods-inundation' of https://github.com…
gislawill Oct 7, 2024
7f401bb
Adding support for Cambodia
gislawill Oct 7, 2024
72d46b7
Merge branch 'feature/google-floods/1317' into feature/google-floods-…
gislawill Oct 7, 2024
e9626dd
Add support for Cambodia
gislawill Oct 7, 2024
d06b5ee
Updating url for data
gislawill Oct 7, 2024
2ce0025
Merge branch 'feature/google-floods-forecast-chart/1317' into feature…
gislawill Oct 7, 2024
35bf7a0
Clean up
gislawill Oct 7, 2024
9760ee6
Fix loading on reload
gislawill Oct 7, 2024
ff92aff
Empty commit
gislawill Oct 7, 2024
03d6ac2
http => https
gislawill Oct 7, 2024
ab5d1cc
Reduce cassettes
gislawill Oct 7, 2024
8735022
Merge branch 'feature/google-floods-inundation' of https://github.com…
wadhwamatic Oct 7, 2024
e39db90
fixing cassettes
gislawill Oct 7, 2024
dcd37e8
Merge branch 'feature/google-floods-inundation' of https://github.com…
wadhwamatic Oct 7, 2024
341a3a7
Merge branch 'master' into feature/google-floods/1317
gislawill Oct 7, 2024
ba7ee64
Merge branch 'feature/google-floods/1317' into feature/google-floods-…
gislawill Oct 7, 2024
cdf65d2
Merge branch 'feature/google-floods-forecast-chart/1317' into feature…
gislawill Oct 7, 2024
1e51479
Merge branch 'master' into feature/google-floods/1317
gislawill Oct 8, 2024
2a890cf
Adding date support
gislawill Oct 9, 2024
481c409
Merge branch 'feature/google-floods/1317' into feature/google-floods-…
gislawill Oct 9, 2024
f37026d
Merge branch 'feature/google-floods-forecast-chart/1317' into feature…
gislawill Oct 9, 2024
33c2692
api lint
gislawill Oct 9, 2024
b51d886
Merge branch 'feature/google-floods-forecast-chart/1317' into feature…
gislawill Oct 9, 2024
e950cc0
Fixing date logic on graph look up
gislawill Oct 9, 2024
2ca409d
Merge branch 'feature/google-floods-forecast-chart/1317' into feature…
gislawill Oct 9, 2024
766d9ed
Updates to chart to denote past vs future
gislawill Oct 10, 2024
efb4735
Adding translation to 'future' label
gislawill Oct 10, 2024
ff01928
Merge branch 'feature/google-floods-forecast-chart/1317' into feature…
gislawill Oct 10, 2024
bfbdb9e
Fix chart tests using mock
gislawill Oct 10, 2024
d825924
Merge branch 'feature/google-floods-forecast-chart/1317' into feature…
gislawill Oct 10, 2024
68e711b
Updating readme
gislawill Oct 10, 2024
0338024
Adding note about ip whitelist
gislawill Oct 10, 2024
a7a29b2
Merge branch 'feature/google-floods-inundation' of https://github.com…
wadhwamatic Oct 10, 2024
6d33543
Google Floods Part 2: Adding tooltip graph; COUNTRY=cambodia (#1330)
gislawill Oct 31, 2024
9204f02
Merge branch 'feature/google-floods/1317' into feature/google-floods-…
gislawill Oct 31, 2024
0963b34
Make the & conditional
ericboucher Oct 31, 2024
c7f3802
Adding inundation layer to moz
gislawill Oct 31, 2024
c8d2adc
updating server response to simpler json
gislawill Nov 7, 2024
334bda5
Layer updates, extending timeouts
gislawill Nov 7, 2024
597d6ff
Update tests and layers
gislawill Nov 7, 2024
c4155ef
Merge branch 'master' into feature/google-floods/1317
gislawill Nov 8, 2024
8c1879c
Merge branch 'feature/google-floods-inundation' of https://github.com…
wadhwamatic Nov 9, 2024
66cba35
Fixing tooltip collapsing
gislawill Nov 12, 2024
05188b3
Updating api with requested changes: test comments, abstracting utili…
gislawill Nov 12, 2024
a45de24
Adding caching
gislawill Nov 12, 2024
93f6b41
Merge branch 'feature/google-floods-inundation' of https://github.com…
wadhwamatic Nov 13, 2024
daaf86c
Update border width
gislawill Nov 15, 2024
439a542
Updates to chart line thickness and time selection
gislawill Nov 15, 2024
5a4c7b8
Merge branch 'feature/google-floods/1317' into feature/google-floods-…
gislawill Nov 22, 2024
5385bc7
lint
gislawill Nov 22, 2024
ee27d9d
requested changes
gislawill Nov 22, 2024
b1b6ec9
Update to cache_geojson
gislawill Nov 22, 2024
9f04de9
fix caching logic
gislawill Nov 22, 2024
3222328
Update cache handling
gislawill Nov 23, 2024
6d8fb11
Merge branch 'master' into feature/google-floods-inundation
gislawill Jan 28, 2025
4736583
Updating cambodia layer config
gislawill Jan 28, 2025
a3caa4b
Update snapshots
gislawill Jan 28, 2025
d4bf748
Update moz layer configuration
gislawill Jan 30, 2025
56306a0
Update snapshot
gislawill Jan 30, 2025
28deed4
Remove cors
gislawill Jan 30, 2025
efaa530
test 2
gislawill Jan 30, 2025
0c3f9c7
Don't wrap in json response
gislawill Jan 30, 2025
acbdb80
Remove double ampersand
gislawill Jan 30, 2025
6c5a00a
adding a cache test
gislawill Jan 30, 2025
9ee7907
cache test
gislawill Jan 30, 2025
7ab21e1
clean up debugging
gislawill Jan 30, 2025
449e44a
Merge branch 'master' into feature/google-floods-inundation
wadhwamatic Feb 4, 2025
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
105 changes: 105 additions & 0 deletions api/app/googleflood.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
"""Get data from Humanitarian Data Cube (HDC) API"""
import logging
import os
import requests
import geopandas as gpd
import pandas as pd
import uuid

from fiona.drvsupport import supported_drivers
supported_drivers['LIBKML'] = 'rw'

logger = logging.getLogger(__name__)

GOOGLE_FLOODS_API_KEY = os.getenv("GOOGLE_FLOODS_API_KEY", "")
if GOOGLE_FLOODS_API_KEY == "":
logger.warning("Missing backend parameter: GOOGLE_FLOODS_API_KEY")

def format_to_geojson(data):
geojson = {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [data["gaugeLocation"]["longitude"], data["gaugeLocation"]["latitude"]]
},
"properties": {
"gaugeId": data["gaugeId"],
"issuedTime": data["issuedTime"],
# not present on all data tested at this point
# handle in the future
# "forecastTimeRange": data["forecastTimeRange"],
# "forecastChange": data["forecastChange"],
# "forecastTrend": data["forecastTrend"],
"severity": data["severity"],
"source": data["source"],
"qualityVerified": data["qualityVerified"]
}
}
if "inundationMapSet" in data:
geojson["properties"]["inundationMapSet"] = data["inundationMapSet"]
return geojson


def get_google_floods_gauges(
iso2: str,
asGeojson: bool = True,
):
"""Get statistical charts data"""

URL = f'https://floodforecasting.googleapis.com/v1/floodStatus:searchLatestFloodStatusByArea?key={GOOGLE_FLOODS_API_KEY}'
response = requests.post(
URL,
json={'regionCode': iso2}
).json().get('floodStatuses', [])

if asGeojson:
geojson_feature_collection = {
"type": "FeatureCollection",
"features": [format_to_geojson(data) for data in response]
}
return geojson_feature_collection
return response


from pydantic import BaseModel
from typing import List

class InundationMap(BaseModel):
level: str
serializedPolygonId: str

class InundationMapSet(BaseModel):
inundationMaps: List[InundationMap]


def get_google_floods_inundations(
inundationMapSet: InundationMapSet,
) -> gpd.GeoDataFrame:
gislawill marked this conversation as resolved.
Show resolved Hide resolved
"""Get statistical charts data"""
level_to_kml = dict()
URL = 'https://floodforecasting.googleapis.com/v1/serializedPolygons/{serializedPolygonId}?key={key}'
for inundationMap in inundationMapSet:
response = requests.get(
URL.format(
serializedPolygonId=inundationMap['serializedPolygonId'],
key = GOOGLE_FLOODS_API_KEY
)
).json()
level_to_kml[inundationMap['level']] = response['kml']

# Create a temp path for writing kmls
tmp_path = os.path.join(f'/tmp/google-floods/{str(uuid.uuid4())}')
if not os.path.exists(tmp_path):
os.makedirs(tmp_path)

gdf_buff = []
for level, kml in level_to_kml.items():
kml_path = os.path.join(tmp_path, f'{level}.kml')
with open(kml_path, 'w') as f:
f.write(kml)
gdf = gpd.read_file(kml_path, driver='KML')
gdf['level'] = level
gdf_buff.append(gdf)

gdf = pd.concat(gdf_buff)
return gdf
16 changes: 16 additions & 0 deletions api/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from app.database.alert_model import AlchemyEncoder, AlertModel
from app.database.database import AlertsDataBase
from app.database.user_info_model import UserInfoModel
from app.googleflood import get_google_floods_gauges, get_google_floods_inundations
from app.hdc import get_hdc_stats
from app.kobo import get_form_dates, get_form_responses, parse_datetime_params
from app.models import AcledRequest, RasterGeotiffModel
Expand Down Expand Up @@ -412,3 +413,18 @@ def post_raster_geotiff(raster_geotiff: RasterGeotiffModel):
return JSONResponse(
content={"download_url": presigned_download_url}, status_code=200
)


@app.get("/google-floods-gauges")
def get_google_floods_gauges_api(
iso2: str,
):
return get_google_floods_gauges(iso2)


@app.get('/google-floods-inundations')
def get_google_floods_inundations_api(
inundationMapSet_JSONString: str,
):
"""Get statistical charts data"""
return get_google_floods_inundations(json.loads(inundationMapSet_JSONString)).to_json()
3 changes: 3 additions & 0 deletions api/app/pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[pytest]
log_cli = true
log_cli_level = INFO
32 changes: 32 additions & 0 deletions api/app/tests/test_google_floods_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from app.googleflood import get_google_floods_gauges, get_google_floods_inundations
from app.main import app
from fastapi.testclient import TestClient
import logging, json

client = TestClient(app)

test_inundation_map_set = [{'level': 'HIGH', 'serializedPolygonId': '9631a3143f2543ae9664c4fba7298931'}, {'level': 'MEDIUM', 'serializedPolygonId': '93444f067f42409493fd907b2b0323b7'}, {'level': 'LOW', 'serializedPolygonId': '757ac60c06ea481aba384201a107d611'}]
test_inundation_map_set_jsonstr = json.dumps(test_inundation_map_set)

def test_get_google_floods_gauges():
gauges = get_google_floods_gauges("BD")
assert len(gauges) > 0


def test_get_google_floods_inundations():
floods = get_google_floods_inundations(test_inundation_map_set)
assert floods.shape[0] > 0


def test_get_google_floods_gauges_api():
response = client.get("/google-floods-gauges?iso2=BD")
assert response.status_code == 200
assert len(response.json()) > 0


def test_get_google_floods_inundation_api():
response = client.get(f"/google-floods-inundations?inundationMapSet_JSONString={test_inundation_map_set_jsonstr}")
assert response.status_code == 200
logging.info(json.dumps(response.json()))
# logging.info(response.json())
assert len(response.json()) > 0
109 changes: 72 additions & 37 deletions api/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion api/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ license = "Apache 2.0"

[tool.poetry.dependencies]
PyJWT = "2.4.0"
python = "<3.11,>=3.8.0"
python = "<3.11,>=3.9.0"
requests = "^2.32.0"
playwright = "1.38.0"
fastapi = "^0.109.1"
Expand All @@ -28,6 +28,7 @@ pystac = "^1.8.4"
pytest-asyncio = "^0.21.1"
pytest-playwright = "^0.4.3"
rasterio = "^1.3.9"
geopandas = "^1.0.1"

[tool.poetry.group.dev.dependencies]
black = "^24.3.0"
Expand Down