Verification report 0.1.0
Every golden test vector in this release, run through the same modules this site and the MCP server use: 5,608 vectors and 22,729 checks across 323 tools, with no failures.
"Largest error" is the observed difference from the reference value at the check that used the most of its tolerance, shown with that tolerance and the share used. Download this report as JSON. See the methodology and the changelog.
What this release is made of
The SHA-256 of every WebAssembly module this site and the MCP server run. The same source gives the same bytes:npm run verify:reproducible builds twice from a clean tree and compares these digests.
| Module | Bytes | SHA-256 |
|---|---|---|
aviation.wasm | 734,215 | bb14bbbfbcc6f01870cc828caa72419b67754d82736a253ce96bd82041bb0a32 |
base.wasm | 297,573 | 6fc7fb207f885387e4fe89907e361f072d91016f0eeeded3807d31f40a723c3d |
drone.wasm | 602,827 | bfceedf2fa9027e66f8f5e473abbec852a6fa77cbf478b065ec02925396625d9 |
geodesy.wasm | 717,281 | 7019e1561de5bec86f0b2401d0f8d276bd31ff1064e32a61787dde11dda3a321 |
geometry.wasm | 547,121 | eaeb10f7b302950be2d070d2db909fb1b3bacff2dc543b311ce75404dceb0033 |
indexing.wasm | 631,077 | 9ccfb2f9a7856f47cf9110313f44d469058e9493a9b3612cd533e2bd209b0a15 |
link.wasm | 245,329 | b03591695a99d3ec3b1075af36b63d3cda62d20096195948c654d1ed3cdaf311 |
navigation.wasm | 579,450 | c9bd1aceb016d8915a36ac6885732d5366868355c68c1d833bc150a5f99becb6 |
raster.wasm | 329,039 | d394fc4dc4111a45b58a989b4fce489c732292fd9bb96358788c0964a7fa3e9d |
search.wasm | 302,661 | dae2b71c7a9d657ca338a08970276ae7678def62f27f91d762ee1399af09d0cd |
survey.wasm | 625,371 | 9903fd97c662823634851b12c6dd9030e2b0f5d99df9c51ea4aba9c60a38f4ca |
time.wasm | 623,147 | 7b563dd5b29684f11e17c22eb1681b55ac14a6847ae905de50514be4ddff4b64 |
Every tool
| Tool | Vectors | Largest error | Tolerance | Used | Sources |
|---|---|---|---|---|---|
| TFR and NOTAM area | 8 | 2.4e-11 (area) | ±0.000001 | 0% | GeographicLib GeodSolve and Planimeter (tools/vectors/gen_tfr.py) (GeodSolve: GeographicLib version 2.7) (7); add-practitioner-essentials TFR scenario (3 NM geodesic circle, SFC to 3,000 ft MSL) (GeodSolve: GeographicLib version 2.7) (1) |
| True airspeed from indicated or calibrated airspeed | 7 | 4.0e-11 (tas) | ±0.000001 + ±1e-9 relative | 0% | Independent Python implementation of the Gracey (NASA RP-1046) airspeed relations, with supersonic Mach by bisection (tools/vectors/gen_aviation.py) (NASA RP-1046 (1980)) (7) |
| Calibrated airspeed from true airspeed or Mach | 6 | 8.0e-13 (cas) | ±0.000001 + ±1e-9 relative | 0% | Independent Python implementation of the Gracey (NASA RP-1046) airspeed relations, with supersonic Mach by bisection (tools/vectors/gen_aviation.py) (NASA RP-1046 (1980)) (6) |
| Total and static air temperature | 5 | 3.4e-14 (sat) | ±0.000001 + ±1e-9 relative | 0% | Independent Python implementation of the Gracey (NASA RP-1046) airspeed relations, with supersonic Mach by bisection (tools/vectors/gen_aviation.py) (NASA RP-1046 (1980)) (5) |
| Cold temperature altitude correction | 7 | 0 (isa_deviation) | ±0.000001 | 0% | ICAO 2020 equation and AIM Table 7-3-1 worked in Python (tools/vectors/gen_coldtemp.py) (2026) (5); add-aviation-suite cold-temperature scenarios (1,500 ft above a 2,000 ft airport at -30 °C: about +218 ft, the 4% rule about +246 ft) (2026) (1); add-aviation-suite cold-temperature scenarios (no correction when warmer than ISA) (2026) (1) |
| Density altitude (stable) | 21 | 9.6 (density_altitude) | ±100 | 10% | Independent Python implementation of the ICAO Doc 7488/3 defining equations (tools/vectors/gen_aviation.py) (Doc 7488/3 (1993)) (20); FAA Pilot's Handbook of Aeronautical Knowledge (FAA-H-8083-25C), worked example read from the published chart or table (FAA-H-8083-25C (2023)) (1) |
| Flight level and altitude | 7 | 5.7e-14 (fl_of_altitude) | ±0.000001 + ±0.000001 relative | 0% | ISA altimetry worked in Python (tools/vectors/gen_qcodes.py) (2026) (6); add-aviation-suite altimetry scenarios (lowest usable flight level FL185 at 29.42 inHg, 14 CFR 91.121(b)) (2026) (1) |
| ISA temperature and deviation | 6 | 4.3e-14 (isa_temperature) | ±0.000001 + ±1e-12 relative | 0% | Independent Python implementation of the ICAO Doc 7488/3 defining equations (tools/vectors/gen_aviation.py) (Doc 7488/3 (1993)) (6) |
| Pressure altitude (stable) | 25 | 0.41 (pressure_altitude) | ±1 | 41% | Independent Python implementation of the ICAO Doc 7488/3 defining equations (tools/vectors/gen_aviation.py) (Doc 7488/3 (1993)) (19); FAA Pilot's Handbook of Aeronautical Knowledge (FAA-H-8083-25C), chapter 11: pressure altitude is the field elevation plus the figure 11-3 correction for the altimeter setting (FAA-H-8083-25C (2023)) (3); FAA Pilot's Handbook of Aeronautical Knowledge (FAA-H-8083-25C), worked example read from the published chart or table (FAA-H-8083-25C (2023)) (3) |
| QNH, QFE, and QNE | 10 | 0.000013 (qnh) | ±0.000001 + ±0.000001 relative | 42% | ISA altimetry worked in Python (tools/vectors/gen_qcodes.py) (2026) (8); add-aviation-suite altimetry scenarios (QFE from QNH 1013 hPa at 1,000 ft by the ISA pressure-height relation) (2026) (1); FAA Aviation Weather Handbook (FAA-H-8083-28B) section 24.4.3.11: altimeter settings are given to hundredths of an inch of mercury; QFE and pressure altitude by the ISA relation as in v001 to v015 (FAA-H-8083-28B) (1) |
| True altitude | 7 | 0 (true_altitude) | ±0.000001 | 0% | ICAO 2020 equation and AIM Table 7-3-1 worked in Python (tools/vectors/gen_coldtemp.py) (2026) (6); add-aviation-suite cold-temperature scenarios (ISA -20 °C at 8,000 ft indicated: true altitude below indicated) (2026) (1) |
| Cloud base and freezing level | 7 | 4.5e-13 (cloud_base_lcl) | ±0.000001 | 0% | Heading arithmetic and Bolton (1980) eq. 15 worked in Python (tools/vectors/gen_heading.py) (2026) (6); add-aviation-suite scenarios (2026) (1) |
| Humidity and moist air | 10 | 3.4e-14 (virtual_temperature) | ±1e-9 + ±1e-9 relative | 0% | Moist-air relations worked in Python (tools/vectors/gen_humidity.py) (2026) (9); add-aviation-suite humid-density scenario (30 °C, 1,000 hPa, dew point 24 °C: moist density below dry) (2026) (1) |
| Standard atmosphere (stable) | 22 | 0.00059 (pressure) | ±0.000003 relative | 68% | Independent Python implementation of the ICAO Doc 7488/3 defining equations (tools/vectors/gen_aviation.py) (Doc 7488/3 (1993)) (10); ambiance (independent Python implementation of the ICAO standard atmosphere 1993) (ambiance 1.3.1) (8); U.S. Standard Atmosphere 1976, Table I (geometric altitude), printed to 5 significant figures (NOAA-S/T 76-1562 (1976)) (4) |
| DME arc lead points | 7 | 8.9e-16 (lead_radials) | ±1e-9 | 0% | Right-triangle and turn geometry worked in Python (tools/vectors/gen_dme.py) (2026) (7) |
| DME slant range to ground distance | 7 | 7.1e-15 (elevation_angle) | ±1e-9 | 0% | Right-triangle and turn geometry worked in Python (tools/vectors/gen_dme.py) (2026) (5); add-practitioner-essentials scenarios (overhead) (2026) (1); add-practitioner-essentials scenarios (slant range: 4.902 NM) (2026) (1) |
| Holding pattern entry (stable) | 35 | 0 (outbound_course) | ±1e-9 | 0% | AIM 5-3-8j FIG 5-3-4 sectors worked by position in Python (tools/vectors/gen_hold_part107.py): the side of the holding course and of the 70-degree line the aircraft comes from (AIM basic with Change 3 (July 9, 2026)) (14); AIM 5-3-8j FIG 5-3-4 sectors worked by position in Python (tools/vectors/gen_hold_part107.py), with the 5-degree zone of flexibility on the sector boundaries from ICAO Doc 8168 Vol I and TC AIM RAC 10.5 (AIM basic with Change 3 (July 9, 2026)) (8); AIM 5-3-8 figure 5-3-2 sectors and table 5-3-1 speeds, applied by hand (AIM (2026)) (7); AIM 5-3-8j FIG 5-3-4 sectors worked by position in Python (tools/vectors/gen_hold_part107.py), with the 5-degree zone of flexibility on the sector boundaries from ICAO Doc 8168 Vol I and TC AIM RAC 10.5; exactly on the teardrop/parallel line the tool names the teardrop for either turn direction, so a left hold mirrors a right one (AIM basic with Change 3 (July 9, 2026)) (2); Required inputs: an entry needs both the inbound course and the heading to the fix (AIM basic with Change 3 (July 9, 2026)) (2); AIM 5-3-8j FIG 5-3-4 sectors worked by position in Python (tools/vectors/gen_hold_part107.py); 3 rad = 171.887 deg (AIM basic with Change 3 (July 9, 2026)) (1); TC AIM (TP 14371E, AIM 2026-1) RAC 10.2 example 2: arriving on track 234 deg at ZHZ, make a right turn and hold on an inbound track of 234 deg (the RAC 10.5 sector 3 direct entry) (TC AIM 2026-1, effective March 19, 2026) (1) |
| Maximum holding airspeed | 6 | 0 (max_ias) | ±1e-9 | 0% | AIM 5-3-8 figure 5-3-2 sectors and table 5-3-1 speeds, applied by hand (AIM (2026)) (6) |
| Holding wind correction and timing | 5 | 0 (inbound_wca) | ±0.000001 + ±1e-9 relative | 0% | Independent Python implementation of the holding wind triangle and triple-the-drift rule in FAA-H-8083-15B (tools/vectors/gen_aviation.py) (FAA-H-8083-15B (2012)) (5) |
| Fix from a radial and distance | 6 | 2.1e-14 (fix_lat) | ±1e-9 | 0% | GeodSolve fixes and WMM2025 declinations (tools/vectors/gen_radial.py) (GeodSolve: GeographicLib version 2.7) (5); add-practitioner-essentials variation scenario (the station's variation is used, and a difference over 1° from WMM is warned) (GeodSolve: GeographicLib version 2.7) (1) |
| Heading to intercept a radial | 9 | 0 (heading) | ±1e-9 | 0% | Plane geometry: the heading of course ± the angle whose track crosses the radial (tools/vectors/gen_dme.py) (2026) (7); Right-triangle and turn geometry worked in Python (tools/vectors/gen_dme.py) (2026) (2) |
| Time and distance to a station | 7 | 0 (time) | ±1e-9 | 0% | Right-triangle and turn geometry worked in Python (tools/vectors/gen_dme.py) (2026) (7) |
| Ballast to move the CG | 5 | 0 (ballast) | ±1e-9 | 0% | Weight-shift and ballast proportions worked in Python (tools/vectors/gen_shift.py) (2026) (5) |
| Fuel planning | 12 | 3.6e-15 (total) | ±1e-9 | 0% | Fuel arithmetic worked in Python (tools/vectors/gen_fuel.py) (2026) (10); add-aviation-suite fuel scenarios (rotorcraft VFR: 20 minutes, 14 CFR 91.151(b)) (2026) (1); add-aviation-suite fuel scenarios (VFR night: 45 minutes at the cruise burn, cited to 14 CFR 91.151(a)(2)) (2026) (1) |
| Fuel weight | 5 | 2.8e-14 (weight) | ±0.000001 + ±1e-12 relative | 0% | Independent Python weight-and-balance arithmetic per FAA-H-8083-1B chapter 2 (tools/vectors/gen_aviation.py) (FAA-H-8083-1B (2016)) (5) |
| Performance table lookup | 13 | 2.3e-13 (table_value) | ±1e-9 | 0% | Multilinear interpolation worked in Python (tools/vectors/gen_table.py) (2026) (10); add-aviation-suite scenarios (2026) (2); add-aviation-suite no-POH scenario (2026) (1) |
| Weight and balance (stable) | 23 | 0.0049 (cg) | ±0.005 | 99% | Independent Python weight-and-balance arithmetic per FAA-H-8083-1B chapter 2 (tools/vectors/gen_aviation.py) (FAA-H-8083-1B (2016)) (20); FAA Aircraft Weight and Balance Handbook (FAA-H-8083-1B), worked example (FAA-H-8083-1B (2016)) (3) |
| Weight shift | 7 | 0 (new_cg) | ±1e-9 | 0% | Weight-shift and ballast proportions worked in Python (tools/vectors/gen_shift.py) (2026) (7) |
| Climb gradient and vertical speed | 5 | 2.3e-13 (vertical_speed) | ±0.000001 + ±1e-9 relative | 0% | Independent Python implementation of the turn, gradient, glide, and pivotal-altitude relations in FAA-H-8083-3C and FAA-H-8083-16B (tools/vectors/gen_aviation.py) (FAA-H-8083-16B (2017)) (5) |
| Glide range with wind | 5 | 1.1e-13 (sink_rate) | ±0.000001 + ±1e-9 relative | 0% | Independent Python implementation of the turn, gradient, glide, and pivotal-altitude relations in FAA-H-8083-3C and FAA-H-8083-16B (tools/vectors/gen_aviation.py) (FAA-H-8083-3C (2021)) (5) |
| Pivotal altitude | 5 | 1.1e-13 (pivotal_altitude) | ±0.000001 + ±1e-12 relative | 0% | Independent Python implementation of the turn, gradient, glide, and pivotal-altitude relations in FAA-H-8083-3C and FAA-H-8083-16B (tools/vectors/gen_aviation.py) (FAA-H-8083-3C (2021)) (5) |
| Specific range | 8 | 1.8e-15 (air_range) | ±1e-9 | 0% | Specific range worked in Python (tools/vectors/gen_range.py) (2026) (8) |
| Top of descent (stable) | 20 | 6.8e-13 (vertical_speed) | ±0.000001 + ±1e-9 relative | 0% | Independent Python implementation of the turn, gradient, glide, and pivotal-altitude relations in FAA-H-8083-3C and FAA-H-8083-16B (tools/vectors/gen_aviation.py) (FAA-H-8083-16B (2017)) (19); FAA Instrument Procedures Handbook (FAA-H-8083-16B), worked example (FAA-H-8083-16B) (1) |
| Turn performance and load factor | 6 | 1.8e-12 (radius) | ±0.000001 + ±1e-9 relative | 0% | Independent Python implementation of the turn, gradient, glide, and pivotal-altitude relations in FAA-H-8083-3C and FAA-H-8083-16B (tools/vectors/gen_aviation.py) (FAA-H-8083-3C (2021)) (6) |
| Visual descent point (stable) | 24 | 2.3e-13 (path_height) | ±0.000001 + ±1e-9 relative | 0% | Independent Python implementation of the turn, gradient, glide, and pivotal-altitude relations in FAA-H-8083-3C and FAA-H-8083-16B (tools/vectors/gen_aviation.py) (FAA-H-8083-16B (2017)) (22); FAA Instrument Procedures Handbook (FAA-H-8083-16B), worked example (FAA-H-8083-16B) (2) |
| Winds aloft (FB) decoder (stable) | 24 | 0 (winds.0.direction) | ±1e-9 | 0% | FAA Aviation Weather Handbook (FAA-H-8083-28A), decoded example (FAA-H-8083-28A (2024)) (9); Winds encoded by an independent Python implementation of the FB coding rules (tools/vectors/gen_aviation.py) (FAA-H-8083-28A (2024)) (8); Hand-decoded per the FAA Aviation Weather Handbook FB coding rules (FAA-H-8083-28) (FAA-H-8083-28 (2022)) (6); FAA Aviation Weather Handbook (FAA-H-8083-28B) section 27.2.1.1.1: forecast speeds of 200 kt or greater are coded as 199 kt; 7799 is decoded as 270° at 199 kt or greater (FAA-H-8083-28B) (1) |
| METAR decoder (stable) | 23 | 0 (wind_direction) | ±1e-9 | 0% | Live Aviation Weather Center reports (2026-09-19), as decoded by python-metar 1.11.0 (metar 1.11.0) (14); Hand-decoded per FAA Order JO 7900.5E Change 1 (METAR body and remarks) and the FAA Aviation Weather Handbook (flight categories) (JO 7900.5E Chg 1 (2022)) (6); FAA Aviation Weather Handbook (FAA-H-8083-28A), decoded example (FAA-H-8083-28A (2024)) (1); FAA Aviation Weather Handbook (FAA-H-8083-28B) section 24.4.3.11: the altimeter group codes tens, units, tenths, and hundredths of inches of mercury (A2992 is 29.92 inHg) (FAA-H-8083-28B) (1); WMO Manual on Codes, FM 15 METAR group QPHPHPHPH: QNH rounded down to whole hectopascals, so no decimals are shown (WMO-No. 306, Volume I.1) (1) |
| TAF decoder (stable) | 21 | 0 (valid_hours) | ±1e-9 | 0% | Live Aviation Weather Center TAFs (2026-09-19), as parsed by pytaf 1.2.1 (pytaf 1.2.1) (15); Hand-decoded per the FAA Aviation Weather Handbook (TAF chapter) (FAA-H-8083-28 (2022)) (5); FAA Aviation Weather Handbook (FAA-H-8083-28A), decoded example (FAA-H-8083-28A (2024)) (1) |
| Winds aloft between levels | 7 | 3.1e-16 (speed) | ±1e-9 | 0% | Meteorological u/v convention and linear interpolation worked in Python (tools/vectors/gen_aloft.py) (2026) (7) |
| Rank runways for the wind | 9 | 1.8e-15 (runways.3.headwind) | ±1e-9 | 0% | Runway wind components ranked in Python (tools/vectors/gen_runway.py) (2026) (7); add-aviation-suite ranking scenario (runway 18 ranks first, every runway listed) (2026) (1); add-aviation-suite variable-wind scenario (worst case 8 kt crosswind and tailwind) (2026) (1) |
| Wind triangle: course and groundspeed from a heading | 8 | 2.8e-14 (groundspeed) | ±1e-9 | 0% | Wind-triangle vectors worked in Python (tools/vectors/gen_triangle.py) (2026) (6); add-aviation-suite heading-and-groundspeed scenario, solved the other way (course about 090° at 108.7 kt) (2026) (1); add-aviation-suite mixed-reference scenario (2026) (1) |
| Wind triangle: find the wind | 5 | 3.6e-15 (wind_speed) | ±0.000001 + ±1e-11 relative | 0% | Independent Python implementation of the ICAO Doc 7488/3 defining equations (tools/vectors/gen_aviation.py) (Doc 7488/3 (1993)) (5) |
| True course to compass heading | 8 | 0 (true_heading) | ±1e-9 | 0% | Heading arithmetic and Bolton (1980) eq. 15 worked in Python (tools/vectors/gen_heading.py) (2026) (7); add-aviation-suite scenarios (2026) (1) |
| Wind triangle: heading and groundspeed (stable) | 22 | 0.37 (heading) | ±1 | 37% | Independent Python implementation of the ICAO Doc 7488/3 defining equations (tools/vectors/gen_aviation.py) (Doc 7488/3 (1993)) (20); FAA Pilot's Handbook of Aeronautical Knowledge (FAA-H-8083-25C), worked example read from the published chart or table (FAA-H-8083-25C (2023)) (1); Hand computation of the PHAK wind triangle (FAA-H-8083-25C, Navigation): a direct headwind needs no correction, and groundspeed = TAS − W (FAA-H-8083-25C (2023)) (1) |
| Off-course correction (1-in-60) | 8 | 7.1e-15 (to_destination) | ±1e-9 | 0% | Flat-plane off-course geometry worked in Python (tools/vectors/gen_offcourse.py) (2026) (7); add-aviation-suite 1-in-60 scenario (3.81° and 7.63° exact; 4° and 8° by the rule) (2026) (1) |
| Runway wind components (stable) | 23 | 0.50 (crosswind) | ±1 | 50% | Independent Python implementation of the ICAO Doc 7488/3 defining equations (tools/vectors/gen_aviation.py) (Doc 7488/3 (1993)) (20); FAA Pilot's Handbook of Aeronautical Knowledge (FAA-H-8083-25C), worked example read from the published chart or table (FAA-H-8083-25C (2023)) (1); Hand computation of the PHAK wind components, headwind = W·cos θ and crosswind = W·sin θ, with θ = 90° or 180° (FAA-H-8083-25C, Aircraft Performance): a wind straight across the runway has no headwind or tailwind component (FAA-H-8083-25C (2023)) (1); Hand computation of the PHAK wind components, headwind = W·cos θ and crosswind = W·sin θ, with θ = 90° or 180° (FAA-H-8083-25C, Aircraft Performance): a wind straight down the runway from behind has no crosswind component (FAA-H-8083-25C (2023)) (1) |
| Wind triangle: airspeed and heading for a groundspeed | 8 | 1.4e-14 (tas) | ±1e-9 | 0% | Wind-triangle vectors worked in Python (tools/vectors/gen_triangle.py) (2026) (7); add-aviation-suite heading-and-groundspeed scenario, solved the other way (about 120 kt on heading 081.7°) (2026) (1) |
| Wind components (u and v) | 15 | 3.6e-15 (speed) | ±1e-9 | 0% | Meteorological u/v convention and linear interpolation worked in Python (tools/vectors/gen_aloft.py) (2026) (15) |
| Radio link budget | 5 | 0 (fspl) | ±1e-9 + ±1e-9 relative | 0% | Worked by hand in Python (tools/vectors/gen_sensing.py) (2026) (4); add-practitioner-essentials scenarios (2.4 GHz at 5 km: about 114.0 dB) (2026) (1) |
| Corridor mapping lines | 5 | 0 (line_count) | ±1e-12 + ±1e-12 relative | 0% | Flight-line arithmetic (Wolf, Dewitt & Wilkinson 2014, ch. 18) evaluated in Python (tools/vectors/gen_drone.py) (4th edition (2014)) (5) |
| Export a mission (KML, GeoJSON, CSV) | 18 | 0 (waypoint_count) | ±1e-9 + ±1e-9 relative | 0% | OGC KML 2.3 section 9.13 altitude modes and RFC 7946, applied by hand (tools/vectors/gen_drone.py) (2026) (12); add-drone-suite scenarios (2026) (5); add-drone-suite scenarios (terrain following requires acknowledgment) (2026) (1) |
| Facade scan | 14 | 1.7e-13 (photo_spacing) | ±1e-9 + ±1e-9 relative | 0% | Coverage with the standoff as the object distance (Wolf, Dewitt & Wilkinson 2014, ch. 6), on the equator where the geodesic is closed form, evaluated in Python (tools/vectors/gen_drone.py) (4th edition (2014)) (10); add-drone-suite scenarios (2026) (4) |
| Geofence around an area | 10 | 0.00026 (area_enclosed) | ±1e-9 + ±0.001 relative | 33% | Geodesic distance on the equator and a meridian in closed form, and Steiner's formula for the fence area, evaluated in Python (tools/vectors/gen_drone.py) (2026) (7); add-drone-suite scenarios (2026) (3) |
| Orbit around a point of interest | 5 | 0 (gimbal_pitch) | ±1e-12 + ±1e-12 relative | 0% | Flight-line arithmetic (Wolf, Dewitt & Wilkinson 2014, ch. 18) evaluated in Python (tools/vectors/gen_drone.py) (4th edition (2014)) (5) |
| Survey grid (lawnmower pattern) | 8 | 0.00034 (survey_length) | ±0.00001 relative | 11% | Published flight-line count (Penn State GEOG 892): ceil(width / spacing) + 1 lines, ceil(length / photo spacing) + 1 + 2 x extra photos per line, on geographiclib arc lengths (tools/vectors/gen_image_count.py) (tool version 1.1.0) (5); King Saud University SE 321, Design of Photogrammetric Flight Plan (CLO3 example): (60,000 / 460) + 1 = 131.4, 132 + 4 = 136 photos per strip; (40,000 / 920) + 1 = 44.4, 45 lines; 136 x 45 = 6,120 photos (faculty.ksu.edu.sa, retrieved 2026-09-23) (1); Penn State GEOG 892 (Q. Abdullah), Designing a Flight Route: (13 x 5,280 / 8,400) + 1 = 9.171, 10 lines; (105,600 / 2,800) + 1 = 38.7, 39, + 4 = 43 images per line; 430 images (390 without the extra images) (Penn State College of Earth and Mineral Sciences, online course text, retrieved 2026-09-23) (1); Penn State GEOG 892 (Q. Abdullah), Designing a Flight Route: (13 x 5,280 / 8,400) + 1 = 9.171, 10 lines; (105,600 / 2,800) + 1 = 38.7, 39, + 4 = 43 images per line; 430 images (Penn State College of Earth and Mineral Sciences, online course text, retrieved 2026-09-23) (1) |
| EASA open subcategory | 6 | no numeric checks | data/regulations.json values (14 CFR 107.51, Regulation (EU) 2019/945 and 2019/947, EASA VLOS guidance) applied in Python (tools/vectors/gen_drone.py) (Rules as of 2026-09-18) (6) | ||
| Drone impact kinetic energy | 5 | 5.7e-14 (energy_ft_lbf) | ±1e-9 + ±1e-9 relative | 0% | data/regulations.json values (14 CFR 107.51, Regulation (EU) 2019/945 and 2019/947, EASA VLOS guidance) applied in Python (tools/vectors/gen_drone.py) (Rules as of 2026-09-18) (5) |
| Part 107 maximum altitude (stable) | 22 | 2.3e-13 (max_hae) | ±1e-9 + ±1e-9 relative | 0% | 14 CFR 107.51(b) as printed on eCFR (current through 2026-09-21), applied in Python (tools/vectors/gen_hold_part107.py): 400 ft AGL, or within a 400-foot radius of a structure up to 400 ft above its immediate uppermost limit (eCFR 14 CFR 107.51, last amended 2016-12-30, read 2026-09-23) (12); data/regulations.json values (14 CFR 107.51, Regulation (EU) 2019/945 and 2019/947, EASA VLOS guidance) applied in Python (tools/vectors/gen_drone.py) (Rules as of 2026-09-18) (5); 14 CFR 107.51(b) needs both the structure and your distance from it; neither can be negative (eCFR 14 CFR 107.51, last amended 2016-12-30, read 2026-09-23) (4); 14 CFR 107.51(b), eCFR: "cannot be higher than 400 feet above ground level" (the rule's printed value, no structure nearby) (eCFR 14 CFR 107.51, last amended 2016-12-30, read 2026-09-23) (1) |
| Part 107 groundspeed check | 5 | 4.5e-15 (margin) | ±1e-9 + ±1e-9 relative | 0% | data/regulations.json values (14 CFR 107.51, Regulation (EU) 2019/945 and 2019/947, EASA VLOS guidance) applied in Python (tools/vectors/gen_drone.py) (Rules as of 2026-09-18) (5) |
| Height for a target GSD (stable) | 21 | 0.091 (height) | ±0.2 | 45% | Photogrammetric formulas (Wolf, Dewitt & Wilkinson 2014, ch. 6) evaluated in Python (tools/vectors/gen_drone.py) (4th edition (2014)) (20); Alshaibani et al., Airplane Type Identification Based on Mask RCNN and Drone Images, arXiv:2108.12811, equation 1 (arXiv v1 (2021)) (1) |
| ASPRS accuracy (Edition 2) | 6 | 4.4e-16 (horizontal) | ±1e-12 + ±1e-12 relative | 0% | ASPRS Positional Accuracy Standards, Edition 2 (quadrature of fit and checkpoint RMSE) (Edition 2, Version 2.0) (5); add-drone-suite scenarios (2026) (1) |
| Ground sampling distance (GSD) (stable) | 22 | 0.0024 (gsd) | ±0.005 | 47% | Photogrammetric formulas (Wolf, Dewitt & Wilkinson 2014, ch. 6) evaluated in Python (tools/vectors/gen_drone.py) (4th edition (2014)) (20); add-drone-suite scenarios (2026) (1); Alshaibani et al., Airplane Type Identification Based on Mask RCNN and Drone Images, arXiv:2108.12811, equation 1 (arXiv v1 (2021)) (1) |
| Image count and survey size (stable) | 21 | 0.0062 (survey_length) | ±0.00001 relative | 37% | Published flight-line count (Penn State GEOG 892): ceil(width / spacing) + 1 lines, ceil(length / photo spacing) + 1 + 2 x extra photos per line, on geographiclib arc lengths (tools/vectors/gen_image_count.py) (tool version 1.1.0) (9); Extra photos per line end are 0 to 10 (tools/vectors/gen_image_count.py) (tool version 1.1.0) (2); Penn State GEOG 892 (Q. Abdullah), Designing a Flight Route: (13 x 5,280 / 8,400) + 1 = 9.171, 10 lines; (105,600 / 2,800) + 1 = 38.7, 39, + 4 = 43 images per line; 430 images (Penn State College of Earth and Mineral Sciences, online course text, retrieved 2026-09-23) (2); An area needs 3 corners (tools/vectors/gen_image_count.py) (tool version 1.1.0) (1); Extra photos per line end must be a whole number (tools/vectors/gen_image_count.py) (tool version 1.1.0) (1); King Saud University SE 321, Design of Photogrammetric Flight Plan (CLO3 example): (60,000 / 460) + 1 = 131.4, 132 + 4 = 136 photos per strip; (40,000 / 920) + 1 = 44.4, 45 lines; 136 x 45 = 6,120 photos (5,940 without the extra photos) (faculty.ksu.edu.sa, retrieved 2026-09-23) (1); King Saud University SE 321, Design of Photogrammetric Flight Plan (CLO3 example): (60,000 / 460) + 1 = 131.4, 132 + 4 = 136 photos per strip; (40,000 / 920) + 1 = 44.4, 45 lines; 136 x 45 = 6,120 photos (faculty.ksu.edu.sa, retrieved 2026-09-23) (1); Line spacing must be positive (tools/vectors/gen_image_count.py) (tool version 1.1.0) (1); Line spacing under 0.5 m (tools/vectors/gen_image_count.py) (tool version 1.1.0) (1); Penn State GEOG 892 (Q. Abdullah), Designing a Flight Route: (13 x 5,280 / 8,400) + 1 = 9.171, 10 lines; (105,600 / 2,800) + 1 = 38.7, 39, + 4 = 43 images per line; 430 images (390 without the extra images) (Penn State College of Earth and Mineral Sciences, online course text, retrieved 2026-09-23) (1); Published flight-line count (Penn State GEOG 892): ceil(width / spacing) + 1 lines, ceil(length / photo spacing) + 1 + 2 x extra photos per line, on geographiclib arc lengths (tools/vectors/gen_image_count.py): spacings a third of the block, ceil(2.29) + 1 = 4 lines of ceil(10.56) + 1 + 4 = 16 photos (tool version 1.1.0) (1) |
| Motion blur and slowest shutter | 5 | 0 (blur) | ±1e-12 + ±1e-12 relative | 0% | Photogrammetric formulas (Wolf, Dewitt & Wilkinson 2014, ch. 6) evaluated in Python (tools/vectors/gen_drone.py) (4th edition (2014)) (5) |
| Oblique GSD and footprint | 14 | 5.7e-12 (gsd_far) | ±1e-9 + ±1e-9 relative | 0% | Tilted-photo geometry (Wolf, Dewitt & Wilkinson 2014, ch. 10) in closed angle form, evaluated in Python (tools/vectors/gen_drone.py) (4th edition (2014)) (11); add-drone-suite scenarios (2026) (3) |
| Overlap over high terrain (stable) | 21 | 0.61 (min_height) | ±1 | 61% | Overlap at the highest relief, o_t = 1 - (1 - o) h / (h - t) (Pryor 1959, HRB Bulletin 228, pp. 36-37), evaluated in Python (tools/vectors/gen_photogrammetry_overlap.py) (Bulletin 228 (1959)) (13); Flight-planning geometry (Wolf, Dewitt & Wilkinson 2014, ch. 18): footprint and fixed photo spacing, evaluated in Python (tools/vectors/gen_drone.py) (4th edition (2014)) (4); add-drone-suite scenarios (2026) (2); Pryor 1959, Relationship of Topographic Relief, Flight Height, and Minimum and Maximum Overlap, HRB Bulletin 228, p. 31 (Bulletin 228 (1959)) (1); Pryor 1959, Relationship of Topographic Relief, Flight Height, and Minimum and Maximum Overlap, HRB Bulletin 228, p. 32 (Bulletin 228 (1959)) (1) |
| Overlap, trigger interval, and line spacing (stable) | 22 | 0.0073 (trigger_interval) | ±0.01 | 73% | Flight-planning relations (Wolf, Dewitt & Wilkinson 2014, ch. 18) evaluated in Python (tools/vectors/gen_photogrammetry_overlap.py) (4th edition (2014)) (14); Photogrammetric formulas (Wolf, Dewitt & Wilkinson 2014, ch. 6) evaluated in Python (tools/vectors/gen_drone.py) (4th edition (2014)) (5); Penn State GEOG 892 (Q. Abdullah), Designing a Flight Route: air base 2,800 ft, line spacing 8,400 ft, 11.067 s between exposures (Penn State College of Earth and Mineral Sciences, retrieved 2026-09-23) (1); Pix4D, Selecting the Image Acquisition Plan Type (forest and dense vegetation: at least 85% frontal and side overlap), with the flight-planning relations of Wolf, Dewitt & Wilkinson 2014, ch. 18: footprint 150 m × 100 m at 100 m; 100 × 0.15 = 15 m; 150 × 0.15 = 22.5 m (Pix4D support page retrieved 2026-09-23) (1); University of Washington CEE 424 (K. M. Ahmed), Flight Planning sheet 1, problems 6 and 7 (courses.washington.edu/cee424, retrieved 2026-09-23) (1) |
| Battery energy (mAh to Wh) (stable) | 21 | 1.4e-14 (energy) | ±1e-9 + ±1e-9 relative | 0% | Momentum theory (Leishman 2006, ch. 2) and battery arithmetic evaluated in Python (tools/vectors/gen_drone.py) (2nd edition (2006)) (19); FAA PackSafe, Batteries Carried by Airline Passengers (Q3 worked example) (December 2024) (1); Worked by hand: I = P / V = 150 W / 15.4 V = 9.740 A; C-rate = 9.740 A / 5.870 Ah = 1.659 (Ohm's-law power relation; checked 2026-09-23) (1) |
| Calibrate hover power from a test flight | 6 | 0 (fm_eta) | ±1e-9 + ±1e-9 relative | 0% | Momentum theory (Leishman 2006, ch. 2) and battery arithmetic evaluated in Python (tools/vectors/gen_drone.py) (2nd edition (2006)) (6) |
| Drone flight time (stable) | 29 | 0.034 (hover_time) | ±0.06 | 57% | Bauersfeld and Scaramuzza (2022) Sec. VII-E step 6, t = E / P, with the spec's reserve, derating, and range, evaluated in Python (tools/vectors/gen_endurance.py) (IEEE RA-L 7(2), 2022) (18); Momentum theory (Leishman 2006, ch. 2) and battery arithmetic evaluated in Python (tools/vectors/gen_drone.py) (2nd edition (2006)) (9); Bauersfeld and Scaramuzza, Range, Endurance, and Optimal Speed Estimates for Multicopters, IEEE RA-L 7(2) 2022, Sec. VII-E step 6 (DJI Mavic 3: C_eff 4.89 Ah and 4.88 Ah, 4S at 3.7 V per cell, 89.5 W and 107.0 W give 2909 s and 2429 s) (IEEE RA-L 7(2), 2022) (2) |
| Multirotor hover power | 5 | 0 (ideal_power) | ±1e-9 + ±1e-9 relative | 0% | Momentum theory (Leishman 2006, ch. 2) and battery arithmetic evaluated in Python (tools/vectors/gen_drone.py) (2nd edition (2006)) (5) |
| Maximum payload for a flight time | 5 | 8.9e-16 (max_payload) | ±1e-9 + ±1e-9 relative | 0% | Momentum theory (Leishman 2006, ch. 2) and battery arithmetic evaluated in Python (tools/vectors/gen_drone.py) (2nd edition (2006)) (5) |
| What a payload costs in flight time | 6 | 3.6e-15 (hover_time_with) | ±1e-9 + ±1e-9 relative | 0% | Momentum theory (Leishman 2006, ch. 2) and battery arithmetic evaluated in Python (tools/vectors/gen_drone.py) (2nd edition (2006)) (6) |
| Return-to-home energy budget | 5 | 3.6e-15 (margin) | ±1e-9 + ±1e-9 relative | 0% | Momentum theory (Leishman 2006, ch. 2) and battery arithmetic evaluated in Python (tools/vectors/gen_drone.py) (2nd edition (2006)) (5) |
| Dataset size estimate | 9 | 0 (ortho_gb) | ±1e-9 + ±1e-9 relative | 0% | Worked by hand in Python (tools/vectors/gen_sensing.py) (2026) (8); add-practitioner-essentials scenarios (orthomosaic: 7.5 GB uncompressed) (2026) (1) |
| Lidar mission planning | 6 | 2.8e-14 (aggregate_density) | ±1e-9 + ±1e-9 relative | 0% | Worked by hand in Python (tools/vectors/gen_sensing.py) (2026) (5); add-practitioner-essentials scenarios (swath about 140.0 m, 171 pulses per m², beyond QL1) (2026) (1) |
| Thermal pixel footprint | 6 | 1.4e-14 (footprint) | ±1e-9 + ±1e-9 relative | 0% | Worked by hand in Python (tools/vectors/gen_sensing.py) (2026) (5); add-practitioner-essentials scenarios (solar panel: 39 mm footprint, 117 mm by the 3 x 3 rule) (2026) (1) |
| Visual line of sight distance (stable) | 25 | 0 (vlos) | ±1e-9 + ±1e-9 relative | 0% | data/regulations.json values (14 CFR 107.51, Regulation (EU) 2019/945 and 2019/947, EASA VLOS guidance) applied in Python (tools/vectors/gen_drone.py) (Rules as of 2026-09-18) (13); Luftfahrt-Bundesamt, Guidance for Dimensioning of Flight Geography, Contingency Volume and Ground Risk Buffer, section 7.1 (maximum VLOS distance table) (LBA guidance (English), retrieved 2026-09-19) (10); EASA, Guidelines for UAS operations in the open and specific category, Part A chapter I, VLOS distance: DLOS = 0.3 x GV, where the ground visibility "minimum value should be at least 5 km" (Issue 03, 17 July 2025, retrieved 2026-09-23) (2) |
| Helmert transformation (7 or 14 parameters) (stable) | 24 | 0.00045 (y) | ±0.0006 | 75% | PROJ +proj=helmert through pyproj (PROJ 9.3 (pyproj 3.6)) (18); IOGP Guidance Note 7-2 worked example (IOGP 373-7-2, September 2019) (4); add-geodesy-suite input rules (2026-09) (2) |
| Transform between ITRF and WGS 84 realizations (stable) | 25 | 3.6e-8 (height) | ±0.00001 | 0% | PROJ +proj=helmert with PROJ's ITRF2020 parameter file, through pyproj (PROJ 9.3 (pyproj 3.6); data/ITRF2020) (21); add-geodesy-suite input rules (2026-09) (2); add-geodesy-suite scenario: coincidence stated (2026-09) (1); add-geodesy-suite scenario: unqualified WGS 84 (2026-09) (1) |
| Legacy datum to or from WGS 84 (stable) | 20 | 6.4e-10 (lon) | ±1e-8 | 6% | PROJ applying the EPSG operation through pyproj (PROJ 9.3, EPSG v10.094) (18); add-geodesy-suite input rules (2026-09) (1); EPSG 1173 area of use (EPSG v10.094) (1) |
| Transform between NAD 83 and ITRF or WGS 84 (stable) | 26 | 0.00055 (height) | ±0.0015 | 37% | NGS HTDP, compiled from htdp.f and initbd.f, menu option 4 (HTDP 3.6.0 (2025-04-07)) (23); add-geodesy-suite input rules (2026-09) (1); add-geodesy-suite scenario: epoch echoed (2026-09) (1); add-geodesy-suite scenario: unqualified WGS 84 (2026-09) (1) |
| Old US datums to NAD 83 (NADCON5) (stable) | 36 | 2.8e-14 (lon) | ±1e-9 | 0% | PROJ +proj=gridshift with the NADCON5 grid us_noaa_nadcon5_nad27_nad83_1986_conus.tif, through pyproj (PROJ 9.3; NADCON5 20160901) (22); PROJ +proj=gridshift with the NADCON5 grid us_noaa_nadcon5_nad27_nad83_1986_alaska.tif, through pyproj (PROJ 9.3; NADCON5 20160901) (4); PROJ +proj=gridshift with the NADCON5 grid us_noaa_nadcon5_gu63_nad83_1993_guamcnmi.tif, through pyproj (PROJ 9.3; NADCON5 20160901) (2); PROJ +proj=gridshift with the NADCON5 grid us_noaa_nadcon5_ohd_nad83_1986_hawaii.tif, through pyproj (PROJ 9.3; NADCON5 20160901) (2); PROJ +proj=gridshift with the NADCON5 grid us_noaa_nadcon5_pr40_nad83_1986_prvi.tif, through pyproj (PROJ 9.3; NADCON5 20160901) (2); add-geodesy-suite scenario: outside grid (2026-09) (1); PROJ +proj=gridshift with the NADCON5 grid us_noaa_nadcon5_as62_nad83_1993_as.tif, through pyproj (PROJ 9.3; NADCON5 20160901) (1); PROJ +proj=gridshift with the NADCON5 grid us_noaa_nadcon5_sp1952_nad83_1986_stpaul.tif, through pyproj (PROJ 9.3; NADCON5 20160901) (1); Regression for a reported defect (2026-09-23 fix-geodesy-indexing): Cites the NADCON 5.0 report (NOAA TR NOS NGS 63) and the biquadratic interpolation memo (NOAA TM NOS NGS 84) separately (was TM 84 alone, mislabeled as the NADCON5 report). (core 0.1.0) (1) |
| Move a position between epochs (ITRF2020 plate motion) (stable) | 22 | 4.5e-13 (lat) | ±1e-10 | 0% | PROJ +proj=helmert with the ITRF2020 plate motion rates of its data/ITRF2020, through pyproj (PROJ 9.3 (pyproj 3.6); data/ITRF2020) (19); add-geodesy-suite input rules (2026-09) (1); add-geodesy-suite scenario: propagation in a deformation zone (2026-09) (1); Site velocity times elapsed time (definition) (2026-09) (1) |
| Auxiliary latitudes (stable) | 31 | 2.2e-10 (isometric) | ±1e-11 + ±1e-12 relative | 33% | mpmath 40-digit evaluation of the defining relations (tools/vectors/gen_frames.py) (mpmath 1.3) (29); add-geodesy-suite input rules (2026-09) (1); GeographicLib 2.7 command-line tools: CartConvert (geocentric and parametric from X and Z), GeodSolve (rectifying from the meridian arc to 45 over the arc to 90), RhumbSolve (isometric, confirmed by the rhumb from the equator making azimuth 45.00000000000), ConicProj -a 0 0 (authalic from the equal-area northing at 45 over the northing at 90) (GeographicLib 2.7) (1) |
| Ellipsoid parameters (stable) | 23 | 3.7e-9 (quarter_meridian) | ±1e-9 + ±1e-14 relative | 4% | mpmath 40-digit evaluation of the defining relations (tools/vectors/gen_frames.py) (mpmath 1.3) (20); add-geodesy-suite input rules (2026-09) (3) |
| Radii of curvature and degree lengths (stable) | 25 | 6.6e-9 (degree_lat) | ±0.000001 + ±1e-13 relative | 1% | mpmath 40-digit evaluation of the defining relations (tools/vectors/gen_frames.py) (mpmath 1.3) (16); mpmath 40-digit evaluation of the defining relations (tools/vectors/gen_frames.py); meridian arcs from GeographicLib's geodesic (mpmath 1.3, geographiclib 2.x) (8); add-geodesy-suite input rules (2026-09) (1) |
| ECEF to latitude, longitude, and height (stable) | 30 | 4.5e-9 (lat) | ±3e-7 | 1% | GeographicLib CartConvert (GeographicLib 2.7) (28); add-geodesy-suite scenario: the Earth's center (2026-09) (1); IOGP Geomatics Guidance Note 7-2, sections 4.1.1 to 4.1.3 (EPSG methods 9602, 9836, 9837), worked examples (IOGP 373-7-2, September 2019) (1) |
| Local ENU, NED, or AER to point (stable) | 23 | 2.3e-9 (lon) | ±3e-7 | 1% | GeographicLib CartConvert (GeographicLib 2.7) (21); add-geodesy-suite input rules (2026-09) (1); IOGP Geomatics Guidance Note 7-2, sections 4.1.1 to 4.1.3 (EPSG methods 9602, 9836, 9837), worked examples (IOGP 373-7-2, September 2019) (1) |
| Latitude, longitude, and height to ECEF (stable) | 25 | 0.00036 (x) | ±0.0005 | 72% | GeographicLib CartConvert (GeographicLib 2.7) (23); add-geodesy-suite input rules (2026-09) (1); IOGP Geomatics Guidance Note 7-2, sections 4.1.1 to 4.1.3 (EPSG methods 9602, 9836, 9837), worked examples (IOGP 373-7-2, September 2019) (1) |
| Point to local ENU, NED, and AER (stable) | 21 | 0.00024 (up) | ±0.0005 | 48% | GeographicLib CartConvert (GeographicLib 2.7) (20); IOGP Geomatics Guidance Note 7-2, sections 4.1.1 to 4.1.3 (EPSG methods 9602, 9836, 9837), worked examples (IOGP 373-7-2, September 2019) (1) |
| Geoid height (EGM96) (stable) | 22 | 0.000047 (geoid_height) | ±0.00005 | 94% | GeographicLib GeoidEval 2.7 with the egm96-15 grid (tools/vectors/gen_geoid_diff.py) (egm96-15 (2009-08-29)) (20); GeographicLib GeoidEval 2.7 with the egm96-15 grid (tools/vectors/gen_geoid_diff.py), bilinear (-l) (egm96-15 (2009-08-29)) (1); Regression for a reported defect (2026-09-23 fix-geodesy-indexing): A negative geoid height reads as below the ellipsoid (was -17.21 m above). (core 0.1.0) (1) |
| Latitude and longitude to GARS (stable) | 23 | no numeric checks | GeographicLib GARS and Georef classes (tools/vectors/gridref_ref.cpp) (GeographicLib 2.7) (21); NGA, Global Area Reference System description (180°E to 179°30'W is band 001, 179°30'W to 179°W band 002; 90°S to 89°30'S is band AA, 89°30'S to 89°S band AB) (earth-info.nga.mil, October 6, 2006) (2) | ||
| GARS to latitude and longitude (stable) | 25 | 2.8e-14 (lon) | ±1e-12 | 3% | GeographicLib GARS and Georef classes (tools/vectors/gridref_ref.cpp) (GeographicLib 2.7) (21); add-geodesy-suite input rules (2026-09) (2); NGA, Global Area Reference System description (180°E to 179°30'W is band 001, 179°30'W to 179°W band 002; 90°S to 89°30'S is band AA, 89°30'S to 89°S band AB) (earth-info.nga.mil, October 6, 2006) (2) |
| Latitude and longitude to GEOREF (stable) | 21 | no numeric checks | GeographicLib GARS and Georef classes (tools/vectors/gridref_ref.cpp) (GeographicLib 2.7) (20); Wikipedia, World Geographic Reference System (NAS Patuxent River, 38.286108, -76.4291704, is at GJPJ3417) (retrieved 2026-09-19) (1) | ||
| GEOREF to latitude and longitude (stable) | 22 | 0.0056 (lat) | ±0.008333333333333333 | 67% | GeographicLib GARS and Georef classes (tools/vectors/gridref_ref.cpp) (GeographicLib 2.7) (20); add-geodesy-suite input rules (2026-09) (1); Wikipedia, World Geographic Reference System (NAS Patuxent River, 38.286108, -76.4291704, is at GJPJ3417) (retrieved 2026-09-19) (1) |
| Latitude and longitude to Maidenhead locator (stable) | 23 | no numeric checks | IARU Maidenhead locator definition, independent Python implementation (tools/vectors/gen_gridref.py) (IARU Region 1 VHF Managers Handbook, version 10.03) (21); add-geodesy-suite input rules (2026-09) (1); Wikipedia, Maidenhead Locator System (W1AW, Newington, Connecticut, is in FN31pr) (retrieved 2026-09-19) (1) | ||
| Maidenhead locator to latitude and longitude (stable) | 25 | 0.015 (lat) | ±0.020833333333333332 | 70% | IARU Maidenhead locator definition, independent Python implementation (tools/vectors/gen_gridref.py) (IARU Region 1 VHF Managers Handbook, version 10.03) (21); add-geodesy-suite input rules (2026-09) (3); Wikipedia, Maidenhead Locator System (W1AW, Newington, Connecticut, is in FN31pr) (retrieved 2026-09-19) (1) |
| Latitude and longitude to MGRS (stable) | 25 | no numeric checks | NGA GEOTRANS MGRS (C) via the mgrs Python package, toMGRS and toLatLon (mgrs 1.5.4) (16); add-geodesy-suite scenarios (GeographicLib values) (GeographicLib 2.x) (5); FGDC-STD-011-2001, United States National Grid, section 5.2.2 and table 1 (latitude and longitude by PROJ 9.3.0) (December 2001) (4) | ||
| MGRS to latitude and longitude (stable) | 24 | 1.3e-7 (corner_lat) | ±2e-7 | 66% | NGA GEOTRANS MGRS (C) via the mgrs Python package, toMGRS and toLatLon (mgrs 1.5.4) (16); add-geodesy-suite scenarios (GeographicLib values) (GeographicLib 2.x) (5); PROJ inverse of the square's corner grid coordinates (EPSG:32761 and EPSG:32633) (PROJ 9.3.0 (pyproj 3.6.1)) (2); FGDC-STD-011-2001, United States National Grid, section 5.2.2 and table 1 (latitude and longitude by PROJ 9.3.0) (December 2001) (1) |
| Latitude and longitude to USNG (stable) | 23 | no numeric checks | GeographicLib GeoConvert -m (MGRS, written with spaces as USNG) (GeographicLib 2.7) (19); FGDC-STD-011-2001, United States National Grid, section 5.2.2 and table 1 (the Washington Monument) (December 2001) (4) | ||
| USNG to latitude and longitude (stable) | 22 | 7.1e-15 (corner_lat) | ±1e-10 | 0% | GeographicLib GeoConvert -m (MGRS, written with spaces as USNG) (GeographicLib 2.7) (20); add-geodesy-suite input rules (2026-09) (1); FGDC-STD-011-2001, United States National Grid, section 5.2.2 and table 1 (the Washington Monument) (December 2001) (1) |
| Ellipsoidal and orthometric height (stable) | 28 | 0.000047 (orthometric) | ±0.00005 | 94% | h = H + N with N from GeographicLib's GeoidEval on the egm96-15 grid, as captured in core/crates/gp-geodesy/tests/data/egm96_diff.csv (GeographicLib GeoidEval 2.7, egm96-15) (18); GeographicLib GeoidEval 2.7 with the egm96-15 grid (tools/vectors/gen_geoid_diff.py) (egm96-15 (2009-08-29)) (8); Regression for a reported defect (2026-09-23 fix-geodesy-indexing): A negative geoid height reads as below the ellipsoid (was -17.21 m above). (core 0.1.0) (1); Regression for a reported defect (2026-09-23 fix-geodesy-indexing): A negative height above ground reads as below the ground (was -152.461 m above the ground). (core 0.1.0) (1) |
| Magnetic declination (stable) | 29 | 0.0049 (inclination) | ±0.005 | 98% | NCEI WMM2025 test values (WMM2025_TestValues.txt, released with the WMM2025 coefficients) (WMM2025 (2024-11-13)) (20); ppigrf 2.1.0 (independent pure-Python IGRF-14 synthesis), on January 1 of coefficient epochs (tools/vectors/gen_magnetic.py) (IGRF-14 (2024-12)) (8); Regression for a reported defect (2026-09-23 fix-geodesy-indexing): The decimal year shows without digit grouping (was 2,026.71). (core 0.1.0) (1) |
| Grid variation (grivation) (stable) | 25 | 0.0046 (grivation) | ±0.006 | 77% | Declination from pygeomag (an independent WMM2025 implementation) and grid convergence from PROJ's Proj.get_factors; grivation G = D - gamma and magnetic = true - variation, east positive (pygeomag / PROJ 9.3.0) (16); NCEI WMM2025 test values (declination) and GeographicLib GeoConvert -c (convergence) (WMM2025 (2024-11-13); GeographicLib 2.x) (9) |
| True and magnetic bearings (stable) | 26 | 8.0e-10 (variation_used) | ±0.0001 | 0% | Declination from pygeomag (an independent WMM2025 implementation) and grid convergence from PROJ's Proj.get_factors; grivation G = D - gamma and magnetic = true - variation, east positive (pygeomag / PROJ 9.3.0) (20); Arithmetic of FAA-H-8083-25C (magnetic = true - east variation; east is least, west is best) (FAA-H-8083-25C (2023)) (6) |
| Add and subtract DMS angles (stable) | 24 | 0 (seconds) | ±0.0001 | 0% | Exact rational arithmetic on arcseconds (tools/vectors/gen_parse_more.py) (definition) (16); Exact sexagesimal arithmetic with Python fractions (tools/vectors/gen_angle_arith.py) (2026) (8) |
| Difference between two bearings (stable) | 23 | 0 (difference) | ±1e-12 | 0% | Exact rational arithmetic on arcseconds (tools/vectors/gen_parse_more.py) (definition) (17); Exact arithmetic (definition) (6) |
| Read any coordinate (stable) | 22 | 0.000022 (lat) | ±0.00005 | 44% | Strings written by tools/vectors/gen_parse_diff.py from integer degrees, minutes, and seconds (seed 44) (10); add-geodesy-suite scenarios (GeographicLib values) (GeographicLib 2.x) (6); Regressions found by core/crates/gp-geodesy/tests/parse_parity.rs (tools/vectors/gen_parse_diff.py) (2026-09-19) (4); Exact arithmetic (definition) (1); Wikipedia, Decimal degrees (worked example) (retrieved 2026-09-19) (1) |
| Format a coordinate (stable) | 21 | 0.0035 (latitude_resolution) | ±0.05 | 7% | Exact rational arithmetic on arcseconds (tools/vectors/gen_parse_more.py) (definition) (16); Exact arithmetic (definition) (3); add-geodesy-suite scenarios (GeographicLib values) (GeographicLib 2.x) (2) |
| Arc-to-chord correction (t − T) (stable) | 23 | 1.2e-9 (ellipsoid_distance) | ±0.000001 | 0% | GeographicLib GeoConvert and GeodSolve (tools/vectors/gen_geodesy_last.py) (GeographicLib 2.7) (16); GeographicLib GeoConvert and GeodSolve (tools/vectors/gen_arc_chord.py) (GeographicLib 2.x) (7) |
| Latitude and longitude to state plane (SPCS83) (stable) | 26 | 3.1e-8 (easting) | ±0.001 | 0% | PROJ 9 (via pyproj) from EPSG:4269 to the zone's EPSG meter CRS (tools/vectors/gen_spcs_diff.py) (PROJ 9.3.0) (25); Regression for a reported defect (2026-09-23 fix-geodesy-indexing): The EPSG code is an identifier and shows without digit grouping (was 32,129). (core 0.1.0) (1) |
| State plane (SPCS83) to latitude and longitude (stable) | 25 | 3.3e-13 (lon) | ±1e-9 | 0% | PROJ 9 (via pyproj) from EPSG:4269 to the zone's EPSG meter CRS (tools/vectors/gen_spcs_diff.py) (PROJ 9.3.0) (25) |
| State plane zone lookup (stable) | 30 | 0 (count) | exact | 0% | The EPSG registry through pyproj: NAD83 State Plane projected CRSs and their areas of use (tools/vectors/gen_spcs_zones.py) (PROJ 9.3.0 EPSG database) (24); SPCS83 zone list, NOAA Manual NOS NGS 5 (NOS NGS 5 (1990)) (6) |
| Latitude and longitude to UPS (stable) | 29 | 0.00038 (easting) | ±0.001 | 38% | PROJ through pyproj: EPSG:32661 and EPSG:32761, WGS 84 / UPS North and South (polar stereographic, k0 = 0.994, false easting and northing 2,000,000 m); the anchor point agrees with GeographicLib's GeoConvert (pyproj 3.6.1 / PROJ 9.3.0) (23); add-geodesy-suite scenarios (GeographicLib values) (GeographicLib 2.x) (2); add-geodesy-suite scenarios (GeographicLib values) by rotational symmetry (GeographicLib 2.x) (2); add-geodesy-suite scenarios (GeographicLib values) by polar symmetry (GeographicLib 2.x) (1); Exact arithmetic (definition) (1) |
| UPS to latitude and longitude (stable) | 26 | 3.4e-9 (lat) | ±1e-8 | 34% | PROJ through pyproj: EPSG:32661 and EPSG:32761, WGS 84 / UPS North and South (polar stereographic, k0 = 0.994, false easting and northing 2,000,000 m); the anchor point agrees with GeographicLib's GeoConvert (pyproj 3.6.1 / PROJ 9.3.0) (21); Exact arithmetic (definition) (2); add-geodesy-suite scenarios (GeographicLib values) (GeographicLib 2.x) (1); add-geodesy-suite scenarios (GeographicLib values) by polar symmetry (GeographicLib 2.x) (1); add-geodesy-suite scenarios (GeographicLib values) by rotational symmetry (GeographicLib 2.x) (1) |
| Latitude and longitude to UTM (stable) | 21 | 0.00028 (northing) | ±0.001 | 28% | GeographicLib TMcoords.dat, point sample (Karney, exact transverse Mercator) (TMcoords 2009) (12); Meridian arc M(lat) by Simpson integration of a(1-e^2)/(1-e^2 sin^2)^1.5 (tools/vectors/gen_geodesy.py) (WGS 84) (6); add-geodesy-suite scenarios (GeographicLib values) (GeographicLib 2.x) (3) |
| UTM to latitude and longitude (stable) | 21 | 2.5e-9 (lat) | ±1e-8 | 25% | GeographicLib TMcoords.dat, point sample (Karney, exact transverse Mercator) (TMcoords 2009) (15); Meridian arc M(lat) by Simpson integration of a(1-e^2)/(1-e^2 sin^2)^1.5 (tools/vectors/gen_geodesy.py) (WGS 84) (5); add-geodesy-suite scenarios (GeographicLib values) (GeographicLib 2.x) (1) |
| UTM zone and band lookup (stable) | 39 | 0 (zone) | exact | 0% | GeographicLib's GeoConvert: -u for the UTM zone and -m for the MGRS grid zone, both carrying the Norway and Svalbard exceptions; central meridian 6z - 183 by definition (GeographicLib 2.7) (33); add-geodesy-suite scenarios (GeographicLib values) (GeographicLib 2.x) (6) |
| Polygon area and perimeter on the ellipsoid (stable) | 29 | 4.6e-11 (area) | ±1e-9 + ±1e-8 relative | 4% | GeographicLib Planimeter (Karney 2013 geodesic polygon area), WGS 84 (GeographicLib 2.7) (23); GeographicLib Planimeter -R (Karney 2024, the area of rhumb polygons), WGS 84 (GeographicLib 2.x) (5); add-navigation-and-geometry shoelace-warning scenario (2026) (1) |
| Buffer a point, line, or polygon (stable) | 30 | 3.7e-7 (max_deviation) | ±0.000001 | 37% | Steiner's formula and plane closed forms on small near-equator shapes, evaluated in Python (tools/vectors/gen_buffer.py) (2026) (23); add-navigation-and-geometry scenarios (2026) (6); GeographicLib 2.7 GeodSolve against 8,004 points sampled along the input rectangle: every one of the 157 boundary vertices lies 500 m from it within 61 nanometres, and the deepest chord midpoint sags 0.124103 m inside, which is what max_deviation reports (GeographicLib 2.7) (1) |
| Compare two tracks (stable) | 20 | 0.0000028 (frechet) | ±0.000001 + ±5e-8 relative | 12% | Distances by GeographicLib's GeodSolve (C++), couplings worked by hand (tools/vectors/gen_distance.py) (GeodSolve: GeographicLib version 2.7) (4); add-navigation-and-geometry scenarios (2026) (1); add-navigation-and-geometry scenarios (GeodSolve: GeographicLib version 2.7) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: a curving track against a straight one (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: a high-latitude pair (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: a pair across the antimeridian (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: a pair near the equator (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: a southern-hemisphere pair (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: a track against a coarser version of itself (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: a two-point track against a many-point one (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: one track much shorter than the other (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: the same track against itself (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: tracks running opposite ways along the same ground (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: tracks that diverge along their length (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: tracks with different vertex counts (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: two tracks running beside each other (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: two tracks that cross (GEOS 3.11.4 / PROJ 9.3.0) (1) |
| Delaunay triangulation of points (stable) | 20 | 0 (triangle_count) | exact | 0% | Qhull via SciPy (tools/vectors/gen_mesh_diff.py) (SciPy 1.x) (5); GEOS 3.11.4 through shapely, delaunay_triangles on PROJ's azimuthal equidistant plane: a dozen points (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, delaunay_triangles on PROJ's azimuthal equidistant plane: a high-latitude scatter (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, delaunay_triangles on PROJ's azimuthal equidistant plane: a jittered 3x3 grid (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, delaunay_triangles on PROJ's azimuthal equidistant plane: a jittered 4x4 grid (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, delaunay_triangles on PROJ's azimuthal equidistant plane: a long thin scatter (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, delaunay_triangles on PROJ's azimuthal equidistant plane: a nudged ring (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, delaunay_triangles on PROJ's azimuthal equidistant plane: a nudged ring with a centre (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, delaunay_triangles on PROJ's azimuthal equidistant plane: a scatter across the antimeridian (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, delaunay_triangles on PROJ's azimuthal equidistant plane: a small scatter (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, delaunay_triangles on PROJ's azimuthal equidistant plane: a southern scatter (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, delaunay_triangles on PROJ's azimuthal equidistant plane: a wider scatter (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, delaunay_triangles on PROJ's azimuthal equidistant plane: an equatorial scatter (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, delaunay_triangles on PROJ's azimuthal equidistant plane: five points (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, delaunay_triangles on PROJ's azimuthal equidistant plane: sixteen scattered points (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, delaunay_triangles on PROJ's azimuthal equidistant plane: two clusters (GEOS 3.11.4 / PROJ 9.3.0) (1) |
| Voronoi cells around points (stable) | 20 | 0 (cell_count) | exact | 0% | Qhull via SciPy (tools/vectors/gen_mesh_diff.py) (SciPy 1.x) (5); GEOS 3.11.4 through shapely, voronoi_polygons in the tool's own clip box on PROJ's azimuthal equidistant plane: a dozen points (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely, voronoi_polygons in the tool's own clip box on PROJ's azimuthal equidistant plane: a high-latitude scatter (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely, voronoi_polygons in the tool's own clip box on PROJ's azimuthal equidistant plane: a jittered 3x3 grid (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely, voronoi_polygons in the tool's own clip box on PROJ's azimuthal equidistant plane: a jittered 4x4 grid (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely, voronoi_polygons in the tool's own clip box on PROJ's azimuthal equidistant plane: a long thin scatter (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely, voronoi_polygons in the tool's own clip box on PROJ's azimuthal equidistant plane: a nudged ring (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely, voronoi_polygons in the tool's own clip box on PROJ's azimuthal equidistant plane: a nudged ring with a centre (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely, voronoi_polygons in the tool's own clip box on PROJ's azimuthal equidistant plane: a scatter across the antimeridian (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely, voronoi_polygons in the tool's own clip box on PROJ's azimuthal equidistant plane: a small scatter (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely, voronoi_polygons in the tool's own clip box on PROJ's azimuthal equidistant plane: a southern scatter (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely, voronoi_polygons in the tool's own clip box on PROJ's azimuthal equidistant plane: a wider scatter (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely, voronoi_polygons in the tool's own clip box on PROJ's azimuthal equidistant plane: an equatorial scatter (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely, voronoi_polygons in the tool's own clip box on PROJ's azimuthal equidistant plane: five points (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely, voronoi_polygons in the tool's own clip box on PROJ's azimuthal equidistant plane: sixteen scattered points (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely, voronoi_polygons in the tool's own clip box on PROJ's azimuthal equidistant plane: two clusters (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1) |
| Overlap, union, or difference of two polygons (stable) | 22 | 5.0e-12 (area) | ±1e-12 + ±1e-10 relative | 21% | Areas by GeographicLib's Planimeter, crossings by Clairaut's relation with GeodSolve (C++), via tools/vectors/gen_overlay.py (GeodSolve: GeographicLib version 2.7) (10); add-navigation-and-geometry scenarios (GeodSolve: GeographicLib version 2.7) (2); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane, with the result measured back on the ellipsoid by geographiclib's PolygonArea: difference of a square inside another, leaving a hole (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane, with the result measured back on the ellipsoid by geographiclib's PolygonArea: difference of two overlapping squares (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane, with the result measured back on the ellipsoid by geographiclib's PolygonArea: difference of two squares that do not meet (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane, with the result measured back on the ellipsoid by geographiclib's PolygonArea: intersection of a square inside another (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane, with the result measured back on the ellipsoid by geographiclib's PolygonArea: intersection of two squares across the antimeridian (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane, with the result measured back on the ellipsoid by geographiclib's PolygonArea: symmetric-difference of two overlapping squares (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane, with the result measured back on the ellipsoid by geographiclib's PolygonArea: union of a square inside another (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane, with the result measured back on the ellipsoid by geographiclib's PolygonArea: union of two overlapping squares (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane, with the result measured back on the ellipsoid by geographiclib's PolygonArea: union of two squares across the antimeridian (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane, with the result measured back on the ellipsoid by geographiclib's PolygonArea: union of two squares that do not meet (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1) |
| Point in polygon (stable) | 22 | 0.0027 (results.1.distance) | ±0.001 + ±0.00005 relative | 10% | Points built with GeographicLib's GeodSolve (C++), classified by hand (tools/vectors/gen_predicate.py) (GeodSolve: GeographicLib version 2.7) (6); add-navigation-and-geometry scenarios (GeodSolve: GeographicLib version 2.7) (2); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: a square (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: a square, points outside (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: a square, scattered points 1 (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: a square, scattered points 2 (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: a square, scattered points 3 (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: a triangle (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: a triangle, points outside (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: a triangle, scattered points 1 (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: a triangle, scattered points 2 (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: a triangle, scattered points 3 (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: an L, points in the arm and in the notch (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: an L, scattered points 1 (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: an L, scattered points 2 (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: an L, scattered points 3 (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1) |
| Bounding box, antimeridian-aware (stable) | 22 | 2.8e-14 (east) | ±1e-9 | 0% | Hand-checked longitude boxes; edge vertices by Clairaut's relation with GeodSolve azimuths (tools/vectors/gen_envelope.py) (2026) (6); Hand-checked longitude boxes; edge vertices by Clairaut's relation with GeodSolve azimuths (tools/vectors/gen_envelope.py) (GeodSolve: GeographicLib version 2.7) (4); add-navigation-and-geometry scenarios (2026) (2); latitude extremes by bisecting Karney's geographiclib for where the azimuth passes due east or west; longitude box by RFC 7946 section 5.2's largest-gap rule: a box across the antimeridian (geographiclib 2.1; RFC 7946) (1); latitude extremes by bisecting Karney's geographiclib for where the azimuth passes due east or west; longitude box by RFC 7946 section 5.2's largest-gap rule: a high-latitude quadrilateral (geographiclib 2.1; RFC 7946) (1); latitude extremes by bisecting Karney's geographiclib for where the azimuth passes due east or west; longitude box by RFC 7946 section 5.2's largest-gap rule: a long mid-latitude line, which bulges poleward (geographiclib 2.1; RFC 7946) (1); latitude extremes by bisecting Karney's geographiclib for where the azimuth passes due east or west; longitude box by RFC 7946 section 5.2's largest-gap rule: a narrow equatorial strip (geographiclib 2.1; RFC 7946) (1); latitude extremes by bisecting Karney's geographiclib for where the azimuth passes due east or west; longitude box by RFC 7946 section 5.2's largest-gap rule: a southern-hemisphere line (geographiclib 2.1; RFC 7946) (1); latitude extremes by bisecting Karney's geographiclib for where the azimuth passes due east or west; longitude box by RFC 7946 section 5.2's largest-gap rule: a transatlantic line (geographiclib 2.1; RFC 7946) (1); latitude extremes by bisecting Karney's geographiclib for where the azimuth passes due east or west; longitude box by RFC 7946 section 5.2's largest-gap rule: a triangle in the northern mid-latitudes (geographiclib 2.1; RFC 7946) (1); latitude extremes by bisecting Karney's geographiclib for where the azimuth passes due east or west; longitude box by RFC 7946 section 5.2's largest-gap rule: points either side of the antimeridian (geographiclib 2.1; RFC 7946) (1); latitude extremes by bisecting Karney's geographiclib for where the azimuth passes due east or west; longitude box by RFC 7946 section 5.2's largest-gap rule: points spread over more than half the world (geographiclib 2.1; RFC 7946) (1); latitude extremes by bisecting Karney's geographiclib for where the azimuth passes due east or west; longitude box by RFC 7946 section 5.2's largest-gap rule: the same pair as bare points, which does not (geographiclib 2.1; RFC 7946) (1) |
| Polygon centroid and interior point (stable) | 24 | 1.9e-7 (centroid_lat) | ±3e-7 | 62% | Symmetry and local-plane centroids, evaluated in Python (tools/vectors/gen_shape.py) (2026) (9); add-navigation-and-geometry scenarios (2026) (3); PROJ's ellipsoidal Lambert azimuthal equal-area (pyproj) with GEOS's planar centroid (shapely), over edges walked by Karney's geographiclib: a C shape, centroid outside (PROJ 9.3.0 / GEOS 3.11.4 / geographiclib 2.1) (1); PROJ's ellipsoidal Lambert azimuthal equal-area (pyproj) with GEOS's planar centroid (shapely), over edges walked by Karney's geographiclib: a long thin strip (PROJ 9.3.0 / GEOS 3.11.4 / geographiclib 2.1) (1); PROJ's ellipsoidal Lambert azimuthal equal-area (pyproj) with GEOS's planar centroid (shapely), over edges walked by Karney's geographiclib: a narrow wedge (PROJ 9.3.0 / GEOS 3.11.4 / geographiclib 2.1) (1); PROJ's ellipsoidal Lambert azimuthal equal-area (pyproj) with GEOS's planar centroid (shapely), over edges walked by Karney's geographiclib: a rectangle straddling the equator (PROJ 9.3.0 / GEOS 3.11.4 / geographiclib 2.1) (1); PROJ's ellipsoidal Lambert azimuthal equal-area (pyproj) with GEOS's planar centroid (shapely), over edges walked by Karney's geographiclib: a shape across the antimeridian (PROJ 9.3.0 / GEOS 3.11.4 / geographiclib 2.1) (1); PROJ's ellipsoidal Lambert azimuthal equal-area (pyproj) with GEOS's planar centroid (shapely), over edges walked by Karney's geographiclib: a southern-hemisphere quadrilateral (PROJ 9.3.0 / GEOS 3.11.4 / geographiclib 2.1) (1); PROJ's ellipsoidal Lambert azimuthal equal-area (pyproj) with GEOS's planar centroid (shapely), over edges walked by Karney's geographiclib: a square at 70 north (PROJ 9.3.0 / GEOS 3.11.4 / geographiclib 2.1) (1); PROJ's ellipsoidal Lambert azimuthal equal-area (pyproj) with GEOS's planar centroid (shapely), over edges walked by Karney's geographiclib: a square in Colorado (PROJ 9.3.0 / GEOS 3.11.4 / geographiclib 2.1) (1); PROJ's ellipsoidal Lambert azimuthal equal-area (pyproj) with GEOS's planar centroid (shapely), over edges walked by Karney's geographiclib: a square on the equator (PROJ 9.3.0 / GEOS 3.11.4 / geographiclib 2.1) (1); PROJ's ellipsoidal Lambert azimuthal equal-area (pyproj) with GEOS's planar centroid (shapely), over edges walked by Karney's geographiclib: a triangle (PROJ 9.3.0 / GEOS 3.11.4 / geographiclib 2.1) (1); PROJ's ellipsoidal Lambert azimuthal equal-area (pyproj) with GEOS's planar centroid (shapely), over edges walked by Karney's geographiclib: a twelve-sided ring (PROJ 9.3.0 / GEOS 3.11.4 / geographiclib 2.1) (1); PROJ's ellipsoidal Lambert azimuthal equal-area (pyproj) with GEOS's planar centroid (shapely), over edges walked by Karney's geographiclib: an L in Colorado (PROJ 9.3.0 / GEOS 3.11.4 / geographiclib 2.1) (1) |
| Add vertices along geodesic edges (densify) (stable) | 21 | 1.1e-10 (longest_piece) | ±1e-9 relative | 0% | GeographicLib GeodSolve inverse and direct on WGS 84 (tools/vectors/gen_densify.py) (GeographicLib 2.x) (6); Karney's geographiclib: ceil(length / max) pieces per edge, placed by the direct problem: a high-latitude line at 10000 m (geographiclib 2.1) (1); Karney's geographiclib: ceil(length / max) pieces per edge, placed by the direct problem: a line across the antimeridian at 20000 m (geographiclib 2.1) (1); Karney's geographiclib: ceil(length / max) pieces per edge, placed by the direct problem: a line of exactly two pieces at 1000 m (geographiclib 2.1) (1); Karney's geographiclib: ceil(length / max) pieces per edge, placed by the direct problem: a meridian line at 60000 m (geographiclib 2.1) (1); Karney's geographiclib: ceil(length / max) pieces per edge, placed by the direct problem: a short line at 2000 m (geographiclib 2.1) (1); Karney's geographiclib: ceil(length / max) pieces per edge, placed by the direct problem: a southern triangle at 15000 m (geographiclib 2.1) (1); Karney's geographiclib: ceil(length / max) pieces per edge, placed by the direct problem: a square as a polygon at 2500 m (geographiclib 2.1) (1); Karney's geographiclib: ceil(length / max) pieces per edge, placed by the direct problem: a three-leg route at 3000 m (geographiclib 2.1) (1); Karney's geographiclib: ceil(length / max) pieces per edge, placed by the direct problem: a transatlantic line at 500000 m (geographiclib 2.1) (1); Karney's geographiclib: ceil(length / max) pieces per edge, placed by the direct problem: a very long route at 40000 m (geographiclib 2.1) (1); Karney's geographiclib: ceil(length / max) pieces per edge, placed by the direct problem: an equatorial line at 50000 m (geographiclib 2.1) (1); Karney's geographiclib: ceil(length / max) pieces per edge, placed by the direct problem: the same line cut finer at 500 m (geographiclib 2.1) (1); Karney's geographiclib: ceil(length / max) pieces per edge, placed by the direct problem: the same line, no cut needed at 50000 m (geographiclib 2.1) (1); Karney's geographiclib: ceil(length / max) pieces per edge, placed by the direct problem: the same route cut finer at 900 m (geographiclib 2.1) (1); Karney's geographiclib: ceil(length / max) pieces per edge, placed by the direct problem: the same square cut finer at 700 m (geographiclib 2.1) (1) |
| Hull, bounding rectangle, and enclosing circle (stable) | 21 | 0.000047 (rect_azimuth) | ±0.0001 | 47% | Circles and rectangles built with GeographicLib's GeodSolve (C++), evaluated in Python (tools/vectors/gen_envelope.py) (GeodSolve: GeographicLib version 2.7) (8); add-navigation-and-geometry scenarios (2026) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: minimum_bounding_circle, convex_hull and minimum_rotated_rectangle, with the hull's area measured on the ellipsoid by geographiclib's PolygonArea: a long thin spread (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: minimum_bounding_circle, convex_hull and minimum_rotated_rectangle, with the hull's area measured on the ellipsoid by geographiclib's PolygonArea: a loose cluster (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: minimum_bounding_circle, convex_hull and minimum_rotated_rectangle, with the hull's area measured on the ellipsoid by geographiclib's PolygonArea: a quadrilateral (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: minimum_bounding_circle, convex_hull and minimum_rotated_rectangle, with the hull's area measured on the ellipsoid by geographiclib's PolygonArea: a scatter at 70 north (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: minimum_bounding_circle, convex_hull and minimum_rotated_rectangle, with the hull's area measured on the ellipsoid by geographiclib's PolygonArea: a scatter at the equator (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: minimum_bounding_circle, convex_hull and minimum_rotated_rectangle, with the hull's area measured on the ellipsoid by geographiclib's PolygonArea: a southern scatter (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: minimum_bounding_circle, convex_hull and minimum_rotated_rectangle, with the hull's area measured on the ellipsoid by geographiclib's PolygonArea: a square, where the rectangle is the hull (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: minimum_bounding_circle, convex_hull and minimum_rotated_rectangle, with the hull's area measured on the ellipsoid by geographiclib's PolygonArea: a tight cluster (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: minimum_bounding_circle, convex_hull and minimum_rotated_rectangle, with the hull's area measured on the ellipsoid by geographiclib's PolygonArea: a triangle (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: minimum_bounding_circle, convex_hull and minimum_rotated_rectangle, with the hull's area measured on the ellipsoid by geographiclib's PolygonArea: points either side of the antimeridian (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: minimum_bounding_circle, convex_hull and minimum_rotated_rectangle, with the hull's area measured on the ellipsoid by geographiclib's PolygonArea: three points in a line (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely on PROJ's azimuthal equidistant plane: minimum_bounding_circle, convex_hull and minimum_rotated_rectangle, with the hull's area measured on the ellipsoid by geographiclib's PolygonArea: two points (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1) |
| Simplify a line or polygon (Douglas-Peucker) (stable) | 29 | 0.000012 (max_deviation) | ±0.000001 + ±0.000001 relative | 13% | Douglas-Peucker (1973) and Visvalingam-Whyatt (1993) in Python on GeographicLib GeodesicProj -z (tools/vectors/gen_simplify.py) (GeographicLib 2.x) (5); GEOS 3.11.4 through shapely, LineString.simplify on PROJ's azimuthal equidistant plane: a gentle curve at 100 m (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, LineString.simplify on PROJ's azimuthal equidistant plane: a gentle curve at 25 m (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, LineString.simplify on PROJ's azimuthal equidistant plane: a gentle curve at 400 m (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, LineString.simplify on PROJ's azimuthal equidistant plane: a gentle curve at 5 m (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, LineString.simplify on PROJ's azimuthal equidistant plane: a high-latitude track at 100 m (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, LineString.simplify on PROJ's azimuthal equidistant plane: a high-latitude track at 25 m (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, LineString.simplify on PROJ's azimuthal equidistant plane: a high-latitude track at 400 m (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, LineString.simplify on PROJ's azimuthal equidistant plane: a high-latitude track at 5 m (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, LineString.simplify on PROJ's azimuthal equidistant plane: a long wandering track at 100 m (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, LineString.simplify on PROJ's azimuthal equidistant plane: a long wandering track at 25 m (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, LineString.simplify on PROJ's azimuthal equidistant plane: a long wandering track at 400 m (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, LineString.simplify on PROJ's azimuthal equidistant plane: a long wandering track at 5 m (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, LineString.simplify on PROJ's azimuthal equidistant plane: a near-straight line at 100 m (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, LineString.simplify on PROJ's azimuthal equidistant plane: a near-straight line at 25 m (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, LineString.simplify on PROJ's azimuthal equidistant plane: a near-straight line at 400 m (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, LineString.simplify on PROJ's azimuthal equidistant plane: a near-straight line at 5 m (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, LineString.simplify on PROJ's azimuthal equidistant plane: a sharp dogleg at 100 m (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, LineString.simplify on PROJ's azimuthal equidistant plane: a sharp dogleg at 25 m (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, LineString.simplify on PROJ's azimuthal equidistant plane: a sharp dogleg at 400 m (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, LineString.simplify on PROJ's azimuthal equidistant plane: a sharp dogleg at 5 m (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, LineString.simplify on PROJ's azimuthal equidistant plane: a zigzag at 100 m (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, LineString.simplify on PROJ's azimuthal equidistant plane: a zigzag at 25 m (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, LineString.simplify on PROJ's azimuthal equidistant plane: a zigzag at 400 m (GEOS 3.11.4 / PROJ 9.3.0) (1); GEOS 3.11.4 through shapely, LineString.simplify on PROJ's azimuthal equidistant plane: a zigzag at 5 m (GEOS 3.11.4 / PROJ 9.3.0) (1) |
| Simplify a line or polygon (Visvalingam) (stable) | 29 | 0.000020 (max_deviation) | ±0.05 | 0% | Douglas-Peucker (1973) and Visvalingam-Whyatt (1993) in Python on GeographicLib GeodesicProj -z (tools/vectors/gen_simplify.py) (GeographicLib 2.x) (5); the simplification package (urschrei), Visvalingam-Whyatt on PROJ's azimuthal equidistant plane: a gentle curve at 1000 m2, keeping vertices [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] (simplification 0.7 / PROJ 9.5.1) (1); the simplification package (urschrei), Visvalingam-Whyatt on PROJ's azimuthal equidistant plane: a gentle curve at 20000 m2, keeping vertices [1, 4, 8, 12] (simplification 0.7 / PROJ 9.5.1) (1); the simplification package (urschrei), Visvalingam-Whyatt on PROJ's azimuthal equidistant plane: a gentle curve at 200000 m2, keeping vertices [1, 8, 12] (simplification 0.7 / PROJ 9.5.1) (1); the simplification package (urschrei), Visvalingam-Whyatt on PROJ's azimuthal equidistant plane: a gentle curve at 2e+06 m2, keeping vertices [1, 12] (simplification 0.7 / PROJ 9.5.1) (1); the simplification package (urschrei), Visvalingam-Whyatt on PROJ's azimuthal equidistant plane: a high-latitude track at 1000 m2, keeping vertices [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] (simplification 0.7 / PROJ 9.5.1) (1); the simplification package (urschrei), Visvalingam-Whyatt on PROJ's azimuthal equidistant plane: a high-latitude track at 20000 m2, keeping vertices [1, 2, 4, 6, 8, 10] (simplification 0.7 / PROJ 9.5.1) (1); the simplification package (urschrei), Visvalingam-Whyatt on PROJ's azimuthal equidistant plane: a high-latitude track at 200000 m2, keeping vertices [1, 4, 8, 10] (simplification 0.7 / PROJ 9.5.1) (1); the simplification package (urschrei), Visvalingam-Whyatt on PROJ's azimuthal equidistant plane: a high-latitude track at 2e+06 m2, keeping vertices [1, 10] (simplification 0.7 / PROJ 9.5.1) (1); the simplification package (urschrei), Visvalingam-Whyatt on PROJ's azimuthal equidistant plane: a long wandering track at 1000 m2, keeping vertices [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] (simplification 0.7 / PROJ 9.5.1) (1); the simplification package (urschrei), Visvalingam-Whyatt on PROJ's azimuthal equidistant plane: a long wandering track at 20000 m2, keeping vertices [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] (simplification 0.7 / PROJ 9.5.1) (1); the simplification package (urschrei), Visvalingam-Whyatt on PROJ's azimuthal equidistant plane: a long wandering track at 200000 m2, keeping vertices [1, 5, 9, 13, 17, 20] (simplification 0.7 / PROJ 9.5.1) (1); the simplification package (urschrei), Visvalingam-Whyatt on PROJ's azimuthal equidistant plane: a long wandering track at 2e+06 m2, keeping vertices [1, 13, 20] (simplification 0.7 / PROJ 9.5.1) (1); the simplification package (urschrei), Visvalingam-Whyatt on PROJ's azimuthal equidistant plane: a near-straight line at 1000 m2, keeping vertices [1, 9] (simplification 0.7 / PROJ 9.5.1) (1); the simplification package (urschrei), Visvalingam-Whyatt on PROJ's azimuthal equidistant plane: a near-straight line at 20000 m2, keeping vertices [1, 9] (simplification 0.7 / PROJ 9.5.1) (1); the simplification package (urschrei), Visvalingam-Whyatt on PROJ's azimuthal equidistant plane: a near-straight line at 200000 m2, keeping vertices [1, 9] (simplification 0.7 / PROJ 9.5.1) (1); the simplification package (urschrei), Visvalingam-Whyatt on PROJ's azimuthal equidistant plane: a near-straight line at 2e+06 m2, keeping vertices [1, 9] (simplification 0.7 / PROJ 9.5.1) (1); the simplification package (urschrei), Visvalingam-Whyatt on PROJ's azimuthal equidistant plane: a sharp dogleg at 1000 m2, keeping vertices [1, 2, 3, 4, 5] (simplification 0.7 / PROJ 9.5.1) (1); the simplification package (urschrei), Visvalingam-Whyatt on PROJ's azimuthal equidistant plane: a sharp dogleg at 20000 m2, keeping vertices [1, 2, 4, 5] (simplification 0.7 / PROJ 9.5.1) (1); the simplification package (urschrei), Visvalingam-Whyatt on PROJ's azimuthal equidistant plane: a sharp dogleg at 200000 m2, keeping vertices [1, 2, 4, 5] (simplification 0.7 / PROJ 9.5.1) (1); the simplification package (urschrei), Visvalingam-Whyatt on PROJ's azimuthal equidistant plane: a sharp dogleg at 2e+06 m2, keeping vertices [1, 5] (simplification 0.7 / PROJ 9.5.1) (1); the simplification package (urschrei), Visvalingam-Whyatt on PROJ's azimuthal equidistant plane: a zigzag at 1000 m2, keeping vertices [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] (simplification 0.7 / PROJ 9.5.1) (1); the simplification package (urschrei), Visvalingam-Whyatt on PROJ's azimuthal equidistant plane: a zigzag at 20000 m2, keeping vertices [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] (simplification 0.7 / PROJ 9.5.1) (1); the simplification package (urschrei), Visvalingam-Whyatt on PROJ's azimuthal equidistant plane: a zigzag at 200000 m2, keeping vertices [1, 14] (simplification 0.7 / PROJ 9.5.1) (1); the simplification package (urschrei), Visvalingam-Whyatt on PROJ's azimuthal equidistant plane: a zigzag at 2e+06 m2, keeping vertices [1, 14] (simplification 0.7 / PROJ 9.5.1) (1) |
| Check and repair a polygon (stable) | 21 | 3.7e-11 (area) | ±1e-9 relative | 6% | Areas by GeographicLib's Planimeter and crossings by GeodSolve (C++), via tools/vectors/gen_validity.py (GeodSolve: GeographicLib version 2.7) (5); add-navigation-and-geometry scenarios (GeodSolve: GeographicLib version 2.7) (2); GEOS 3.11.4 through shapely: is_valid and make_valid on PROJ's azimuthal equidistant plane, with the repaired area measured on the ellipsoid by geographiclib's PolygonArea: a bow tie (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely: is_valid and make_valid on PROJ's azimuthal equidistant plane, with the repaired area measured on the ellipsoid by geographiclib's PolygonArea: a bow tie across the antimeridian (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely: is_valid and make_valid on PROJ's azimuthal equidistant plane, with the repaired area measured on the ellipsoid by geographiclib's PolygonArea: a bow tie at the equator (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely: is_valid and make_valid on PROJ's azimuthal equidistant plane, with the repaired area measured on the ellipsoid by geographiclib's PolygonArea: a crossed quadrilateral (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely: is_valid and make_valid on PROJ's azimuthal equidistant plane, with the repaired area measured on the ellipsoid by geographiclib's PolygonArea: a ring pinched to a point (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely: is_valid and make_valid on PROJ's azimuthal equidistant plane, with the repaired area measured on the ellipsoid by geographiclib's PolygonArea: a square with a repeated corner (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely: is_valid and make_valid on PROJ's azimuthal equidistant plane, with the repaired area measured on the ellipsoid by geographiclib's PolygonArea: a square with a spike (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely: is_valid and make_valid on PROJ's azimuthal equidistant plane, with the repaired area measured on the ellipsoid by geographiclib's PolygonArea: a valid L (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely: is_valid and make_valid on PROJ's azimuthal equidistant plane, with the repaired area measured on the ellipsoid by geographiclib's PolygonArea: a valid square (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely: is_valid and make_valid on PROJ's azimuthal equidistant plane, with the repaired area measured on the ellipsoid by geographiclib's PolygonArea: a valid square across the antimeridian (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely: is_valid and make_valid on PROJ's azimuthal equidistant plane, with the repaired area measured on the ellipsoid by geographiclib's PolygonArea: a valid square at 70 north (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely: is_valid and make_valid on PROJ's azimuthal equidistant plane, with the repaired area measured on the ellipsoid by geographiclib's PolygonArea: a valid square at the equator (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely: is_valid and make_valid on PROJ's azimuthal equidistant plane, with the repaired area measured on the ellipsoid by geographiclib's PolygonArea: a valid square, wound the other way (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1); GEOS 3.11.4 through shapely: is_valid and make_valid on PROJ's azimuthal equidistant plane, with the repaired area measured on the ellipsoid by geographiclib's PolygonArea: a valid triangle (GEOS 3.11.4 / PROJ 9.3.0 / geographiclib 2.1) (1) |
| One place in every index, at a matched cell size (stable) | 21 | 3.6e-12 (cells.3.cell_size) | ±0.000001 + ±1e-9 relative | 0% | Cell-size tables for each system worked independently in Python (tools/vectors/gen_cross.py) (2026-09-22) (21) |
| Geohashes covering an area (stable) | 22 | 0 (count) | exact | 0% | Slippy-map and geohash arithmetic in Python (tools/vectors/gen_cover.py) (2026) (22) |
| Geohash decoder (stable) | 24 | 0.000027 (lon) | ±0.0005 | 5% | Geohash algorithm implemented in Python (tools/vectors/gen_indexing.py) (2026) (22); add-spatial-indexing-and-raster scenarios (2026) (1); Wikipedia, Geohash (worked example) (retrieved 2026-09-19) (1) |
| Geohash encoder (stable) | 23 | 0 (south) | ±1e-9 | 0% | Geohash algorithm implemented in Python (tools/vectors/gen_indexing.py) (2026) (21); add-spatial-indexing-and-raster scenarios (2026) (1); Wikipedia, Geohash (worked example) (retrieved 2026-09-19) (1) |
| Geohash neighbors (stable) | 24 | no numeric checks | Geohash algorithm implemented in Python (tools/vectors/gen_indexing.py) (2026) (21); add-spatial-indexing-and-raster scenarios (2026) (2); Chris Veness, latlon-geohash test suite (test.js) (2.0.0) (1) | ||
| H3 cell inspector (stable) | 23 | 4.7e-12 (boundary.0.lat) | ±5e-11 + ±1e-11 relative | 1% | H3 C 4.4.1 via h3-py 4.4.2 (H3 4.4.1) (19); add-spatial-indexing-and-raster scenarios (2026) (3); add-spatial-indexing-and-raster scenarios (H3 4.4.1) (1) |
| H3 local IJ for a cell (cellToLocalIj) (stable) | 22 | 0 (i) | ±1e-9 + ±1e-11 relative | 0% | H3 C 4.4.1 via h3-py 4.4.2 (H3 4.4.1) (22) |
| H3 cell set outline (cellsToMultiPolygon) (stable) | 24 | 1.8e-8 (area) | ±1e-9 + ±1e-9 relative | 24% | H3 C 4.4.1 via h3-py 4.4.2 (H3 4.4.1) (24) |
| H3 children cells (stable) | 20 | 0 (count) | ±5e-11 + ±1e-11 relative | 0% | H3 C 4.4.1 via h3-py 4.4.2 (H3 4.4.1) (19); add-spatial-indexing-and-raster scenarios (H3 4.4.1) (1) |
| H3 compact (stable) | 20 | 0 (count) | ±5e-11 + ±1e-11 relative | 0% | H3 C 4.4.1 via h3-py 4.4.2 (H3 4.4.1) (20) |
| H3 edges and vertexes (stable) | 20 | 3.0e-7 (edges.0.length) | ±0.000001 + ±1e-11 relative | 29% | H3 C 4.4.1 via h3-py 4.4.2 (H3 4.4.1) (20) |
| H3 grid disk (k-ring) (stable) | 22 | 0 (count) | ±5e-11 + ±1e-11 relative | 0% | H3 C 4.4.1 via h3-py 4.4.2 (H3 4.4.1) (21); add-spatial-indexing-and-raster scenarios (2026) (1) |
| H3 grid path and distance (stable) | 20 | 0 (distance) | ±5e-11 + ±1e-11 relative | 0% | H3 C 4.4.1 via h3-py 4.4.2 (H3 4.4.1) (20) |
| H3 grid ring (stable) | 20 | 0 (count) | ±5e-11 + ±1e-11 relative | 0% | H3 C 4.4.1 via h3-py 4.4.2 (H3 4.4.1) (20) |
| H3 cell for a point (stable) | 25 | 9.6e-10 (area) | ±1e-9 + ±1e-11 relative | 69% | H3 C 4.4.1 via h3-py 4.4.2 (H3 4.4.1) (23); add-spatial-indexing-and-raster scenarios (2026) (1); add-spatial-indexing-and-raster scenarios (H3 4.4.1) (1) |
| H3 cell at local IJ (localIjToCell) (stable) | 22 | 6.2e-14 (lon) | ±1e-9 + ±1e-11 relative | 0% | H3 C 4.4.1 via h3-py 4.4.2 (H3 4.4.1) (22) |
| H3 parent cell (stable) | 20 | 0 (child_position) | ±5e-11 + ±1e-11 relative | 0% | H3 C 4.4.1 via h3-py 4.4.2 (H3 4.4.1) (19); add-spatial-indexing-and-raster scenarios (H3 4.4.1) (1) |
| H3 polygon fill (polygonToCells) (stable) | 23 | 0 (count) | ±5e-11 + ±1e-11 relative | 0% | H3 C 4.4.1 via h3-py 4.4.2 (H3 4.4.1) (20); H3 C test suite, testPolygonToCells.c (sfGeoPolygon, holeGeoPolygon) (H3 v4.4.1) (2); add-spatial-indexing-and-raster scenarios (2026) (1) |
| H3 resolution chooser (stable) | 22 | 4.3e-10 (average_area) | ±5e-10 + ±1e-11 relative | 85% | H3 average hexagon areas (h3.average_hexagon_area) (H3 4.4.1) (13); H3 average hexagon edge lengths (h3.average_hexagon_edge_length) (H3 4.4.1) (7); add-spatial-indexing-and-raster scenarios (H3 4.4.1) (1); H3 documentation, Tables of cell statistics across resolutions (h3geo.org, retrieved 2026-09-19) (1) |
| H3 uncompact (stable) | 20 | 0 (count) | ±5e-11 + ±1e-11 relative | 0% | H3 C 4.4.1 via h3-py 4.4.2 (H3 4.4.1) (20) |
| Plus Code decoder (stable) | 49 | 5.1e-13 (east) | ±1e-9 | 0% | Open Location Code test data, decoding.csv (open-location-code main) (42); Open Location Code test data, encoding.csv (open-location-code main) (5); add-spatial-indexing-and-raster scenarios (2026) (1); Open Location Code specification (recover nearest) (open-location-code main) (1) |
| Plus Code encoder (stable) | 35 | no numeric checks | Open Location Code test data, encoding.csv (open-location-code main) (35) | ||
| Shorten a Plus Code (stable) | 21 | no numeric checks | Open Location Code test data, shortCodeTests.csv (open-location-code main) (15); Open Location Code specification (shorten) (open-location-code main) (5); add-spatial-indexing-and-raster scenarios (2026) (1) | ||
| S2 cell details (stable) | 22 | 1.8e-11 (lat) | ±1e-9 | 2% | s2sphere, an independent Python implementation of the S2 algorithms (tools/vectors/gen_s2.py) (s2sphere 0.2.5) (22) |
| S2 cells covering a region (stable) | 22 | 0 (count) | exact | 0% | The covering this implementation produces, pinned so a change in the refinement is visible; containment is checked independently against s2sphere in tests/s2_cover_parity.rs (2026-09-23) (16); The covering this implementation produces, pinned so a change in the refinement is visible; containment, budget, and level range are checked against sampled points by the core tests (2026-09-22) (6) |
| S2 cell for a point (stable) | 22 | 1.8e-11 (lat) | ±1e-9 | 2% | s2sphere, an independent Python implementation of the S2 algorithms (tools/vectors/gen_s2.py) (s2sphere 0.2.5) (22) |
| S2 edge neighbours (stable) | 22 | 0 (level) | ±1e-9 | 0% | s2sphere, an independent Python implementation of the S2 algorithms (tools/vectors/gen_s2.py) (s2sphere 0.2.5) (22) |
| Map tile bounds (stable) | 26 | 1.4e-14 (south) | ±1e-9 | 0% | OpenStreetMap slippy-map formulas and Bing quadkeys in Python (tools/vectors/gen_indexing.py) (2026) (21); add-spatial-indexing-and-raster scenarios (2026) (3); mercantile README (Mapbox), worked examples (mercantile 1.2.1) (1); Microsoft, Bing Maps Tile System (worked quadkey example and ground-resolution table) (2018-02-28) (1) |
| Map tiles covering a box (stable) | 21 | 0 (count) | exact | 0% | Slippy-map and geohash arithmetic in Python (tools/vectors/gen_cover.py) (2026) (21) |
| Map tile parent and children (stable) | 23 | no numeric checks | Slippy-map and geohash arithmetic in Python (tools/vectors/gen_cover.py) (2026) (23) | ||
| Map tile for a point (XYZ, TMS, quadkey) (stable) | 25 | 0.000036 (ground_resolution) | ±0.00005 | 72% | OpenStreetMap slippy-map formulas and Bing quadkeys in Python (tools/vectors/gen_indexing.py) (2026) (20); add-spatial-indexing-and-raster scenarios (2026) (2); mercantile README (Mapbox), worked examples (mercantile 1.2.1) (1); Microsoft, Bing Maps Tile System (worked quadkey example and ground-resolution table) (2018-02-28) (1); Regression for a reported defect (2026-09-23 fix-geodesy-indexing): tile_size given as the JSON number 512 is accepted like the string "512" (was rejected as not a string). (core 0.1.0) (1) |
| Map ground resolution and scale (stable) | 30 | 0.000046 (resolution) | ±0.00005 | 91% | OpenStreetMap slippy-map formulas and Bing quadkeys in Python (tools/vectors/gen_indexing.py) (2026) (20); Microsoft, Bing Maps Tile System (worked quadkey example and ground-resolution table) (2018-02-28) (9); add-spatial-indexing-and-raster scenarios (2026) (1) |
| Destination from a start, course, and distance (geodesic) (stable) | 28 | 4.0e-8 (lat2) | ±1e-7 | 40% | GeographicLib GeodTest-short.dat, line sample (Karney, high-precision reference) (GeodTest 2010) (18); GeographicLib GeodSolve -E (GeodesicExact), custom ellipsoids (GeographicLib 2.x) (5); Closed form on WGS 84: equatorial arc s = a * dlon; meridian quadrant 10,001,965.729313 m (GeographicLib 2.x) (4); add-navigation-and-geometry geodesic scenarios (GeographicLib GeodSolve values) (GeographicLib 2.x) (1) |
| Haversine distance (spherical) (stable) | 20 | 0.15 (difference) | ±1 | 15% | Haversine evaluated in Python with R1 = 6,371,008.771 m (Moritz 2000) (19); Rosetta Code, Haversine formula (task description) (retrieved 2026-09-19) (1) |
| Point part way along a great circle (stable) | 48 | 7.0e-12 (ellipsoidal_lon) | ±1e-9 | 1% | GeographicLib's GeodSolve, called per quantity (tools/vectors/gen_nav_geodesic.py) (GeographicLib 2.7) (42); Spherical formulas in Python and GeographicLib GeodSolve (tools/vectors/gen_sphere.py) (GeodSolve: GeographicLib version 2.7) (6) |
| Where two geodesic segments cross (stable) | 62 | 0.0000047 (along_b) | ±0.000001 + ±5e-12 relative | 35% | GeographicLib IntersectTool -i (Karney 2024, geodesic intersections) (GeographicLib 2.x) (61); GeographicLib IntersectTool -i (Karney 2024); found by the differential runner, where the Wasm build once kept the far crossing (GeographicLib 2.x) (1) |
| Distance between two points (geodesic) (stable) | 31 | 4.5e-7 (distance) | ±0.000001 | 45% | GeographicLib GeodTest-short.dat, line sample (Karney, high-precision reference) (GeodTest 2010) (18); GeographicLib GeodSolve -E (GeodesicExact), custom ellipsoids (GeographicLib 2.x) (5); Closed form on WGS 84: equatorial arc s = a * dlon; meridian quadrant 10,001,965.729313 m (GeographicLib 2.x) (4); add-navigation-and-geometry geodesic scenarios (GeographicLib GeodSolve values) (GeographicLib 2.x) (2); add-navigation-and-geometry high-flattening scenario (GeodSolve -E) (GeographicLib 2.x) (1); Regression for a reported defect (2026-09-23 fix-geodesy-indexing): A 0.859 m distance keeps three significant digits (was 0.001 km). (core 0.1.0) (1) |
| Midpoint on the geodesic (stable) | 23 | 6.2e-12 (lon) | ±1e-9 | 1% | GeographicLib's GeodSolve, called per quantity (tools/vectors/gen_nav_geodesic.py) (GeographicLib 2.7) (18); Closed form on WGS 84: equatorial arc s = a * dlon; meridian quadrant 10,001,965.729313 m (GeographicLib 2.x) (5) |
| Great-circle destination (spherical) (stable) | 21 | 3.1e-12 (final_course) | ±1e-8 | 0% | The great-circle formulas on a sphere of 6,371.008771 km, transcribed from their definitions (tools/vectors/gen_nav_sphere_vincenty.py) (definition) (16); Spherical formulas in Python and GeographicLib GeodSolve (tools/vectors/gen_sphere.py) (GeodSolve: GeographicLib version 2.7) (5) |
| Great-circle distance and course (spherical) (stable) | 21 | 3.7e-11 (course_difference) | ±1e-9 | 4% | The great-circle formulas on a sphere of 6,371.008771 km, transcribed from their definitions (tools/vectors/gen_nav_sphere_vincenty.py) (definition) (16); Spherical formulas in Python and GeographicLib GeodSolve (tools/vectors/gen_sphere.py) (GeodSolve: GeographicLib version 2.7) (4); add-navigation-and-geometry geodesic scenarios (JFK to Heathrow: 5,540,019 m on R1, about 14,890 m shorter than the geodesic) (GeodSolve: GeographicLib version 2.7) (1) |
| Highest point of a geodesic (vertex) (stable) | 21 | 4.8e-8 (along) | ±0.000001 | 5% | GeographicLib's GeodSolve, called per quantity (tools/vectors/gen_nav_geodesic.py) (GeographicLib 2.7) (14); GeographicLib GeodSolve -a (Karney 2013), checked against Clairaut's relation (GeographicLib 2.x) (7) |
| Vincenty direct (legacy) (stable) | 21 | 4.0e-8 (lat2) | ±1e-7 | 40% | Vincenty's 1975 inverse and direct methods, implemented from the paper's own formulas (tools/vectors/gen_nav_sphere_vincenty.py) (Vincenty (1975), Survey Review XXIII no. 176) (16); Closed form on WGS 84: equatorial arc s = a * dlon; meridian quadrant 10,001,965.729313 m (Vincenty agrees within 1 mm) (GeographicLib 2.x) (4); add-navigation-and-geometry geodesic scenarios (GeographicLib GeodSolve values) (Vincenty agrees within 1 mm) (GeographicLib 2.x) (1) |
| Vincenty inverse (legacy) (stable) | 21 | 4.4e-7 (distance) | ±0.000001 | 44% | Vincenty's 1975 inverse and direct methods, implemented from the paper's own formulas (tools/vectors/gen_nav_sphere_vincenty.py) (Vincenty (1975), Survey Review XXIII no. 176) (16); Closed form on WGS 84: equatorial arc s = a * dlon; meridian quadrant 10,001,965.729313 m (GeographicLib 2.x) (3); add-navigation-and-geometry geodesic scenarios (GeographicLib GeodSolve values) (GeographicLib 2.x) (2) |
| Waypoints along a route line (stable) | 22 | 5.5e-12 (length) | ±1e-9 | 1% | Karney's geographiclib (Python): points along the geodesic by the direct problem (2026) (22) |
| Dip of the horizon (stable) | 23 | 3.6e-15 (dip) | ±1e-9 + ±1e-10 relative | 0% | Spherical Earth with effective radius R/(1 - k), evaluated in Python (tools/vectors/gen_los.py) (2026) (22); Bowditch (NGA Pub. 9, 2024) Table 12's horizon rule 1.17 sqrt(h ft) and the printed dip rule 1.76' sqrt(h m), which together fix the effective radius at 7666208 m, i.e. k = 0.1689; the rule value is that printed coefficient evaluated directly, and the dip is held only to the 0.25% the two rules agree to (NGA Pub. 9, 2024 edition) (1) |
| Fresnel zone and radio link clearance (stable) | 23 | 0.0095 (fresnel_radius) | ±0.001 relative | 84% | Spherical Earth with effective radius R/(1 - k), evaluated in Python (tools/vectors/gen_los.py) (2026) (22); ITU-R P.530's printed working form F1 = 17.3 sqrt(d1 d2 / (f d)) and the microwave-path Earth bulge d1 d2 / (12.75 K), K = 4/3; each published constant is short of the exact form by its own rounding, 0.084% and 0.063% (ITU-R P.530) (1) |
| Distance to the horizon (stable) | 29 | 0.050 (rule_visual) | ±0.051 | 98% | Spherical Earth with effective radius R/(1 - k), evaluated in Python (tools/vectors/gen_los.py) (2026) (22); Bowditch, The American Practical Navigator (NGA Pub. 9), Volume II, Table 12, Distance of the Horizon (2024 edition) (7) |
| Can two points see each other? (stable) | 23 | 0.24 (max_range) | ±0.2432 | 97% | Spherical Earth with effective radius R/(1 - k), evaluated in Python (tools/vectors/gen_los.py) (2026) (22); Bowditch (NGA Pub. 9, 2024) Table 12: 700 ft (213.36 m) has a horizon of 31.0 nmi, and the range at which two objects see each other is the two horizon distances added (NGA Pub. 9, 2024 edition) (1) |
| Destination on a constant course (rhumb line) (stable) | 25 | 0.017 (lat2) | ±0.02 | 85% | GeographicLib RhumbSolve (Karney's Rhumb), WGS 84 (GeographicLib 2.7) (24); Bowditch, The American Practical Navigator (NGA Pub. 9), Art. 910, Mercator sailing (2024 edition) (1) |
| Rhumb line distance and course (stable) | 24 | 2.5 (distance) | ±2.778 | 92% | GeographicLib RhumbSolve (Karney's Rhumb), WGS 84 (GeographicLib 2.7) (22); Bowditch, The American Practical Navigator (NGA Pub. 9), Art. 910, Mercator sailing (2024 edition) (1); Regression for a reported defect (2026-09-23 fix-geodesy-indexing): A short rhumb distance keeps three significant digits; the rhumb-minus-geodesic difference stays at millimeter decimals. (core 0.1.0) (1) |
| Closest point on a route (stable) | 23 | 7.9e-10 (along_route) | ±1e-8 | 8% | Karney's geographiclib (Python): per-leg perpendicularity bisection, clamped to each leg (2026) (22); GeographicLib GeodSolve: the five legs by the inverse problem, the closest point by the course to the position being 90 deg from the leg, the along-route distance as the first leg plus the run to it (GeographicLib 2.7) (1) |
| Where two courses cross | 8 | 1.3e-8 (distance1) | ±0.000001 | 1% | GeographicLib IntersectTool, GeodSolve, and RhumbSolve (tools/vectors/gen_intersect.py) (GeodSolve: GeographicLib version 2.7) (8) |
| Closest point of approach (stable) | 27 | 1.7e-13 (separation) | ±1e-12 relative | 0% | Relative motion in a flat plane: t = -(r.v)/|v|^2, evaluated in Python (2026) (22); Relative motion in a local east-north-up frame: t = -(r.v)/|v|^2, evaluated in Python (2026) (4); exactly solvable by hand: r = (1000, 1200) m and v = (-10, -10) m/s give t = -(r.v)/|v|^2 = 22000/200 = 110 s, relative position (-100, +100) m, separation 100*sqrt(2) on a bearing of 315 deg, present separation sqrt(1000^2 + 1200^2) (closed form) (1) |
| Cross-track and along-track distance (stable) | 23 | 0.068 (along_track) | ±0.08 | 85% | Karney's geographiclib (Python): perpendicularity bisection along the geodesic (geographiclib 2.1) (22); Ed Williams, Aviation Formulary, Cross track error worked example (LAX to JFK) (version 1.47) (1) |
| Fly-by turn anticipation (stable) | 23 | 2.7e-12 (lead_distance) | ±1e-9 + ±1e-12 relative | 0% | Coordinated turn: R = V^2/(g tan bank), lead = R tan(dpsi/2), evaluated in Python (2026) (22); the FAA's standard-rate turn (Instrument Flying Handbook, FAA-H-8083-15B): 3 deg/s is 360 deg in two minutes, so at 120 kt the radius is V*T/(2 pi) and the bank that holds it is atan(V*omega/g); a 90 deg turn then takes 30 s and covers 120 kt * 30 s = one nautical mile of arc (FAA-H-8083-15B) (1) |
| Intercept a moving target | 17 | 3.3e-9 (meet_lon) | ±1e-8 | 33% | GeographicLib's GeodSolve: the intercept time found by bracketing and bisecting range(t) - v.t (tools/vectors/gen_nav_route.py) (GeographicLib 2.7) (12); GeographicLib IntersectTool, GeodSolve, and RhumbSolve (tools/vectors/gen_intersect.py) (GeodSolve: GeographicLib version 2.7) (4); add-navigation-and-geometry route-geometry scenarios (unreachable: the target opens faster than the pursuer closes) (GeodSolve: GeographicLib version 2.7) (1) |
| Route legs, courses, and totals (stable) | 22 | 9.1e-13 (total_distance) | ±1e-9 | 0% | Karney's geographiclib (Python) geodesic inverse per leg (2026) (22) |
| Range rings (stable) | 21 | 6.6e-11 (summary.0.area) | ±1e-9 + ±1e-9 relative | 0% | GeographicLib's GeodSolve, called per quantity (tools/vectors/gen_nav_geodesic.py) (GeographicLib 2.7) (10); Ring points by GeodSolve and areas by Planimeter (GeographicLib, C++), via tools/vectors/gen_rings.py (GeodSolve: GeographicLib version 2.7) (7); add-navigation-and-geometry scenarios (2026) (4) |
| Time, speed, and distance (stable) | 29 | 0.042 (distance) | ±0.051 | 82% | distance = speed x time, evaluated in Python (2026) (22); Bowditch, The American Practical Navigator (NGA Pub. 9), Volume II, Table 11, Speed, Time, and Distance (2024 edition) (7) |
| 3D distance between two points (stable) | 20 | 5.4e-8 (slant_range) | ±0.000001 | 5% | PROJ through pyproj, EPSG:4979 to EPSG:4978 (WGS 84 geodetic to geocentric), with the east-north-up rotation applied from its own definition (tools/vectors/gen_nav_vector.py) (pyproj 3.6.1 / PROJ 9.3.0) (12); GeographicLib CartConvert -l, GeodSolve -i, and GeoidEval (egm96-15) (tools/vectors/gen_vector3d.py) (GeographicLib 2.x) (6); add-navigation-and-geometry scenarios (2026) (2) |
| Look angles to a target (stable) | 21 | 1.0e-9 (slant_range) | ±0.000001 | 0% | PROJ through pyproj, EPSG:4979 to EPSG:4978 (WGS 84 geodetic to geocentric), with the east-north-up rotation applied from its own definition (tools/vectors/gen_nav_vector.py) (pyproj 3.6.1 / PROJ 9.3.0) (16); GeographicLib CartConvert -l, GeodSolve -i, and GeoidEval (egm96-15) (tools/vectors/gen_vector3d.py) (GeographicLib 2.x) (5) |
| Vector sum, dot, and cross product (stable) | 22 | 0 (magnitude) | ±1e-12 | 0% | Exact trigonometry and vector algebra from the definitions (tools/vectors/gen_nav_vector.py) (definition) (16); Vector algebra evaluated in Python (tools/vectors/gen_vector3d.py) (2026) (6) |
| Vector components and direction (stable) | 25 | 6.1e-16 (y) | ±1e-12 | 0% | Exact trigonometry and vector algebra from the definitions (tools/vectors/gen_nav_vector.py) (definition) (16); Vector algebra evaluated in Python (tools/vectors/gen_vector3d.py) (2026) (8); add-navigation-and-geometry scenarios (2026) (1) |
| Band math | 12 | 0 (value) | ±1e-12 | 0% | Index formulas transcribed from their papers in Python (tools/vectors/gen_raster.py) (2026-09-22) (12) |
| dNBR (burn severity) | 10 | 0 (dnbr) | ±1e-12 | 0% | Index formulas transcribed from their papers in Python (tools/vectors/gen_raster.py) (2026-09-22) (10) |
| EVI | 10 | 0 (evi) | ±1e-12 | 0% | Index formulas transcribed from their papers in Python (tools/vectors/gen_raster.py) (2026-09-22) (10) |
| EVI2 | 10 | 0 (evi2) | ±1e-12 | 0% | Index formulas transcribed from their papers in Python (tools/vectors/gen_raster.py) (2026-09-22) (10) |
| MNDWI | 10 | 0 (mndwi) | ±1e-12 | 0% | Index formulas transcribed from their papers in Python (tools/vectors/gen_raster.py) (2026-09-22) (10) |
| NBR | 10 | 0 (nbr) | ±1e-12 | 0% | Index formulas transcribed from their papers in Python (tools/vectors/gen_raster.py) (2026-09-22) (10) |
| NDBI | 10 | 0 (ndbi) | ±1e-12 | 0% | Index formulas transcribed from their papers in Python (tools/vectors/gen_raster.py) (2026-09-22) (10) |
| NDVI | 10 | 0 (ndvi) | ±1e-12 | 0% | Index formulas transcribed from their papers in Python (tools/vectors/gen_raster.py) (2026-09-22) (10) |
| NDWI (Gao, vegetation water) | 10 | 0 (ndwi) | ±1e-12 | 0% | Index formulas transcribed from their papers in Python (tools/vectors/gen_raster.py) (2026-09-22) (10) |
| NDWI (McFeeters, open water) | 10 | 0 (ndwi) | ±1e-12 | 0% | Index formulas transcribed from their papers in Python (tools/vectors/gen_raster.py) (2026-09-22) (10) |
| SAVI | 30 | 0 (savi) | ±1e-12 | 0% | Index formulas transcribed from their papers in Python (tools/vectors/gen_raster.py) (2026-09-22) (30) |
| Digital number to reflectance | 17 | 0 (reflectance) | ±1e-12 | 0% | Index formulas transcribed from their papers in Python (tools/vectors/gen_raster.py) (2026-09-22) (17) |
| Terrain ruggedness and position | 7 | 0 (tri) | ±1e-9 | 0% | Index formulas transcribed from their papers in Python (tools/vectors/gen_raster.py) (2026-09-22) (7) |
| Slope, aspect, and hillshade | 7 | 0 (slope) | ±1e-9 | 0% | Index formulas transcribed from their papers in Python (tools/vectors/gen_raster.py) (2026-09-22) (7) |
| Angular closure of a loop traverse | 6 | 7.3e-11 (misclosure) | ±1e-9 + ±1e-12 relative | 7% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (5); add-survey-suite scenarios (2026) (1) |
| Area by coordinates (acreage) (stable) | 20 | 3.6e-12 (perimeter) | ±1e-9 + ±1e-11 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (17); add-survey-suite scenarios (2026) (2); Wikipedia, Shoelace formula (worked example) (retrieved 2026-09-19) (1) |
| Coordinates from a bearing and distance | 5 | 0 (northing) | ±1e-9 + ±1e-11 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (5) |
| Intersection (bearings and distances) | 6 | 1.4e-14 (solutions.0.easting) | ±1e-9 + ±1e-12 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (5); add-survey-suite scenarios (2026) (1) |
| Inverse between two coordinates | 6 | 5.7e-14 (distance) | ±1e-9 + ±1e-12 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (4); add-survey-suite scenarios (2026) (2) |
| Least-squares network adjustment (2D) | 6 | 1.3e-11 (adjusted.1.semi_major) | ±0.000001 + ±0.00001 relative | 0% | Weighted least squares with numerical Jacobians, NumPy and SciPy (tools/vectors/gen_lsq.py) (NumPy 2.x, SciPy 1.x) (5); add-survey-suite least-squares scenarios (chi-square failure) (NumPy 2.x, SciPy 1.x) (1) |
| Total-station offset shot | 6 | 2.3e-13 (distance) | ±1e-9 + ±1e-12 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (5); add-survey-suite scenarios (2026) (1) |
| Three-point resection | 5 | 7.8e-12 (northing) | ±1e-9 + ±1e-8 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (4); add-survey-suite scenarios (2026) (1) |
| Station and offset from a line | 6 | 0 (offset) | ±1e-9 + ±1e-11 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (6) |
| Traverse closure and adjustment (stable) | 26 | 0.00048 (misclosure) | ±0.0005 | 97% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (22); add-survey-suite scenarios (2026) (2); University of Memphis CIVL 1112, Surveying - Traverse Calculations (latitudes and departures example, group example 1) (course notes, retrieved 2026-09-19) (2) |
| Horizontal circular curve (stable) | 20 | 0.0045 (length) | ±0.005 | 90% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (12); Headquarters, Department of the Army, FM 5-233 Construction Surveying, chapter 3 (simple curves) (FM 5-233 (1985)) (4); add-survey-suite scenarios (2026) (3); Arc definition D = 18000/(πR) with stationing (15th edition (2018)) (1) |
| Circular curve layout table | 6 | 1.4e-14 (tangent) | ±1e-9 + ±1e-12 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (5); add-survey-suite scenarios (2026) (1) |
| Vertical curve length for sight distance | 7 | 0 (min_length) | ±1e-9 + ±1e-12 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (6); add-survey-suite scenarios (2026) (1) |
| Spiral-curve-spiral transition | 6 | 4.3e-12 (total_tangent) | ±0.000001 | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (5); add-survey-suite scenarios (2026) (1) |
| Unequal-tangent vertical curve | 7 | 1.4e-14 (turning_elevation) | ±1e-9 + ±1e-12 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (5); add-survey-suite scenarios (2026) (1); Worked by hand: curve elevation at the PVI station = 100 + 300 x 300 x (-0.03 - 0.02) / (2 x 600) = 96.25 ft, 3.75 ft below the PVI (Ghilani and Wolf 2021, ch. 25) (Elementary Surveying, 16th edition (2021)) (1) |
| Vertical curve (stable) | 21 | 0 (pvc_elevation) | ±1e-9 + ±1e-11 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (19); add-survey-suite scenarios (2026) (1); Indiana Department of Transportation, Indiana Design Manual chapter 44, example 44-3.1 (figure 44-3G) (Chapter 44 (current), retrieved 2026-09-19) (1) |
| Average end area volume | 5 | 3.6e-12 (volume_ft3) | ±1e-9 + ±1e-11 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (4); add-survey-suite scenarios (2026) (1) |
| Grid (borrow-pit) volume | 6 | 3.4e-13 (cut_volume) | ±1e-9 + ±1e-11 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (5); add-survey-suite scenarios (2026) (1) |
| Side slope and grade (H:V) | 10 | 2.8e-14 (slope_length) | ±1e-9 + ±1e-12 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (8); add-survey-suite scenarios (2026) (2) |
| Prismoidal volume | 6 | 8.0e-13 (difference) | ±1e-9 + ±1e-11 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (4); add-survey-suite scenarios (2026) (2) |
| Profile grade analysis | 6 | 0 (segments.1.grade) | ±1e-9 + ±1e-12 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (5); add-survey-suite scenarios (2026) (1) |
| Cross-section cut and fill areas | 6 | 2.9e-9 (cut_area) | ±0.000001 + ±0.000001 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (5); add-survey-suite scenarios (2026) (1) |
| Swell, shrink, and truck loads | 5 | 4.5e-13 (loose_volume) | ±1e-9 + ±1e-11 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (4); add-survey-suite scenarios (2026) (1) |
| Slope stake (catch point) | 6 | 1.8e-14 (catch_offset) | ±1e-9 + ±0.000001 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (5); add-survey-suite scenarios (2026) (1) |
| Cone, frustum, and prism volumes | 6 | 9.1e-13 (volume) | ±1e-9 + ±1e-12 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (6) |
| Stockpile volume (TIN) | 6 | 9.1e-13 (volume) | ±1e-9 + ±1e-10 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (6) |
| Antenna height from a slant measurement | 5 | 0 (vertical) | ±1e-9 | 0% | Worked by hand in Python (tools/vectors/gen_gnss.py) (2026) (4); add-practitioner-essentials GNSS scenarios (1.800 m slant, 0.100 m radius: about 1.7972 m) (2026) (1) |
| Site localization (calibration) | 7 | 5.8e-11 (rms) | ±0.000001 | 0% | Least squares by NumPy lstsq (tools/vectors/gen_localize.py) (NumPy 2.x) (4); add-practitioner-essentials localization scenarios (feet entered as meters) (NumPy 2.x) (1); add-practitioner-essentials localization scenarios (two points: no redundancy) (NumPy 2.x) (1); Least squares by NumPy lstsq (tools/vectors/gen_localize.py) (three points: no redundancy) (NumPy 2.x) (1) |
| OPUS session planning | 6 | 0 (day_of_year) | ±1e-9 | 0% | Worked by hand in Python (tools/vectors/gen_gnss.py) (2026) (5); add-practitioner-essentials GNSS scenarios (a one-hour session gets rapid-static processing) (2026) (1) |
| RTK and PPK precision budget | 5 | 7.1e-15 (horizontal) | ±1e-9 | 0% | Worked by hand in Python (tools/vectors/gen_gnss.py) (2026) (4); add-practitioner-essentials GNSS scenarios (8 mm + 1 ppm at 15 km: 23 mm) (2026) (1) |
| ALTA/NSPS relative positional precision | 5 | 2.8e-17 (allowable) | ±1e-12 | 0% | Worked by hand in Python (tools/vectors/gen_gnss.py) (2026) (3); add-practitioner-essentials GNSS scenarios (0.12 ft allowable at 1,000 ft) (2026) (1); add-practitioner-essentials GNSS scenarios (a misclosure is refused: RPP comes from the error ellipse) (2026) (1) |
| Basis-of-bearing rotation | 5 | 7.6e-15 (rotation) | ±1e-9 + ±1e-12 relative | 0% | Independent Python arithmetic on the BLM Manual unit definitions and latitudes and departures (tools/vectors/gen_survey.py) (BLM Manual of Surveying Instructions (2009)) (5) |
| Deed parser (metes and bounds) | 5 | 0 (count) | ±1e-9 + ±1e-12 relative | 0% | Hand-parsed call forms (Brown's Boundary Control, ch. 5) (7th edition (2014)) (5) |
| Deed plot, closure, and area (stable) | 20 | 0.00047 (misclosure) | ±0.0005 | 93% | Independent Python arithmetic on the BLM Manual unit definitions and latitudes and departures (tools/vectors/gen_survey.py) (Ghilani and Wolf, 15th ed. (2018)) (17); Independent Python arithmetic on the BLM Manual unit definitions and latitudes and departures (tools/vectors/gen_survey.py) (BLM Manual of Surveying Instructions (2009)) (2); University of Memphis CIVL 1112, Surveying - Traverse Calculations (latitudes and departures example, group example 1) (course notes, retrieved 2026-09-19) (1) |
| Legacy land units | 7 | 3.6e-15 (us_survey_feet) | ±1e-9 + ±1e-12 relative | 0% | Independent Python arithmetic on the BLM Manual unit definitions and latitudes and departures (tools/vectors/gen_survey.py) (BLM Manual of Surveying Instructions (2009)) (7) |
| PLSS legal description reader | 5 | 0 (nominal_area) | ±1e-9 + ±1e-12 relative | 0% | Independent Python arithmetic on the BLM Manual unit definitions and latitudes and departures (tools/vectors/gen_survey.py) (BLM Manual of Surveying Instructions (2009)) (5) |
| Combined scale factor (grid and ground) (stable) | 22 | 0.00045 (grid_distance) | ±0.0005 | 89% | NOAA Manual NOS NGS 5 (Stem 1990), section 4, evaluated in Python (1990) (16); NOAA Manual NOS NGS 5, State Plane Coordinate System of 1983 (Stem), section 4.4 example, steps 4 and 5 (1990) (5); add-survey-suite scenarios (2026) (1) |
| Curvature and refraction correction | 6 | 2.2e-19 (correction) | ±1e-9 + ±1e-12 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (4); add-survey-suite scenarios (2026) (2) |
| EDM atmospheric and prism corrections | 9 | 0 (corrected) | ±1e-9 | 0% | IAG 1999 closed formula worked in Python (tools/vectors/gen_edm.py) (2026) (8); add-survey-suite ppm scenario (1,000.000 + 0.012 - 0.030 = 999.982 m) (2026) (1) |
| Height of an inaccessible object | 6 | 1.4e-13 (distance_used) | ±1e-9 + ±1e-10 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (5); add-survey-suite scenarios (2026) (1) |
| Level run reduction and closure | 6 | 0 (sum_backsights) | ±1e-9 + ±1e-12 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (6) |
| Slope distance to horizontal and vertical | 10 | 0 (horizontal_distance) | ±1e-9 + ±1e-12 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (7); add-survey-suite scenarios (2026) (3) |
| Stadia reduction | 6 | 2.8e-14 (horizontal_distance) | ±1e-9 + ±1e-12 relative | 0% | Surveying formulas (Ghilani & Wolf 2018) evaluated in Python (tools/vectors/gen_survey.py) (15th edition (2018)) (6) |
| Block time (out to in) (stable) | 24 | 0 (minutes) | ±0.000001 + ±1e-15 relative | 0% | Exact integer arithmetic on minutes, adding 24 h when a clock-only in time precedes out (definition) (18); Clock arithmetic with Python datetime (tools/vectors/gen_time.py) (2026) (5); add-practitioner-essentials scenarios (2026) (1) |
| Decimal hours to hours and minutes (stable) | 25 | 0 (minutes) | ±0.000001 + ±1e-15 relative | 0% | Exact integer arithmetic on minutes: minutes = round(hours x 60); hours = h + mm/60 (definition) (20); Hours-to-minutes arithmetic (tools/vectors/gen_time.py) (2026) (4); add-practitioner-essentials scenarios (2026) (1) |
| GPS week and seconds to UTC (stable) | 22 | 0 (gps_week) | ±0.000001 + ±1e-15 relative | 0% | TAI - UTC accumulated from the IANA tzdb leapseconds file (10 s at 1972-01-01); GPS - UTC = TAI - UTC - 19 s; week and seconds of week from the GPS epoch 1980-01-06 (IANA tzdb 2026c) (16); add-practitioner-essentials scenarios (2026) (3); Python datetime and the IERS Bulletin C 72 leap-second table (tools/vectors/gen_time.py) (Bulletin C 72 (2026-07-06)) (3) |
| UTC to GPS week and seconds (stable) | 24 | 0 (gps_week) | ±0.000001 + ±1e-15 relative | 0% | TAI - UTC accumulated from the IANA tzdb leapseconds file (10 s at 1972-01-01); GPS - UTC = TAI - UTC - 19 s; week and seconds of week from the GPS epoch 1980-01-06 (IANA tzdb 2026c) (16); add-practitioner-essentials scenarios (2026) (4); Python datetime and the IERS Bulletin C 72 leap-second table (tools/vectors/gen_time.py) (Bulletin C 72 (2026-07-06)) (4) |
| Julian date, MJD, and day of year (stable) | 24 | 0 (jd) | ±0.000001 + ±1e-15 relative | 0% | JD = 2440587.5 + (POSIX seconds)/86400, with the calendar and day of year from Python's datetime (proleptic Gregorian); MJD = JD - 2400000.5 (CPython 3.13 datetime) (17); USNO Julian date definition evaluated with Python datetime (tools/vectors/gen_time.py) (2024) (4); add-practitioner-essentials scenarios (2026) (2); USNO Julian date definition (2024) (1) |
| Local time to UTC (Zulu) (stable) | 24 | 0 (day_shift) | ±0.000001 + ±1e-15 relative | 0% | Python zoneinfo on tzdata 2026d (core/crates/gp-time/tests/data/tz_diff.csv) (2026d) (7); Python zoneinfo documentation, America/Los_Angeles examples (docs.python.org/3/library/zoneinfo.html) (retrieved 2026-09-19) (5); Python datetime with fixed offsets (tools/vectors/gen_time.py) (2026) (4); add-practitioner-essentials scenarios (2026) (3); IANA tzdb 2026d (US DST: second Sunday in March to first Sunday in November, 2:00 local) (2026d) (3); IANA tzdb 2026d America/Anchorage: AKDT is UTC−8 in July, so 0300Z on July 2 is 19:00 on July 1 local (2026d) (1); IANA tzdb 2026d America/Anchorage: AKDT is UTC−8 in July, so 2300Z is 15:00 local (2026d) (1) |
| Time zone rules at a date (stable) | 26 | no numeric checks | Python zoneinfo on the system IANA release: offset, abbreviation, DST state, and the next transition by bisection (IANA tzdb 2026c) (20); IANA tzdb 2026d (checked with Python zoneinfo on tzdata 2026d) (2026d) (5); add-practitioner-essentials scenarios (2026) (1) | ||
| The four aviation nights (stable) | 22 | no numeric checks | USNO sunset and civil twilight (retrieved 2026-09-19, tools/vectors/gen_usno_sun.py --nights) with 14 CFR 61.57(b) and 1.1 (API 4.0.1) (16); USNO sunset and civil twilight (retrieved 2026-09-18) with the 14 CFR 61.57(b) and 1.1 definitions (API 4.0.1) (4); add-practitioner-essentials scenarios (2026) (2) | ||
| Sunrise, sunset, and twilight (stable) | 23 | 1.0 (day_minutes) | ±2 | 50% | USNO Astronomical Applications API rstt/oneday, retrieved 2026-09-19 (tools/vectors/gen_usno_sun.py) (API 4.0.1) (13); USNO Astronomical Applications API rstt/oneday, retrieved 2026-09-18 (API 4.0.1) (7); add-practitioner-essentials scenarios (2026) (1); Hand computation of the sun's lowest altitude, latitude + declination − 90°: at Anchorage (61.22° N) on the June solstice (declination 23.44°) it is −5.34°, above the −6° civil twilight limit, so civil twilight neither begins nor ends (Meeus, Astronomical Algorithms, 2nd edition) (1); Hand computation of the sun's lowest altitude, latitude + declination − 90°: at Utqiagvik (71.29° N) on the June solstice (declination 23.44°) it is +4.73°, above the −0.833° sunrise altitude, so the sun does not set (Meeus, Astronomical Algorithms, 2nd edition) (1) |
| Sun hotspot in a camera frame (stable) | 23 | 0.0082 (sun_azimuth) | ±0.02 | 41% | Sun position from pvlib's NREL SPA (sea level, 101325 Pa, 12 C); antisolar point and hotspot angle by vector geometry (tools/vectors/gen_sun_pvlib.py) (pvlib 0.13.0) (17); NOAA solar equations (tools/vectors/gen_sun.py) and vector geometry (tools/vectors/gen_hotspot.py) (NOAA GML 2023) (6) |
| Mapping light window (stable) | 21 | 0.0025 (max_elevation) | ±0.01 | 25% | Sun position from pvlib's NREL SPA (sea level, 101325 Pa, 12 C); threshold crossings by bisection (tools/vectors/gen_sun_pvlib.py) (pvlib 0.13.0) (16); NOAA solar calculator equations transcribed in Python (tools/vectors/gen_sun.py) (NOAA GML 2023) (5) |
| Night passenger currency (stable) | 22 | 0 (aircraft.0.takeoffs) | exact | 0% | Sun position from pvlib's NREL SPA (sea level, 101325 Pa, 12 C); 14 CFR 61.57(b) applied by hand (tools/vectors/gen_sun_pvlib.py) (pvlib 0.13.0) (16); Counting worked by hand (tools/vectors/gen_currency.py) (2026) (5); add-practitioner-essentials currency scenario (May 1, May 10, and June 2 give currency through July 30, 2026) (2026) (1) |
| Sun position (azimuth and elevation) (stable) | 28 | 0.0000078 (equation_of_time) | ±0.00001 | 78% | pvlib.solarposition.spa_python (NREL SPA port) (pvlib 0.13.0) (25); add-practitioner-essentials scenarios (2026) (2); NREL/TP-560-34302 Table A5.1 (published to 1e-5) (2008) (1) |
| Acceleration converter (stable) | 22 | 5.6e-17 (converted) | ±5e-16 relative | 36% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (22) |
| Angle converter (stable) | 110 | 3.4e-21 (converted) | ±5e-16 relative | 41% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (110) |
| Degrees to radians (stable) | 3 | 0 (converted) | ±2e-15 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Radians to degrees (stable) | 3 | 0 (converted) | ±2e-15 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Angular rate converter (stable) | 40 | 3.2e-27 (converted) | ±5e-16 relative | 29% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (40) |
| Acres to hectares (stable) | 3 | 5.7e-14 (converted) | ±5e-16 relative | 44% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Area converter (stable) | 75 | 3.6e-15 (converted) | ±5e-16 relative | 44% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (75) |
| Square feet to acres (stable) | 3 | 0 (converted) | ±5e-16 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Hectares to acres (stable) | 3 | 3.6e-15 (converted) | ±5e-16 relative | 29% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Battery charge converter (stable) | 22 | 0 (converted) | ±5e-16 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (22) |
| Data rate converter (stable) | 22 | 1.3e-23 (converted) | ±5e-16 relative | 44% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (22) |
| Density converter (stable) | 22 | 2.3e-13 (converted) | ±5e-16 relative | 45% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (22) |
| Energy converter (stable) | 34 | 5.7e-14 (converted) | ±5e-16 relative | 32% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (34) |
| Frequency converter (stable) | 40 | 4.2e-22 (converted) | ±5e-16 relative | 34% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (40) |
| Fuel volume and weight (stable) | 20 | 7.1e-15 (volume) | ±5e-16 relative | 36% | FAA-H-8083-25C Chapter 10 nominal fuel weights (avgas 6 lb/gal, jet fuel 6.7 lb/gal); mass = volume x density in SI from the exact gallon, litre and pound, by rational arithmetic (FAA-H-8083-25C (2023)) (14); FAA-H-8083-25C Chapter 10 nominal fuel weights (avgas 6 lb/gal, jet fuel 6.7 lb/gal); mass = volume x density by exact rational arithmetic (FAA-H-8083-25C (2023)) (6) |
| Length converter (stable) | 135 | 1.8e-12 (converted) | ±5e-16 relative | 44% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (135) |
| Feet to meters (stable) | 3 | 0 (converted) | ±5e-16 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| US survey feet to international feet (stable) | 3 | 2.3e-10 (converted) | ±5e-16 relative | 23% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| US survey feet to meters (stable) | 3 | 0 (converted) | ±5e-16 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Inches to millimeters (stable) | 3 | 0 (converted) | ±5e-16 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Kilometers to miles (stable) | 3 | 0 (converted) | ±5e-16 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Kilometers to nautical miles (stable) | 3 | 0 (converted) | ±5e-16 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Meters to feet (stable) | 3 | 0 (converted) | ±5e-16 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Meters to US survey feet (stable) | 3 | 1.2e-10 (converted) | ±5e-16 relative | 23% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Miles to kilometers (stable) | 3 | 0 (converted) | ±5e-16 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Statute miles to nautical miles (stable) | 3 | 0 (converted) | ±5e-16 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Millimeters to inches (stable) | 3 | 1.1e-16 (converted) | ±5e-16 relative | 22% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Nautical miles to kilometers (stable) | 3 | 2.8e-14 (converted) | ±5e-16 relative | 31% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Nautical miles to statute miles (stable) | 3 | 0 (converted) | ±5e-16 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Mass converter (stable) | 24 | 4.5e-13 (converted) | ±5e-16 relative | 43% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (24) |
| Kilograms to pounds (stable) | 3 | 0 (converted) | ±5e-16 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Pounds to kilograms (stable) | 3 | 2.3e-13 (converted) | ±5e-16 relative | 39% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Power converter (stable) | 22 | 2.2e-16 (converted) | ±5e-16 relative | 33% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (22) |
| Pressure converter (stable) | 73 | 8.9e-16 (converted) | ±5e-16 relative | 43% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (73) |
| HPa to inHg (stable) | 3 | 0 (converted) | ±5e-16 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| InHg to hPa (stable) | 3 | 1.1e-13 (converted) | ±5e-16 relative | 22% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| KPa to psi (stable) | 3 | 3.6e-15 (converted) | ±5e-16 relative | 24% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Psi to kPa (stable) | 3 | 2.8e-14 (converted) | ±5e-16 relative | 27% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Normalize a unit-tagged value (stable) | 24 | 2.3e-13 (normalized) | ±5e-16 relative | 39% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (24) |
| Slope and grade converter (stable) | 25 | 1.4e-14 (percent) | ±1e-15 + ±2e-15 relative | 12% | Definition of grade: ratio = rise/run = tan(angle); angles from Python math.tan and math.atan (definition) (19); Definition of grade: ratio = rise/run = tan(angle); angles from Python math.atan (definition) (6) |
| Speed converter (stable) | 47 | 4.5e-13 (converted) | ±5e-16 relative | 41% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (47) |
| Km/h to knots (stable) | 3 | 0 (converted) | ±5e-16 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Knots to km/h (stable) | 3 | 1.4e-14 (converted) | ±5e-16 relative | 44% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Knots to mph (stable) | 3 | 0 (converted) | ±5e-16 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Knots to m/s (stable) | 3 | 0 (converted) | ±5e-16 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Mph to knots (stable) | 3 | 0 (converted) | ±5e-16 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| M/s to knots (stable) | 3 | 3.6e-15 (converted) | ±5e-16 relative | 37% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Temperature difference converter (stable) | 22 | 0 (converted) | ±5e-16 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (22) |
| Celsius to Fahrenheit (stable) | 3 | 0 (converted) | ±5e-16 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Temperature converter (stable) | 22 | 0 (converted) | ±5e-16 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (22) |
| Fahrenheit to Celsius (stable) | 3 | 0 (converted) | ±5e-16 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Time converter (stable) | 25 | 0 (converted) | ±5e-16 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (25) |
| Vertical speed converter (stable) | 22 | 1.1e-16 (converted) | ±5e-16 relative | 24% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (22) |
| Ft/min to m/s (stable) | 3 | 0 (converted) | ±5e-16 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Volume converter (stable) | 45 | 8.7e-19 (converted) | ±5e-16 relative | 44% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (45) |
| US gallons to liters (stable) | 3 | 0 (converted) | ±5e-16 relative | 0% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |
| Liters to US gallons (stable) | 3 | 1.1e-16 (converted) | ±5e-16 relative | 22% | NIST SP 811 (2008) Appendix B.8 and NIST Handbook 44 Appendix C exact definitions; expected value by exact rational arithmetic (tools/vectors/gen_units.py) (SP 811 2008; HB44 2026) (3) |