GRIB: nearest gridpoint¶
First we ensure the example file is available.
[1]:
from earthkit.geo.distance import GeoKDTree, nearest_point_haversine, nearest_point_kdtree
import earthkit.data as ekd
[2]:
ekd.download_example_file("test.grib")
ds = ekd.from_source("file", "test.grib").to_fieldlist()
Using the KDTree method¶
We define a reference point and get the index of the nearest gridpoint from the first field.
[3]:
lat, lon = ds[0].geography.latlons()
p_ref = (51.45, -0.97)
# distance is in m
idx, distance = nearest_point_kdtree(p_ref, (lat, lon))
idx, distance
[3]:
(array([56]), array([175096.60480163]))
With the resulting index we can get the value at the nearest gridpoint.
[4]:
v = ds[0].values[idx]
v
[4]:
array([285.29272461])
The same method works with multiple reference points.
[5]:
p_ref = [[51.45, 44.49, 50.73], [-0.97, 18.34, -17.1]]
idx, distance = nearest_point_kdtree(p_ref, (lat, lon))
idx
[5]:
array([56, 73, 53])
[6]:
v = ds[0].values[idx]
v
[6]:
array([285.29272461, 297.87768555, 284.27905273])
Using a KDTree object¶
The problem with nearest_point_kdtree() is that the KDTree is rebuilt at each call (since it is not cached at the moment). This can be a costly operation for large grids. To overcome this difficulty we can create a GeoKDTree object and call the nearest point computations directly on it multiple times.
[7]:
tree = GeoKDTree(lat, lon)
idx, distance = tree.nearest_point(p_ref)
idx, distance
[7]:
(array([56, 73, 53]),
array([175096.60480163, 142841.04317786, 169632.89688725]))
[8]:
v = ds[0].values[idx]
v
[8]:
array([285.29272461, 297.87768555, 284.27905273])
[9]:
p_ref = (44.49, 18.34)
idx, distance = tree.nearest_point(p_ref)
idx, distance
[9]:
(array([73]), array([142841.04317786]))
[10]:
v = ds[0].values[idx]
v
[10]:
array([297.87768555])
Using the Haversine method¶
The nearest gridpoint can also be determined with the Haversine method, which is a “brute-force” approach since it computes all the distances between the reference point and the other points using the Haversine distance formula, then finds the points with the shortest distance.
The nearest_point_haversine() method can be used exactly in the same way as nearest_point_kdtree().
We define a reference point and get the index of the nearest gridpoint from the first field.
[11]:
latlon = ds[0].geography.latlons()
p_ref = (51.45, -0.97)
# distance is in m
idx, distance = nearest_point_haversine(p_ref, (lat, lon))
idx, distance
[11]:
(array([56]), array([175096.60480163]))
With the resulting index we can get the value at the nearest gridpoint.
[12]:
v = ds[0].values[idx]
v
[12]:
array([285.29272461])
This time we use 3 reference points.
[13]:
p_ref = [[51.45, 44.49, 50.73], [-0.97, 18.34, -17.1]]
idx, dist = nearest_point_haversine(p_ref, (lat, lon))
idx
[13]:
array([56, 73, 53])
[14]:
v = ds[0].values[idx]
v
[14]:
array([285.29272461, 297.87768555, 284.27905273])