Accessing EMF public spatial products with R

2026-03-11

Accessing EMF public spatial products with R
Víctor
Víctor Granda-García

Ecosystem Modelling Facility - CREAF

Introduction

Along with the main activities we at the EMF work on, including the development and maintenance of the web apps in the LFC, we generate several data products. This products are made publicly available for anyone to use them.

Datasets available

Accessing the data

The simplest way of using the data is downloading the desired files from the public reposiory (https://data-emf.creaf.cat/public/gpkg/). But because the size of the files, this can be time, memory and disk storage consuming.
Given the formats offered, in this case we can make use of the capabilities of the GDAL system library and its implementation in R by the sf package to avoid this costs.

Simple example

If we only need to access one day, the simplest way is to use sf to read the file directly from the server.

1# libraries needed
2library(sf)
Linking to GEOS 3.12.2, GDAL 3.11.4, PROJ 9.4.1; sf_use_s2() is TRUE
1library(dplyr)
Attaching package: 'dplyr'

The following objects are masked from 'package:stats':

    filter, lag

The following objects are masked from 'package:base':

    intersect, setdiff, setequal, union
1library(mapSpain)
2library(glue)
3
4# retrieving 25th April 2025
5data_20250425 <- st_read(
6  "https://data-emf.creaf.cat/public/gpkg/daily_interpolated_meteo/20250425.gpkg"
7)
Reading layer `20250425' from data source 
  `https://data-emf.creaf.cat/public/gpkg/daily_interpolated_meteo/20250425.gpkg' 
  using driver `GPKG'
Simple feature collection with 1988410 features and 24 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: -13237.5 ymin: 3988462 xmax: 1125762 ymax: 4858462
Projected CRS: ETRS89 / UTM zone 30N
1# explore result
2data_20250425
Simple feature collection with 1988410 features and 24 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: -13237.5 ymin: 3988462 xmax: 1125762 ymax: 4858462
Projected CRS: ETRS89 / UTM zone 30N
First 10 features:
   elevation    aspect     slope        TPI partition      dates DOY
1    44.1015 309.44631 3.5304249  16.290937        15 2025-04-25 115
2    41.2945 267.64572 1.8394422   0.837438        15 2025-04-25 115
3    29.4370 327.55463 0.9359342  13.133563        15 2025-04-25 115
4    11.0610  65.39845 1.8948245  -5.665062        15 2025-04-25 115
5    37.0690 231.37968 2.3435920  22.689000        15 2025-04-25 115
6    43.3040 193.34568 2.3342511  16.185438        15 2025-04-25 115
7    97.3895 326.60791 4.2136355  58.339062        15 2025-04-25 115
8    39.9230 239.78689 1.2984658  25.387063        15 2025-04-25 115
9    30.6355  90.18747 1.6958913  16.813000        15 2025-04-25 115
10   45.4990 334.25661 5.7842953 -27.030876        15 2025-04-25 115
   MeanTemperature MinTemperature MaxTemperature Precipitation
1         14.85347       12.47154       16.40212      1.170740
2         14.87700       12.51194       16.41468      1.171610
3         15.00206       12.77808       16.44801      1.205206
4         15.11709       12.98610       16.50259      1.144229
5         14.91845       12.58773       16.43380      1.172206
6         14.87069       12.49993       16.41208      1.185449
7         14.57880       11.99755       16.25703      1.484663
8         14.93944       12.66118       16.42069      1.244125
9         14.99840       12.76619       16.44970      1.208068
10        14.87326       12.57591       16.36691      1.335326
   MeanRelativeHumidity MinRelativeHumidity MaxRelativeHumidity Radiation
1              87.33471            79.08665           100.00000  10.45841
2              87.25151            79.06795           100.00000  10.59436
3              86.56603            78.91359           100.00000  10.29172
4              85.96987            78.67865            98.71368  10.06622
5              87.09487            79.04080           100.00000  10.61602
6              87.33051            79.12048           100.00000  10.75071
7              88.52361            79.48637           100.00000  10.85287
8              86.92086            79.05558           100.00000  10.51207
9              86.63630            78.95054           100.00000  10.35829
10             86.75567            78.83911           100.00000  10.18524
   WindSpeed WindDirection      PET ThermalAmplitude day month year
1   4.400000            NA 2.174045         3.930580  25     4 2025
2   4.400000            NA 2.203128         3.902745  25     4 2025
3   4.400000            NA 2.171483         3.669932  25     4 2025
4   4.400000            NA 2.176963         3.516493  25     4 2025
5   4.414037            NA 2.215269         3.846070  25     4 2025
6   4.419019            NA 2.231693         3.912151  25     4 2025
7   4.400000            NA 2.193226         4.259476  25     4 2025
8   4.400000            NA 2.198797         3.759505  25     4 2025
9   4.400000            NA 2.182352         3.683511  25     4 2025
10  4.400000            NA 2.130263         3.790991  25     4 2025
                                     geom_hex               geom_text
1  010100000000000000e86bf040000000a087615241 POINT (67262.5 4818462)
2  010100000000000000e86bf040000000a00a615241 POINT (67262.5 4817962)
3  010100000000000000d066ee40000000a08d605241 POINT (62262.5 4817462)
4  01010000000000000050a5ee40000000a08d605241 POINT (62762.5 4817462)
5  010100000000000000a84cf040000000a08d605241 POINT (66762.5 4817462)
6  010100000000000000e86bf040000000a08d605241 POINT (67262.5 4817462)
7  010100000000000000d0efec40000000a010605241 POINT (59262.5 4816962)
8  010100000000000000d066ee40000000a010605241 POINT (62262.5 4816962)
9  01010000000000000050a5ee40000000a010605241 POINT (62762.5 4816962)
10 01010000000000000050b1ec40000000a0935f5241 POINT (58762.5 4816462)
                      geom
1  POINT (67262.5 4818462)
2  POINT (67262.5 4817962)
3  POINT (62262.5 4817462)
4  POINT (62762.5 4817462)
5  POINT (66762.5 4817462)
6  POINT (67262.5 4817462)
7  POINT (59262.5 4816962)
8  POINT (62262.5 4816962)
9  POINT (62762.5 4816962)
10 POINT (58762.5 4816462)

But this is not so different from downloading the data and reading it locally, as the default behaviour of st_read is to download the file to a temporal folder and read it from there.
It’s also not so efficient in terms of time, as we need to wait to download the file and read all the data, which also means storing all data in memory.

Filtering by polygon

If we don’t need all the data extent (peninsular Spain and Balearic Islands), but an smaller area instead, we can take advantage of the wkt_filter argument in st_read.
Given a polygon (in Well Known Text format), st_read uses GDAL to access and retrieve only the part of the files that intersects with that polygon. This is useful because reduces transfer size (only a part of the file is read and transfered), time and memory used.
For this, before reading the remote file, we need to get the polygon of the area we want. In the following example we’ll use the mapSpain R package to obtain the polygon corresponding to Posada de Valdeón (Léon) municipality and use it to retrieve meteorological data for that polygon from the same file as before:

1posada_wkt <- mapSpain::esp_get_munic(munic = "Posada de Valdeón") |>
2  # ensure the poly is in the same CRS that the data
3  sf::st_transform(crs = 25830) |>
4  # get the polygon geometry
5  dplyr::pull("geometry") |>
6  # transform to text (Well Known Text, wkt)
7  sf::st_as_text()
! The file to be downloaded has size 74.6 Mb.
1# retrieving 25th April 2025 only for Posada
2data_posada_20250425 <- st_read(
3  "https://data-emf.creaf.cat/public/gpkg/daily_interpolated_meteo/20250425.gpkg",
4  wkt_filter = posada_wkt
5)
Reading layer `20250425' from data source 
  `https://data-emf.creaf.cat/public/gpkg/daily_interpolated_meteo/20250425.gpkg' 
  using driver `GPKG'
Simple feature collection with 660 features and 24 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 337762.5 ymin: 4772962 xmax: 350262.5 ymax: 4788962
Projected CRS: ETRS89 / UTM zone 30N
1# explore result
2data_posada_20250425
Simple feature collection with 660 features and 24 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 337762.5 ymin: 4772962 xmax: 350262.5 ymax: 4788962
Projected CRS: ETRS89 / UTM zone 30N
First 10 features:
   elevation    aspect     slope       TPI partition      dates DOY
1   1375.875 283.27479  6.528737 -49.38017        19 2025-04-25 115
2   1434.002 288.97189  9.650236 -52.99203        19 2025-04-25 115
3   1551.576 343.19092  5.846972  36.80266        19 2025-04-25 115
4   1490.074 344.87441  9.266371 -66.80790        19 2025-04-25 115
5   1636.578 311.98249 13.085693  51.79424        19 2025-04-25 115
6   1683.808 311.22276 12.595003  11.19392        19 2025-04-25 115
7   1771.919 337.50742  9.771273  50.60201        19 2025-04-25 115
8   1754.044  32.32764 11.101343  36.49842        19 2025-04-25 115
9   1652.695 357.09260  7.898497 -77.63956        19 2025-04-25 115
10  1722.074 285.44047 12.642417 -48.54472        19 2025-04-25 115
   MeanTemperature MinTemperature MaxTemperature Precipitation
1         13.76025       4.815477       19.57583      6.528750
2         13.48020       4.581549       19.26579      6.435703
3         12.90728       4.096716       18.63560      6.249397
4         13.19269       4.359613       18.93565      6.348672
5         12.45904       3.745736       18.12413      6.119528
6         12.20375       3.546991       17.83208      6.048183
7         11.73559       3.170681       17.30419      5.915649
8         11.80104       3.246387       17.36298      5.944145
9         12.30387       3.685165       17.90746      6.100725
10        11.92162       3.384304       17.47229      5.995743
   MeanRelativeHumidity MinRelativeHumidity MaxRelativeHumidity Radiation
1              82.50033            57.01226                 100  19.39115
2              83.72868            57.92193                 100  19.18948
3              86.61378            60.03243                 100  19.01024
4              84.70466            58.70404                 100  18.40383
5              88.54516            61.53508                 100  18.39183
6              89.70303            62.43815                 100  18.51165
7              92.15792            64.30271                 100  18.57665
8              91.39795            63.81123                 100  18.49715
9              88.06260            61.40946                 100  18.76046
10             89.93778            62.85809                 100  19.35640
   WindSpeed WindDirection      PET ThermalAmplitude day month year
1   2.580353            NA 3.498776         14.76035  25     4 2025
2   2.616275            NA 3.430047         14.68424  25     4 2025
3   2.645677            NA 3.322786         14.53889  25     4 2025
4   2.669256            NA 3.255552         14.57603  25     4 2025
5   2.687456            NA 3.155307         14.37839  25     4 2025
6   2.700068            NA 3.145606         14.28509  25     4 2025
7   2.698855            NA 3.093759         14.13351  25     4 2025
8   2.688307            NA 3.088102         14.11659  25     4 2025
9   2.673474            NA 3.206316         14.22229  25     4 2025
10  2.656094            NA 3.261536         14.08799  25     4 2025
                                     geom_hex                geom_text
1  0101000000000000008a9d1441000000a08f365241 POINT (337762.5 4774462)
2  0101000000000000005aa51441000000a08f365241 POINT (338262.5 4774462)
3  0101000000000000002aad1441000000a08f365241 POINT (338762.5 4774462)
4  010100000000000000fab41441000000a08f365241 POINT (339262.5 4774462)
5  010100000000000000cabc1441000000a08f365241 POINT (339762.5 4774462)
6  0101000000000000009ac41441000000a08f365241 POINT (340262.5 4774462)
7  0101000000000000006acc1441000000a08f365241 POINT (340762.5 4774462)
8  0101000000000000003ad41441000000a08f365241 POINT (341262.5 4774462)
9  0101000000000000000adc1441000000a08f365241 POINT (341762.5 4774462)
10 010100000000000000dae31441000000a08f365241 POINT (342262.5 4774462)
                       geom
1  POINT (337762.5 4774462)
2  POINT (338262.5 4774462)
3  POINT (338762.5 4774462)
4  POINT (339262.5 4774462)
5  POINT (339762.5 4774462)
6  POINT (340262.5 4774462)
7  POINT (340762.5 4774462)
8  POINT (341262.5 4774462)
9  POINT (341762.5 4774462)
10 POINT (342262.5 4774462)

Important

Be sure that the polygon is in the same Coordinate Reference System (CRS) as the data (EPSG:25380). wkt_filter don’t check this and assumes the filter polygon is in the same CRS, so most probably it will return no data when a different CRS is used.

Filtering by other variables (with queries)

Another option we have to reduce the data read into memory is retrieving only the data we are really interested on. Besides the spatial filter we saw in the previous section, GDAL also exposes an SQL dialect that can be used to query only the parts of the data we need. This means we can only read the columns and rows that comply with the supplied query.
We will use the query argument in st_read to make use of this GDAL feature and read only temperatures data in Posada de Valdeón for points above 1500m asl:

 1# creating the query text
 2query_text <- glue::glue(
 3  "SELECT
 4    geom, elevation, MeanTemperature, MinTemperature, MaxTemperature
 5  FROM '20250425'
 6  WHERE elevation >= 1500;"
 7)
 8
 9# retrieving 25th April 2025 temperatures only for Posada >= 1500m
10data_posada_1500m_20250425 <- st_read(
11  "https://data-emf.creaf.cat/public/gpkg/daily_interpolated_meteo/20250425.gpkg",
12  wkt_filter = posada_wkt,
13  query = query_text
14)
Reading query `SELECT
  geom, elevation, MeanTemperature, MinTemperature, MaxTemperature
FROM '20250425'
WHERE elevation >= 1500;'
from data source `https://data-emf.creaf.cat/public/gpkg/daily_interpolated_meteo/20250425.gpkg' 
  using driver `GPKG'
Simple feature collection with 356 features and 4 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 337762.5 ymin: 4772962 xmax: 350262.5 ymax: 4787962
Projected CRS: ETRS89 / UTM zone 30N
1# explore result
2data_posada_1500m_20250425
Simple feature collection with 356 features and 4 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 337762.5 ymin: 4772962 xmax: 350262.5 ymax: 4787962
Projected CRS: ETRS89 / UTM zone 30N
First 10 features:
   elevation MeanTemperature MinTemperature MaxTemperature
1   1714.730        12.25840       3.757355       17.78548
2   1994.477        11.24679       2.686823       16.81218
3   1865.795        11.71265       3.174516       17.26384
4   1704.162        12.31471       3.793404       17.85496
5   1515.876        13.03160       4.520778       18.56504
6   1845.979        11.54822       3.206440       16.97176
7   2124.161        10.74204       2.180587       16.30839
8   2043.219        11.02119       2.482460       16.57277
9   1973.810        11.26110       2.741995       16.79992
10  1552.001        12.89499       4.374182       18.43493
                       geom
1  POINT (344262.5 4787962)
2  POINT (342262.5 4787462)
3  POINT (342762.5 4787462)
4  POINT (343262.5 4787462)
5  POINT (343762.5 4787462)
6  POINT (348262.5 4787462)
7  POINT (341762.5 4786962)
8  POINT (342262.5 4786962)
9  POINT (342762.5 4786962)
10 POINT (343262.5 4786962)

Let’s see the query with more detail:

  • SELECT geom, elevation, MeanTemperature, MinTemperature, MaxTemperature selects the specified data columns. If we want to retrieve all columns, we can use SELECT *, were * means all columns.

  • FROM '20250425' the table, in this case, the name of the file without the extension.

  • WHERE elevation >= 1500 the filters we apply. If we apply more than one filter we need to use logical connectors, like WHERE elevation >= 1500 AND MinTemperature < 3

If both arguments, query and wkt_filter are used, the geometry column must be always selected (SELECT geom in this example) or the wkt_filter will not work.

Tip

For more info about the GDAL SQL dialect, visit https://gdal.org/en/stable/user/ogr_sql_dialect.html

Temporal series (loop)

All the previous examples are using only one file (day). If we want to read more than one, then the simplest way is to make a loop for all the dates we want to work with

 1# create the dates to read, but in the format of the files in the server
 2dates_to_read <-
 3  seq(as.Date("2025-04-25"), as.Date("2025-04-27"), by = "day") |>
 4  as.character() |>
 5  stringr::str_remove_all("-")
 6
 7# loop by dates
 8data_posada_days <- purrr::map(
 9  dates_to_read,
10  \(day) {
11    # query for the day
12    query_text <- glue::glue(
13      "SELECT
14        geom, dates, elevation, MeanTemperature, MinTemperature, MaxTemperature
15      FROM '{day}'
16      WHERE elevation >= 1500;"
17    )
18    # read the posada data of that day
19    st_read(
20      glue::glue("https://data-emf.creaf.cat/public/gpkg/daily_interpolated_meteo/{day}.gpkg"),
21      wkt_filter = posada_wkt,
22      query = query_text
23    )
24  }
25) |>
26  # bind the results in a dataframe
27  purrr::list_rbind()
Reading query `SELECT
  geom, dates, elevation, MeanTemperature, MinTemperature, MaxTemperature
FROM '20250425'
WHERE elevation >= 1500;'
from data source `https://data-emf.creaf.cat/public/gpkg/daily_interpolated_meteo/20250425.gpkg' 
  using driver `GPKG'
Simple feature collection with 356 features and 5 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 337762.5 ymin: 4772962 xmax: 350262.5 ymax: 4787962
Projected CRS: ETRS89 / UTM zone 30N
Reading query `SELECT
  geom, dates, elevation, MeanTemperature, MinTemperature, MaxTemperature
FROM '20250426'
WHERE elevation >= 1500;'
from data source `https://data-emf.creaf.cat/public/gpkg/daily_interpolated_meteo/20250426.gpkg' 
  using driver `GPKG'
Simple feature collection with 356 features and 5 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 337762.5 ymin: 4772962 xmax: 350262.5 ymax: 4787962
Projected CRS: ETRS89 / UTM zone 30N
Reading query `SELECT
  geom, dates, elevation, MeanTemperature, MinTemperature, MaxTemperature
FROM '20250427'
WHERE elevation >= 1500;'
from data source `https://data-emf.creaf.cat/public/gpkg/daily_interpolated_meteo/20250427.gpkg' 
  using driver `GPKG'
Simple feature collection with 356 features and 5 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 337762.5 ymin: 4772962 xmax: 350262.5 ymax: 4787962
Projected CRS: ETRS89 / UTM zone 30N
1# explore result
2head(data_posada_days)
       dates elevation MeanTemperature MinTemperature MaxTemperature
1 2025-04-25  1714.730        12.25840       3.757355       17.78548
2 2025-04-25  1994.477        11.24679       2.686823       16.81218
3 2025-04-25  1865.795        11.71265       3.174516       17.26384
4 2025-04-25  1704.162        12.31471       3.793404       17.85496
5 2025-04-25  1515.876        13.03160       4.520778       18.56504
6 2025-04-25  1845.979        11.54822       3.206440       16.97176
                      geom
1 POINT (344262.5 4787962)
2 POINT (342262.5 4787462)
3 POINT (342762.5 4787462)
4 POINT (343262.5 4787462)
5 POINT (343762.5 4787462)
6 POINT (348262.5 4787462)