.. raw:: html :file: ../embed_widgets/windfield.html A Mode S based wind field ------------------------- ADS-B data broadcasted by aircraft contains information about groundspeed and true track angle of its trajectory. When proper requests are sent by a Secondary surveillance radar, aircraft also send more information with true airspeed and heading angle in specific BDS5,0 and BDS6,0 messages (see `Junzi Sun's website `__) Groundspeeds and true track angles are derived from the GNSS positions whereas true airspeed is computed with traditional onboard instruments like `Pitot tubes `__. Here, aircraft behave as a distributed network of moving sensors and researchers [1]_ [2]_ have been recommending methods to derive wind fields from Mode S data. The following method is a very basic approach to compute wind. Please note I am not a meteorology specialist, so feel free to improve this page where it should. .. raw:: html
The example above is wind averaged between 25°W and 55°E and between 32°N and 65°N, from FL200 and above on February 23th 2019, between 14:00 and 16:30 UTC. .. code:: python from traffic.core import Traffic t = Traffic.from_file("") t_extended = ( traffic # download and decode EHS messages (DF 20/21) .query_ehs() # resample/interpolate one sample per second .resample("1s") # median filters .filter(altitude=23, track=53, heading=53, groundspeed=53, TAS=53) # wind triangle computation .compute_wind() # median filter .filter(wind_u=53, wind_v=53) # resample one sample per minute .resample("1 min") # do not use multiprocessing to avoid denial of service .eval(desc="preprocessing") ) # t_extended.to_pickle("wind_backup.pkl") The result of this computation is a set of trajectories: each aircraft yields one point per minute with a 4D-position (timestamp, latitude, longitude, altitude) and a wind vector decomposed along a zonal speed (`wind_u`) and a meridional speed (`wind_v`). We then use `ipyleaflet `__ to display the wind field. The `Velocity` widget requires two 2D matrices of zonal and meridional components of the wind. The following method rounds lat/lon coordinates to the closest integer and average wind in each resulting cell. .. code:: python import xarray as xr def compute_grid(traffic: Traffic) -> xr.Dataset: avg = ( traffic # remove NaN values, just in case .query("wind_u == wind_u") # prepare coordinates for the 4d-grid, also remove NaN in wind .assign( # round coordinates to the closest .33 latitude/longitude lat_=lambda df: (3 * df.latitude.round(0)) / 3, lon_=lambda df: (3 * df.longitude.round(0)) / 3, # This basic version averages on all altitudes/timeranges # but it is easy to use the following fields to display # wind fields in particular time ranges and altitude levels. alt_=lambda df: (3e-3 * df.altitude).round(0) / 3e-3, hour=lambda df: df.timestamp.dt.round("h"), ) # compute the average wind .data[["wind_u", "wind_v", "lat_", "lon_"]] .groupby(["lat_", "lon_"]) .mean() ) # Unstack then fill the holes where possible (2D interpolation) u = avg[["wind_u"]].unstack().interpolate().values v = avg[["wind_v"]].unstack().interpolate().values return xr.Dataset( data_vars={ "u_wind": xr.DataArray(u, coords=avg.index.levels), "v_wind": xr.DataArray(v, coords=avg.index.levels), } ) The following is a basic rendering delegated to ipyleaflet library. .. code:: python from ipyleaflet import Map, basemaps from ipyleaflet.velocity import Velocity # t_extended = Traffic.from_file("wind_backup.pkl") map_ = Map( center=(52, 15), zoom=4, interpolation="nearest", basemap=basemaps.CartoDB.DarkMatter, ) wind = Velocity( data=compute_grid(t_extended), zonal_speed="u_wind", meridional_speed="v_wind", latitude_dimension="lat_", longitude_dimension="lon_", velocity_scale=0.002, max_velocity=150, ) map_.add_layer(wind) map_ .. [1] | Hurter, C., R. Alligier, D. Gianazza, S. Puechmorel, G. Andrienko, and N. Andrienko. | « Wind Parameters Extraction from Aircraft Trajectories ». Computers, Environment and Urban Systems 47 (2014): 28‑43. | https://doi.org/10.1016/j.compenvurbsys.2014.01.005. .. [2] | Sun, Junzi, Huy Vu, Joost Ellerbroek, and Jacco Hoekstra. | « Ground-Based Wind Field Construction from Mode-S and ADS-B Data with a Novel Gas Particle Model », 2017, 9.