1cimport h3lib
2from h3lib cimport H3int
3from .util cimport deg2coord
4
5from cython cimport boundscheck, wraparound
6from libc.math cimport sqrt, sin, cos, asin
7
8cdef double haversineDistance(double th1, double ph1, double th2, double ph2) nogil:
9    cdef:
10        double dx, dy, dz
11        double R = 6371.0088
12
13    ph1 -= ph2
14
15    dz = sin(th1) - sin(th2)
16    dx = cos(ph1) * cos(th1) - cos(th2)
17    dy = sin(ph1) * cos(th1)
18
19    return asin(sqrt(dx*dx + dy*dy + dz*dz) / 2)*2*R
20
21
22@boundscheck(False)
23@wraparound(False)
24cpdef void haversine_vect(
25    const H3int[:] a,
26    const H3int[:] b,
27         double[:] out
28) nogil:
29
30    cdef h3lib.GeoCoord p1, p2
31
32    with nogil:
33        # todo: add these back in when cython 3.0 comes out
34        #assert len(a) == len(b)
35        #assert len(a) <= len(out)
36
37        for i in range(len(a)):
38            h3lib.h3ToGeo(a[i], &p1)
39            h3lib.h3ToGeo(b[i], &p2)
40            out[i] = haversineDistance(
41                p1.lat, p1.lng,
42                p2.lat, p2.lng
43            )
44
45
46@boundscheck(False)
47@wraparound(False)
48cpdef void geo_to_h3_vect(
49    const double[:] lat,
50    const double[:] lng,
51    int res,
52    H3int[:] out
53) nogil:
54
55    cdef h3lib.GeoCoord c
56
57    with nogil:
58        for i in range(len(lat)):
59            c = deg2coord(lat[i], lng[i])
60            out[i] = h3lib.geoToH3(&c, res)
61
62
63@boundscheck(False)
64@wraparound(False)
65cpdef void h3_to_parent_vect(
66    const H3int[:] h,
67    int[:] res,
68    H3int[:] out
69) nogil:
70
71    cdef Py_ssize_t i
72
73    with nogil:
74        for i in range(len(h)):
75            out[i] = h3lib.h3ToParent(h[i], res[i])
76
77
78@boundscheck(False)
79@wraparound(False)
80cpdef void h3_get_resolution_vect(
81    const H3int[:] h,
82    int[:] out,
83) nogil:
84
85    cdef Py_ssize_t i
86
87    with nogil:
88        for i in range(len(h)):
89            out[i] = h3lib.h3GetResolution(h[i])
90