How to Connect Google Earth Engine with R Shiny
Visualizing spatial data is always more challenging than it seems at first. There are too many moving parts, and the whole thing can quickly slow down your dashboard. Today you'll learn how to connect Google Earth Engine with R Shiny. We'll start by signing up for a free GEE account and configuring everything on the R end.
<blockquote>Want to integrate plain Google Maps in R Shiny dashboards? <a href="https://appsilon.com/interactive-google-maps-with-r-shiny/" target="_blank" rel="noopener">Our detailed google maps guide has you covered</a>.</blockquote>
Table of contents:
<ul><li><a href="#setup">How to Setup Google Earth Engine with R</a></li><li><a href="#gee-map">How to Render a Google Earth Map with R</a></li><li><a href="#gee-shiny">Connect Google Earth Engine with R Shiny - Start Here</a></li><li><a href="#summary">Summary of R Shiny + Google Earth Engine</a></li></ul>
<hr />
<h2 id="setup">How to Setup Google Earth Engine with R</h2>
Before you can connect Google Earth Engine with R Shiny, you'll have to <a href="https://code.earthengine.google.com/" target="_blank" rel="noopener">register for a GEE account</a>. It's completely free, but the registration page states it could take some time for your account to get approved. In our experience registration was a breeze, as we got a confirmation mail seconds after submitting:
<img class="size-full wp-image-12902" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d3ef9202e0e0262557ea_f675d7b1_1-1.webp" alt="Image 1 - Google Earth Engine registration mail" width="1422" height="990" /> Image 1 - Google Earth Engine registration mail
Once that's done, you'll have to install the <code>rgee</code> R package. Now, R isn't officially supported by the Google Earth Engine (only JavaScript and Python), so this package serves as a bridge. It allows you to write R code that essentially boils down to Python behind the scenes.
<blockquote>But how can R call Python code? <a href="https://appsilon.com/use-r-and-python-together/" target="_blank" rel="noopener">We have a complete guide on using R and Python together</a>.</blockquote>
Use the following command to install the <code>rgee</code> package:
<pre>install.packages("rgee")
</pre>
The setup isn't done yet. You'll have to load the package and call the <code>ee_install()</code> function. It will create a Python virtual environment and install all Python dependencies for you. It goes without saying, but you should have Python 3 installed before running the code snippet below:
<pre>library(rgee)
rgee::ee_install()
</pre>
We're using <a href="https://github.com/conda-forge/miniforge" target="_blank" rel="noopener">Miniforge</a>, a minimal distribution of Anaconda, and the above snippet worked without any issues.
The final step in this setup section is to call the <code>ee_Initialize()</code> function. It will do all the heavy lifting for you - initialize the previously created Python virtual environment and install all the required libraries:
<pre><code>library(rgee)
ee_Initialize()
</code></pre>
Here's what you should see in RStudio:
<img class="size-full wp-image-12904" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d3ef29ecb62f89b3162b_50850199_2-1.webp" alt="Image 2 - Initializing Python virtual environment for rgee" width="1258" height="608" /> Image 2 - Initializing Python virtual environment for rgee
After a couple of seconds, a new browser window will open asking you to authenticate with a Google account that is connected with the Google Earth Engine service:
<img class="size-full wp-image-12906" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d3f0eb75c0de9df88029_508800b7_3-1.webp" alt="Image 3 - Authenticating Google account for Python libraries" width="1992" height="1762" /> Image 3 - Authenticating Google account for Python libraries
Once you click on <i>Allow</i>, you will get an authentication code, as shown in the image below:
<img class="size-full wp-image-12908" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d3f1237e4636e90d3a4c_ed4d0f0a_4-1.webp" alt="Image 4 - Google account authentication code" width="1964" height="1652" /> Image 4 - Google account authentication code
And that's it - paste the code into the R console when prompted and hit Enter:
<img class="size-full wp-image-12910" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d3f1fb3d70e0efa0bbe2_99c9c171_5-1.webp" alt="Image 5 - Pasting Google account authentication code in R console" width="1350" height="192" /> Image 5 - Pasting Google account authentication code in the R console
The authentication part is now complete. The only thing left to do is to specify a directory where Google Earth Engine will store everything:
<img class="size-full wp-image-12912" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d3f25c2b4c98eb7f5913_65ce344b_6-1.webp" alt="Image 6 - Google Earth Engine local root directory" width="1310" height="170" /> Image 6 - Google Earth Engine local root directory
Once that's out of the way, you have everything needed to connect Google Earth Engine with R Shiny. Let's see how it works in plain R first.
<h2 id="gee-map">How to Render a Google Earth Map with R</h2>
The hard part is now over and we're ready to have some fun with Google Earth Engine in R. The example you'll see is quite basic, and can be found on the <a href="https://github.com/r-spatial/rgee" target="_blank" rel="noopener">official package GitHub page</a>.
It's sort of a <i>Hello World</i> of Google Earth Engine program in R but will be enough to understand the fundamentals.
First, we'll write a function <code>createTimeBand</code> that adds a band containing image data as years since 1991. Then, we map the time band creation helper over the <a href="https://developers.google.com/earth-engine/datasets/catalog/NOAA_DMSP-OLS_NIGHTTIME_LIGHTS/" target="_blank" rel="noopener">night-time lights collection</a> image dataset.
Finally, we will compute a linear fit over the series of values at each pixel, visualizing the y-intercept in green, and positive/negative slopes in red/blue:
<pre>library(rgee)
createTimeBand <- function(img) {
year <- ee$Date(img$get("system:time_start"))$get("year")$subtract(1991L)
ee$Image(year)$byte()$addBands(img)
}
collection <- ee$
ImageCollection("NOAA/DMSP-OLS/NIGHTTIME_LIGHTS")$
select("stable_lights")$
map(createTimeBand)
col_reduce <- collection$reduce(ee$Reducer$linearFit())
col_reduce <- col_reduce$addBands(
col_reduce$select("scale")
)
ee_print(col_reduce)
</pre>
<img class="size-full wp-image-12914" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d3f388e64fe97f77dbdd_d5f1e33d_7-1.webp" alt="Image 7 - Google Earth Engine program output" width="1330" height="764" /> Image 7 - Google Earth Engine program output
From here, it's easy to create a map. First, we have to center it around some latitude and longitude and give it the value for zoom. Then, we'll overlay the normal Google Earth map with our custom <code>col_reduce</code> layer:
<pre>Map$setCenter(9.08203, 47.39835, 3)
Map$addLayer(
eeObject = col_reduce,
visParams = list(
bands = c("scale", "offset", "scale"),
min = 0,
max = c(0.18, 20, -0.18)
),
name = "stable lights trend"
)
</pre>
Here's what the finished map looks like:
<img class="size-full wp-image-12916" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d3f42210fb3996705be5_5cdf87b5_8-1.webp" alt="Image 8 - Google Earth Engine map in R" width="2624" height="1940" /> Image 8 - Google Earth Engine map in R
That's amazing, but how can we make this map interactive in R Shiny? That's what the next section covers.
<h2 id="gee-shiny">Connect Google Earth Engine with R Shiny - Start Here</h2>
<a href="https://appsilon.com/" target="_blank" rel="noopener">R Shiny</a> is our favorite R package for creating interactive dashboards, so naturally, we want to see if it's possible to connect R Shiny with Google Earth Engine.
<b>Spoiler alert: </b>It is, and the syntax will be near-identical to what we covered in the previous section. There's no <code>renderGoogleEarthEngine</code> function available, unfortunately, so we'll have to use the Leaflet package to render the map.
Our dashboard will have two panels:
<ol><li><code>sidebarPanel</code> - Contains the configurable values for latitude and longitude that update the map on the button click.</li><li><code>mainPanel</code> - Contains the Google Earth Engine map rendered by Leaflet.</li></ol>
Here's the code for the entire Shiny app. There's nothing that you should find unclear if you've read the previous section:
<pre>library(rgee)
library(leaflet)
library(shiny)
createTimeBand <- function(img) {
year <- ee$Date(img$get("system:time_start"))$get("year")$subtract(1991L)
ee$Image(year)$byte()$addBands(img)
}
collection <- ee$
ImageCollection("NOAA/DMSP-OLS/NIGHTTIME_LIGHTS")$
select("stable_lights")$
map(createTimeBand)
col_reduce <- collection$reduce(ee$Reducer$linearFit())
col_reduce <- col_reduce$addBands(
col_reduce$select("scale")
)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
numericInput(inputId = "in_latitude", label = "Latitude", value = 9.08203, min = -90, max = 90, step = 0.1),
numericInput(inputId = "in_longitude", label = "Longitude", value = 47.39835, min = -180, max = 180, step = 0.1),
actionButton(inputId = "reposition", label = "Reposition Map")
),
mainPanel(
leafletOutput(outputId = "map")
)
)
)
server <- function(input, output) {
map <- eventReactive(input$reposition,
{
Map$setCenter(input$in_latitude, input$in_longitude, 3)
Map$addLayer(
eeObject = col_reduce,
visParams = list(
bands = c("scale", "offset", "scale"),
min = 0,
max = c(0.18, 20, -0.18)
),
name = "stable lights trend"
)
},
ignoreNULL = FALSE
)
output$map <- renderLeaflet({
map()
})
}
shinyApp(ui = ui, server = server)
</pre>
<img class="size-full wp-image-12918" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d3f585b6bd7053b63ffd_5f5851a8_9.gif" alt="Image 9 - R Shiny dashboard rendering the Google Earth Engine map" width="952" height="516" /> Image 9 - R Shiny dashboard rendering the Google Earth Engine map
Yes, it's that easy. We've covered a lot of ground, so let's make a short recap next.
<hr />
<h2 id="summary">Summary of R Shiny + Google Earth Engine</h2>
Today you've learned how to connect Google Earth Engine with R Shiny. There are a lot of setups involved, but we hope it wasn't too tedious to follow. You can certainly use Google Earth Engine in your Shiny dashboards to overlay interesting layers around the base map. We went over a simple example, but encourage you to experiment further on your own.
Share your results with us on Twitter - <a href="https://twitter.com/appsilon" target="_blank" rel="noopener">@appsilon</a>. We'd love to see what you come up with.
<blockquote>Want to dive deeper into Leaflet? <a href="https://appsilon.com/leaflet-geomaps/" target="_blank" rel="noopener">Our detailed guide is all you need to make stunning geomaps</a>.</blockquote>