- consolidate Haversine: CoordinateUtils delegates to GeoUtils;
InfoLive.haversine/4 reuses it (m -> km)
- AprsSymbol: collapse 3 sprite-info builders onto build_sprite_info/2
and add a sprite_info @type
- DataBuilder: 3 weather unit converters share convert_unit/4 with
explicit clauses for "N/A", numeric, and binary inputs
- mobile_channel: do_callsign_match/2 uses pattern-match clauses for
wildcard handling instead of nested if
- info_live: replace nested case in position_changed? with multi-clause
coords_changed?/1; format_timestamp_for_display pipelines into a
guarded build_timestamp_display/1
- api_docs_live: collapse chained single-key assigns into keyword-list
assign/2 calls
- add strict @spec coverage on all touched helpers; tighten new specs to
match dialyzer success typing (no contract_supertype warnings)
Fixed issue where stationary stations like K5SGD-D were showing multiple
positions due to minor GPS accuracy variations. The previous 15-meter
threshold was too strict for typical GPS drift which can vary 5-30 meters.
- Increased default threshold in GeoUtils from 10m to 50m
- Updated packet processor to use 50m threshold for movement detection
- Verified with K5SGD-D showing ~24m variations that are now ignored
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>