create-rgb-s2-images-for-tfs

Introduction

Objective

  • Create a time series of RGB satellite images for Tiny Forest locations

  • Using Harmonized Sentinel 2 data

  • 10 resolution

  • Frequent and near real-time

TF data

suppressPackageStartupMessages(library(tinyForestR))
tinyForestR::initialise_tf()
Virtual environment 'tinyforest' removed.
Using Python: /opt/homebrew/Cellar/python@3.11/3.11.3/Frameworks/Python.framework/Versions/3.11/bin/python3.11
Creating virtual environment 'tinyforest' ... 
Done!
Installing packages: 'pip', 'wheel', 'setuptools', 'numpy'
Virtual environment 'tinyforest' successfully created.
Using virtual environment 'tinyforest' ...
tf_dat <- df

head(df) |> gt::gt()
tf_id plant_date area trees lat lon date
85 14 March 2020 207 Apple, crab(Malus sylvestris) 51.77789 -1.469139 2020-03-14
85 14 March 2020 207 Birch, downy(Betula pubescens) 51.77789 -1.469139 2020-03-14
85 14 March 2020 207 Birch, silver(Betula pendula) 51.77789 -1.469139 2020-03-14
85 14 March 2020 207 Blackthorn(Prunus spinosa) 51.77789 -1.469139 2020-03-14
85 14 March 2020 207 Dogwood(Cornus sanguinea) 51.77789 -1.469139 2020-03-14
85 14 March 2020 207 Elder(Sambucus nigra) 51.77789 -1.469139 2020-03-14

Create TF sf data

library(sf); library(tidyverse); library(mapview)

tf_dat_sf <- tf_dat |>
  select(-trees) |>
  distinct() |>
  st_as_sf(coords = c("lon", "lat"), crs = 4326) |>
  st_transform(27700) 

tf_dat_sf |>
  head() |>
  gt::gt()
tf_id plant_date area date geometry
85 14 March 2020 207 2020-03-14 c(436721.679892361, 208935.561590291)
86 28 January 2021 201 2021-01-28 c(454232.81873778, 208120.156586318)
87 04 February 2021 206 2021-02-04 c(452589.693142388, 204280.741276084)
88 04 February 2021 205 2021-02-04 c(358425.070462347, 178097.717290365)
89 19 February 2021 206 2021-02-19 c(264944.275381102, 666786.515153779)
90 22 February 2021 200 2021-02-22 c(393360.348573678, -78496.2220085778)

Load S2 image collection and filter

ee <- import("ee")
geemap <- import("geemap")

library(rgee)
ee$Initialize()

start_date <- "2017-01-01"
end_date <- "2019-01-01"

poly <- tf_dat_sf |>
  filter(tf_id == params$tf_id) |>
  select(tf_id) |>
  st_buffer(1000) |>
  st_transform(4326)

point <- tf_dat_sf|>
  filter(tf_id == params$tf_id) |>
  select(tf_id) |>
  rgee::sf_as_ee()
  

buff <- rgee::sf_as_ee(poly)

