meteospain

Víctor Granda (EMF)

Introduction

What is meteospain?

meteospain is an R package that allows access to several Spanish meteorological services APIs:

  • uniformized access to different services
  • standardized data compatible between services

Which services are available in meteospain?

  • AEMET*, the Spanish State Meteorological Agency.
  • MeteoCat*, the Catalan Meteorology Service.
  • MeteoGalicia, the Galician Meteorological Service.
  • RIA, the Andalucian Agroclimatic Information Network.
  • Meteoclimatic, the Spanish non-professional meteorological stations network.

* These services need a personal API key to be able to access the data

Which services are available in meteospain?

Using meteospain

Installation

install.packages("meteospain")

Basic usage

library(meteospain)

# RIA service
ria_config <- ria_options(
  resolution = 'daily',
  start_date = as.Date("2023-05-20")
)

ria_example_data <- get_meteo_from("ria", ria_config)
ria_example_data
Simple feature collection with 100 features and 17 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: -7.1454 ymin: 36.1706 xmax: -1.4613 ymax: 38.2946
Geodetic CRS:  WGS 84
First 10 features:
    timestamp service station_id          station_name station_province
1  2023-05-20     ria       14-2                Adamuz          Córdoba
2  2023-05-20     ria       4-10                  Adra          Almería
3  2023-05-20     ria       23-6             Alcaudete             Jaén
4  2023-05-20     ria        4-2               Almería          Almería
5  2023-05-20     ria      21-10               Almonte           Huelva
6  2023-05-20     ria     21-103 Almonte bajo plástico           Huelva
7  2023-05-20     ria      18-11             Almuñecar          Granada
8  2023-05-20     ria      29-10             Antequera           Málaga
9  2023-05-20     ria      29-11             Archidona           Málaga
10 2023-05-20     ria       21-6                Aroche           Huelva
   altitude mean_temperature min_temperature max_temperature
1   145 [m]       16.45 [°C]      9.920 [°C]      25.94 [°C]
2     2 [m]       18.34 [°C]     14.800 [°C]      22.37 [°C]
3   640 [m]       14.26 [°C]      8.720 [°C]      23.46 [°C]
4     5 [m]       17.90 [°C]     13.550 [°C]      21.69 [°C]
5    13 [m]       18.15 [°C]     12.390 [°C]      23.75 [°C]
6    38 [m]       19.42 [°C]     12.470 [°C]      28.71 [°C]
7    29 [m]       17.19 [°C]     11.640 [°C]      22.26 [°C]
8   440 [m]       15.20 [°C]      8.700 [°C]      22.26 [°C]
9   529 [m]       13.65 [°C]      7.380 [°C]      21.97 [°C]
10  293 [m]       14.46 [°C]      6.195 [°C]      24.17 [°C]
   mean_relative_humidity min_relative_humidity max_relative_humidity
1               65.95 [%]             22.49 [%]              96.4 [%]
2               70.10 [%]             55.37 [%]              81.9 [%]
3               59.30 [%]             23.87 [%]              86.3 [%]
4               76.30 [%]             48.16 [%]              96.6 [%]
5               69.81 [%]             48.85 [%]              96.4 [%]
6               71.00 [%]             40.63 [%]              97.0 [%]
7               71.80 [%]             45.91 [%]              89.2 [%]
8               64.07 [%]             31.10 [%]              91.3 [%]
9               76.00 [%]             36.76 [%]              96.4 [%]
10              70.90 [%]             27.19 [%]              89.8 [%]
   precipitation mean_wind_direction mean_wind_speed  solar_radiation
1   10.2 [L/m^2]           335.2 [°]     0.486 [m/s] 22.47 [MJ/d/m^2]
2    0.0 [L/m^2]            87.9 [°]     1.072 [m/s] 23.32 [MJ/d/m^2]
3    0.4 [L/m^2]           199.6 [°]     0.648 [m/s] 19.98 [MJ/d/m^2]
4    0.0 [L/m^2]           135.4 [°]     0.531 [m/s] 17.40 [MJ/d/m^2]
5    0.0 [L/m^2]           151.0 [°]     1.505 [m/s] 20.58 [MJ/d/m^2]
6     NA [L/m^2]              NA [°]        NA [m/s] 15.08 [MJ/d/m^2]
7    0.0 [L/m^2]           259.6 [°]     0.941 [m/s] 25.29 [MJ/d/m^2]
8    0.4 [L/m^2]           330.3 [°]     1.111 [m/s] 14.42 [MJ/d/m^2]
9    3.8 [L/m^2]            91.8 [°]     0.834 [m/s] 17.18 [MJ/d/m^2]
10   9.8 [L/m^2]           133.4 [°]     1.009 [m/s] 15.09 [MJ/d/m^2]
   under_plastic                   geometry
