| 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 |
|
|