|
import torch |
|
import reverse_geocoder |
|
import numpy as np |
|
|
|
|
|
def haversine(pred, gt): |
|
|
|
|
|
|
|
|
|
lat_diff = pred[:, 0] - gt[:, 0] |
|
lon_diff = pred[:, 1] - gt[:, 1] |
|
|
|
|
|
lhs = torch.sin(lat_diff / 2) ** 2 |
|
rhs = torch.cos(pred[:, 0]) * torch.cos(gt[:, 0]) * torch.sin(lon_diff / 2) ** 2 |
|
a = lhs + rhs |
|
|
|
|
|
c = 2 * torch.arctan2(torch.sqrt(a), torch.sqrt(1 - a)) |
|
distance = 6371 * c |
|
|
|
return distance |
|
|
|
def haversine_np(pred, 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)) |
|
distance = 6371 * c |
|
|
|
return distance |
|
|
|
|
|
def reverse(pred, gt, area): |
|
df = {} |
|
gt_area = {} |
|
nan_mask = {} |
|
areas = ["_".join(["unique", ar]) for ar in area] |
|
if "unique_continent" in areas: |
|
areas.remove("unique_continent") |
|
for ar in areas: |
|
inter = np.array(gt[ar]) |
|
nan_mask[ar] = inter != "nan" |
|
gt_area[ar] = inter[nan_mask[ar]] |
|
location = reverse_geocoder.search( |
|
[ |
|
(lat, lon) |
|
for lat, lon in zip( |
|
np.degrees(pred[:, 0].cpu()), np.degrees(pred[:, 1].cpu()) |
|
) |
|
] |
|
) |
|
if "continent" in area: |
|
continent = torch.load("continent.pt") |
|
inter = np.array([l.get("cc", "") for l in location])[ |
|
nan_mask["unique_country"] |
|
] |
|
df["continent"] = np.array([continent[i] for i in inter]) |
|
gt_area["unique_continent"] = np.array( |
|
[continent[i] for i in gt_area["unique_country"]] |
|
) |
|
|
|
if "country" in area: |
|
df["country"] = np.array([l.get("cc", "") for l in location])[ |
|
nan_mask["unique_country"] |
|
] |
|
if "region" in area: |
|
df["region"] = np.array( |
|
["_".join([l.get("admin1", ""), l.get("cc", "")]) for l in location] |
|
)[nan_mask["unique_region"]] |
|
if "sub-region" in area: |
|
df["sub-region"] = np.array( |
|
[ |
|
"_".join([l.get("admin2", ""), l.get("admin1", ""), l.get("cc", "")]) |
|
for l in location |
|
] |
|
)[nan_mask["unique_sub-region"]] |
|
if "city" in area: |
|
df["city"] = np.array( |
|
[ |
|
"_".join( |
|
[ |
|
l.get("name", ""), |
|
l.get("admin2", ""), |
|
l.get("admin1", ""), |
|
l.get("cc", ""), |
|
] |
|
) |
|
for l in location |
|
] |
|
)[nan_mask["unique_city"]] |
|
|
|
return df, gt_area |
|
|