1          FALSE    POINT (-4.2643 37.5951)
2          FALSE    POINT (-2.5932 36.4448)
3          FALSE    POINT (-4.0442 37.3438)
4          FALSE    POINT (-2.2408 36.5007)
5          FALSE    POINT (-6.2835 37.0853)
6           TRUE POINT (-6.334227 37.04303)
7          FALSE    POINT (-3.4044 36.4506)
8          FALSE    POINT (-4.3345 37.0203)
9          FALSE   POINT (-4.2505 37.06139)
10         FALSE    POINT (-6.5642 37.5729)

Basic usage

# aemet service
aemet_config <- aemet_options(
  resolution = 'daily',
  start_date = as.Date("2023-05-20"),
  api_key = "my_api_key"
)

aemet_example_data <- get_meteo_from("aemet", aemet_config)
aemet_example_data
Simple feature collection with 236 features and 12 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: -17.91528 ymin: 27.73583 xmax: 4.215556 ymax: 43.78611
Geodetic CRS:  WGS 84
# A tibble: 236 × 13
   timestamp           service station_id station_name station_province altitude
   <dttm>              <chr>   <chr>      <chr>        <chr>                 [m]
 1 2023-05-20 00:00:00 aemet   0016A      "REUS AEROP… TARRAGONA              71
 2 2023-05-20 00:00:00 aemet   0076       "BARCELONA … BARCELONA               4
 3 2023-05-20 00:00:00 aemet   0149X      "MANRESA"    BARCELONA             291
 4 2023-05-20 00:00:00 aemet   0200E      "BARCELONA,… BARCELONA             408
 5 2023-05-20 00:00:00 aemet   0201D      "BARCELONA"  BARCELONA               6
 6 2023-05-20 00:00:00 aemet   0252D      "ARENYS DE … BARCELONA              74
 7 2023-05-20 00:00:00 aemet   0324A      "RIPOLL"     GIRONA                675
 8 2023-05-20 00:00:00 aemet   0367       "GIRONA AER… GIRONA                143
 9 2023-05-20 00:00:00 aemet   0372C      "PORQUERES"  GIRONA                157
10 2023-05-20 00:00:00 aemet   1002Y      "BAZTAN, IR… NAVARRA               183
# ℹ 226 more rows
# ℹ 7 more variables: mean_temperature [°C], min_temperature [°C],
#   max_temperature [°C], precipitation [L/m^2], mean_wind_speed [m/s],
#   insolation [h], geometry <POINT [°]>

API keys

AEMET and MeteoCat need personal API keys issued by those services to access the data:

Obtaining the key is automatic in AEMET, we can try in the course to obtain our key and use it

API options

(the devil is in the details)

API options

The help for the service options functions (aemet_options, meteocat_opions…) is a good starting point to know waht we need:

?service_options

API options

  1. Resolution (all)

  2. Start date (all except MeteoClimatic)

  3. End date (all except MeteoCat)

  4. Stations (all)

  5. API key (only AEMET and MeteoCat)

Resolution

  • current_day: last 24 hours (only available in AEMET and MeteoClimatic)
  • instant: latest measures for each station (only available in MeteoCat and MeteoGalicia)
  • hourly: hourly values for the desired day (only available in MeteoCat)
  • daily: daily values for the desired dates (available in all execep MeteoClimatic)
  • monthly: monthly values for the desired months (available in all execep MeteoClimatic)
  • yearly: yearly values for the desired years (available only in AEMET and MeteoCat)

Stations

A vector with station codes can be supplied to filter out the returned data to show only the desired stations. For that we need to know the station codes.

?get_stations_info_from

Stations

meteogalicia_stations_info <- get_stations_info_from("meteogalicia", options = meteogalicia_options())
meteogalicia_stations_info
Simple feature collection with 156 features and 5 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: -9.178318 ymin: 41.8982 xmax: -6.765224 ymax: 43.7383
Geodetic CRS:  WGS 84
# A tibble: 156 × 6
   service      station_id station_name             station_province altitude
 * <chr>        <chr>      <chr>                    <chr>                 [m]
 1 meteogalicia 10157      Coruña-Torre de Hércules A Coruña               21
 2 meteogalicia 14000      Coruña-Dique             A Coruña                5
 3 meteogalicia 10045      Mabegondo                A Coruña               94
 4 meteogalicia 14003      Punta Langosteira        A Coruña                5
 5 meteogalicia 10144      Arzúa                    A Coruña              362
 6 meteogalicia 19005      Guísamo                  A Coruña              175
 7 meteogalicia 19012      Cespón                   A Coruña               59
 8 meteogalicia 10095      Sergude                  A Coruña              231
 9 meteogalicia 10800      Camariñas                A Coruña                5
