130 lines
2.6 KiB
Go
130 lines
2.6 KiB
Go
// FILE: ./internal/normalizers/common/wmo_text.go
|
|
package common
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"gitea.maximumdirect.net/ejr/weatherfeeder/internal/model"
|
|
)
|
|
|
|
// WMOFromTextDescription is a cross-provider fallback that tries to infer a WMO code
|
|
// from a human-readable condition string.
|
|
//
|
|
// This is intentionally “coarse” and conservative. It is useful when a provider:
|
|
//
|
|
// - does not provide a condition code, or
|
|
// - provides it inconsistently / null, or
|
|
// - provides only textual conditions for some endpoints.
|
|
//
|
|
// Providers may still choose to override this with richer signals
|
|
// (METAR phenomena, explicit numeric codes, etc.).
|
|
func WMOFromTextDescription(desc string) model.WMOCode {
|
|
s := strings.ToLower(strings.TrimSpace(desc))
|
|
if s == "" {
|
|
return model.WMOUnknown
|
|
}
|
|
|
|
// Thunder / hail
|
|
if strings.Contains(s, "thunder") {
|
|
if strings.Contains(s, "hail") {
|
|
return 99
|
|
}
|
|
return 95
|
|
}
|
|
|
|
// Freezing hazards
|
|
if strings.Contains(s, "freezing rain") {
|
|
if strings.Contains(s, "light") {
|
|
return 66
|
|
}
|
|
return 67
|
|
}
|
|
if strings.Contains(s, "freezing drizzle") {
|
|
if strings.Contains(s, "light") {
|
|
return 56
|
|
}
|
|
return 57
|
|
}
|
|
|
|
// Drizzle
|
|
if strings.Contains(s, "drizzle") {
|
|
if strings.Contains(s, "heavy") || strings.Contains(s, "dense") {
|
|
return 55
|
|
}
|
|
if strings.Contains(s, "light") {
|
|
return 51
|
|
}
|
|
return 53
|
|
}
|
|
|
|
// Showers
|
|
if strings.Contains(s, "showers") {
|
|
if strings.Contains(s, "heavy") {
|
|
return 82
|
|
}
|
|
if strings.Contains(s, "light") {
|
|
return 80
|
|
}
|
|
return 81
|
|
}
|
|
|
|
// Rain
|
|
if strings.Contains(s, "rain") {
|
|
if strings.Contains(s, "heavy") {
|
|
return 65
|
|
}
|
|
if strings.Contains(s, "light") {
|
|
return 61
|
|
}
|
|
return 63
|
|
}
|
|
|
|
// Snow (check snow showers first)
|
|
if strings.Contains(s, "snow showers") {
|
|
if strings.Contains(s, "light") {
|
|
return 85
|
|
}
|
|
return 86
|
|
}
|
|
if strings.Contains(s, "snow grains") {
|
|
return 77
|
|
}
|
|
if strings.Contains(s, "snow") {
|
|
if strings.Contains(s, "heavy") {
|
|
return 75
|
|
}
|
|
if strings.Contains(s, "light") {
|
|
return 71
|
|
}
|
|
return 73
|
|
}
|
|
|
|
// Fog / mist
|
|
if strings.Contains(s, "rime fog") {
|
|
return 48
|
|
}
|
|
if strings.Contains(s, "fog") || strings.Contains(s, "mist") {
|
|
return 45
|
|
}
|
|
|
|
// Sky-only
|
|
if strings.Contains(s, "overcast") {
|
|
return 3
|
|
}
|
|
if strings.Contains(s, "cloudy") {
|
|
return 3
|
|
}
|
|
if strings.Contains(s, "partly cloudy") {
|
|
return 2
|
|
}
|
|
if strings.Contains(s, "mostly sunny") || strings.Contains(s, "mostly clear") ||
|
|
strings.Contains(s, "mainly sunny") || strings.Contains(s, "mainly clear") {
|
|
return 1
|
|
}
|
|
if strings.Contains(s, "clear") || strings.Contains(s, "sunny") {
|
|
return 0
|
|
}
|
|
|
|
return model.WMOUnknown
|
|
}
|