import geopandas as gpd
from scipy.spatial import cKDTree
import numpy as np
import pyproj
from functools import lru_cache

# Constants
EPSG_WGS84 = 4326
EPSG_WebMercator = 3857

# Load the geodata.
gdf = gpd.read_file("berlin-latest-free.shp/gis_osm_pois_free_1.shp")

# Get all restaurant points and represent as meters on web mercator projection.
rest = gdf[gdf['fclass'].isin(['restaurant','cafe','fast_food','biergarten','pub'])].to_crs(epsg=EPSG_WGS84)

# Construct a cKDTree of all restaurant points for easy nearest-neighbor lookup.
coords_rest = np.vstack([rest.geometry.x, rest.geometry.y]).T
tree_rest = cKDTree(coords_rest)

# Construct a projection from lat/long to web mercator.
proj_rest = pyproj.Transformer.from_crs(EPSG_WGS84, EPSG_WebMercator, always_xy=True)

def distance_to_nearest_restaurant(lon: float, lat: float) -> float:

	# Project coordinates to mercator.
    x, y = proj.transform(lon, lat)

    # Get the closest point from the tree.
    dist, idx = tree.query([x, y])

    # Returned distance is in meters (from mercator projection).
    return float(dist)