cat(unlist((buff$getInfo())))
FeatureCollection String Integer Feature Polygon -2.0774125 49.193427 -2.0774321 49.1938978 -2.0774892 49.1943673 -2.0775837 49.1948342 -2.0777154 49.1952972 -2.0778839 49.1957551 -2.0780887 49.1962065 -2.0783293 49.1966503 -2.0786051 49.1970852 -2.0789151 49.1975101 -2.0792587 49.1979238 -2.0796349 49.1983251 -2.0800426 49.198713 -2.0804807 49.1990863 -2.0809481 49.1994441 -2.0814434 49.1997854 -2.0819653 49.2001093 -2.0825123 49.2004147 -2.083083 49.2007011 -2.0836758 49.2009674 -2.084289 49.201213 -2.084921 49.2014373 -2.0855701 49.2016396 -2.0862345 49.2018193 -2.0869123 49.201976 -2.0876017 49.2021093 -2.0883008 49.2022187 -2.0890077 49.202304 -2.0897204 49.2023649 -2.090437 49.2024013 -2.0911555 49.2024131 -2.091874 49.2024002 -2.0925905 49.2023626 -2.093303 49.2023006 -2.0940096 49.2022142 -2.0947083 49.2021037 -2.0953972 49.2019693 -2.0960744 49.2018116 -2.0967381 49.2016308 -2.0973864 49.2014275 -2.0980176 49.2012022 -2.09863 49.2009556 -2.0992218 49.2006883 -2.0997914 49.2004011 -2.1003373 49.2000948 -2.100858 49.1997701 -2.101352 49.199428 -2.1018181 49.1990695 -2.1022548 49.1986955 -2.1026611 49.1983069 -2.1030358 49.197905 -2.1033779 49.1974908 -2.1036864 49.1970655 -2.1039605 49.1966301 -2.1041995 49.1961859 -2.1044026 49.1957341 -2.1045694 49.195276 -2.1046994 49.1948128 -2.1047922 49.1943458 -2.1048476 49.1938762 -2.1048655 49.1934054 -2.1048456 49.1929346 -2.1047883 49.1924651 -2.1046935 49.1919982 -2.1045616 49.1915352 -2.1043928 49.1910774 -2.1041878 49.190626 -2.103947 49.1901823 -2.1036711 49.1897474 -2.1033608 49.1893226 -2.1030171 49.188909 -2.1026408 49.1885077 -2.102233 49.1881199 -2.1017948 49.1877467 -2.1013274 49.187389 -2.1008321 49.1870478 -2.1003103 49.186724 -2.0997633 49.1864186 -2.0991927 49.1861324 -2.0986 49.1858661 -2.0979868 49.1856206 -2.097355 49.1853964 -2.096706 49.1851941 -2.0960419 49.1850145 -2.0953643 49.1848578 -2.0946751 49.1847246 -2.0939762 49.1846152 -2.0932696 49.18453 -2.0925571 49.1844691 -2.0918408 49.1844327 -2.0911225 49.1844209 -2.0904042 49.1844338 -2.089688 49.1844713 -2.0889758 49.1845334 -2.0882695 49.1846197 -2.087571 49.1847302 -2.0868823 49.1848645 -2.0862053 49.1850222 -2.0855418 49.1852029 -2.0848936 49.1854062 -2.0842625 49.1856314 -2.0836503 49.1858779 -2.0830586 49.1861451 -2.082489 49.1864322 -2.0819432 49.1867385 -2.0814225 49.1870631 -2.0809284 49.187405 -2.0804624 49.1877635 -2.0800255 49.1881375 -2.0796192 49.1885259 -2.0792444 49.1889277 -2.0789021 49.1893419 -2.0785935 49.1897672 -2.0783192 49.1902025 -2.07808 49.1906466 -2.0778766 49.1910983 -2.0777096 49.1915564 -2.0775793 49.1920196 -2.0774863 49.1924866 -2.0774306 49.1929562 -2.0774125 49.193427 0 90

Filter

ic <- ee$ImageCollection("COPERNICUS/S2_SR_HARMONIZED")
s2 <- ic$filterBounds(buff)
s2 <- s2$filterDate(start = "2018-01-01", opt_end = "2019-01-01")
s2 <- s2$filter(ee$Filter$lt("CLOUDY_PIXEL_PERCENTAGE", 10))


rgee::ee_get_date_ic(s2) |>
  select(time_start)
            time_start
1  2018-01-22 11:13:42
2  2018-02-21 11:12:02
3  2018-03-13 11:08:26
4  2018-05-07 11:08:35
5  2018-05-17 11:10:20
6  2018-06-26 11:14:13
7  2018-07-11 11:11:39
8  2018-07-21 11:09:39
9  2018-07-26 11:16:15
10 2018-07-31 11:14:37
11 2018-10-09 11:09:42
12 2018-11-18 11:17:32

Plot image

ee <- import("ee")
ee$Initialize()
m <- rgee::Map
m$centerObject(point)
m$addLayer(s2$median()$clip(buff), visParams = list(bands = c("B4", "B3", "B2"), min = 0, max = 1500), name = "2018") 

Side by side…

ic <- ee$ImageCollection("COPERNICUS/S2_SR_HARMONIZED")
s3 <- ic$filterBounds(buff)
s3 <- s3$filterDate(start = "2020-01-01", opt_end = "2023-01-01")
s3 <- s3$filter(ee$Filter$lt("CLOUDY_PIXEL_PERCENTAGE", 10))

#rgee::ee_get_date_ic(s3)

n <- rgee::Map

n$addLayer(s2$median()$clip(buff), visParams = list(bands = c("B4", "B3", "B2"), min = 0, max = 1500), name = "2018") | n$addLayer(s3$median()$clip(buff), visParams = list(bands = c("B4", "B3", "B2"), min = 0, max = 1500), name = "2022")