Skip to content

Commit 1652ae2

Browse files
committed
- Adapted as per changes suggested in rstudio/leaflet/#294.
1 parent c09299e commit 1652ae2

File tree

14 files changed

+5401
-5622
lines changed

14 files changed

+5401
-5622
lines changed

NAMESPACE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ export(colorFactor)
5252
export(colorNumeric)
5353
export(colorQuantile)
5454
export(createLeafletMap)
55-
export(crs)
5655
export(dispatch)
5756
export(fitBounds)
5857
export(hideGroup)
@@ -63,6 +62,7 @@ export(labelFormat)
6362
export(labelOptions)
6463
export(layersControlOptions)
6564
export(leaflet)
65+
export(leafletCRS)
6666
export(leafletMap)
6767
export(leafletOutput)
6868
export(leafletProxy)

R/layers.R

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ clearImages = function(map) {
242242
#' minZoom,maxZoom,maxNativeZoom,tileSize,subdomains,errorTileUrl,tms,continuousWorld,noWrap,zoomOffset,zoomReverse,zIndex,unloadInvisibleTiles,updateWhenIdle,detectRetina,reuseTiles
243243
#' the tile layer options; see
244244
#' \url{http://leafletjs.com/reference.html#tilelayer}
245+
#' @param ... extra options passed to underlying Javascript object constructor.
245246
#' @describeIn map-options Options for tile layers
246247
#' @export
247248
tileOptions = function(
@@ -261,8 +262,8 @@ tileOptions = function(
261262
unloadInvisibleTiles = NULL,
262263
updateWhenIdle = NULL,
263264
detectRetina = FALSE,
264-
reuseTiles = FALSE
265-
# bounds = TODO
265+
reuseTiles = FALSE,
266+
...
266267
) {
267268
list(
268269
minZoom = minZoom, maxZoom = maxZoom, maxNativeZoom = maxNativeZoom,
@@ -271,7 +272,8 @@ tileOptions = function(
271272
zoomOffset = zoomOffset, zoomReverse = zoomReverse, opacity = opacity,
272273
zIndex = zIndex, unloadInvisibleTiles = unloadInvisibleTiles,
273274
updateWhenIdle = updateWhenIdle, detectRetina = detectRetina,
274-
reuseTiles = reuseTiles
275+
reuseTiles = reuseTiles,
276+
...
275277
)
276278
}
277279

@@ -333,8 +335,6 @@ addWMSTiles = function(
333335
#' @param version version of the WMS service to use
334336
#' @param crs Coordinate Reference System to use for the WMS requests, defaults
335337
#' to map CRS (don't change this if you're not sure what it means)
336-
#' @param ... other tile options for \code{WMSTileOptions()} (all arguments of
337-
#' \code{tileOptions()} can be used)
338338
#' @describeIn map-options Options for WMS tile layers
339339
#' @export
340340
WMSTileOptions = function(
@@ -398,12 +398,13 @@ popupOptions = function(
398398
# autoPanPadding = TODO,
399399
zoomAnimation = TRUE,
400400
closeOnClick = NULL,
401-
className = ""
401+
className = "",
402+
...
402403
) {
403404
list(
404405
maxWidth = maxWidth, minWidth = minWidth, maxHeight = maxHeight,
405406
autoPan = autoPan, keepInView = keepInView, closeButton = closeButton,
406-
zoomAnimation = zoomAnimation, closeOnClick = closeOnClick, className = className
407+
zoomAnimation = zoomAnimation, closeOnClick = closeOnClick, className = className, ...
407408
)
408409
}
409410

@@ -451,13 +452,14 @@ labelOptions = function(
451452
textsize = "10px",
452453
textOnly = FALSE,
453454
style = NULL,
454-
zoomAnimation = TRUE
455+
zoomAnimation = TRUE,
456+
...
455457
) {
456458
list(
457459
clickable = clickable, noHide = noHide, direction = direction,
458460
opacity = opacity, offset = offset,
459461
textsize = textsize, textOnly = textOnly, style = style,
460-
zoomAnimation = zoomAnimation, className = className
462+
zoomAnimation = zoomAnimation, className = className, ...
461463
)
462464
}
463465

@@ -731,12 +733,13 @@ markerOptions = function(
731733
zIndexOffset = 0,
732734
opacity = 1.0,
733735
riseOnHover = FALSE,
734-
riseOffset = 250
736+
riseOffset = 250,
737+
...
735738
) {
736739
list(
737740
clickable = clickable, draggable = draggable, keyboard = keyboard,
738741
title = title, alt = alt, zIndexOffset = zIndexOffset, opacity = opacity,
739-
riseOnHover = riseOnHover, riseOffset = riseOffset
742+
riseOnHover = riseOnHover, riseOffset = riseOffset, ...
740743
)
741744
}
742745

@@ -865,11 +868,12 @@ pathOptions = function(
865868
lineJoin = NULL,
866869
clickable = TRUE,
867870
pointerEvents = NULL,
868-
className = ""
871+
className = "",
872+
...
869873
) {
870874
list(
871875
lineCap = lineCap, lineJoin = lineJoin, clickable = clickable,
872-
pointerEvents = pointerEvents, className = className
876+
pointerEvents = pointerEvents, className = className, ...
873877
)
874878
}
875879

@@ -1094,9 +1098,10 @@ addLayersControl = function(map,
10941098
#' to have the layers control always appear in its expanded state.
10951099
#' @param autoZIndex if \code{TRUE}, the control will automatically maintain
10961100
#' the z-order of its various groups as overlays are switched on and off.
1101+
#' @param ... other options for \code{layersControlOptions()}
10971102
#' @export
1098-
layersControlOptions = function(collapsed = TRUE, autoZIndex = TRUE) {
1099-
list(collapsed = collapsed, autoZIndex = autoZIndex)
1103+
layersControlOptions = function(collapsed = TRUE, autoZIndex = TRUE, ...) {
1104+
list(collapsed = collapsed, autoZIndex = autoZIndex, ...)
11001105
}
11011106

11021107
#' @rdname addLayersControl

R/leaflet.R

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,24 @@
1919
#' @param width the width of the map
2020
#' @param height the height of the map
2121
#' @param padding the padding of the map
22-
#' @param mapOptions the map options
22+
#' @param options the map options
2323
#' @return A HTML widget object, on which we can add graphics layers using
2424
#' \code{\%>\%} (see examples).
2525
#' @example inst/examples/leaflet.R
2626
#' @export
2727
leaflet = function(data = NULL, width = NULL, height = NULL,
28-
padding = 0, mapOptions = list()) {
28+
padding = 0, options = list()) {
2929

3030
# Validate the CRS if specified
31-
if(!is.null(mapOptions[['crs']]) &&
32-
!inherits(mapOptions[['crs']], 'leaflet_crs')) {
33-
stop("CRS in mapOptions should be a return value of crs() function")
31+
if(!is.null(options[['crs']]) &&
32+
!inherits(options[['crs']], 'leaflet_crs')) {
33+
stop("CRS in mapOptions should be a return value of leafletCRS() function")
3434
}
3535

3636
htmlwidgets::createWidget(
3737
'leaflet',
3838
structure(
39-
list(options = mapOptions),
39+
list(options = options),
4040
leafletData = data
4141
),
4242
width = width, height = height,
@@ -72,10 +72,6 @@ getMapData = function(map) {
7272
attr(map$x, "leafletData", exact = TRUE)
7373
}
7474

75-
getMapOptions = function(map) {
76-
attr(map$x, "options", exact = TRUE)
77-
}
78-
7975
#' Set options on a leaflet map object
8076
#'
8177
#' @param map A map widget object created from \code{\link{leaflet}()}
@@ -126,7 +122,7 @@ crsClasses <- list( 'L.CRS.EPSG3857', 'L.CRS.EPSG4326', 'L.CRS.EPSG3395',
126122
#' @param tileSize Tile size, in pixels, to use in this CRS (Default 256)
127123
#' Only needed when crsClass = 'L.Proj.CRS.TMS'
128124
#' @export
129-
crs <- function(
125+
leafletCRS <- function(
130126
crsClass = 'L.CRS.EPSG3857',
131127
code = NULL,
132128
proj4def = NULL,

inst/examples/polarProjections.R

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
#' ---
2+
#' title: "Polar Maps in Leaflet"
3+
#' author: "Bhaskar V. Karambelkar"
4+
#' ---
5+
6+
library(leaflet)
7+
8+
#' ## Artic Projections
9+
10+
#' There is a [polarmap.js](http://webmap.arcticconnect.org/)
11+
#' leaflet plugin available, but that one is not easy to integrate in to the R package.<br/>
12+
#' But thankfully it does provide Tiles in different projections
13+
#' which can be used with Proj4Leaflet.
14+
#' In all it supports 6 projections and corresponding tile layers.
15+
#' <br/>
16+
#' The polarmap.js supports only Artic data, for Antartica see the end of this document.
17+
18+
19+
#' All these numbers and calculations come from the polarmap.js plugin, specifically from these files
20+
#'
21+
#' - http://webmap.arcticconnect.org/polarmap.js/dist/polarmap-src.js
22+
#' - http://webmap.arcticconnect.org/tiles.html
23+
#' - http://webmap.arcticconnect.org/usage.html
24+
#'
25+
extent <- 11000000 + 9036842.762 + 667
26+
origin = c(-extent, extent)
27+
maxResolution <- ((extent - -extent) / 256)
28+
center <- c(90,0)
29+
defZoom <- 4
30+
bounds <- list(c(-extent, extent),c(extent, -extent))
31+
minZoom <- 0
32+
maxZoom <- 18
33+
resolutions <- purrr::map_dbl(minZoom:maxZoom,function(x) maxResolution/(2^x))
34+
35+
# 6 Projection EPSG Codes
36+
projections <- c('3571', '3572', '3573', '3574', '3575', '3576')
37+
# Corresponding proj4defs codes for each projection
38+
proj4defs <- list(
39+
'3571' = '+proj=laea +lat_0=90 +lon_0=180 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs',
40+
'3572' = '+proj=laea +lat_0=90 +lon_0=-150 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs',
41+
'3573' = '+proj=laea +lat_0=90 +lon_0=-100 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs',
42+
'3574' = '+proj=laea +lat_0=90 +lon_0=-40 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs',
43+
'3575' = '+proj=laea +lat_0=90 +lon_0=10 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs',
44+
'3576' = '+proj=laea +lat_0=90 +lon_0=90 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs'
45+
)
46+
47+
# create a CRS instance for each projection
48+
crses <- purrr::map(projections, function(code) {
49+
leafletCRS(
50+
crsClass = 'L.Proj.CRS',
51+
code = sprintf("EPSG:%s",code),
52+
proj4def = proj4defs[[code]],
53+
origin = origin,
54+
resolutions = resolutions,
55+
bounds = bounds
56+
)
57+
})
58+
59+
# Tile URL Template for each projection
60+
tileURLtemplates <- purrr::map(projections, function(code) {
61+
sprintf('http://{s}.tiles.arcticconnect.org/osm_%s/{z}/{x}/{y}.png',
62+
code)
63+
})
64+
65+
# We can't add all 6 tiles to our leaflet map,
66+
# because each one is in a different projection,
67+
# and you can have only one projection per map in Leaflet.
68+
# So we create 6 maps.
69+
polarmaps <- purrr::map2(crses, tileURLtemplates,
70+
function(crs, tileURLTemplate) {
71+
leaflet(options= list(crs=crs, zoom=defZoom, center = center)) %>%
72+
addTiles(urlTemplate = tileURLTemplate,
73+
attribution = "Map © ArcticConnect. Data © OpenStreetMap contributors",
74+
options = tileOptions(subdomains = "abc", noWrap = TRUE,
75+
continuousWorld = FALSE))
76+
})
77+
78+
#' #### EPSG:3571
79+
polarmaps[[1]] %>%
80+
addGraticule()
81+
82+
#' #### EPSG:3572
83+
polarmaps[[2]]
84+
85+
#' #### EPSG:3573
86+
polarmaps[[3]]
87+
88+
#' #### EPSG:3574
89+
polarmaps[[4]]
90+
91+
#' #### EPSG:3575
92+
polarmaps[[5]]
93+
94+
#' #### EPSG:3576
95+
polarmaps[[6]]
96+
97+
#' ## Antartica
98+
#' ### NOT YET WORKING
99+
#' Code adapted from
100+
#' https://github.com/nasa-gibs/gibs-web-examples/blob/release/examples/leaflet/antarctic-epsg3031.js <br/>
101+
#' This should work in theory but not working yet.
102+
103+
resolutions <- c(8192, 4096, 2048, 1024, 512, 256)
104+
center <- c(-90,0)
105+
zoom <- 0
106+
maxZoom <- 5
107+
108+
crsAntartica <- leafletCRS(
109+
crsClass = 'L.Proj.CRS',
110+
code = 'EPSG:3031',
111+
proj4def = '+proj=stere +lat_0=-90 +lat_ts=-71 +lon_0=0 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs',
112+
resolutions = resolutions,
113+
origin = c(-4194304, 4194304),
114+
bounds = list( c(-4194304, -4194304), c(4194304, 4194304) )
115+
)
116+
117+
antarticaTilesURL <- "//map1{s}.vis.earthdata.nasa.gov/wmts-antarctic/MODIS_Aqua_CorrectedReflectance_TrueColor/default/2014-12-01/EPSG3031_250m/{z}/{y}/{x}.jpg"
118+
119+
leaflet(options= list(
120+
crs=crsAntartica,
121+
zoom=zoom, maxZoom=maxZoom, center= center,
122+
continuousWorld = TRUE, worldCopyJump = FALSE)) %>%
123+
setView(-90,0,0) %>%
124+
addTiles(urlTemplate = antarticaTilesURL,
125+
layerId = "antartica_tiles",
126+
attribution = "<a href='https://earthdata.nasa.gov/gibs'> NASA EOSDIS GIBS</a>&nbsp;&nbsp;&nbsp; <a href='https://github.com/nasa-gibs/web-examples/blob/release/leaflet/js/antarctic-epsg3031.js'> View Source </a>",
127+
options = tileOptions(
128+
tileSize =512,
129+
subdomains = "abc",
130+
noWrap = TRUE,
131+
continuousWorld = TRUE,
132+
format = "image%2Fjpeg"
133+
)) %>%
134+
htmlwidgets::onRender(
135+
"function(el, t){
136+
var myMap = this;
137+
debugger;
138+
var tileLayer = myMap.layerManager._byLayerId['tile\\nantartica_tiles'];
139+
140+
// HACK: BEGIN
141+
// Leaflet does not yet handle these kind of projections nicely. Monkey
142+
// patch the getTileUrl function to ensure requests are within
143+
// tile matrix set boundaries.
144+
var superGetTileUrl = tileLayer.getTileUrl;
145+
146+
tileLayer.getTileUrl = function(coords) {
147+
debugger;
148+
var max = Math.pow(2, tileLayer._getZoomForUrl() + 1);
149+
if ( coords.x < 0 ) { return ''; }
150+
if ( coords.y < 0 ) { return ''; }
151+
if ( coords.x >= max ) { return ''; }
152+
if ( coords.y >= max ) { return ''; }
153+
return superGetTileUrl.call(tileLayer, coords);
154+
};
155+
// HACK: END
156+
}")

0 commit comments

Comments
 (0)