Skip to content

Commit d6918ce

Browse files
authored
Merge pull request #385 from rstudio/joe/feature/groupzoom
Ability to show/hide layer groups based on zoom level
2 parents 9275d66 + a5d3f2c commit d6918ce

File tree

7 files changed

+198
-12
lines changed

7 files changed

+198
-12
lines changed

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ export(expandLimitsBbox)
107107
export(filterNULL)
108108
export(fitBounds)
109109
export(getMapData)
110+
export(groupOptions)
110111
export(hideGroup)
111112
export(highlightOptions)
112113
export(iconList)

NEWS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
leaflet 1.1.1
2+
--------------------------------------------------------------------------------
3+
4+
* Add `groupOptions` parameter, currently the only option is letting you specify
5+
zoom levels at which a group should be visible.
6+
17
leaflet 1.1.0
28
--------------------------------------------------------------------------------
39

R/layers.R

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,40 @@ hideGroup <- function(map, group) {
9898
invokeMethod(map, getMapData(map), 'hideGroup', group)
9999
}
100100

101+
#' Set options on layer groups
102+
#'
103+
#' Change options on layer groups. Currently the only option is to control what
104+
#' zoom levels a layer group will be displayed at. The \code{zoomLevels} option
105+
#' is not compatible with \link[=addLayersControl]{layers control}; do not both
106+
#' assign a group to zoom levels and use it with \code{addLayersControl}.
107+
#'
108+
#' @param map the map to modify
109+
#' @param group character vector of one or more group names to set options on
110+
#' @param zoomLevels numeric vector of zoom levels at which group(s) should be
111+
#' visible, or \code{TRUE} to display at all zoom levels
112+
#'
113+
#' @examples
114+
#' pal <- colorQuantile("YlOrRd", quakes$mag)
115+
#'
116+
#' leaflet() %>%
117+
#' # Basic markers
118+
#' addTiles(group = "basic") %>%
119+
#' addMarkers(data = quakes, group = "basic") %>%
120+
#' # When zoomed in, we'll show circles at the base of each marker whose
121+
#' # radius and color reflect the magnitude
122+
#' addProviderTiles(providers$Stamen.TonerLite, group = "detail") %>%
123+
#' addCircleMarkers(data = quakes, group = "detail", fillOpacity = 0.5,
124+
#' radius = ~mag * 5, color = ~pal(mag), stroke = FALSE) %>%
125+
#' # Set the detail group to only appear when zoomed in
126+
#' groupOptions("detail", zoomLevels = 7:18)
127+
#'
128+
#' @export
129+
groupOptions <- function(map, group, zoomLevels = NULL) {
130+
invokeMethod(map, getMapData(map), 'setGroupOptions', group,
131+
list(zoomLevels = zoomLevels)
132+
)
133+
}
134+
101135
#' Graphics elements and layers
102136
#'
103137
#' Add graphics elements and layers to the map widget.

inst/htmlwidgets/leaflet.js

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,6 +1023,15 @@ var LayerManager = function () {
10231023
});
10241024
return result;
10251025
}
1026+
}, {
1027+
key: "getAllGroupNames",
1028+
value: function getAllGroupNames() {
1029+
var result = [];
1030+
_jquery2.default.each(this._groupContainers, function (k, v) {
1031+
result.push(k);
1032+
});
1033+
return result;
1034+
}
10261035
}, {
10271036
key: "clearGroup",
10281037
value: function clearGroup(group) {
@@ -1930,6 +1939,49 @@ methods.showGroup = function (group) {
19301939
});
19311940
};
19321941