10 meteogalicia 19001      Rus                      A Coruña              134
# ℹ 146 more rows
# ℹ 1 more variable: geometry <POINT [°]>

Stations

Now, we can filter the stations we want:

get_meteo_from("meteogalicia", meteogalicia_options("daily", stations = c("10157", "14000")))
Simple feature collection with 2 features and 16 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: -8.409202 ymin: 43.36506 xmax: -8.374706 ymax: 43.38276
Geodetic CRS:  WGS 84
# A tibble: 2 × 17
  timestamp           service  station_id station_name station_province altitude
  <dttm>              <chr>    <chr>      <chr>        <chr>                 [m]
1 2023-06-20 00:00:00 meteoga… 10157      Coruña-Torr… A Coruña               21
2 2023-06-20 00:00:00 meteoga… 14000      Coruña-Dique A Coruña                5
# ℹ 11 more variables: mean_temperature [°C], min_temperature [°C],
#   max_temperature [°C], mean_relative_humidity [%],
#   min_relative_humidity [%], max_relative_humidity [%],
#   precipitation [L/m^2], mean_wind_direction [°], mean_wind_speed [m/s],
#   insolation [h], geometry <POINT [°]>

A simple process

Example

To download all daily data for the last month (May 2023) from RIA for the stations localized in Granada province we just need:

library(meteospain)
library(dplyr)
# get the stations info to see which are in Granada
ria_stations <- get_stations_info_from("ria")
ria_stations
Simple feature collection with 122 features and 7 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: -7.1454 ymin: 36.1706 xmax: -1.4613 ymax: 38.2946
Geodetic CRS:  WGS 84
# A tibble: 122 × 8
   service station_id station_name         station_province province_id altitude
 * <chr>   <chr>      <chr>                <chr>                  <int>      [m]
 1 ria     14-2       Adamuz               Córdoba                   14      145
 2 ria     4-10       Adra                 Almería                    4        2
 3 ria     23-6       Alcaudete            Jaén                      23      640
 4 ria     4-2        Almería              Almería                    4        5
 5 ria     21-10      Almonte              Huelva                    21       13
 6 ria     21-103     Almonte bajo plásti… Huelva                    21       38
 7 ria     21-104     Almonte bajo plásti… Huelva                    21       23
 8 ria     18-11      Almuñecar            Granada                   18       29
 9 ria     18-9       Almuñecar            Granada                   18       49
10 ria     29-3       Antequera            Málaga                    29      457
# ℹ 112 more rows
# ℹ 2 more variables: under_plastic <lgl>, geometry <POINT [°]>

Example

To download all daily data for the last month (May 2023) from RIA for the stations localized in Granada province we just need:

library(meteospain)
library(dplyr)
# get the stations info to see which are in Granada
ria_stations <- get_stations_info_from("ria")
granada_stations <- ria_stations |>
  filter(station_province == "Granada") |>
  pull(station_id)
granada_stations
 [1] "18-11"  "18-9"   "18-1"   "18-7"   "18-102" "18-101" "18-5"   "18-6"  
 [9] "18-3"   "18-10"  "18-4"   "18-12"  "18-2"   "18-8"  

Example

To download all daily data for the last month (May 2023) from RIA for the stations localized in Granada province we just need:

library(meteospain)
library(dplyr)
# get the stations info to see which are in Granada
ria_stations <- get_stations_info_from("ria")
granada_stations <- ria_stations |>
  filter(station_province == "Granada") |>
  pull(station_id)
# create the options
api_options <- ria_options(
  resolution = "daily",
  start_date = as.Date("2023-05-01"),
  end_date = as.Date("2023-05-31"),
  stations = granada_stations
)
# get the data
granada_may_2023 <- get_meteo_from("ria", api_options)

Example

granada_may_2023
Simple feature collection with 372 features and 17 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: -4.0913 ymin: 36.4506 xmax: -2.2254 ymax: 37.5233
Geodetic CRS:  WGS 84
First 10 features:
    timestamp service station_id station_name station_province altitude
