如何将 Thunderforest API 键传递给 R ggspatial 包以创建地图

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

我正在使用 rosmggspatial R 包创建地图。 ggosm 函数易于使用,可以根据提供的空间对象提取底图图层。这是一个例子。

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

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

效果很好。我可以将底图图层更改为其他类型(请参阅 osm.types() 了解可用类型。这里是使用 cartolight 作为底图图层的示例。

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

这也行。现在我的问题是 如何传递 Thunderforest API 密钥?如果我将类型用作 thunderforestoutdoors,我会得到以下输出。

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

显然,我需要 Thunderforest API 密钥,所以我从 https://www.thunderforest.com/. This page (https://www.thunderforest.com/docs/apikeys/ 注册了一个 API 密钥)展示了如何使用 API 密钥。 rosm 的文档还表明,用户可以通过提供 URL(参见 ?as.tile_source)来定义地图图块。尽管如此,URL 的一般结构似乎是:https://{s}.tile.thunderforest.com/outdoors/{z}/{x}/{y}.png?apikey=<insert-your-apikey-here>。我需要知道 zxy(缩放级别和图块编号)来指定图块。这是不可能的,因为我有很多空间对象要绘制,我需要 ggosm 来为我确定正确的缩放级别和图块。如果有人能对此有所了解,那就太好了。

目前似乎没有办法使用 ggspatial 或 rosm 来执行此操作。 So, I forked rosm 并修改了其中一个函数以包含 api 键(如果在您的环境中找到了它)。

短期解决方案

您可以只使用分叉的仓库。

# Packages
devtools::install_github("jonathande4/rosm")
library(rosm)
library(ggspatial)

# Set environment.
Sys.setenv("THUNDERFOREST_KEY" = "YOUR_API_KEY")

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

输出这张地图,没有水印。

长期解决方案

我想尝试提交此更改的拉取请求。如果实施中有任何偏离原始解决方案的更改,我将 post 进行更新。

希望对您有所帮助。

解决方案:

Chuckle - 有一种方法可以使用 rosm 无需 修改库.

  • 使用rosm:: source_from_url_format()函数。这就是它的设计目的,它记录在 rosm 包中。 [诚然有点简短]

注意 - 为了完整起见,我在单独的后续项目符号下介绍了如何在使用共享代码时隐藏 public API 密钥。

我希望这会有所帮助,它至少应该让那些想要在不需要修改库的情况下执行您的建议的人更容易。

保重 T.

用法示例:source_from_url_format()

注意:用您在 Thunderforest 网站上的私钥替换 <insert key>

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")

示例运行时输出:

> 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!

输出图:

从 public 代码

中隐藏您的 Thunderforest API 密钥

一个单独但相关的问题是如何从 public 代码中隐藏 API 密钥。推荐的方法是将 API 密钥添加到 ~/.Renviron 文件。

THUNDERFOREST_API_KEY="<insert api key"`

我们也通过调用获取环境变量:

Sys.getenv("THUNDERFOREST_API_KEY")

现在我们可以从 R 程序中调用它,如下所示:

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")

执行的代码

使用此示例可以更轻松地共享您的代码。 发布的代码中不需要包含密钥 ;-)

> 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

输出图: