Skip to content

API References

This part of the project documentation focuses on an information-oriented approach. Use it as a reference for the technical implementation of the calculator project code.

Computation of geospatial distances (WGS84).

Computation of Geospatial Distances (WGS84)

Coordinates are assumed to be in Latitude and Longitude (WGS 84). Accepting numpy arrays as input.

The geospatial distance calculation is based on Vincenty's inverse method formula and accelerated with Numba (see geokernels.geodesics.geodesic_vincenty and references).

In a few cases (<0.01%) Vincenty's inverse method can fail to converge, and a fallback option using the slower geographiclib solution is implemented.

Functions Included:

  • geodist: returns a list of distances between points of two lists: dist[i] = distance(XA[i], XB[i])
  • geodist_matrix: returns a distance matrix between all possible combinations of pairwise distances (either between all points in one list or points between two lists). dist[i,j] = distance(XA[i], XB[j]) or distance(X[i], X[j])

This implementation provides a fast computation of geo-spatial distances in comparison to alternative methods for computing geodesic distance (tested: geopy and GeographicLib, see geokernels.test_geodesics for test functions).

References:

geodist(coords1, coords2, metric='meter')

Return distances between two coordinates or two lists of coordinates.

Coordinates are assumed to be in Latitude, Longitude (WGS 84) format.

For distances between all pair combinations, see geo_pdist and geo_cdist.

Parameters:

Name Type Description Default
coords1 array - like

The first set of coordinates in the format (latitude, longitude) or an array with shape (n_points1, 2) for multiple points.

required
coords2 array - like

The second set of coordinates in the format (latitude, longitude) or an array with shape (n_points2, 2) for multiple points. The shape of coords1 should match the shape of coords2.

required
metric str

The unit of measurement for the calculated distances. Possible values are 'meter', 'km', 'mile', or 'nmi'. Default is 'meter'.

'meter'

Returns:

Type Description

float or ndarray: The distance(s) between points, with a length of n_points.

Raises:

Type Description
ValueError
  • If the input coordinates do not have the expected shape.
  • If latitude values are not in the range [-90, 90].
  • If longitude values are not in the range [-180, 180].

Examples:

>>> geodist((52.5200, 13.4050), (48.8566, 2.3522), metric='km')
878.389841013836
>>> coords1 = [(37.7749, -122.4194), (34.0522, -118.2437)]
>>> coords2 = [(40.7128, -74.0060), (41.8781, -87.6298)]
>>> geodist(coords1, coords2, metric='mile')
array([2449.92107243, 1745.82567572])
>>> geodist((37.7749, -122.4194), (37.7749, -122.4194))
0.0
Source code in geodistpy/distance.py
 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
106
107
108
109
110
def geodist(coords1, coords2, metric="meter"):
    """
    Return distances between two coordinates or two lists of coordinates.

    Coordinates are assumed to be in Latitude, Longitude (WGS 84) format.

    For distances between all pair combinations, see geo_pdist and geo_cdist.

    Parameters:
        coords1 (array-like): The first set of coordinates in the format (latitude, longitude) or an array with shape (n_points1, 2) for multiple points.
        coords2 (array-like): The second set of coordinates in the format (latitude, longitude) or an array with shape (n_points2, 2) for multiple points.
            The shape of coords1 should match the shape of coords2.
        metric (str, optional): The unit of measurement for the calculated distances. Possible values are 'meter', 'km', 'mile', or 'nmi'.
            Default is 'meter'.

    Returns:
        float or ndarray: The distance(s) between points, with a length of n_points.

    Raises:
        ValueError:
            - If the input coordinates do not have the expected shape.
            - If latitude values are not in the range [-90, 90].
            - If longitude values are not in the range [-180, 180].

    Examples:
        >>> geodist((52.5200, 13.4050), (48.8566, 2.3522), metric='km')
        878.389841013836

        >>> coords1 = [(37.7749, -122.4194), (34.0522, -118.2437)]
        >>> coords2 = [(40.7128, -74.0060), (41.8781, -87.6298)]
        >>> geodist(coords1, coords2, metric='mile')
        array([2449.92107243, 1745.82567572])

        >>> geodist((37.7749, -122.4194), (37.7749, -122.4194))
        0.0
    """
    coords1 = np.asarray(coords1)
    coords2 = np.asarray(coords2)
    assert coords1.shape == coords2.shape

    conv_fac = _get_conv_factor(metric)

    if np.size(coords1) == 2:
        if coords1.shape[0] != 2 or coords2.shape[0] != 2:
            raise ValueError(
                "coords1 and coords2 must have two dimensions: Latitude, Longitude"
            )
        if (abs(coords1[0]) > 90).any() or (abs(coords2[0]) > 90).any():
            raise ValueError("Latitude values must be in the range [-90, 90]")
        if (abs(coords1[1]) > 180).any() or (abs(coords2[1]) > 180).any():
            raise ValueError("Longitude values must be in the range [-180, 180]")
        return geodesic_vincenty(coords1, coords2) * conv_fac

    if coords1.shape[1] != 2:
        raise ValueError(
            "coords1 and coords2 must have two dimensions: Latitude, Longitude"
        )
    if (abs(coords1[:, 0]) > 90).any() or (abs(coords2[:, 0]) > 90).any():
        raise ValueError("Latitude values must be in the range [-90, 90]")
    if (abs(coords1[:, 1]) > 180).any() or (abs(coords2[:, 1]) > 180).any():
        raise ValueError("Longitude values must be in the range [-180, 180]")
    n_points = len(coords1)
    dist = np.asarray(
        [geodesic_vincenty(coords1[i], coords2[i]) for i in range(n_points)]
    )
    return dist * conv_fac

geodist_matrix(coords1, coords2=None, metric='meter')

Compute distance between each pair of possible combinations.

If coords2 is None, compute distance between all possible pair combinations in coords1. dist[i, j] = distance(XA[i], XB[j])

If coords2 is given, compute distance between each possible pair of the two collections of inputs: dist[i, j] = distance(X[i], X[j])

Coordinates are assumed to be in Latitude, Longitude (WGS 84) format.

Parameters:

Name Type Description Default
coords1 list of tuples

List of coordinates in the format [(lat, long)] or an array with shape (n_points1, 2).

required
coords2 list of tuples

List of coordinates in the format [(lat, long)] or an array with shape (n_points2, 2). If coords2 is not None, coords1.shape must match coords2.shape. Default is None.

None
metric str

The unit of measurement for the calculated distances. Possible values are 'meter', 'km', 'mile', or 'nmi'. Default is 'meter'.

'meter'

Returns:

Name Type Description
ndarray

A distance matrix is returned. - If only coords1 is given, for each i and j, the metric dist(u=XA[i], v=XA[j]) is computed. - If coords2 is not None, for each i and j, the metric dist(u=XA[i], v=XB[j]) is computed and stored in the ij-th entry.

Raises:

Type Description
ValueError
  • If the input coordinates do not have the expected shape.
  • If latitude values are not in the range [-90, 90].
  • If longitude values are not in the range [-180, 180].

Examples:

>>> coords1 = [(52.5200, 13.4050), (48.8566, 2.3522), (37.7749, -122.4194)]
>>> geodist_matrix(coords1, metric='km')
array([[   0.        ,  878.38984101, 8786.58652276],
       [ 878.38984101,    0.        , 9525.03650888],
       [8786.58652276, 9525.03650888,    0.        ]])
>>> coords2 = [(40.7128, -74.0060), (41.8781, -87.6298)]
>>> geodist_matrix(coords1, coords2, metric='mile')
array([[ 3060.81391478, 2437.78157493],
       [ 4290.62813902, 1745.82567572],
       [ 2449.92107243, 1746.57308007]])
Source code in geodistpy/distance.py
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
def geodist_matrix(coords1, coords2=None, metric="meter"):
    """
    Compute distance between each pair of possible combinations.

    If coords2 is None, compute distance between all possible pair combinations in coords1.
    dist[i, j] = distance(XA[i], XB[j])

    If coords2 is given, compute distance between each possible pair of the two collections
    of inputs: dist[i, j] = distance(X[i], X[j])

    Coordinates are assumed to be in Latitude, Longitude (WGS 84) format.

    Parameters:
        coords1 (list of tuples): List of coordinates in the format [(lat, long)] or an array with shape (n_points1, 2).
        coords2 (list of tuples, optional): List of coordinates in the format [(lat, long)] or an array with shape (n_points2, 2).
            If coords2 is not None, coords1.shape must match coords2.shape.
            Default is None.
        metric (str, optional): The unit of measurement for the calculated distances. Possible values are 'meter', 'km', 'mile', or 'nmi'.
            Default is 'meter'.

    Returns:
        ndarray: A distance matrix is returned.
            - If only coords1 is given, for each i and j, the metric dist(u=XA[i], v=XA[j]) is computed.
            - If coords2 is not None, for each i and j, the metric dist(u=XA[i], v=XB[j]) is computed and stored in the ij-th entry.

    Raises:
        ValueError:
            - If the input coordinates do not have the expected shape.
            - If latitude values are not in the range [-90, 90].
            - If longitude values are not in the range [-180, 180].

    Examples:
        >>> coords1 = [(52.5200, 13.4050), (48.8566, 2.3522), (37.7749, -122.4194)]
        >>> geodist_matrix(coords1, metric='km')
        array([[   0.        ,  878.38984101, 8786.58652276],
               [ 878.38984101,    0.        , 9525.03650888],
               [8786.58652276, 9525.03650888,    0.        ]])

        >>> coords2 = [(40.7128, -74.0060), (41.8781, -87.6298)]
        >>> geodist_matrix(coords1, coords2, metric='mile')
        array([[ 3060.81391478, 2437.78157493],
               [ 4290.62813902, 1745.82567572],
               [ 2449.92107243, 1746.57308007]])
    """
    conv_fac = _get_conv_factor(metric)

    coords1 = np.asarray(coords1)
    if coords1.shape[1] != 2:
        raise ValueError(
            "coords1 and coords2 must have two dimensions: Latitude, Longitude"
        )
    if (abs(coords1[:, 0]) > 90).any() or (abs(coords1[:, 1]) > 180).any():
        raise ValueError(
            "Latitude values must be in the range [-90, 90] and Longitude values must be in the range [-180, 180]."
        )

    if coords2 is None:
        dist = pdist(coords1, metric=lambda u, v: geodesic_vincenty(u, v))
        dist = squareform(dist)
    else:
        coords2 = np.asarray(coords2)

        # If two lists of coordinates are given
        assert coords1.shape == coords2.shape
        if (abs(coords2[:, 0]) > 90).any() or (abs(coords2[:, 1]) > 180).any():
            raise ValueError(
                "Latitude values must be in the range [-90, 90] and Longitude values must be in the range [-180, 180]."
            )
        dist = cdist(coords1, coords2, metric=lambda u, v: geodesic_vincenty(u, v))
    return dist * conv_fac

greatcircle(coords1, coords2, metric='meter')

Calculate the distance between two sets of coordinates using the Great Circle approximation.

Parameters:

Name Type Description Default
coords1 array - like

The first set of coordinates in the format (latitude, longitude) or an array with shape (n_points1, 2) for multiple points.

required
coords2 array - like

The second set of coordinates in the format (latitude, longitude) or an array with shape (n_points2, 2) for multiple points. The shape of coords1 should match the shape of coords2.

required
metric str

The unit of measurement for the calculated distances. Possible values are 'meter', 'km', 'mile', or 'nmi'. Default is 'meter'.

'meter'

Returns:

Type Description

float or ndarray: The distance(s) between the points. If multiple points are provided, an ndarray is returned.

Raises:

Type Description
ValueError
  • If the input coordinates do not have the expected shape.
  • If latitude values are not in the range [-90, 90].
  • If longitude values are not in the range [-180, 180].
Notes

The Great Circle formula assumes a spherical Earth and may not be completely accurate for very long distances or in regions with significant variation in the Earth's curvature.

Examples:

>>> greatcircle((52.5200, 13.4050), (48.8566, 2.3522), metric='km')
878.389841013836
>>> coords1 = [(37.7749, -122.4194), (34.0522, -118.2437)]
>>> coords2 = [(40.7128, -74.0060), (41.8781, -87.6298)]
>>> greatcircle(coords1, coords2, metric='mile')
array([2449.92107243, 1745.82567572])
>>> greatcircle((37.7749, -122.4194), (37.7749, -122.4194))
0.0
Source code in geodistpy/distance.py
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
def greatcircle(coords1, coords2, metric="meter"):
    """Calculate the distance between two sets of coordinates using the Great Circle approximation.

    Args:
        coords1 (array-like): The first set of coordinates in the format (latitude, longitude) or an array with shape (n_points1, 2) for multiple points.
        coords2 (array-like): The second set of coordinates in the format (latitude, longitude) or an array with shape (n_points2, 2) for multiple points.
            The shape of coords1 should match the shape of coords2.
        metric (str, optional): The unit of measurement for the calculated distances. Possible values are 'meter', 'km', 'mile', or 'nmi'.
            Default is 'meter'.

    Returns:
        float or ndarray: The distance(s) between the points. If multiple points are provided, an ndarray is returned.

    Raises:
        ValueError:
            - If the input coordinates do not have the expected shape.
            - If latitude values are not in the range [-90, 90].
            - If longitude values are not in the range [-180, 180].

    Notes:
        The Great Circle formula assumes a spherical Earth and may not be completely accurate
        for very long distances or in regions with significant variation in the Earth's curvature.

    Examples:
        >>> greatcircle((52.5200, 13.4050), (48.8566, 2.3522), metric='km')
        878.389841013836

        >>> coords1 = [(37.7749, -122.4194), (34.0522, -118.2437)]
        >>> coords2 = [(40.7128, -74.0060), (41.8781, -87.6298)]
        >>> greatcircle(coords1, coords2, metric='mile')
        array([2449.92107243, 1745.82567572])

        >>> greatcircle((37.7749, -122.4194), (37.7749, -122.4194))
        0.0
    """
    coords1 = np.asarray(coords1)
    coords2 = np.asarray(coords2)
    assert coords1.shape == coords2.shape

    conv_fac = _get_conv_factor(metric)

    if np.size(coords1) == 2:
        return great_circle_array(coords1, coords2) * conv_fac
    if coords1.shape[1] != 2:
        raise ValueError(
            "coords1 and coords2 must have two dimensions: Latitude, Longitude"
        )
    if (abs(coords1[:, 0]) > 90).any() or (abs(coords2[:, 0]) > 90).any():
        raise ValueError("Latitude values must be in the range [-90, 90]")
    if (abs(coords1[:, 1]) > 180).any() or (abs(coords2[:, 1]) > 180).any():
        raise ValueError("Longitude values must be in the range [-180, 180]")

    dist = great_circle_array(coords1, coords2)
    return dist * conv_fac

greatcircle_matrix(coords1, coords2=None, metric='meter')

Compute distance between each pair of possible combinations using spherical asymmetry (Great Circle approximation).

If coords2 is None, compute distance between all possible pair combinations in coords1. dist[i, j] = distance(XA[i], XB[j])

If coords2 is given, compute distance between each possible pair of the two collections of inputs: dist[i, j] = distance(X[i], X[j])

Coordinates are assumed to be in Latitude, Longitude (WGS 84) format.

Parameters:

Name Type Description Default
coords1 list of tuples

List of coordinates in the format [(lat, long)] or an array with shape (n_points1, 2).

required
coords2 list of tuples

List of coordinates in the format [(lat, long)] or an array with shape (n_points2, 2). If coords2 is not None, coords1.shape must match coords2.shape. Default is None.

None
metric str

The unit of measurement for the calculated distances. Possible values are 'meter', 'km', 'mile', or 'nmi'. Default is 'meter'.

'meter'

Returns:

Name Type Description
ndarray

A distance matrix is returned. - If only coords1 is given, for each i and j, the metric dist(u=XA[i], v=XA[j]) is computed. - If coords2 is not None, for each i and j, the metric dist(u=XA[i], v=XB[j]) is computed and stored in the ij-th entry.

Raises:

