我已成功使用以下方法下载 OSM 切片:
for (zoom in 8:9)
GetMapTiles(lonR = xlim, latR = ylim, zoom = zoom, nTiles = round(c(20,20)/(17-zoom)),
verbose = 1, type = "osm", tileDir = "mapTiles/OSM/", CheckExistingFiles = TRUE)
我可以使用以下方法让它们闪亮显示:
# Start serving working folder on port 8000 in demon mode
deamon_id <- servr::httd(dir = "mapTiles", port = 8000, daemon = TRUE)
# Plot with leaflet
#shiny ui
ui = fluidPage(leafletOutput("map"))
#create basic map, load tiles from directory and set view to centre of downloaded tiles
server = function(input, output, server){
addResourcePath("mytiles", "mapTiles")
# m = leaflet() %>%
# addTiles( urlTemplate = "http:/localhost:8000/C:/GitHub/culturalmapper/mapTiles/OSM/{z}_{x}_{y}.png")
output$map = renderLeaflet({
leaflet() %>%
addTiles(urlTemplate = "/mytiles/OSM/{z}_{x}_{y}.png") %>%
setView(115.6, -31.63, zoom = 8)
})
}
但我还想下载 ESRI 世界图像图块以离线显示。 (就像将其添加到传单地图中一样):
addProviderTiles('Esri.WorldImagery')
这是我能找到的唯一一个有人下载 ESRI 切片以离线使用的示例。但他没有显示下载图块的代码,只显示它们。
我有一段时间没有这样做了,但我找到了我的旧代码,稍微编辑了一下,它似乎仍然有效。它需要
RgoogleMaps
包以及 jpeg
和 png
。
本质上,我从
RgoogleMaps::GetMapTiles
获取了代码,只是对其进行了一些修改以与https://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer一起使用。就像我说的,我不久前就这样做了,所以现在 RgoogleMaps::GetMapTiles
中的代码可能略有不同。但是,如果您对函数参数有疑问,那么您应该查看这里 (?RgoogleMaps::GetMapTiles
)。
这是该函数的代码(确保您拥有所需的三个包)。
library(RgoogleMaps)
getmaptiles <- function (center = c(lat = 52.431635, lon = 13.194773),
lonR, latR,
nTiles = c(3, 3), zoom = 13,
urlBase = "http://services.arcgisonline.com/arcgis/rest/services/World_Topo_Map/MapServer",
CheckExistingFiles = TRUE,
TotalSleep = NULL, tileExt = ".png",
tileDir= "~/mapTiles/WorldTopoMap/",
returnTiles = FALSE, verbose = 1)
{
require(png)
require(jpeg)
if (is.character(center)) {
if (verbose)
cat("geocoding ", center, "\n")
center = getGeoCode(center, verbose)
if (verbose)
cat("result:", center, "\n")
}
if (all(c("lat", "lon") %in% names(center)))
center = center[c("lat", "lon")]
else names(center) = c("lat", "lon")
fakeZoom = zoom
if (!missing(lonR) & !missing(latR)) {
XYmin = RgoogleMaps::LatLon2XY(lat = latR[1], lon = lonR[1], zoom = zoom)
XYmax = RgoogleMaps::LatLon2XY(lat = latR[2], lon = lonR[2], zoom = zoom)
nTiles[1] = abs(XYmax$Tile[1, 1] - XYmin$Tile[1, 1]) +
1
nTiles[2] = abs(XYmax$Tile[1, 2] - XYmin$Tile[1, 2]) +
1
center = c(lat = mean(latR), lon = mean(lonR))
if (verbose) {
cat("nTiles=", nTiles, ", center=", round(center,
3), "\n")
}
}
XY = RgoogleMaps::LatLon2XY(lat = center["lat"], lon = center["lon"],
zoom = zoom)
tileXY = XY$Tile + as.numeric(XY$Coords > 256)
if (nTiles[1]%%2 == 0) {
X = (tileXY[1, 1] - nTiles[1]/2):(tileXY[1, 1] + nTiles[1]/2 -
1)
}
else {
X = (tileXY[1, 1] - (nTiles[1] - 1)/2):(tileXY[1, 1] +
(nTiles[1] - 1)/2)
}
if (nTiles[2]%%2 == 0) {
Y = (tileXY[1, 2] - nTiles[2]/2):(tileXY[1, 2] + nTiles[2]/2 -
1)
}
else {
Y = (tileXY[1, 2] - (nTiles[2] - 1)/2):(tileXY[1, 2] +
(nTiles[2] - 1)/2)
}
if (verbose > 1)
browser()
if (!dir.exists(tileDir)) {
if (verbose)
cat("trying to create dir", tileDir, "\n")
dir.create(tileDir, recursive = TRUE)
}
if (CheckExistingFiles)
ExistingFiles = list.files(path = tileDir)
NumTiles = length(X) * length(Y)
if (verbose)
cat(NumTiles, "tiles to download \n")
DOWNLOAD = TRUE
k = 1
tiles = list()
for (x in X) {
for (y in Y) {
if(is.null(urlBase)){
cat("Not downloading any tiles. No url provided. \n")
}
else if (grepl("ESRI", urlBase)) {
url <- paste0(urlBase, zoom, "/", x, "/", y, ".jpeg")
}
else if (grepl("openstreetmap", urlBase)) {
url <- paste0(urlBase, zoom, "/", x, "/", y, ".png")
}
else if (grepl("google", urlBase)) {
url <- paste0(urlBase, "&x=", x, "&y=", y, "&z=", zoom)
}
else if (grepl("arcgis", urlBase)) {
url <- paste0(urlBase, "/tile/", zoom, "/", x, "/", y)
}
f = paste(zoom, x, y, sep = "_")
if (CheckExistingFiles)
if (paste0(f, tileExt) %in% ExistingFiles) {
if (verbose)
cat("NOT downloading existing file ", f,
tileExt, "\n", sep = "")
DOWNLOAD = FALSE
}
else {
DOWNLOAD = TRUE
}
destfile = file.path(tileDir, f)
mapFile = paste0(destfile, tileExt)
if (DOWNLOAD) {
if (!is.null(TotalSleep)) {
Sys.sleep(round(runif(1, max = 2 * TotalSleep/NumTiles),
1))
}
if(is.null(urlBase)){ ######################################
NULL
} else {
download.file(url, mapFile, mode = "wb", quiet = TRUE)
}###########################################################
}
if (returnTiles) {
res = try(readPNG(mapFile, native = TRUE))
if (class(res) == "try-error") {
res = try(readJPEG(mapFile, native = TRUE))
}
else if (class(res) == "try-error") {
download.file(url, mapFile, mode = "w", quiet = TRUE)
}
else tiles[[k]] = res
}
k = k + 1
}
}
mt = list(X = X, Y = Y, zoom = zoom, tileDir = tileDir, tileExt = tileExt,
tiles = tiles)
class(mt) = "mapTiles"
invisible(mt)
}
这是从给定的
urlBase
下载一些地图图块到我的工作目录的 tileDir
子文件夹中的示例。
getmaptiles(center = c(lat = 52.431635, lon = 13.194773),
#lonR, latR,
nTiles = c(3, 3), zoom = 13,
urlBase = "http://services.arcgisonline.com/arcgis/rest/services/World_Topo_Map/MapServer",
CheckExistingFiles = FALSE,
TotalSleep = NULL, tileExt = ".jpg",
tileDir= "~/mapTiles/WorldTopoMap/",
returnTiles = FALSE, verbose = 1)
如果您想直接下载特定的地图图块,类似这样的方法可能会起作用。
download.file("http://services.arcgisonline.com/arcgis/rest/services/World_Topo_Map/MapServer/tile/13/4397/2690",
"~/mapTiles/WorldTopoMap//13_4397_2690.jpg", mode = "wb")