1  2023-05-01     ria      18-11    Almuñecar          Granada   29 [m]
2  2023-05-02     ria      18-11    Almuñecar          Granada   29 [m]
3  2023-05-03     ria      18-11    Almuñecar          Granada   29 [m]
4  2023-05-04     ria      18-11    Almuñecar          Granada   29 [m]
5  2023-05-05     ria      18-11    Almuñecar          Granada   29 [m]
6  2023-05-06     ria      18-11    Almuñecar          Granada   29 [m]
7  2023-05-07     ria      18-11    Almuñecar          Granada   29 [m]
8  2023-05-08     ria      18-11    Almuñecar          Granada   29 [m]
9  2023-05-09     ria      18-11    Almuñecar          Granada   29 [m]
10 2023-05-10     ria      18-11    Almuñecar          Granada   29 [m]
   mean_temperature min_temperature max_temperature mean_relative_humidity
1        18.92 [°C]      12.44 [°C]      24.86 [°C]              73.60 [%]
2        19.82 [°C]      12.37 [°C]      27.20 [°C]              60.66 [%]
3        19.03 [°C]      11.77 [°C]      26.00 [°C]              51.33 [%]
4        17.60 [°C]      10.18 [°C]      23.80 [°C]              68.86 [%]
5        18.47 [°C]      11.64 [°C]      24.06 [°C]              74.40 [%]
6        19.28 [°C]      13.56 [°C]      25.60 [°C]              71.90 [%]
7        19.86 [°C]      13.76 [°C]      26.46 [°C]              73.30 [%]
8        19.69 [°C]      14.69 [°C]      24.40 [°C]              73.40 [%]
9        20.70 [°C]      15.23 [°C]      29.09 [°C]              75.20 [%]
10       22.28 [°C]      15.36 [°C]      29.14 [°C]              59.20 [%]
   min_relative_humidity max_relative_humidity precipitation
1              52.72 [%]              88.2 [%]     0 [L/m^2]
2              34.77 [%]              88.8 [%]     0 [L/m^2]
3              27.56 [%]              76.7 [%]     0 [L/m^2]
4              41.62 [%]              89.7 [%]     0 [L/m^2]
5              51.18 [%]              89.4 [%]     0 [L/m^2]
6              37.10 [%]              89.5 [%]     0 [L/m^2]
7              36.77 [%]              98.8 [%]     0 [L/m^2]
8              50.72 [%]              91.9 [%]     0 [L/m^2]
9              29.04 [%]              94.2 [%]     0 [L/m^2]
10             29.17 [%]              86.0 [%]     0 [L/m^2]
   mean_wind_direction mean_wind_speed  solar_radiation under_plastic
1           164.20 [°]     0.880 [m/s] 27.14 [MJ/d/m^2]         FALSE
2            16.72 [°]     0.884 [m/s] 24.58 [MJ/d/m^2]         FALSE
3           278.90 [°]     0.870 [m/s] 22.67 [MJ/d/m^2]         FALSE
4           241.84 [°]     0.820 [m/s] 22.58 [MJ/d/m^2]         FALSE
5           148.90 [°]     0.845 [m/s] 25.82 [MJ/d/m^2]         FALSE
6           200.50 [°]     0.889 [m/s] 25.81 [MJ/d/m^2]         FALSE
7           161.80 [°]     0.763 [m/s] 27.14 [MJ/d/m^2]         FALSE
8           215.00 [°]     0.877 [m/s] 25.46 [MJ/d/m^2]         FALSE
9           190.80 [°]     0.904 [m/s] 26.20 [MJ/d/m^2]         FALSE
10          165.90 [°]     0.987 [m/s] 27.64 [MJ/d/m^2]         FALSE
                  geometry
1  POINT (-3.4044 36.4506)
2  POINT (-3.4044 36.4506)
3  POINT (-3.4044 36.4506)
4  POINT (-3.4044 36.4506)
5  POINT (-3.4044 36.4506)
6  POINT (-3.4044 36.4506)
7  POINT (-3.4044 36.4506)
8  POINT (-3.4044 36.4506)
9  POINT (-3.4044 36.4506)
10 POINT (-3.4044 36.4506)

API limits

(the sad part of meteospain)

API limits

Some services, like AEMET and MeteoCat, impose limits to the data that can be downloaded. For example, AEMET only allows to download 31 days worth of daily data. See what happens when we go beyond those limits:

get_meteo_from(
  'aemet',
  aemet_options(
    api_key = Sys.getenv("aemet"),
    resolution = 'daily',
    start_date = as.Date('1990-01-01'),
    end_date = as.Date('1990-12-31')
  )
)
Error in `api_function()`:
✖ 404
ℹ AEMET API returned no data: El rango de fechas no puede ser superior a 31
  dias

AEMET limits

  • Daily data limited to 31 days for query
  • Monthly and yearly data limited to 3 years per query

