rstudio / leaflet

R Interface to Leaflet Maps
http://rstudio.github.io/leaflet/
Other
805 stars 509 forks source link

zindex, pane, or layer ordering #427

Open dcaud opened 7 years ago

dcaud commented 7 years ago

The current leaflet implementation doesn't seem to allow setting the zIndex or pane properly (tiles and images are placed on the tile pane whereas polygons/lines/circles are placed on the overlay pane which has a higher zIndex).

How do you set the layer order in R's leaflet package so that tiles show up on top of polygons filled with color?

More here.

jcheng5 commented 7 years ago

Can you try addingoptions=list(zIndex=xxxx) to your various layer function calls? I believe these pass straight through to leaflet.js.

tim-salabim commented 7 years ago

The add* functions don't seem to respect zIndex

library(mapview)

leaflet() %>%
  addCircleMarkers(data = breweries, options = list(zIndex = 400), color = "red") %>%
  addPolygons(data = franconia, options = list(zIndex = 200),
              fillOpacity = 1)

leaflet() %>%
  addPolygons(data = franconia, options = list(zIndex = 400),
              fillOpacity = 1) %>%
  addCircleMarkers(data = breweries, options = list(zIndex = 200), color = "red")
jcheng5 commented 7 years ago

Ohhh, I see what's happening here. I was surprised the jsfiddle in the stackoverflow post works at all--because Leaflet imposes a strict ordering between different types of objects (see http://leafletjs.com/reference-0.7.7.html#map-panes).

Look at how the jsfiddle accomplishes putting the labels above the polygons:

//create map sandwich
var topPane = map._createPane('leaflet-top-pane', map.getPanes().mapPane);
topPane.appendChild(cdbLabels.getContainer());

It actually creates its own custom pane using the undocumented _createPane. That's why no zIndex approach alone is ever going to work.

If we wanted to support this pattern, I think it'd have to be via specifically allowing basemaps to render in a custom topmost pane, rather than trying to have a general facility for setting custom ordering across all layer types.

tim-salabim commented 7 years ago

Is this strict ordering also still the case in leaflet 1.0?

jcheng5 commented 7 years ago

@tim-salabim Yeah, it would appear so: http://leafletjs.com/reference-1.0.3.html#map-pane

tim-salabim commented 7 years ago

@jcheng5 ok, but don't the "Options inherited from GridLayer" in http://leafletjs.com/reference-1.0.3.html#tilelayer imply that we should be able to set the pane where to render the layer?

jcheng5 commented 7 years ago

Oh, that's news to me! It does look like not only tiles but lots of layer types (all of them?) let you specify the layer by name. So yeah, it looks like you will be able to manually put layers in whatever pane you want once we move to 1.0.x. Thanks!

tim-salabim commented 7 years ago

I am still scared of the move to 1.0 but this adds to easing the pain a little :-)

dcaud commented 7 years ago

Thanks for all the thought given to this topic!

I guess the answer at the moment is:

  1. It's not currently possible to control the layer on which tiles appear in R's version of Leaflet (although workarounds are available in other implementations).

  2. It may become possible in a newer version of leaflet.

Any ideas on how to know whether the new version of leaflet is available?

Thanks!

mrmalloy commented 7 years ago

Hi - Just wanted to second the last question on this thread. I see there have been a few new updates of Leaflet recently, but I'm assuming there's an update to the R package that comes first before the custom pane feature is accessible? Or that the R package is not yet using Leaflet 1.0.x?

Also I'm wondering, is there any way to achieve this functionality in R by adding code in an htmlwidgets::onRender statement? I'm pretty new to Leaflet/R so apologies if this is a dumb question, I don't know much about how that statement works.

mtennekes commented 6 years ago

addPolygons doesn't seem to pass on zIndex correctly.

What I want to achieve is: tile layer without text -> polygon layer -> tile layer with text only

library(spData)
leaflet(us_states) %>% 
  addProviderTiles("CartoDB.PositronNoLabels", options=providerTileOptions(zIndex = 1)) %>%
  addPolygons(group="polygons", color = "blue", fillOpacity = .8, options=list(zIndex = 2)) %>% 
  addProviderTiles("CartoDB.PositronOnlyLabels", group="labels", 
    options=providerTileOptions(zIndex = 3, pane = 'overlayPane')) %>% 
  addLayersControl(overlayGroups = c("polygons", "labels"))

However, the polygons are drawn on top of the text layer: screenshot from 2018-04-04 19-19-40

In Firefox, the HTML code is

screenshot from 2018-04-04 19-13-42

So, the pane argument seems to work, but the z-index of the text layer is 2, while it is set to 3 in the code chunk above. Furthermore, the polygon layer does not have z-index attribute in the HTML code.

An obvious workaround is to put the text layer in a higher pane, e.g. "markerPane". Then it works: screenshot from 2018-04-04 19-19-51

Do you know why the z-index is not working correctly for polygons?

Swoorup commented 6 years ago

It seems that leaflet-pane div has z-index set to 400 for odd reason?

schloerke commented 6 years ago

v1.x of leaflet.js now allows for custom panes. @Swoorup The odd leaflet-pane z-index value is set to 400 (and other panes are on the 100's) to allow for many custom layers in between the panes. See https://github.com/Leaflet/Leaflet/pull/3591/files

549 addresses this issue and I believe will be the solution going forward. Creating the custom panes allows for you to define the z-index and have more control over the plot ordering.