-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
88 lines (69 loc) · 3.14 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
from fastapi import FastAPI, Query
from pyproj import CRS, Transformer
from shapely.geometry import Point
from google.cloud import secretmanager
from secretmanager import Config
import requests
import geopandas as gpd
config = Config()
api_key = config.get_api_key()
statsector_parquet = 'data/statistical_sectors_2022.parquet'
app = FastAPI()
@app.get("/get-statsector/")
async def get_statsector(
lat: float = Query(None, description="Latitude"),
lon: float = Query(None, description="Longitude"),
address: str = Query(None, description="Address")
):
if lat is None and lon is None:
if address is not None:
# Additional validation: Ensure address is a string
if not isinstance(address, str):
return {"error": "'address' must be of type string."}
base_url = "https://maps.googleapis.com/maps/api/geocode/json"
params = {
"address": address,
"key": api_key,
}
try:
response = requests.get(base_url, params=params)
data = response.json()
if response.status_code == 200:
if data["status"] == "OK":
location = data["results"][0]["geometry"]["location"]
lat = location["lat"]
lon = location["lng"]
else:
return {"error": f"Geocoding API response status: {data['status']}"}
else:
return {"error": f"Request failed with status code: {response.status_code}"}
except Exception as e:
return {"error": f"An error occurred: {e}"}
else:
return {"error": "Either 'lat' and 'lon' or 'address' must be provided."}
else:
if not isinstance(lat, float) or not isinstance(lon, float):
return {"error": "'lat' and 'lon' must be of type float."}
# Stat Sector uses Lambert projection
# So we have to have transformers, World Geodetic System to Lambert and back
# https://www.ngi.be/website/de-lambert-kaartprojectie-2/
crs_lambert = CRS.from_string("EPSG:31370")
crs_wgs = CRS.from_string("EPSG:4326")
transformer_l2w = Transformer.from_crs(crs_lambert, crs_wgs)
transformer_w2l = Transformer.from_crs(crs_wgs, crs_lambert)
# The following file takes a short while to load
statsectors = gpd.read_parquet(statsector_parquet)
# Transform to Lambert projection
res_lam = transformer_w2l.transform(lat, lon)
lam_coo = Point(res_lam[0], res_lam[1])
try:
# Look up coordinates in the file
sector_results = statsectors[statsectors['geometry'].contains(lam_coo)]
first_sector_result = sector_results.iloc[0]
response = {"sector_id": first_sector_result['cd_sector'], "sector_name": first_sector_result['tx_sector_descr_nl']}
if first_sector_result['cd_sector']:
return response
else:
return {"error": "Sector not found for the given coordinates"}
except Exception as e:
return {"error": str(e)}