Type Description
ValueError
  • If the input coordinates do not have the expected shape.
  • If latitude values are not in the range [-90, 90].
  • If longitude values are not in the range [-180, 180].

Examples:

>>> coords1 = [(52.5200, 13.4050), (48.8566, 2.3522), (37.7749, -122.4194)]
>>> greatcircle_matrix(coords1, metric='km')
array([[   0.        ,  878.38984101, 8786.58652276],
       [ 878.38984101,    0.        , 9525.03650888],
       [8786.58652276, 9525.03650888,    0.        ]])
>>> coords2 = [(40.7128, -74.0060), (41.8781, -87.6298)]
>>> greatcircle_matrix(coords1, coords2, metric='mile')
array([[ 3060.81391478, 2437.78157493],
       [ 4290.62813902, 1745.82567572],
       [ 2449.92107243, 1746.57308007]])
Source code in geodistpy/distance.py
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
def greatcircle_matrix(coords1, coords2=None, metric="meter"):
    """
    Compute distance between each pair of possible combinations
    using spherical asymmetry (Great Circle approximation).

    If coords2 is None, compute distance between all possible pair combinations in coords1.
    dist[i, j] = distance(XA[i], XB[j])

    If coords2 is given, compute distance between each possible pair of the two collections
    of inputs: dist[i, j] = distance(X[i], X[j])

    Coordinates are assumed to be in Latitude, Longitude (WGS 84) format.

    Parameters:
        coords1 (list of tuples): List of coordinates in the format [(lat, long)] or an array with shape (n_points1, 2).
        coords2 (list of tuples, optional): List of coordinates in the format [(lat, long)] or an array with shape (n_points2, 2).
            If coords2 is not None, coords1.shape must match coords2.shape.
            Default is None.
        metric (str, optional): The unit of measurement for the calculated distances. Possible values are 'meter', 'km', 'mile', or 'nmi'.
            Default is 'meter'.

    Returns:
        ndarray: A distance matrix is returned.
            - If only coords1 is given, for each i and j, the metric dist(u=XA[i], v=XA[j]) is computed.
            - If coords2 is not None, for each i and j, the metric dist(u=XA[i], v=XB[j]) is computed and stored in the ij-th entry.

    Raises:
        ValueError:
            - If the input coordinates do not have the expected shape.
            - If latitude values are not in the range [-90, 90].
            - If longitude values are not in the range [-180, 180].

    Examples:
        >>> coords1 = [(52.5200, 13.4050), (48.8566, 2.3522), (37.7749, -122.4194)]
        >>> greatcircle_matrix(coords1, metric='km')
        array([[   0.        ,  878.38984101, 8786.58652276],
               [ 878.38984101,    0.        , 9525.03650888],
               [8786.58652276, 9525.03650888,    0.        ]])

        >>> coords2 = [(40.7128, -74.0060), (41.8781, -87.6298)]
        >>> greatcircle_matrix(coords1, coords2, metric='mile')
        array([[ 3060.81391478, 2437.78157493],
               [ 4290.62813902, 1745.82567572],
               [ 2449.92107243, 1746.57308007]])
    """
    conv_fac = _get_conv_factor(metric)

    coords1 = np.asarray(coords1)
    if coords1.shape[1] != 2:
        raise ValueError(
            "coords1 and coords2 must have two dimensions: Latitude, Longitude"
        )
    if (abs(coords1[:, 0]) > 90).any() or (abs(coords1[:, 1]) > 180).any():
        raise ValueError(
            "Latitude values must be in the range [-90, 90] and Longitude values must be in the range [-180, 180]."
        )

    if coords2 is None:
        # If only one list of coordinates is given:
        dist = pdist(coords1, metric=lambda u, v: great_circle(u, v))
        dist = squareform(dist)
    else:
        coords2 = np.asarray(coords2)
        assert coords1.shape == coords2.shape

        if (abs(coords2[:, 0]) > 90).any() or (abs(coords2[:, 1]) > 180).any():
            raise ValueError(
                "Latitude values must be in the range [-90, 90] and Longitude values must be in the range [-180, 180]."
            )
        dist = cdist(coords1, coords2, metric=lambda u, v: great_circle(u, v))
    return dist * conv_fac