mirror of
https://github.com/searxng/searxng.git
synced 2025-08-02 18:12:21 +02:00
[mod] weather results: add types, i18n/l10n, symbols & unit conversions
The types necessary for weather information such as GeoLocation, DateTime, Temperature,Pressure, WindSpeed, RelativeHumidity, Compass (wind direction) and symbols for the weather have been implemented. There are unit conversions and translations for weather property labels. Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
This commit is contained in:
parent
a800dd0473
commit
ff206e9679
13 changed files with 980 additions and 181 deletions
|
@ -5,6 +5,7 @@ Coordinates`_
|
|||
.. _SPARQL/WIKIDATA Precision, Units and Coordinates:
|
||||
https://en.wikibooks.org/wiki/SPARQL/WIKIDATA_Precision,_Units_and_Coordinates#Quantities
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
__all__ = ["convert_from_si", "convert_to_si", "symbol_to_si"]
|
||||
|
||||
|
@ -13,6 +14,47 @@ import collections
|
|||
from searx import data
|
||||
from searx.engines import wikidata
|
||||
|
||||
|
||||
class Beaufort:
|
||||
"""The mapping of the Beaufort_ contains values from 0 to 16 (55.6 m/s),
|
||||
wind speeds greater than 200km/h (55.6 m/s) are given as 17 Bft. Thats why
|
||||
a value of 17 Bft cannot be converted to SI.
|
||||
|
||||
.. hint::
|
||||
|
||||
Negative values or values greater 16 Bft (55.6 m/s) will throw a
|
||||
:py:obj:`ValueError`.
|
||||
|
||||
_Beaufort: https://en.wikipedia.org/wiki/Beaufort_scale
|
||||
"""
|
||||
|
||||
# fmt: off
|
||||
scale: list[float] = [
|
||||
0.2, 1.5, 3.3, 5.4, 7.9,
|
||||
10.7, 13.8, 17.1, 20.7, 24.4,
|
||||
28.4, 32.6, 32.7, 41.1, 45.8,
|
||||
50.8, 55.6
|
||||
]
|
||||
# fmt: on
|
||||
|
||||
@classmethod
|
||||
def from_si(cls, value) -> float:
|
||||
if value < 0 or value > 55.6:
|
||||
raise ValueError(f"invalid value {value} / the Beaufort scales from 0 to 16 (55.6 m/s)")
|
||||
bft = 0
|
||||
for bft, mps in enumerate(cls.scale):
|
||||
if mps >= value:
|
||||
break
|
||||
return bft
|
||||
|
||||
@classmethod
|
||||
def to_si(cls, value) -> float:
|
||||
idx = round(value)
|
||||
if idx < 0 or idx > 16:
|
||||
raise ValueError(f"invalid value {value} / the Beaufort scales from 0 to 16 (55.6 m/s)")
|
||||
return cls.scale[idx]
|
||||
|
||||
|
||||
ADDITIONAL_UNITS = [
|
||||
{
|
||||
"si_name": "Q11579",
|
||||
|
@ -26,6 +68,12 @@ ADDITIONAL_UNITS = [
|
|||
"to_si": lambda val: (val + 459.67) * 5 / 9,
|
||||
"from_si": lambda val: (val * 9 / 5) - 459.67,
|
||||
},
|
||||
{
|
||||
"si_name": "Q182429",
|
||||
"symbol": "Bft",
|
||||
"to_si": Beaufort.to_si,
|
||||
"from_si": Beaufort.from_si,
|
||||
},
|
||||
]
|
||||
"""Additional items to convert from a measure unit to a SI unit (vice versa).
|
||||
|
||||
|
@ -55,6 +103,7 @@ ALIAS_SYMBOLS = {
|
|||
'°C': ('C',),
|
||||
'°F': ('F',),
|
||||
'mi': ('L',),
|
||||
'Bft': ('bft',),
|
||||
}
|
||||
"""Alias symbols for known unit of measure symbols / by example::
|
||||
|
||||
|
@ -65,11 +114,11 @@ ALIAS_SYMBOLS = {
|
|||
|
||||
|
||||
SYMBOL_TO_SI = []
|
||||
UNITS_BY_SI_NAME: dict | None = None
|
||||
UNITS_BY_SI_NAME: dict = {}
|
||||
|
||||
|
||||
def convert_from_si(si_name: str, symbol: str, value: float | int) -> float:
|
||||
from_si = units_by_si_name(si_name)[symbol][symbol]["from_si"]
|
||||
from_si = units_by_si_name(si_name)[symbol][pos_from_si]
|
||||
if isinstance(from_si, (float, int)):
|
||||
value = float(value) * from_si
|
||||
else:
|
||||
|
@ -78,7 +127,7 @@ def convert_from_si(si_name: str, symbol: str, value: float | int) -> float:
|
|||
|
||||
|
||||
def convert_to_si(si_name: str, symbol: str, value: float | int) -> float:
|
||||
to_si = units_by_si_name(si_name)[symbol][symbol]["to_si"]
|
||||
to_si = units_by_si_name(si_name)[symbol][pos_to_si]
|
||||
if isinstance(to_si, (float, int)):
|
||||
value = float(value) * to_si
|
||||
else:
|
||||
|
@ -88,20 +137,32 @@ def convert_to_si(si_name: str, symbol: str, value: float | int) -> float:
|
|||
|
||||
def units_by_si_name(si_name):
|
||||
|
||||
global UNITS_BY_SI_NAME
|
||||
if UNITS_BY_SI_NAME is not None:
|
||||
global UNITS_BY_SI_NAME # pylint: disable=global-statement,global-variable-not-assigned
|
||||
if UNITS_BY_SI_NAME:
|
||||
return UNITS_BY_SI_NAME[si_name]
|
||||
|
||||
UNITS_BY_SI_NAME = {}
|
||||
# build the catalog ..
|
||||
for item in symbol_to_si():
|
||||
by_symbol = UNITS_BY_SI_NAME.get(si_name)
|
||||
|
||||
item_si_name = item[pos_si_name]
|
||||
item_symbol = item[pos_symbol]
|
||||
|
||||
by_symbol = UNITS_BY_SI_NAME.get(item_si_name)
|
||||
if by_symbol is None:
|
||||
by_symbol = {}
|
||||
UNITS_BY_SI_NAME[si_name] = by_symbol
|
||||
by_symbol[item["symbol"]] = item
|
||||
UNITS_BY_SI_NAME[item_si_name] = by_symbol
|
||||
by_symbol[item_symbol] = item
|
||||
|
||||
return UNITS_BY_SI_NAME[si_name]
|
||||
|
||||
|
||||
pos_symbol = 0 # (alias) symbol
|
||||
pos_si_name = 1 # si_name
|
||||
pos_from_si = 2 # from_si
|
||||
pos_to_si = 3 # to_si
|
||||
pos_symbol = 4 # standardized symbol
|
||||
|
||||
|
||||
def symbol_to_si():
|
||||
"""Generates a list of tuples, each tuple is a measure unit and the fields
|
||||
in the tuple are:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue