2

我正在使用rosmand ggspatialR 包创建地图。该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 密钥?如果我使用类型 as thunderforestoutdoors,我得到以下输出。

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

在此处输入图像描述

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

4

2 回答 2

2

解决方案:

Chuckle - 有一种方法可以在不 修改库的情况下使用 rosm 做到这一点

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

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

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

保重T。

示例用法:source_from_url_format()

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

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!

输出图:

在此处输入图像描述

从公共代码中隐藏您的 Thunderforest API 密钥

一个单独但相关的问题是您应该如何从公共代码中隐藏您的 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

输出图:

在此处输入图像描述

于 2017-10-24T04:26:45.133 回答
2

目前似乎没有办法用 ggspatial 或 rosm 做到这一点。因此,我分叉了 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")

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

输出

长期解决方案

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

希望有帮助。

于 2017-10-21T14:29:11.573 回答