1942+
function setupShowHideGroupsOnZoom(map) {
1943+
if (map.leafletr._hasInitializedShowHideGroups) {
1944+
return;
1945+
}
1946+
map.leafletr._hasInitializedShowHideGroups = true;
1947+
1948+
function setVisibility(layer, visible) {
1949+
if (visible !== map.hasLayer(layer)) {
1950+
if (visible) map.addLayer(layer);else map.removeLayer(layer);
1951+
}
1952+
}
1953+
1954+
function showHideGroupsOnZoom() {
1955+
if (!map.layerManager) return;
1956+
1957+
var zoom = map.getZoom();
1958+
map.layerManager.getAllGroupNames().forEach(function (group) {
1959+
var layer = map.layerManager.getLayerGroup(group, false);
1960+
if (layer && typeof layer.zoomLevels !== "undefined") {
1961+
setVisibility(layer, layer.zoomLevels === true || layer.zoomLevels.indexOf(zoom) >= 0);
1962+
}
1963+
});
1964+
}
1965+
1966+
map.showHideGroupsOnZoom = showHideGroupsOnZoom;
1967+
map.on("zoomend", showHideGroupsOnZoom);
1968+
}
1969+
1970+
methods.setGroupOptions = function (group, options) {
1971+
var _this8 = this;
1972+
1973+
_jquery2.default.each((0, _util.asArray)(group), function (i, g) {
1974+
var layer = _this8.layerManager.getLayerGroup(g, true);
1975+
// This slightly tortured check is because 0 is a valid value for zoomLevels
1976+
if (typeof options.zoomLevels !== "undefined" && options.zoomLevels !== null) {
1977+
layer.zoomLevels = (0, _util.asArray)(options.zoomLevels);
1978+
}
1979+
});
1980+
1981+
setupShowHideGroupsOnZoom(this);
1982+
this.showHideGroupsOnZoom();
1983+
};
1984+
19331985
methods.addRasterImage = function (uri, bounds, opacity, attribution, layerId, group) {
19341986
// uri is a data URI containing an image. We want to paint this image as a
19351987
// layer at (top-left) bounds[0] to (bottom-right) bounds[1].
@@ -2213,7 +2265,7 @@ methods.removeMeasure = function () {
22132265
};
22142266

22152267
methods.addSelect = function (ctGroup) {
2216-
var _this8 = this;
2268+
var _this9 = this;
22172269

22182270
methods.removeSelect.call(this);
22192271

@@ -2224,42 +2276,42 @@ methods.addSelect = function (ctGroup) {
22242276
title: "Make a selection",
22252277
onClick: function onClick(btn, map) {
22262278
btn.state("select-active");
2227-
_this8._locationFilter = new _leaflet2.default.LocationFilter2();
2279+
_this9._locationFilter = new _leaflet2.default.LocationFilter2();
22282280

22292281
if (ctGroup) {
22302282
(function () {
22312283
var selectionHandle = new global.crosstalk.SelectionHandle(ctGroup);
22322284
selectionHandle.on("change", function (e) {
22332285
if (e.sender !== selectionHandle) {
2234-
if (_this8._locationFilter) {
2235-
_this8._locationFilter.disable();
2286+
if (_this9._locationFilter) {
2287+
_this9._locationFilter.disable();
22362288
btn.state("select-inactive");
22372289
}
22382290
}
22392291
});
22402292
var handler = function handler(e) {
2241-
_this8.layerManager.brush(_this8._locationFilter.getBounds(), { sender: selectionHandle });
2293+
_this9.layerManager.brush(_this9._locationFilter.getBounds(), { sender: selectionHandle });
22422294
};
2243-
_this8._locationFilter.on("enabled", handler);
2244-
_this8._locationFilter.on("change", handler);
2245-
_this8._locationFilter.on("disabled", function () {
2295+
_this9._locationFilter.on("enabled", handler);
2296+
_this9._locationFilter.on("change", handler);
2297+
_this9._locationFilter.on("disabled", function () {
22462298
selectionHandle.close();
2247-
_this8._locationFilter = null;
2299+
_this9._locationFilter = null;
22482300
});
22492301
})();
22502302
}
22512303

2252-
_this8._locationFilter.addTo(map);
2304+
_this9._locationFilter.addTo(map);
22532305
}
22542306
}, {
22552307
stateName: "select-active",
22562308
icon: "ion-close-round",
22572309
title: "Dismiss selection",
22582310
onClick: function onClick(btn, map) {
22592311
btn.state("select-inactive");
2260-
_this8._locationFilter.disable();
2312+
_this9._locationFilter.disable();
22612313
// If explicitly dismissed, clear the crosstalk selections
2262-
_this8.layerManager.unbrush();
2314+
_this9.layerManager.unbrush();
22632315
}
22642316
}]
22652317
});

javascript/src/layer-manager.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,14 @@ export default class LayerManager {
282282
return result;
283283
}
284284

285+
getAllGroupNames() {
286+
let result = [];
287+
$.each(this._groupContainers, (k, v) => {
288+
result.push(k);
289+
});
290+
return result;
291+
}
292+
285293
clearGroup(group) {
286294
// Find all layers in _byGroup[group]
287295
let groupTable = this._byGroup[group];

javascript/src/methods.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,52 @@ methods.showGroup = function(group) {
871871
});
872872
};
873873

874+
function setupShowHideGroupsOnZoom(map) {
875+
if (map.leafletr._hasInitializedShowHideGroups) {
876+
return;
877+
}
878+
map.leafletr._hasInitializedShowHideGroups = true;
879+
880+
function setVisibility(layer, visible) {
881+
if (visible !== map.hasLayer(layer)) {
882+
if (visible)
883+
map.addLayer(layer);
884+
else
885+
map.removeLayer(layer);
886+
}
887+
}
888+
889+
function showHideGroupsOnZoom() {
890+
if (!map.layerManager)
891+
return;
892+
893+
let zoom = map.getZoom();
894+
map.layerManager.getAllGroupNames().forEach(group => {
895+
let layer = map.layerManager.getLayerGroup(group, false);
896+
if (layer && typeof(layer.zoomLevels) !== "undefined") {
897+
setVisibility(layer,
898+
layer.zoomLevels === true || layer.zoomLevels.indexOf(zoom) >= 0);
899+
}
900+
});
901+
}
902+
903+
map.showHideGroupsOnZoom = showHideGroupsOnZoom;
904+
map.on("zoomend", showHideGroupsOnZoom);
905+
}
906+
907+
methods.setGroupOptions = function(group, options) {
908+
$.each(asArray(group), (i, g) => {
909+
let layer = this.layerManager.getLayerGroup(g, true);
910+
// This slightly tortured check is because 0 is a valid value for zoomLevels
911+
if (typeof(options.zoomLevels) !== "undefined" && options.zoomLevels !== null) {
912+
layer.zoomLevels = asArray(options.zoomLevels);
913+
}
914+
});
915+
916+
setupShowHideGroupsOnZoom(this);
917+
this.showHideGroupsOnZoom();
918+
};
919+
874920
methods.addRasterImage = function(uri, bounds, opacity, attribution, layerId, group) {
875921
// uri is a data URI containing an image. We want to paint this image as a
876922
// layer at (top-left) bounds[0] to (bottom-right) bounds[1].

man/groupOptions.Rd

Lines changed: 39 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)