Open-Meteo 天气 API 使用 FlatBuffers 高效地编码 API 响应。各种编程语言的已编译架构文件可以在此存储库中找到。
FlatBuffers 的最大优势在于,大型浮点数组可以直接编码,而无需进行昂贵的 JSON ASCII 转换。特别是对于历史天气数据,处理速度明显更快。而且,即使在低功耗设备上显示常规天气预报,二进制数据编码也能节省能源。
FlatBuffers 架构定义可以在 ./flatbuffers 目录中找到。仅接受非破坏性更改。二进制兼容性得到保证。每个更改都将在遵循语义版本控制的新版本中宣布。
已编译的架构文件不包含任何执行 HTTP 调用的代码。它们旨在供开发人员构建客户端库使用。
有关如何使用已编译架构文件的更多信息,可以在每种编程语言的目录中找到
并非所有编程语言都已支持。验证所有语言是一个耗时的过程。请打开 issue 工单,询问是否支持其他语言和/或软件包分发系统。
Open-Meteo 提供各种 API。每个 API 端点都使用不同的 FlatBuffers 架构来编码其 API 响应。这实现了严格的类型化。例如,天气数据 API 提供不同的变量,而地理编码 API 返回不同的结构。默认情况下,Open-Meteo API 返回 JSON,但在 URL 中指定 &format=flatbuffers
将返回 FlatBuffers 编码的数据。
根据编程语言,您可以使用 HTTP 客户端获取所有数据,并根据每个 API 端点解码响应。以下 API 响应架构文件可用
每个响应包含一个位置和一个天气模型的数据。如果请求多个位置,则将返回多个 ApiResponses 作为使用 size-prefixed
编码(见下文)的数组。
主要的 WeatherApiResponse
结构包含
latitude
& longitude
float: 天气模型网格单元的坐标elevation
float: 请求坐标的地形海拔generation_time_milliseconds
floatlocation_id
int64: 位置标识符model
Model: 天气模型名称,作为枚举utc_offset_seconds
int32: 与 GMT 时间的时区偏移量,以秒为单位。例如 3600
timezone
string: 时区名称,例如 Europe/Berlin
timezone_abbreviation
string: 缩写,例如 CET
current
VariablesWithTime: 所有使用 ¤t=
请求的变量daily
VariablesWithTime: 所有使用 &daily=
请求的变量hourly
VariablesWithTime: 所有使用 &hourly=
请求的变量minutely_15
VariablesWithTime: 所有使用 &minutely_15=
请求的变量six_hourly
VariablesWithTime: 所有使用 &six_hourly=
请求的变量所有 hourly
或 daily
天气变量都分组到 VariablesWithTime
类中。它包含开始和结束时间以及间隔。
属性
start
int64: GMT 中第一个值的 Unix 时间戳end
int64: 不包含在时间间隔内的最后一个时间戳。因此,是最后一个包含的时间步之后的一步。interval
int32: 每个步长的秒数。对于每小时数据,这是 3600 秒
,对于每日数据,这是 86400 秒
。variables
[VariableWithValues]: 天气变量数组时间戳始终使用 Unix 时间(秒)。时间始终为 GMT!如果您想再次显示本地时间,可以使用响应结构中的属性 utc_offset_seconds
每个天气变量都附带元数据,例如天气变量的名称或单位。
属性
variable
Variable: 天气变量的枚举。例如 temperature
(温度)unit
Unit: 结果使用的单位。例如 celsius
(摄氏度)value
float: 对于 current
值,数据存储在此字段中values
[float]: 任何其他时间序列数据都作为浮点数组存储在此处values_int64
[int64]: 变量 sunrise
(日出) 和 sunset
(日落) 使用此字段将数据存储为 Unix 时间戳altitude
int16: 给定变量的高度。例如,2 米处温度为 2
,10 米处风速为 10
aggregation
Aggregation: 每日变量的聚合类型,例如 minimum
(最小值)、mean
(平均值) 或 maximum
(最大值)pressure_level
int16: 如果请求较高大气层中的天气变量,则此字段包含压力水平,单位为百帕斯卡。例如 850
表示 850 hPa。depth
int16: 对于土壤变量,这定义了上限。例如 soil_moisture_7_to_28
中的 7
depth_to
int16: 下限。例如 soil_moisture_7_to_28
中的 28
ensemble_member
int16: 对于集合数据,此处设置每个集合的成员。0
通常是控制运行。Model
枚举包含所有可用的模型,例如 icon_global
或 best_match
。
根据编程语言,您将需要解码模型以获得可用的字符串。例如,对于 Python
from openmeteo_sdk import Model
def model_to_name(code):
"""convert Model to name"""
for name, value in Model.Model.__dict__.items():
if value == code:
return name
return None
print(response.Model()) # 1
print(model_to_name(result.Model())) # "best_match"
Variable
枚举包含所有可用的变量,例如 temperature
(温度) 或 wind_speed
(风速)。请注意,高度不包含在变量名称中。temperature_2m
编码为 variable=temperature
和 altitude=2
。
Unit
枚举包含所有可用的单位,例如 celsius
(摄氏度) 或 metre_per_second
(米/秒)。
Aggregation
枚举包含每日变量的所有聚合类型,例如 minimum
(最小值) 或 maximum
(最大值)。
多个天气变量编码为列表。如果要访问单个变量,您将需要循环遍历数组,并按变量名称和高度进行过滤。这是一个获取 temperature_2m
(2 米温度) 和 precipitation
(降水) 的示例。
from openmeteo_sdk.Variable import Variable
response = ...
hourly = response.Hourly()
hourly_variables = list(map(lambda i: hourly.Variables(i), range(0, hourly.VariablesLength())))
temperature_2m = next(filter(lambda x: x.Variable() == Variable.temperature and x.Altitude() == 2, hourly_variables))
precipitation = next(filter(lambda x: x.Variable() == Variable.precipitation, hourly_variables))
print(temperature_2m.ValuesAsNumpy())
print(precipitation.ValuesAsNumpy())
根据变量的不同,您只需按变量名称进行过滤。如果您选择多个高度的风速,例如 wind_speed_10m
(10 米风速) 和 wind_speed_80m
(80 米风速),则按 altitude
(高度) 过滤是相关的。
如果您选择不同的每日聚合,请确保也检查正确的聚合。示例
from openmeteo_sdk.Variable import Variable
from openmeteo_sdk.Aggregation import Aggregation
daily = response.Daily()
daily_variables = list(map(lambda i: daily.Variables(i), range(0, daily.VariablesLength())))
temperature_2m_max = next(filter(lambda x: x.Variable() == Variable.temperature and x.Altitude() == 2 and x.Aggregation() == Aggregation.maximum, daily_variables))
temperature_2m_min = next(filter(lambda x: x.Variable() == Variable.temperature and x.Altitude() == 2 and x.Aggregation() == Aggregation.minimum, daily_variables))
print(temperature_2m_max.ValuesAsNumpy())
print(temperature_2m_min.ValuesAsNumpy())
请求变量的顺序将被保留。例如 ¤t=temperature_2m,wind_speed_10m,weather_code
将完全保持此顺序。因此,您可以直接使用索引。注意:current
仅返回一个变量,编码到 value
字段中。
current = response.Current()
timestamp = current.start()
temperature_2m = current.Variables(0).value()
wind_speed_10m = current.Variables(1).value()
weather_code = current.Variables(2).value()
可以在一个 API 调用中请求多个位置和多个天气模型的数据。例如 &latitude=47.1,49.7&longitude=8.6,9.4
。要一次返回多个位置,将发送多个 FlatBuffers 消息。
为了区分多个消息,每个消息都以其长度作为 32 位整数(小端字节序)作为前缀。这被称为 size-prefixed
FlatBuffer 消息。在线传输的消息看起来像这样
在解码响应时,您可以循环遍历数据并逐个处理。作为参考,这是 Python 代码。
一次最多可以请求 1000 个位置。Open-Meteo API 预取所有位置的数据,但将逐个位置处理并“流式传输”响应。因此,可以在服务器仍在处理后续消息时解码第一个消息。这对于摄取大量数据可能很有用,但这是一个相当复杂的方法。为了简单起见,等待整个响应然后开始处理数据也效果很好。
如果您想检查 Open-Meteo API 以二进制 FlatBuffers 格式返回的数据,可以使用 FlatBuffers 架构编译器 flatc
。这可以帮助理解 API 响应的结构。
首先,您需要安装 FlatBuffers 编译器。Mac: brew install flatbuffers
。Ubuntu sudo apt install flatbuffers-compiler
。
从该存储库获取 weather_api.fbs
。
# Make sure the URL contains `&format=flatbuffers`
wget -O data.bin https://api.open-meteo.com/v1/forecast\?latitude\=52.52\&longitude\=13.41\&daily\=weather_code,temperature_2m_max,temperature_2m_min\&timezone\=auto\&format\=flatbuffers
flatc --json --size-prefixed --raw-binary weather_api.fbs -- data.bin
cat data.json
{
latitude: 52.52,
longitude: 13.419998,
elevation: 38.0,
generation_time_milliseconds: 0.247002,
model: "best_match",
utc_offset_seconds: 3600,
timezone: "Europe/Berlin",
timezone_abbreviation: "CET",
daily: {
time: 1698620400,
time_end: 1699225200,
interval: 86400,
variables: [
{
variable: "weather_code",
unit: "wmo_code",
values: [
3.0,
80.0,
3.0,
61.0,
61.0,
61.0,
61.0
]
},
{
variable: "temperature",
unit: "celsius",
values: [
14.8455,
12.7955,
14.0455,
13.938999,
12.389,
12.3695,
14.4695
],
altitude: 2,
aggregation: "maximum"
},
{
variable: "temperature",
unit: "celsius",
values: [
11.1455,
8.1455,
7.4955,
8.488999,
8.188999,
6.389,
9.0195
],
altitude: 2,
aggregation: "minimum"
}
]
}
}
注意:model
(模型)、variable
(变量)、unit
(单位) 和 aggregation
(聚合) 的值被编码为枚举,枚举使用整数而不是字符串。只有 timezone
(时区) 和 timezone_abbreviation
(时区缩写) 是实际的字符串,它们在二进制 API 响应中进行编码。
MIT