Changelog
What changed, newest first. A result change means a published answer moved; it names the test vectors it replaced, which stay in each tool's downloadable test vectors, marked superseded. Every release also has a verification report.
2026-09-23
Fixed Converting UTC to local time, the sentence repeated the Zulu time you entered ("That is 2300Z.") instead of the answer. It now gives the local time and zone ("That is 15:00 AKDT."), and when the date changes it gives the local date. Three outputs are new: answer (the converted time in the direction asked), to_local (1 for UTC to local, 0 for local to UTC), and local_date_change. Local to UTC reads as before. The tool is now version 1.1.0.
Tools: Local time to UTC (Zulu)
Fixed Where a twilight or the sunrise does not happen, the page showed codes like "no-civil-twilight-begin" and "polar-day", and the sentence read "Sunrise is polar-day". The result keeps those documented codes for machines, but the page now shows plain words, like "None: the sun does not get low enough for civil twilight to begin", and the sentence says "The sun stays up all day, so there is no sunrise or sunset." The tool is now version 1.0.1.
Fixed A wind straight across the runway read "0 kt tailwind", and one straight down it read "0 kt crosswind from the none": float noise like −0.0000000000000018 kt was taken as a tailwind. Components under a billionth of a knot are now exactly zero, and the sentence says "no headwind or tailwind" or "No crosswind" whenever a component rounds to zero. The wind triangle said "a wind correction of 0° to the right" with no crosswind; it now says "with no wind correction". Runway wind components and the wind triangle are now version 1.0.1.
Tools: Runway wind components, Wind triangle: heading and groundspeed
Fixed An altimeter setting of A2980 showed as 29.8 inHg. Settings are given to hundredths (FAA-H-8083-28B section 24.4.3.11), so the METAR decoder and the QNH of the Q-codes tool now keep the trailing zero: 29.80 inHg. In hPa they read as before. The METAR decoder is now version 1.1.1 and the Q-codes tool 1.1.1.
Tools: METAR decoder, QNH, QFE, and QNE
Fixed The winds aloft code 7799 decoded as "270° true at 199 kt". FB forecasts code 200 kt and more as 199 kt (FAA-H-8083-28B section 27.2.1.1.1), so it now reads "270° true at 199 kt or greater", the row carries speed_bound "at-least", and the result has a SPEED_AT_LEAST note. The decoder is now version 1.1.0.
Tools: Winds aloft (FB) decoder
Fixed NADCON5 (version 1.0.1) cited NOAA Technical Memorandum NOS NGS 84 as the NADCON5 report. That memo is Dru Smith's Biquadratic Interpolation (2022). The tool now cites the NADCON 5.0 report, NOAA Technical Report NOS NGS 63 (Smith and Bilich, 2017, revised 2020), and cites TM 84 separately for the interpolation between grid nodes, which the tool does use. Results are unchanged.
Fixed Identifiers no longer show digit grouping: the EPSG code in SPCS83 forward and zone lookup reads 32129, not 32,129, and the decimal year in magnetic declination reads 2026.71, not 2,026.71 (all version 1.0.1). SPCS83 forward in US survey feet also gave the deprecated-unit warning (LEGACY_UNIT) twice, once for easting and once for northing; every tool now gives it once per result. Values are unchanged.
Tools: Latitude and longitude to state plane (SPCS83), State plane zone lookup, Magnetic declination
Fixed Short distances lost their meaning: a 0.859 m geodesic showed as 0.001 km. Distances in the navigation tools (version 1.0.1) still show to the meter in kilometers, but a short one now keeps three significant digits, down to the millimeter, so it shows as 0.000859 km. Differences such as the rhumb line's extra distance keep fixed decimals. Values are unchanged.
Tools: Distance between two points (geodesic), Haversine distance (spherical), Where two geodesic segments cross, Midpoint on the geodesic, Great-circle distance and course (spherical), Highest point of a geodesic (vertex), Waypoints along a route line, Destination on a constant course (rhumb line), Rhumb line distance and course, Closest point on a route, Where two courses cross, Cross-track and along-track distance, Intercept a moving target, Range rings
Fixed Where the geoid is below the ellipsoid, the sentence said the geoid was a negative height above it ("-17.21 m above the ellipsoid"). It now says "17.21 m below the ellipsoid", and a point under the ground given reads as below the ground. The height converter's second example, a drone reporting 120 m above the ellipsoid over 250 m terrain, put the drone underground; it is replaced by a drone at 180 m above the ellipsoid over 40 m terrain, 117.539 m above the ground. Both tools are version 1.0.1; values are unchanged.
Tools: Geoid height (EGM96), Ellipsoidal and orthometric height
Fixed Tile from point (version 1.0.1) rejected a tile size given as the number 512 ("Tile size must be a string"). Every tool now accepts a numeric option such as 512 as a number or as text.
Result change The forest overlap preset (version 1.1.0) is now 85% front and 85% side. It used 85% front and 70% side, but Pix4D's page recommends at least 85% frontal and side overlap for forest and dense vegetation; 85/70 is its advice for snow and sand. With the preset, flight lines are now closer together: 22.5 m instead of 45 m for a 1-inch camera at 100 m. The superseded vector pinned the old line spacing.
Tools: Overlap, trigger interval, and line spacing
Replaced vectors: drone.photogrammetry.trigger v010
Fixed Visual line of sight (version 1.2.0) now warns when the ground visibility is below 5 km, the least EASA's guidelines recommend. It gave no warning at 1 km or 0.3 km. Above 5 km it still counts only 5 km, but it now credits that cap to the LBA guidance EASA points to, and cites it; it wrongly called 5 km the most the EASA procedure assumes. No distance changes.
Fixed Plain-number results in a fixed unit now show that unit: the battery current reads 9.7 A where it read 9.7, and decibels, gigabytes, pulses per square meter, grams per kilogram, nautical miles per gallon, hours, nanoteslas, and minutes now carry their units too. The numbers themselves do not change. Each tool's patch version went up.
Tools: Battery energy (mAh to Wh), Radio link budget, Dataset size estimate, Lidar mission planning, Humidity and moist air, Specific range, TAF decoder, Magnetic declination, Sunrise, sunset, and twilight
Fixed The unequal-tangent vertical curve's sentence said the curve passed, for example, "96.25 ft under the PVI", when 96.25 ft is the curve's elevation at the PVI station and the curve is 3.75 ft below the PVI. It now says "At the PVI station it is at 96.25 ft, and the PVI is at 100 ft". Version 1.0.1; no numbers change.
Fixed Survey tools cite Ghilani and Wolf's Elementary Surveying, 16th edition (2021), but their method notes said "Ghilani & Wolf 2018". The notes now give 2021, the edition cited. No results change.
Tools: Angular closure of a loop traverse, Intersection (bearings and distances), Least-squares network adjustment (2D), Total-station offset shot, Three-point resection, Station and offset from a line, Circular curve layout table, Vertical curve length for sight distance, Spiral-curve-spiral transition, Unequal-tangent vertical curve, Grid (borrow-pit) volume, Cross-section cut and fill areas, Slope stake (catch point), Stockpile volume (TIN), Site localization (calibration), Curvature and refraction correction, Height of an inaccessible object, Level run reduction and closure, Slope distance to horizontal and vertical, Stadia reduction
Fixed The worked example was titled a 600 m by 150 m field, but its corners are 602 m apart along the lines, which is why it gives 22 photos a line and 104 in all. The title now says 602 m by 150 m. No results change.
Tools: Image count and survey size, Survey grid (lawnmower pattern)
Result change Image count and the survey grid (version 1.1.0) now count the way published flight planning does (Penn State GEOG 892): ⌈width / spacing⌉ + 1 lines with the outer lines on the edges, and ⌈length / photo spacing⌉ + 1 photos per line plus extra photos past each end, 2 by default (a new input; 0 leaves them out). Most areas gain a line. The Penn State block now gives its published 10 lines and 430 photos, where 1.0.0 gave 9 and 342. The superseded vectors pinned the old line counts.
Tools: Image count and survey size, Survey grid (lawnmower pattern)
Replaced vectors: drone.photogrammetry.image-count v001, drone.photogrammetry.image-count v002, drone.photogrammetry.image-count v003, drone.photogrammetry.image-count v004, drone.photogrammetry.image-count v005, drone.mission.survey-grid v001, drone.mission.survey-grid v002, drone.mission.survey-grid v003, drone.mission.survey-grid v004, drone.mission.survey-grid v005
Fixed A left-turn hold flown exactly on the reciprocal of the inbound course got the parallel entry, while the mirror-image right-turn hold got the teardrop. Both entries are acceptable on that line, and the tool still says so, but it now names the teardrop for either turn direction, so a left hold mirrors a right one exactly. Every other heading is unchanged. The worked-out steps now show an arrival along the inbound course as 0 degrees rather than 360. The page diagram also drew each sector label on the wrong side of the fix, as a heading instead of where you arrive from, and drew the pattern to the east of the fix whatever the inbound course; both now match the AIM figure. The tool is now version 1.1.0 and stable.
Tools: Holding pattern entry
Changed Drone flight time is stable. It reproduces the endurance step of Bauersfeld and Scaramuzza's DJI Mavic 3 example (IEEE Robotics and Automation Letters, 2022): 4.89 Ah at 4 × 3.7 V and 89.5 W is 2,909 s, and 4.88 Ah at 107.0 W is 2,429 s, both within the rounding of the printed capacity. The derating field's help now asks for a percent, like 15, where it used to suggest 0.85, which the tool would have read as 0.85%. The reserve's help now says it is a share of the usable energy, which is what the tool has always computed. Results are unchanged.
Tools: Drone flight time
Result change Promoting this tool to stable removed EXPERIMENTAL_TOOL from its warnings, which moved OVERLAP_BELOW_TARGET from index 1 to index 0 and broke eight vectors that pinned the index. Nothing computed changed. v001, v003, v004, v005, v007, v010, v011, and v012 are superseded by v015 to v022, which name the warning with the meta.warnings.*.code form.
Tools: Overlap over high terrain
Replaced vectors: drone.photogrammetry.terrain-overlap v001, drone.photogrammetry.terrain-overlap v003, drone.photogrammetry.terrain-overlap v004, drone.photogrammetry.terrain-overlap v005, drone.photogrammetry.terrain-overlap v007, drone.photogrammetry.terrain-overlap v010, drone.photogrammetry.terrain-overlap v011, drone.photogrammetry.terrain-overlap v012
Result change Station pressure now comes from the altimeter-setting relation instead of a sea-level ratio shortcut. The worked example moved from 5,108 to 5,112 ft pressure altitude and 7,932 to 7,937 ft density altitude; at an 8,000 ft field with 28.20 inHg the old answer was 90 ft low.
Tools: Pressure altitude, Density altitude, QNH, QFE, and QNE, Flight level and altitude
Replaced vectors: aviation.altimetry.pressure-altitude v001, aviation.altimetry.pressure-altitude v004, aviation.altimetry.pressure-altitude v005, aviation.altimetry.pressure-altitude v006, aviation.altimetry.pressure-altitude v007, aviation.altimetry.pressure-altitude v008, aviation.altimetry.pressure-altitude v009, aviation.altimetry.pressure-altitude v010, aviation.altimetry.pressure-altitude v011, aviation.altimetry.pressure-altitude v012, aviation.altimetry.pressure-altitude v013, aviation.altimetry.pressure-altitude v014, aviation.altimetry.pressure-altitude v015, aviation.altimetry.pressure-altitude v016, aviation.altimetry.pressure-altitude v018, aviation.altimetry.pressure-altitude v019, aviation.altimetry.density-altitude v001, aviation.altimetry.density-altitude v002, aviation.altimetry.density-altitude v004, aviation.altimetry.density-altitude v005, aviation.altimetry.density-altitude v006, aviation.altimetry.density-altitude v007, aviation.altimetry.density-altitude v008, aviation.altimetry.density-altitude v010, aviation.altimetry.density-altitude v011, aviation.altimetry.density-altitude v012, aviation.altimetry.density-altitude v013, aviation.altimetry.density-altitude v014, aviation.altimetry.density-altitude v015, aviation.altimetry.density-altitude v016, aviation.altimetry.density-altitude v017, aviation.altimetry.density-altitude v018, aviation.altimetry.density-altitude v019, aviation.altimetry.density-altitude v020, aviation.altimetry.q-codes v001, aviation.altimetry.q-codes v002, aviation.altimetry.q-codes v004, aviation.altimetry.q-codes v005, aviation.altimetry.q-codes v006, aviation.altimetry.q-codes v007, aviation.altimetry.flight-level v001, aviation.altimetry.flight-level v002, aviation.altimetry.flight-level v003, aviation.altimetry.flight-level v004, aviation.altimetry.flight-level v005, aviation.altimetry.flight-level v006
Result change Promoting this tool to stable removed EXPERIMENTAL_TOOL from its warnings, which moved POLE_ENCLOSED from index 1 to index 0 and broke v008, which pinned the index. Nothing computed changed. v008 is superseded by v018, which names the warning by its code with the meta.warnings.*.code form the runner supports, so no warning sorting above it can shift it again -- the same fix time.scale.gps-week v007 took.
Tools: Range rings
Replaced vectors: navigation.route.range-rings v008
Result change Promoting this tool to stable removed EXPERIMENTAL_TOOL from its warnings, which moved LEAP_SECOND_TABLE_EXPIRED from index 1 to index 0 and broke v007, which pinned the index. Nothing computed changed. v007 is superseded by v025, which names the warning by its code with the meta.warnings.*.code form the runner supports, so no warning sorting above it can shift it again -- the same fix units.fuel.convert v001 took.
Tools: UTC to GPS week and seconds
Replaced vectors: time.scale.gps-week v007
Result change Promoting these two tools to stable removed EXPERIMENTAL_TOOL from their warnings, which moved NOMINAL_VALUE_USED and UNIT_ASSUMED from index 1 to index 0 and broke the two vectors that pinned the index. Nothing computed changed. v001 is superseded by v021 and v002 by v025, both naming the warning by its code with the meta.warnings.*.code form the runner supports, so no warning sorting above them can shift them again -- the same fix geometry.validity.make-valid v001 took for the same reason.
Tools: Fuel volume and weight, Normalize a unit-tagged value
Replaced vectors: units.fuel.convert v001, units.quantity.normalize v002
Result change Promoting this tool to stable removed EXPERIMENTAL_TOOL from its warnings, which moved GEOMETRY_INVALID from index 1 to index 0 and broke v001, which pinned the index. Nothing computed changed. v001 is superseded by v022, which names the warning by its code with the meta.warnings.*.code form the runner supports, so no warning sorting above it can shift it again -- the same fix geometry.area.polygon v030 took for the same reason.
Tools: Check and repair a polygon
Replaced vectors: geometry.validity.make-valid v001
2026-09-22
Result change The planar-area vector now names the warning it expects by its code rather than by its place in the list, using the meta.warnings.*.code form the runner already supports. Nothing computed changed. v029 had pinned index 1 and broke when promotion removed EXPERIMENTAL_TOOL from the list; v030 pinned index 0, which would have broken again the next time a warning sorted above this one. v031 cannot be shifted by either.
Tools: Polygon area and perimeter on the ellipsoid
Replaced vectors: geometry.area.polygon v030
Result change Promotion to stable removed the EXPERIMENTAL_TOOL warning from the envelope, and the warnings are ordered by severity, so PLANAR_ON_GEOGRAPHIC moved from index 1 to index 0. The area, the perimeter, and every other value are unchanged; what moved is where the warning sits in the list. v029 is superseded by v030, which pins the same warning at its new index.
Tools: Polygon area and perimeter on the ellipsoid
Replaced vectors: geometry.area.polygon v029
Result change The cross-index tool now includes S2, which sits between Maidenhead and MGRS in its list, so the rows after it shift by one. The cell each system reports is unchanged; only the positions in the list moved, and the golden vectors that addressed rows by position were superseded.
Tools: One place in every index, at a matched cell size
Replaced vectors: indexing.convert.cross-index v001, indexing.convert.cross-index v002, indexing.convert.cross-index v003, indexing.convert.cross-index v004, indexing.convert.cross-index v005
Changed Geodesic distance and destination now work on strongly flattened ellipsoids (|f| from 0.02 up to 0.5) by the exact method, where they used to refuse. On 480 geodesics at six flattenings they match GeographicLib's GeodesicExact to rounding. Results on WGS 84 and other catalog ellipsoids are unchanged.
Tools: Distance between two points (geodesic), Destination from a start, course, and distance (geodesic)
Changed Traverse closure now offers the Crandall rule: it holds every measured bearing and puts the whole correction into the distances. Existing compass and transit results are unchanged.
Result change The reserve basis now links 14 CFR 91.151 and 91.167 where eCFR files them, in subpart B; the first release pointed at subpart C, which does not hold them. The fuel figures are unchanged. Tool version 1.1.0.
Tools: Fuel planning
Replaced vectors: aviation.loading.fuel-plan v001
2026-09-19
Changed Distance to the horizon is stable. Its rule-of-thumb figure reproduces all 126 heights of Bowditch's printed Distance of the Horizon table (NGA Pub. 9, Volume II, 2024 edition), in both the nautical and statute columns, to the tenth of a mile the table shows. One row is a misprint: the table gives 29.5 nautical miles at 640 feet where 1.17 times the square root of 640 is 29.6, and that row's own statute figure follows the rule. The tool gives 29.6, and a test pins the difference. Results are unchanged.
Tools: Distance to the horizon
Changed Time, speed, and distance is stable. It reproduces every one of the 4,800 cells of Bowditch's printed Speed, Time, and Distance table (NGA Pub. 9, Volume II, 2024 edition) to the tenth of a mile the table shows, with one exception: the table prints 6.8 nautical miles for 38 minutes at 10.5 knots, where the arithmetic gives 6.65 and every neighboring cell follows speed times time. The tool gives 6.65, and a test pins the difference. Results are unchanged.
Tools: Time, speed, and distance
Changed The site has a simpler shell. The header now carries only the site title, a one-line description, and a light/dark control; Units, All tools, Agents, Settings, and Source moved to the footer. The display modes are down to two, paper and ink: sunlight, night, and high contrast are gone, and a saved choice of any of them now opens in its closest replacement. The home page explains what the site does, then offers one search field and the topic categories, and a new page at /tools/ lists every calculator by category.
Changed Cross-track distance is stable. Its spherical method reproduces the Aviation Formulary's LAX to JFK example (7.4512 nm off course, 99.588 nm along it) once the formulary's minute-of-arc radius is accounted for, and the ellipsoidal foot point matches a brute-force search along the geodesic within a millimeter. Results are unchanged.
Changed The rhumb-line tools are stable. They reproduce Bowditch's Mercator sailing examples (NGA Pub. 9, 2024 edition) to within its 1 minute = 1 nautical mile convention, and match GeographicLib's RhumbSolve within 0.4 µm on 2,000 pairs run through the tools, including nearly east-west, nearly meridional, and near-pole lines. The Bowditch citation is now the 2024 edition, verified at NGA. Results are unchanged.
Tools: Rhumb line distance and course, Destination on a constant course (rhumb line)
Changed The GARS, GEOREF, Maidenhead, and USNG tools are stable, both directions. They reproduce NGA's GARS band definitions, the Wikipedia GEOREF (NAS Patuxent River) and Maidenhead (W1AW) examples, and the FGDC USNG Washington Monument, and match GeographicLib, pygeodesy, an exact Maidenhead reference, and NGA GEOTRANS on thousands of points. Results are unchanged apart from the fix below.
Tools: Latitude and longitude to GARS, GARS to latitude and longitude, Latitude and longitude to GEOREF, GEOREF to latitude and longitude, Latitude and longitude to Maidenhead locator, Maidenhead locator to latitude and longitude, Latitude and longitude to USNG, USNG to latitude and longitude
Fixed A longitude or latitude typed on a Maidenhead grid line in decimal degrees (like 145.83333333333334 for 145°50′) could land in the cell on either side of the line, depending on floating-point rounding. It now always falls in the cell east or north of the line. The tool is now version 1.1.0.
Changed The four frame conversions are stable: geodetic to ECEF and back, and to and from a local east-north-up frame. They reproduce the IOGP Guidance Note 7-2 worked examples and agree with GeographicLib's CartConvert within 15 nm on 1,000 ECEF points (poles to beyond geostationary orbit) and 500 local targets. Results are unchanged.
Tools: Latitude, longitude, and height to ECEF, ECEF to latitude, longitude, and height, Point to local ENU, NED, and AER, Local ENU, NED, or AER to point
Changed Every indexing tool is now stable. Geohash decode and neighbors match pygeohash on 1,000 and 500 cases; the Plus Code tools pass every row of the Open Location Code test data; tile ground resolution matches the Bing Maps table; the H3 resolution chooser matches H3's resolution table; and H3 polygon fill gives H3 C's own test counts (1,253 cells, 1,214 with a hole). Results are unchanged apart from the fix below.
Tools: Geohash decoder, Geohash neighbors, Plus Code encoder, Plus Code decoder, Shorten a Plus Code, Map ground resolution and scale, H3 resolution chooser, H3 polygon fill (polygonToCells)
Fixed Shortening an 8-digit Plus Code next to its own center returned a bare "+", which is not a valid code. It now keeps the last pair (for example 8F+), so the short code always recovers. The tool is now version 1.1.0.
Tools: Shorten a Plus Code
Changed Eight more H3 tools are stable: the cell inspector, grid ring, grid path, parent, children, compact, uncompact, and edges. On 300 cells at every resolution, one in eight a pentagon, they match H3 C exactly, including every path H3 C refuses; cell areas agree to 2e-8 relative even at resolution 15. Results are unchanged.
Tools: H3 cell inspector, H3 grid ring, H3 grid path and distance, H3 parent cell, H3 children cells, H3 compact, H3 uncompact, H3 edges and vertexes
Added Every tool page now explains its abbreviations under "Terms on this page": 92 plain-language definitions (METAR, GSD, HAE, PLSS, and more), each with its expansion and a cited source. A build gate stops any new label from using an undefined abbreviation. Two labels were reworded to plain language (motor and speed-controller efficiency; the station part of the daily file name).
Fixed VLOS guidance now takes ground visibility as at most 5 km, as EASA's procedure and the German LBA guidance assume, so VLOS never exceeds 1,500 m. Without a visibility it used only the aircraft's size, so a 10 m multirotor showed 3,290 m. It is now stable, matching the LBA's worked table, and cites EASA's guidelines at Issue 03 (17 July 2025). Tool version 1.1.0.
Fixed The deed plotter now reports in the unit the calls use. It converted every call to US survey feet, so a deed in meters came back in US survey square feet, international feet were shifted by 2 parts per million, and each result carried the legacy-unit warning three times. Mixing US survey and international feet is now refused, as in the traverse tool. Tool version 1.1.0. It is now stable, matching the University of Memphis worked traverse (0.182 ft misclosure, 36,320 sq ft).
Tools: Deed plot, closure, and area
Fixed The coordinate reader had three defects, found by 1,500 independently written strings in ten notations and now fixed: spaced DMS with a one- or two-digit longitude (like 30 34 14.3 N 1 25 23.9 E) was misread as packed aviation notation, so 1°25′ became 125°; signed DMS with degree signs and no hemisphere letters crashed; and one-digit decimal degrees with a hemisphere letter could fail. Tool version 1.1.0. It is now stable.
Tools: Read any coordinate
Changed Battery energy (mAh to Wh) is now stable. It matches the FAA PackSafe worked example (12 V and 8 Ah is 96 Wh) and 19 vectors from a separate implementation. Results are unchanged.
Tools: Battery energy (mAh to Wh)
Changed Large H3 polygon fills run about four times faster on the web and in the MCP server (a 250,000-cell county-sized fill: 12.5 s to about 3 s), because the H3 code is now compiled for speed instead of size. Results are unchanged.
Fixed The TAF decoder now reads the ICAO TX and TN maximum and minimum temperature groups (they were listed as not decoded) and flags a change group that falls outside the forecast's valid period instead of placing it silently (found in a live Geneva TAF). Tool version 1.2.0. It is now stable, agreeing with pytaf on 588 live TAFs and with the FAA Aviation Weather Handbook's example.
Tools: TAF decoder
Result change Present weather now reads as the FAA Aviation Weather Handbook does, with intensity on the precipitation: +TSRA is "thunderstorm with heavy rain" (was "heavy thunderstorm rain"), +SHRA is "heavy rain showers", and VCSH is "showers in the vicinity". Tool versions 1.1.0. The METAR and winds-aloft decoders are now stable.
Tools: METAR decoder, TAF decoder
Replaced vectors: aviation.weather.metar-decode v004
Fixed A differential against python-metar on 612 live reports found three METAR defects, now fixed: cloud layers with /// (type not determined by an automated station) were dropped, BECMG and TEMPO trend groups were applied to the current observation (a forecast wind could replace the observed one), and 9999NDV visibility was not read. The winds-aloft decoder now accepts a whole pasted FB product and takes its levels from the FT header.
Changed The Aviation Weather Handbook is now cited at its current edition, FAA-H-8083-28A (2024), which cancels and supersedes FAA-H-8083-28 (2022). Its altimetry, flight-category, METAR, and FB rules used here are unchanged.
Changed Top of descent and the visual descent point are now stable. Both match the FAA Instrument Procedures Handbook examples (FL 310 to 6,000 ft is 75 NM by the 3-to-1 rule; 300 ft per NM on a three-degree path) and 18 to 19 vectors each from a separate implementation. Results are unchanged.
Tools: Top of descent, Visual descent point
Result change The horizontal curve, vertical curve, and area by coordinates are now stable, so their results no longer carry the EXPERIMENTAL_TOOL warning; the legacy-unit warning on area moved to the first position. They match FM 5-233 (Army Construction Surveying), the Indiana Design Manual vertical-curve example, and Wikipedia's shoelace example. No numbers changed.
Tools: Horizontal circular curve, Vertical curve, Area by coordinates (acreage)
Replaced vectors: survey.cogo.area-by-coordinates v006
Fixed The circular curve now solves from any two elements in every case: external with middle ordinate failed (the formulas lost all precision near zero), and a tangent with a middle ordinate, which fit two different curves, could fail or pick one silently. It now returns the flatter curve and names the other with AMBIGUOUS_INPUT. A chord-definition degree of curve (degree_chord) is accepted as an input, as the survey spec requires.
Tools: Horizontal circular curve
Changed The four aviation nights and local time to Zulu are now stable. The nights match 491 regulatory windows built from US Naval Observatory times at 100 places; Zulu matches Python zoneinfo on 2,388 instants and the Python documentation's Los Angeles examples. Results are unchanged.
Fixed Short and legacy tzdb zone names such as CET, EET, and EST5EDT are now accepted wherever a time zone is asked for; before, they were refused as malformed UTC offsets.
Tools: Local time to UTC (Zulu), Sunrise, sunset, and twilight, The four aviation nights, Mapping light window
Changed Sunrise, sunset, and twilight is now stable, checked against 1,200 US Naval Observatory events at 300 places and dates (all within a minute, 94% to the same minute).
Fixed Sun event times now use the NREL SPA geometric sun instead of the low-precision NOAA series, and each side of the day is decided on its own. A twilight that grazes its altitude is now placed correctly: at 67.19°S on February 1, 2026, evening civil twilight ends at 23:59 local (matching USNO) instead of never. Across 1,200 USNO events every time is within a minute; published vectors are unchanged.
Tools: Sunrise, sunset, and twilight, The four aviation nights, Mapping light window
Changed Weight and balance is now stable. It matches three worked examples in the FAA Aircraft Weight and Balance Handbook (FAA-H-8083-1B): a weighed airplane, a loaded light twin inside its CG range, and a CG in percent of MAC. Results are unchanged.
Tools: Weight and balance
Changed MGRS encode and decode are now stable. They match the Washington Monument example in the FGDC US National Grid standard and 2,000 references from NGA GEOTRANS; where GEOTRANS's own projection is 1.5 cm off near the poles and in Svalbard, PROJ confirms geoprims. Results are unchanged.
Tools: Latitude and longitude to MGRS, MGRS to latitude and longitude
Fixed Stable tools no longer list the EXPERIMENTAL_TOOL warning in geoprims_describe and the catalog; they never emit it. The stable-promotion gate now checks this.
Result change Traverse closure and the combined grid-to-ground factor are now stable, so their results no longer carry the EXPERIMENTAL_TOOL warning; the perfect-closure and elevation-as-ellipsoid-height warnings moved to the first position. Both match published worked examples (University of Memphis traverse notes and NOAA Manual NOS NGS 5) to every printed digit. No numbers changed.
Tools: Traverse closure and adjustment, Combined scale factor (grid and ground)
Replaced vectors: survey.cogo.traverse-closure v006, survey.reduction.combined-factor v006
Changed Ground sampling distance and height for a target GSD are now stable. Both match a published worked example (a 1-inch camera at 120 m gives 3.13 cm per pixel) and 20 vectors each from a separate implementation. Results are unchanged.
Tools: Ground sampling distance (GSD), Height for a target GSD
Result change The geohash encoder, map tile for a point, tile bounds, H3 grid disk, and haversine distance are now stable, so their results no longer carry the EXPERIMENTAL_TOOL warning; the Web Mercator clamp and pentagon warnings moved to the first position. Each matches published worked examples (Wikipedia, the mercantile README, the Bing Maps Tile System, H3 C, and Rosetta Code) and agrees with a separately written library on 250 to 1,000 cases. No numbers changed.
Tools: Geohash encoder, Map tile for a point (XYZ, TMS, quadkey), Map tile bounds, H3 grid disk (k-ring), Haversine distance (spherical)
Replaced vectors: indexing.tile.from-point v006, indexing.h3.grid-disk v007
Changed Pressure altitude, density altitude, runway crosswind and headwind, and the wind triangle are now stable. Each matches the worked examples in the FAA Pilot's Handbook of Aeronautical Knowledge (FAA-H-8083-25C) and at least 20 vectors from a separate implementation. Results are unchanged.
Tools: Pressure altitude, Density altitude, Runway wind components, Wind triangle: heading and groundspeed
Fixed An input so small that it rounds to zero in meters (like 5e-324 ft) is now refused as out of range for every tool, instead of being treated as zero; bounds fuzzing found it through the circular-curve tool. A non-positive curve element is now reported on the field that holds it.
Tools: Horizontal circular curve
Added New navigation tools: rhumb lines, cross-track and along-track distance, fly-by turn anticipation, time-speed-distance with arrival times, closest point of approach, and route legs with true and magnetic courses; and the first geometry tool, polygon area on the ellipsoid.
Tools: Rhumb line distance and course, Destination on a constant course (rhumb line), Cross-track and along-track distance, Fly-by turn anticipation, Time, speed, and distance, Closest point of approach, Route legs, courses, and totals, Polygon area and perimeter on the ellipsoid
Changed Five more tools passed the stable verification bar: geodesic distance and destination (checked against GeographicLib's GeodTest), UTM forward and inverse (checked against exact transverse Mercator values), and the standard atmosphere (checked against a separately written implementation).
Tools: Distance between two points (geodesic), Destination from a start, course, and distance (geodesic), Latitude and longitude to UTM, UTM to latitude and longitude, Standard atmosphere
Result change UTM forward is now stable, so its results no longer carry the EXPERIMENTAL_TOOL warning. The nonstandard-zone warning moved to the first position; no numbers changed.
Tools: Latitude and longitude to UTM
Replaced vectors: geodesy.utm.forward v009
Result change State plane convergence and scale factor in the Hotine oblique Mercator zone (Alaska zone 1) are now computed with Richardson-extrapolated differences. They moved by up to 0.0000001°, well inside the published tolerance, and now agree between the forward and inverse tools.
Result change Sun position is now stable, so its results no longer carry the EXPERIMENTAL_TOOL warning. The UT1 warning moved to the first position; no numbers changed.
Tools: Sun position (azimuth and elevation)
Replaced vectors: time.sun.position v028
Added The site installs as an app and works offline after the first visit, has a command palette (press / or Ctrl+K), and ships a strict Content Security Policy.
2026-09-18
Changed The first six tools passed the stable verification bar: a derivation, an independent worked example, invariant and differential tests, and at least 20 golden vectors each.
Tools: Magnetic declination, Latitude and longitude to state plane (SPCS83), State plane (SPCS83) to latitude and longitude, Geoid height (EGM96), H3 cell for a point, Sun position (azimuth and elevation)
Result change Named IANA time zones like America/Denver are supported, so inputs that returned UNSUPPORTED now resolve to local times.
Tools: Local time to UTC (Zulu), Sunrise, sunset, and twilight
Replaced vectors: time.scale.utc-offset v006, time.sun.events v007
Result change Sun position uses the NREL Solar Position Algorithm (±0.0003°) instead of the NOAA equations (about ±0.01°). Elevation and azimuth changed by up to a few hundredths of a degree.
Tools: Sun position (azimuth and elevation)
Replaced vectors: time.sun.position v001, time.sun.position v002, time.sun.position v003, time.sun.position v004, time.sun.position v005, time.sun.position v006, time.sun.position v007
Fixed Bounds fuzzing found 16 inputs that produced non-finite numbers, a trap, or a hang. Each now returns a clear error and is pinned as a regression test.