Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass Thunderforest API key to the R ggspatial package to create a map

I am creating maps using the rosm and ggspatial R package. The ggosm function is easy to use to extract a base map layer based on the spatial object provided. Here is an example.

library(ggplot2)
library(sp)
library(rosm)
library(ggspatial)

ggosm() + 
  geom_spatial(longlake_waterdf, fill = NA, color = "black")

enter image description here

This works great. I can change the base map layer to other types (See osm.types() for available types. Here is an example to use cartolight as the base map layer.

ggosm(type = "cartolight") + 
  geom_spatial(longlake_waterdf, fill = NA, color = "black")

enter image description here

This also works. Now my question is how to pass Thunderforest API key? If I used the type as thunderforestoutdoors, I got the following output.

ggosm(type = "thunderforestoutdoors") + 
  geom_spatial(longlake_waterdf, fill = NA, color = "black")

enter image description here

Clearly, I need the Thunderforest API key, so I have registered an API key from https://www.thunderforest.com/. This page (https://www.thunderforest.com/docs/apikeys/) shows how to use the API key. The documentation of rosm also shows that users can define map tiles by providing the URL (See ?as.tile_source). Nevertheless, it seems like the general structure of URL is like: https://{s}.tile.thunderforest.com/outdoors/{z}/{x}/{y}.png?apikey=<insert-your-apikey-here>. I will need to know the z, x, and y (zoom level and tile number) to specify the tile. It is not possible because I have a lot of spatial objects to plot and I need ggosm to determine the right zoom level and tiles for me. It would be great if anyone can shed some light on this.

like image 626
www Avatar asked Sep 07 '25 12:09

www


1 Answers

Solution:

Chuckle - There is a way to do this do this with rosm without modifying the library.

  • Use the rosm:: source_from_url_format() function. This is what it was designed to do, it is documented in the rosm package. [Admittedly somewhat briefly]

Note - I cover how to hide your public API key when using shared code under a separate follow-on bullet for completeness.

I hope this helps, it should at the very least make it easier for those who want to do what you propose without requiring library modifications.

Take Care T.

Example Usage: source_from_url_format()

Note: Replace <insert key> with your private key from the Thunderforest website.

if (!require(ggplot2)) install.packages("ggplot2")
if (!require(rosm)) install.packages("rosm")
if (!require(ggspatial)) install.packages("ggspatial")
if (!require(sp)) install.packages("sp")

thunderforest = source_from_url_format(
  url_format = c('http://a.tile.thunderforest.com/landscape/${z}/${x}/${y}.png?apikey=<insert key>',
                 'http://b.tile.thunderforest.com/landscape/${z}/${x}/${y}.png?apikey=<insert key>',
                 'http://c.tile.thunderforest.com/landscape/${z}/${x}/${y}.png?apikey=<insert key>'),
  attribution = "More on Thunderforest at http://www.thunderforest.com/"
)

ggosm(type = thunderforest) + 
  geom_spatial(longlake_waterdf, fill = NA, color = "black")

Example Runtime output:

> if (!require(ggplot2)) install.packages("ggplot2")
> if (!require(rosm)) install.packages("rosm")
> if (!require(ggspatial)) install.packages("ggspatial")
> if (!require(sp)) install.packages("sp")
> thunderforest = source_from_url_format(

+   url_format = c('http://a.tile.thunderforest.com/landscape/${z}/${x}/${y}.png?apikey=<secret>',
+                  'http://b.tile.thunderforest.com/landscape/${z}/${x}/${y}.png?apikey=<secret>',
+                  'http://c.tile.thunderforest.com/landscape/${z}/${x}/${y}.png?apikey=<secret>'),
+   attribution = "More on Thunderforest at http://www.thunderforest.com/"
+ )
> ggosm(type = thunderforest) + 
+   geom_spatial(longlake_waterdf, fill = NA, color = "black")
Converting coordinates to lat/lon (epsg:4326)
Zoom: 15
Fetching 4 missing tiles
  |===================================================================================================================================| 100%
...complete!

Output Plot:

enter image description here

Hide your Thunderforest API Key from public Code

A separate but related problem is how you should hide your API key from your public code. The recommended approach is to add your API key to your ~/.Renviron file.

THUNDERFOREST_API_KEY="<insert api key"`

we retrieve the environment variable via a call too:

Sys.getenv("THUNDERFOREST_API_KEY")

now we can invoke this from within an R program as follows:

if (!require(ggplot2)) install.packages("ggplot2")
if (!require(rosm)) install.packages("rosm")
if (!require(ggspatial)) install.packages("ggspatial")
if (!require(sp)) install.packages("sp")

thunderforest = source_from_url_format(
  url_format = c(paste0('http://a.tile.thunderforest.com/landscape/${z}/${x}/${y}.png?apikey=',Sys.getenv("THUNDERFOREST_API_KEY")),
                 paste0('http://b.tile.thunderforest.com/landscape/${z}/${x}/${y}.png?apikey=',Sys.getenv("THUNDERFOREST_API_KEY")),
                 paste0('http://c.tile.thunderforest.com/landscape/${z}/${x}/${y}.png?apikey=',Sys.getenv("THUNDERFOREST_API_KEY"))),
  attribution = "More on Thunderforest at http://www.thunderforest.com/"
)

ggosm(type = thunderforest) +
  geom_spatial(longlake_waterdf, fill = NA, color = "black")

Executed Code

Using this example it is much easier to share your code. No keys need to be included in the published code ;-)

> if (!require(ggplot2)) install.packages("ggplot2")
> if (!require(rosm)) install.packages("rosm")
> if (!require(ggspatial)) install.packages("ggspatial")
> if (!require(sp)) install.packages("sp")    
> thunderforest = source_from_url_format(

+   url_format = c(paste0('http://a.tile.thunderforest.com/landscape/${z}/${x}/${y}.png?apikey=',Sys.getenv("THUNDERFOREST_API_KEY")),
+                  paste0('http://b.tile.thunderforest.com/landscape/${z}/${x}/${y}.png?apikey=',Sys.getenv("THUNDERFOREST_API_KEY")),
+                  paste0('http://c.tile.thunderforest.com/landscape/${z}/${x}/${y}.png?apikey=',Sys.getenv("THUNDERFOREST_API_KEY"))),
+   attribution = "More on Thunderforest at http://www.thunderforest.com/"
+ )
> ggosm(type = thunderforest) +
+   geom_spatial(longlake_waterdf, fill = NA, color = "black")
Converting coordinates to lat/lon (epsg:4326)
Zoom: 15

Output Plot:

enter image description here

like image 161
Technophobe01 Avatar answered Sep 10 '25 02:09

Technophobe01