File size: 3,255 Bytes
c4c7cee
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import torch
import reverse_geocoder
import numpy as np


def haversine(pred, gt):
    # expects inputs to be np arrays in (lat, lon) format as radians
    # N x 2

    # calculate the difference in latitude and longitude between the predicted and ground truth points
    lat_diff = pred[:, 0] - gt[:, 0]
    lon_diff = pred[:, 1] - gt[:, 1]

    # calculate the haversine formula components
    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

    # calculate the final distance using the haversine formula
    c = 2 * torch.arctan2(torch.sqrt(a), torch.sqrt(1 - a))
    distance = 6371 * c

    return distance

def haversine_np(pred, gt):
    # expects inputs to be np arrays in (lat, lon) format as radians
    # N x 2

    # calculate the difference in latitude and longitude between the predicted and ground truth points
    lat_diff = pred[0] - gt[0]
    lon_diff = pred[1] - gt[1]

    # calculate the haversine formula components
    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

    # calculate the final distance using the haversine formula
    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