Skip to content

Commit a3a83dd

Browse files
committed
add reverse geolocation local db populate script
1 parent c480b2e commit a3a83dd

File tree

2 files changed

+121
-0
lines changed

2 files changed

+121
-0
lines changed
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import json
2+
import logging
3+
import os
4+
from io import BytesIO
5+
6+
import folium
7+
import requests
8+
from dotenv import load_dotenv
9+
from google.cloud import storage
10+
11+
from reverse_geolocation_processor import reverse_geolocation_process
12+
13+
HOST = "localhost"
14+
PORT = 9023
15+
BUCKET_NAME = "verifier"
16+
feed_stable_id = "mdb-1"
17+
18+
station_information_url = (
19+
"https://data.rideflamingo.com/gbfs/3/auckland/station_information.json"
20+
)
21+
vehicle_status_url = "https://data.rideflamingo.com/gbfs/3/auckland/vehicle_status.json"
22+
free_bike_status_url = None
23+
24+
# Load environment variables from .env.local
25+
load_dotenv(dotenv_path=".env.local")
26+
27+
28+
def download_to_local(url: str, filename: str):
29+
"""
30+
Download a file from a URL and upload it to the Google Cloud Storage emulator.
31+
If the file already exists, it will not be downloaded again.
32+
Args:
33+
url (str): The URL to download the file from.
34+
filename (str): The name of the file to save in the emulator.
35+
"""
36+
blob_path = f"{feed_stable_id}/{filename}"
37+
client = storage.Client()
38+
bucket = client.bucket(BUCKET_NAME)
39+
blob = bucket.blob(blob_path)
40+
41+
# Check if the blob already exists in the emulator
42+
if not blob.exists():
43+
logging.info(f"Downloading and uploading: {blob_path}")
44+
with requests.get(url, stream=True) as response:
45+
response.raise_for_status()
46+
blob.content_type = "application/json"
47+
# The file is downloaded into memory before uploading to ensure it's seekable.
48+
# Be careful with large files.
49+
data = BytesIO(response.content)
50+
blob.upload_from_file(data, rewind=True)
51+
else:
52+
logging.info(f"Blob already exists: gs://{BUCKET_NAME}/{blob_path}")
53+
54+
55+
if __name__ == "__main__":
56+
import geopandas as gpd
57+
from gcp_storage_emulator.server import create_server
58+
from flask import Flask, Request
59+
60+
data = {
61+
"stable_id": feed_stable_id,
62+
"dataset_id": "example_dataset_id",
63+
"station_information_url": f"http://{HOST}:{PORT}/{BUCKET_NAME}/{feed_stable_id}/station_information.json",
64+
"vehicle_status_url": f"http://{HOST}:{PORT}/{BUCKET_NAME}/{feed_stable_id}/vehicle_status.json",
65+
"free_bike_status_url": free_bike_status_url,
66+
"strategy": "per-point",
67+
"data_type": "gbfs",
68+
"public": "False",
69+
}
70+
app = Flask(__name__)
71+
72+
try:
73+
os.environ["STORAGE_EMULATOR_HOST"] = f"http://{HOST}:{PORT}"
74+
os.environ["DATASETS_BUCKET_NAME_GBFS"] = BUCKET_NAME
75+
os.environ["DATASETS_BUCKET_NAME_GTFS"] = BUCKET_NAME
76+
server = create_server(
77+
host=HOST, port=PORT, in_memory=False, default_bucket=BUCKET_NAME
78+
)
79+
server.start()
80+
81+
download_to_local(
82+
url=station_information_url, filename="station_information.json"
83+
)
84+
download_to_local(url=vehicle_status_url, filename="vehicle_status.json")
85+
86+
with app.test_request_context(
87+
path="/reverse_geolocation",
88+
method="POST",
89+
data=json.dumps(data),
90+
headers={"Content-Type": "application/json"},
91+
):
92+
request = Request.from_values(
93+
method="POST",
94+
path="/reverse_geolocation",
95+
data=json.dumps(data),
96+
headers={"Content-Type": "application/json"},
97+
)
98+
reverse_geolocation_process(request)
99+
100+
# Visualize the resulting geojson file
101+
url = f"http://{HOST}:{PORT}/{BUCKET_NAME}/{feed_stable_id}/geolocation.geojson"
102+
gdf = gpd.read_file(url)
103+
104+
# Calculate centroid for map center
105+
center = gdf.geometry.union_all().centroid
106+
m = folium.Map(location=[center.y, center.x], zoom_start=2)
107+
108+
# Add GeoJSON overlay
109+
folium.GeoJson(gdf).add_to(m)
110+
111+
# Automatically zoom to fit the full polygon bounds
112+
minx, miny, maxx, maxy = gdf.total_bounds
113+
m.fit_bounds([[miny, minx], [maxy, maxx]]) # [[south, west], [north, east]]
114+
115+
# Save the map
116+
m.save(f".cloudstorage/verifier/{feed_stable_id}/geojson_map.html")
117+
except Exception as e:
118+
logging.error(f"Error verifying download content: {e}")
119+
finally:
120+
server.stop()

functions-python/reverse_geolocation_populate/.coveragerc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ omit =
44
*/helpers/*
55
*/database_gen/*
66
*/shared/*
7+
*/scripts/*
78

89
[report]
910
exclude_lines =

0 commit comments

Comments
 (0)