---
title: "Reshaping meteorological data for meteoland"
author: "Victor Granda"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Reshaping meteorological data for meteoland}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

```{r setup}
library(meteoland)
library(stars)
library(dplyr)
```

```{r data_preparation, echo=FALSE}
unformatted_meteo <- tibble(
  date = rep(seq(from = as.Date("2022-12-01"), to = as.Date("2022-12-05"), by = 1), 3),
  station = rep(letters[1:3], each = 5),
  latitude = rep(c(41.35, 40.11, 42.00), each = 5),
  longitude = rep(c(-0.33, 0.12, 1.12), each = 5),
  min_temp = rnorm(15, 10, 6),
  max_temp = min_temp + rnorm(15, 10, 3),
  rh = rnorm(15, 50, 25)
) |>
  dplyr::mutate(
    rh = dplyr::if_else(rh > 100, 100, rh),
    rh = dplyr::if_else(rh < 20, 20, rh)
  )
```


## Meteorological data format

For the interpolation of meteorological variables on our target locations, we need meteorological data for a reference set of locations. In `meteoland` this is a `sf` object with the spatial coordinates of our reference
locations (usually meteorological stations) and daily values of the meteorological
variables needed to perform the interpolation, *i.e.*:

```{r meteoland_meteo_example}
meteoland_meteo_example
```

`meteoland` expects names to be as in the example:

```{r meteo_names}
names(meteoland_meteo_example)
```

The only mandatory variables are `MinTemperature` and `MaxTemperature`. Other variables
(`Precipitation`, `WindSpeed`...), when present, allow for a more complete
interpolation.

## Converting meteorological data to `meteoland` format

Meteorological data can come in many formats and with different names for the same
variables. As we saw above, we need to convert it to a `meteoland` compliant
format (`sf` object with correct names).

### Converting from data frames

If we have our meteorological data in a data.frame (*i.e.* we obtained it from
our own weather stations, or download it from other source in this format) we can
just simply transform it to the desired format:

```{r unformatted_meteo}
unformatted_meteo
```

```{r unformatted_transformation}
ready_meteo <- unformatted_meteo |>
  # convert names to correct ones
  dplyr::mutate(
    MinTemperature = min_temp,
    MaxTemperature = max_temp,
    MeanRelativeHumidity = rh
  ) |>
  # transform to sf (WGS84)
  sf::st_as_sf(
    coords = c("longitude", "latitude"),
    crs = sf::st_crs(4326)
  )

ready_meteo
```

And *voilà*, we have our meteo data in the correct format

### Meteorological data from other R packages

`meteoland` offers transformation functions for meteorological data downloaded from the
[`meteospain`](https://emf-creaf.github.io/meteospain/) and
[`worldmet`](https://openair-project.github.io/worldmet/) R packages.

#### `meteospain` data

For data coming from `meteospain` package we have the `meteospain2meteoland`
function that transforming the data for us:

```{r meteospain, eval = FALSE}
library(meteospain)
get_meteo_from(
  "meteogalicia",
  meteogalicia_options('daily', as.Date("2022-12-01"), as.Date("2022-12-05"))
) |>
  meteospain2meteoland()
```

#### `worldmet` data

For data coming from `worldmet` package we have the `worldmet2meteoland`
function that do the reshaping for us:

```{r worldmet, eval = FALSE}
library(worldmet)
worldmet::importNOAA("081120-99999", year = 2022) |>
  worldmet2meteoland()
```

### Meteorological data from raster sources

As we have seen, we need the meteorological reference data in a `sf` object (points).
To be able to create an interpolator from a raster, we need to transform the cell values to points
(*i.e.* using the cell center coordinates) for each variable and day and use it to create the
interpolator.

So if we have a multi-layered raster with several dates of meteorological data:

    > Remember that the raster, besides the meteo data, needs to contain also the topographic
    (elevation, aspect and slope) data for the interpolator to work.

```{r raster_meteo_preparing, echo = FALSE}
raster_meteo_reference <- interpolate_data(
  raster_to_interpolate_example, meteoland_interpolator_example, verbose = FALSE
)
```

```{r}
raster_meteo_reference
```

we need to convert it to points:

```{r raster_to_points}
points_meteo_reference <- names(raster_meteo_reference) |>
  # for each variable
  purrr::map(
    # take the variable raster
    ~ raster_meteo_reference[.x] |>
      # convert to sf
      sf::st_as_sf(as_points = TRUE, na.rm = FALSE) |>
      # pivot the data for dates to be in one column
      tidyr::pivot_longer(cols = -geometry, names_to = "dates", values_to = .x) |>
      # convert to tibble to fasten the process
      dplyr::as_tibble() |>
      # convert to date and create stationID
      dplyr::mutate(
        dates = as.Date(dates),
        stationID = as.character(geometry)
      )
  ) |>
  # join all variables
  purrr::reduce(dplyr::left_join) |>
  # create the points sf object
  sf::st_as_sf()

points_meteo_reference
```

And now we can use it to build an interpolator object:

```{r raster_interpolator}
with_meteo(points_meteo_reference) |>
  create_meteo_interpolator()
```
