Encoding Wind Direction from Degrees to Compass Labels

Encode 0-360 degree wind into compass labels: rounding, calm versus northerly wrap-around, and mph, knot, and m/s unit conversions as metrology.

Back to Personal weather station notebooks

Wind direction on a station site is a coded measurement, not a caption. The sensor reports a bearing. The page must map that bearing onto a compass rose, preserve wrap-around at north, refuse to call calm air “northerly,” and convert speed units with stated factors. This notebook treats those steps as metrology. Psychrometric indices such as dew point and heat index belong in a separate notebook.

Historical context

The historical TNET Weather notebooks published small PHP helpers that turned a 0–360° value into a 16-point label and converted temperature, wind, and length units. Those recovered functions are evidence of the subject, not a package to redistribute. The durable problem is unchanged: Weather Display, Cumulus, and most loggers store wind as a meteorological degree, while readers expect N, NE, or ENE, and while U.S. pages often display miles per hour beside files that store knots.

Input

You need four facts before any label is honest:

  1. Direction, meteorological convention. Degrees from which the wind blows. North is 0° and 360°. East is 90°. South is 180°. West is 270°. This is the WMO surface-wind convention used in METAR and in almost every personal-station logger.
  2. Speed in a known unit. Knots, miles per hour, or metres per second. Direction without speed cannot distinguish calm from a northerly breeze.
  3. Rose resolution. 8-point, 16-point, or 32-point. Sixteen points (22.5° sectors) is the usual website compromise.
  4. Calm rule. The speed at or below which direction is withheld. NWS and METAR treat calm as a distinct state, not as 0° from the north.

Optional but useful: sensor height, averaging period (for example 2-minute versus 10-minute), and whether the logger already rounded the degree to an integer.

Process: binning 0–360° onto a rose

A 16-point rose divides the circle into sectors 22.5° wide. North must be centered on 0°, not start at 0°. If you bin with floor(deg / 22.5), values from 0° to 22.5° all become N, and true north-northeast is shifted. The correct geometric offset is half a sector: 11.25°.

Conceptual procedure (original; not a recovered script):

  1. If speed is missing, output a missing token such as --- and stop.
  2. If speed is at or below the calm threshold, output Calm (or VRB only if the logger documented variable wind) and stop.
  3. Reduce the degree into [0, 360) with a true modulo so that 360 becomes 0 and negative logger glitches are not silently mapped to south.
  4. Compute sector = floor(((deg + 11.25) % 360) / 22.5) % 16.
  5. Index a 16-label table: N, NNE, NE, ENE, E, ESE, SE, SSE, S, SSW, SW, WSW, W, WNW, NW, NNW.

The wrap-around cases are the ones that fail unit tests:

| Degree | Speed | Honest label | Failure mode if you skip calm or modulo | |---|---|---|---| | 0 | 8 kt | N | Fine if you remember 0 is north and speed is non-calm | | 360 | 8 kt | N | Breaks if you treat 360 as out of range | | 359.9 | 8 kt | N | Breaks if you round down into NNW without the 11.25° offset | | 11.2 | 8 kt | N | Still north; 11.3° is the 16-point boundary toward NNE | | 348.76 | 8 kt | N | 348.75° is the NNW/N boundary | | 0 | 0 kt | Calm | Calling this N invents a northerly |

Integer loggers that already emit 0–359 need the same offset. Adding 11 instead of 11.25 is a historical shortcut that slightly squeezes the north sector. Prefer 11.25° and document it.

Eight-point roses use 45° sectors and a 22.5° offset. Thirty-two-point roses (N, NbE, NNE, …) are rarely worth the clutter on a public dashboard.

Process: unit conversion as metrology

Convert after you have identified the stored unit. Convert once. Round once, at display time.

Defined factors (international, not vendor folklore):

  • Knot to metre per second. One international nautical mile is 1852 m. One knot is 1852/3600 m s−1, which is 0.514444… m s−1.
  • Mile per hour to metre per second. One international mile is 1609.344 m. One mile per hour is 0.44704 m s−1 exactly.
  • Knot to mile per hour. 1.150779… mph per knot (1852/1609.344).
  • Temperature. °C = (°F − 32) / 1.8. The factor 1.8 is exact (9/5). Do not use 2, and do not convert a rounded display value a second time.
  • Rain length. 1 inch = 2.54 cm exactly. A factor of 0.39 in/cm is a rounded reciprocal and will drift monthly rain totals.

Worked example. A ClientRaw-style packet stores 8.5 knots. Display in miles per hour at one decimal: 8.5 × 1.150779 = 9.7816…, shown as 9.8 mph. The same value in SI is 8.5 × 0.514444 ≈ 4.4 m s−1. Label the unit on the page. Mixing “8.5” from the file with an mph axis is a silent error, not a style choice.

Precision rule: keep one extra significant figure in the stored conversion, then round to the resolution of the sensor or the table. A Davis-class cup anemometer does not justify 0.001 mph.

Output

A complete encoding result is a small record:

  • dir_deg — original degree, or null
  • dir_label — 16-point label, Calm, or missing
  • speed_native + native_unit
  • speed_display + display_unit
  • rose — 8, 16, or 32
  • calm_threshold and its unit
  • converted_at — whether rounding happened before or after unit conversion

That record can feed a dashboard, a METAR-like line, or a chart. It is also the object you archive when you later ask why two pages disagreed.

Troubleshooting

North is too wide or too narrow. You omitted the half-sector offset, or you used 11 instead of 11.25 and then rounded the degree first.

360° becomes empty or “---”. The upper bound was written as < 360 instead of modulo wrap. 360 is north.

Calm nights plot as a north spike on the wind rose. The logger stored 0° whenever speed was 0. Filter on speed before you histogram direction.

Variable wind labeled as a point. If the station reports a direction range or a “variable” flag, do not pick the midpoint and call it NE. Show variable.

mph and knots disagree by about 15%. That is the conversion you skipped, not a sensor fault.

Temperature conversion looks a degree off. You rounded °F, converted, then rounded °C. Convert the higher-resolution logger value first.

You copied a function from an old notebook. Do not. Re-implement from the sector math above, or from your logger’s documented enum. Historical PHP is not a standard.

Modern relevance

Encoded wind is still an input family for any system that interprets weather-sensitive performance: direction tells you exposure and fetch; speed unit errors will fake a wind-chill or a “calm” period. How TNET treats public weather sources, units, and quality control is described in data sources and methodology. That page is the next step if you are moving from a station packet to research-grade interpretation. It is not a compass converter.

Related notebooks: reading ClientRaw packets, the ClientRaw field-family reference, and psychrometric indices. The cluster index is the notebooks hub.

Sources

  • World Meteorological Organization. Surface-wind direction is reported as the direction from which the wind blows, in degrees clockwise from true north. See WMO-No. 8, Guide to Instruments and Methods of Observation, wind chapter (current edition via community.wmo.int).
  • International System of Units. Metre, second; nautical mile of 1852 m as used for the knot.
  • National Weather Service. Wind products and METAR calm/variable practice: weather.gov.
  • Weather Display stores ClientRaw wind speed in knots and direction in compass degrees; confirm against the vendor’s current clientrawdescription.txt. Official site: weather-display.com.