|
import os
|
|
import numpy as np
|
|
import reverse_geocoder
|
|
|
|
|
|
def get_loc(x):
|
|
location = reverse_geocoder.search(x[0].tolist())[0]
|
|
country = location.get("cc", "")
|
|
region = location.get("admin1", "")
|
|
sub_region = location.get("admin2", "")
|
|
city = location.get("name", "")
|
|
|
|
a = country if country != "" else None
|
|
b, c, d = None, None, None
|
|
if a is not None:
|
|
b = country + "," + region if region != "" else None
|
|
if b is not None:
|
|
c = country + "," + region + "," + sub_region if sub_region != "" else None
|
|
d = (
|
|
country + "," + region + "," + sub_region + "," + city
|
|
if city != ""
|
|
else None
|
|
)
|
|
|
|
return a, b, c, d
|
|
|
|
|
|
def get_match_values(pred, gt, N, pos):
|
|
xa, xb, xc, xd = get_loc(gt)
|
|
ya, yb, yc, yd = get_loc(pred)
|
|
|
|
if xa is not None:
|
|
N["country"] += 1
|
|
if xa == ya:
|
|
pos["country"] += 1
|
|
if xb is not None:
|
|
N["region"] += 1
|
|
if xb == yb:
|
|
pos["region"] += 1
|
|
if xc is not None:
|
|
N["sub-region"] += 1
|
|
if xc == yc:
|
|
pos["sub-region"] += 1
|
|
if xd is not None:
|
|
N["city"] += 1
|
|
if xd == yd:
|
|
pos["city"] += 1
|
|
|
|
|
|
def compute_print_accuracy(N, pos):
|
|
for k in N.keys():
|
|
pos[k] /= N[k]
|
|
|
|
|
|
print(
|
|
f'Accuracy: {pos["country"]*100.0:.2f} (country), {pos["region"]*100.0:.2f} (region), {pos["sub-region"]*100.0:.2f} (sub-region), {pos["city"]*100.0:.2f} (city)'
|
|
)
|
|
print(
|
|
f'Haversine: {pos["haversine"]:.2f} (haversine), {pos["geoguessr"]:.2f} (geoguessr)'
|
|
)
|
|
|
|
|
|
def get_filenames(idx):
|
|
from autofaiss import build_index
|
|
|
|
path = join(args.features_parent, f"features-{idx}/")
|
|
files = [f for f in os.listdir(path)]
|
|
full_files = [join(path, f) for f in os.listdir(path)]
|
|
index = build_index(
|
|
embeddings=np.concatenate([np.load(f) for f in tqdm(full_files)], axis=0),
|
|
nb_cores=12,
|
|
save_on_disk=False,
|
|
)[0]
|
|
return index, files
|
|
|
|
|
|
def normalize(x):
|
|
lat, lon = x[:, 0], x[:, 1]
|
|
"""Used to put all lat lon inside ±90 and ±180."""
|
|
lat = (lat + 90) % 360 - 90
|
|
if lat > 90:
|
|
lat = 180 - lat
|
|
lon += 180
|
|
lon = (lon + 180) % 360 - 180
|
|
return np.stack([lat, lon], axis=1)
|
|
|
|
|
|
def haversine(pred, gt, N, p):
|
|
|
|
|
|
pred = np.radians(normalize(pred))
|
|
gt = np.radians(normalize(gt))
|
|
|
|
|
|
lat_diff = pred[:, 0] - gt[:, 0]
|
|
lon_diff = pred[:, 1] - gt[:, 1]
|
|
|
|
|
|
lhs = np.sin(lat_diff / 2) ** 2
|
|
rhs = np.cos(pred[:, 0]) * np.cos(gt[:, 0]) * np.sin(lon_diff / 2) ** 2
|
|
a = lhs + rhs
|
|
|
|
|
|
c = 2 * np.arctan2(np.sqrt(a), np.sqrt(1 - a))
|
|
|
|
haversine_distance = 6371 * c[0]
|
|
geoguessr_sum = 5000 * np.exp(-haversine_distance / 1492.7)
|
|
|
|
N["geoguessr"] += 1
|
|
p["geoguessr"] += geoguessr_sum
|
|
|
|
N["haversine"] += 1
|
|
p["haversine"] += haversine_distance
|
|
|