MeteoCat limits

  • Daily data is downloaded for all the month
  • Monthly data is downloaded for all the year
  • Yearly data donwload all available years

Example loop

To solve this, we need to download the data in blocks, to avoid hitting the API limits:

start_dates <- seq(as.Date('1990-01-01'), as.Date('1990-06-01'), 'months')
end_dates <- seq(as.Date('1990-02-01'), as.Date('1990-07-01'), 'months') - 1

# base for loop
aemet_1990_data <- data.frame()

for (index in seq_along(start_dates)) {
  temp_res <- get_meteo_from(
    'aemet',
    aemet_options(
      api_key = Sys.getenv("aemet"),
      resolution = 'daily',
      start_date = start_dates[index],
      end_date = end_dates[index]
    )
  )
  
  aemet_1990_data <- rbind(aemet_1990_data, temp_res)
}

Example loop

aemet_1990_data
Simple feature collection with 21553 features and 12 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: -17.88889 ymin: 27.81889 xmax: 4.215556 ymax: 43.56694
Geodetic CRS:  WGS 84
# A tibble: 21,553 × 13
   timestamp           service station_id station_name station_province altitude
 * <dttm>              <chr>   <chr>      <chr>        <chr>                 [m]
 1 1990-01-01 00:00:00 aemet   0002I      "VANDELLÒS … TARRAGONA              32
 2 1990-01-01 00:00:00 aemet   0016A      "REUS AEROP… TARRAGONA              71
 3 1990-01-01 00:00:00 aemet   0076       "BARCELONA … BARCELONA               4
 4 1990-01-01 00:00:00 aemet   0200E      "BARCELONA,… BARCELONA             408
 5 1990-01-01 00:00:00 aemet   0229I      "SABADELL A… BARCELONA             146
 6 1990-01-01 00:00:00 aemet   0324A      "RIPOLL"     GIRONA                675
 7 1990-01-01 00:00:00 aemet   0367       "GIRONA AER… GIRONA                143
 8 1990-01-01 00:00:00 aemet   1014       "HONDARRIBI… GIPUZKOA                4
 9 1990-01-01 00:00:00 aemet   1024E      "DONOSTIA /… GIPUZKOA              251
10 1990-01-01 00:00:00 aemet   1082       "BILBAO AER… BIZKAIA                42
# ℹ 21,543 more rows
# ℹ 7 more variables: mean_temperature [°C], min_temperature [°C],
#   max_temperature [°C], precipitation [L/m^2], mean_wind_speed [m/s],
#   insolation [h], geometry <POINT [°]>

Extras

Results objects

Lets take a look to the data returned by get_meteo_from

aemet_1990_data
Simple feature collection with 21553 features and 12 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: -17.88889 ymin: 27.81889 xmax: 4.215556 ymax: 43.56694
Geodetic CRS:  WGS 84
# A tibble: 21,553 × 13
   timestamp           service station_id station_name station_province altitude
 * <dttm>              <chr>   <chr>      <chr>        <chr>                 [m]
 1 1990-01-01 00:00:00 aemet   0002I      "VANDELLÒS … TARRAGONA              32
 2 1990-01-01 00:00:00 aemet   0016A      "REUS AEROP… TARRAGONA              71
 3 1990-01-01 00:00:00 aemet   0076       "BARCELONA … BARCELONA               4
 4 1990-01-01 00:00:00 aemet   0200E      "BARCELONA,… BARCELONA             408
 5 1990-01-01 00:00:00 aemet   0229I      "SABADELL A… BARCELONA             146
 6 1990-01-01 00:00:00 aemet   0324A      "RIPOLL"     GIRONA                675
 7 1990-01-01 00:00:00 aemet   0367       "GIRONA AER… GIRONA                143
 8 1990-01-01 00:00:00 aemet   1014       "HONDARRIBI… GIPUZKOA                4
 9 1990-01-01 00:00:00 aemet   1024E      "DONOSTIA /… GIPUZKOA              251
10 1990-01-01 00:00:00 aemet   1082       "BILBAO AER… BIZKAIA                42
# ℹ 21,543 more rows
# ℹ 7 more variables: mean_temperature [°C], min_temperature [°C],
#   max_temperature [°C], precipitation [L/m^2], mean_wind_speed [m/s],
#   insolation [h], geometry <POINT [°]>

Results objects

Results are spatial objects, so we can plot them

library(sf)
aemet_1990_data |>
  filter(timestamp == as.Date("1990-04-25")) |>
  select(mean_temperature) |>
  plot()

All you need is docs

meteospain has a nice online documentation where you can find all we saw here today and more