0

This is more of a general question regarding R Leaflet than a specific coding problem. Google hasn't been too helpful for me this morning so I'm reaching out to the SO community in the hope that someone can help.

I know that it is possible to include tiled WMS data into a leaflet map using addWMSTiles(). This is useful if the aim is to understand the spatial distribution of your data without reference to any information associated with that spatial data (e.g. the area that a rendered shape takes up, or the name of that shape etc.). To resolve this, it's possible to specify a shapefile polygon instead using addPolygons(). This allows Leaflet to display data associated with each polygon using a click/mouse over (e.g. mousing over a polygon could tell you the name of that feature, it's area and even a hyperlink to external data).

The problem with shapefiles is that they're computationally expensive to render when the area of extent becomes large, even if the polygons are simplified (e.g. using st_simplify() or similar process). In addition, if your mapping application has several shapefile layers, the render time increases as some function of the number of layers and it can quickly get out of hand.

I am therefore wondering if there is a way to render polygons on-screen in a similar way to rendering tiles? That is, the polygons are only rendered when the user is focussed on a particular area. This way, you have all of the benefits of polygons and associated data but with the substantially faster rendering times of tiled datasets.

I stumbled across WFS in R during my research (e.g. here) which I initially thought would be my saviour, but in the few examples I've come across, it seems that it's necessary to first download all the spatial data (e.g. using st_read()) before plotting it on a map, which doesn't seem to address the loading/rendering time issue that I have detailed previously.

As there is no addWFSTiles() function within leaflet(), I suspect it's not possible to have my cake and eat it too. However, if there is some reasonably robust 'hacky' way to solve the rendering time issue, I am certainly all-ears. For context, my ultimate aim is to present my maps within an R Shiny application so fast rendering times and reduced bandwidth requirements via tiling would be an optimal solution for me. I'm not sure whether caching could be a viable solution so would be keen to discuss this aspect further if someone thinks it might be useful.


Based on the comments associated with this question, I have copied some basic code below which displays the distribution of ancient woodland in England. It uses WMS data provided by Natural England (source here.)

library(leaflet)
library(leaflet.extras)


leaflet() %>% 

  setView(zoom=11, lng=-1.19, lat=52.8) %>% 

  # Defines open-source base maps
  addProviderTiles(group = "OpenSM", providers$OpenStreetMap) %>% 

  # Defines ancient woodland WMS from Natural England
  addWMSTiles(group = "Ancient Woodland", 
              baseUrl = "https://environment.data.gov.uk/spatialdata/ancient-woodland-england/wms?", 
              layers = "Ancient_Woodland_England", 
              options = WMSTileOptions(format = "image/png", transparent = TRUE, crs = "EPSG:4326", interactive = TRUE, minZoom = 7, maxZoom = 15)) %>% 

  addLayersControl(
    baseGroups = c("OpenSM"),
    overlayGroups = c("Ancient Woodland"),
    options = layersControlOptions(collapsed = FALSE)

  ) 

For now, it would be interesting to see whether this data can be 'interactive' in the sense that upon clicking a patch of woodland, its name/area etc. can be displayed as a popup. If WMS is able to do this, I can test adding 10-20 different layers to assess performance across the UK. However, as I mentioned in the original iteration of this question, I don't think it's possible to have this functionality in WMS (but could potentially be viable with WFS).

Simon
  • 991
  • 8
  • 30
  • Do you want to pre-render the polygons into flat image tiles? (https://stackoverflow.com/questions/41620176/how-to-render-custom-map-tiles-created-with-gdal2tiles-in-leaflet-for-r?rq=1) or do you want to add logic to not include a shapefile unless the map users's bounding box overlaps it? – Brian Aug 19 '19 at 23:19
  • Also see https://cran.r-project.org/web/packages/tiler/vignettes/tiler.html – Brian Aug 19 '19 at 23:24
  • Thanks for the response. I didn't want to pre-render shapefiles into tiles as this converts the polygons into an image, with a subsequent loss of information. As far as I'm aware, I can't attach metadata to the images (i.e. you can't click on, say, a habitat patch and get its name, area etc). I was hoping there would be a way to tile shapefiles so that only the polygons within a map users' bounding box. As a user pans and zooms around, the polygons are drawn in real time. I'm guessing that this would be computationally expensive and hence why I haven't been able to find a solution so far. – Simon Aug 20 '19 at 07:07
  • The Leaflet object returns its own bbox and zoom level, so you can certainly feed that info back into a reactive context that chooses which polygons to show, but I think you're ultimately still going to find performance is poor if your shapefiles are that complex. You said you tried `st_simplify`, but maybe another approach is needed. Can you post any examples of your data? – Brian Aug 20 '19 at 12:01
  • Hi Brian, I've updated my question with a simple Leaflet map displaying the distribution of ancient woodland across England as an example of the kind of data that I'm working with. Thanks for your continued interest! – Simon Aug 23 '19 at 09:43

1 Answers1

0

For now, it would be interesting to see whether this data can be 'interactive' in the sense that upon clicking a patch of woodland, its name/area etc. can be displayed as a popup. If WMS is able to do this [...]

Yes, WMS is able to do this, but not all WMS layers enable this. This is called WMS GetFeatureInfo, and optional.

You can check if the layer is queryable in the WMS GetCapabilities: <Layer queryable="1" >

However, the GetFeatureInfo requests have not been integrated in r leaflet. This was an issue in the leaflet.extras package, but not (yet) implemented. See https://github.com/bhaskarvk/leaflet.extras/issues/84

Lennert
  • 964
  • 10
  • 16
  • Thanks for the info. I wish I had the experience and expertise to contribute to the `r` `leaflet` package to help implement this feature. – Simon Feb 04 '20 at 07:43