fix(webpub): the Distance column was empty for every QSO logged here

Nothing computes a distance when a QSO is logged. The DISTANCE field is only
ever filled by an ADIF import that carried one, so publishing it straight gave
an empty column to anyone whose log was made in OpsLog — which is everyone who
reported it.

It falls back to the two locators, which are on the QSO already. A stored
distance still wins: it came from the log that recorded the contact, which knew
more than two four-character squares do. No grids means an empty cell, not a
zero — an empty cell is honest, a zero is a claim.

Rounded to whole kilometres. The squares are tens of kilometres across and a
decimal would assert an accuracy nobody has.

The geometry moved to internal/geo on the way. It lived in package main, which
internal packages cannot import, so the PSK Reporter watcher already had its
maths injected from main and this would have been a third copy. A bearing that
disagrees with itself between two panels is a fault nobody reports, because each
screen looks perfectly plausible on its own.
This commit is contained in:
2026-08-11 19:41:47 +02:00
parent 102097c5c4
commit f7b9bfd0bc
5 changed files with 143 additions and 43 deletions
+22 -1
View File
@@ -33,6 +33,7 @@ import (
"github.com/jlaffaye/ftp"
"hamlog/internal/geo"
"hamlog/internal/qso"
)
@@ -93,6 +94,26 @@ func flt(p *float64) string {
return strconv.FormatFloat(*p, 'f', -1, 64)
}
// distanceKm is the path length for the Distance column.
//
// The stored DISTANCE field is only ever filled by an ADIF import that carried
// one — OpsLog does not compute it when logging — so publishing it straight gave
// an empty column for every QSO made here, which is how this was reported.
//
// So it falls back to the two locators, which are on the QSO already. Rounded to
// whole kilometres: the grids are squares tens of kilometres across, and a
// decimal on a figure that imprecise claims an accuracy nobody has.
func distanceKm(q *qso.QSO) string {
if q.Distance != nil && *q.Distance > 0 {
return flt(q.Distance)
}
km, ok := geo.DistanceBetweenGrids(q.MyGrid, q.Grid)
if !ok || km <= 0 {
return ""
}
return strconv.FormatFloat(km, 'f', 0, 64)
}
func stamp(t time.Time) string {
if t.IsZero() {
return ""
@@ -218,7 +239,7 @@ var Columns = []Column{
{"my_sig_info", "My sig info", "My station", func(q *qso.QSO) string { return q.MySIGInfo }},
{"wwff_ref", "WWFF", "Awards", func(q *qso.QSO) string { return q.WWFFRef }},
{"my_wwff_ref", "My wwff ref", "My station", func(q *qso.QSO) string { return q.MyWWFFRef }},
{"distance", "Distance", "Location", func(q *qso.QSO) string { return flt(q.Distance) }},
{"distance", "Distance", "Location", distanceKm},
{"rx_pwr", "RX pwr", "QSO", func(q *qso.QSO) string { return flt(q.RXPower) }},
{"a_index", "A", "QSO", func(q *qso.QSO) string { return flt(q.AIndex) }},
{"k_index", "K", "QSO", func(q *qso.QSO) string { return flt(q.KIndex) }},