r-spatial / leafgl

R package for fast web gl rendering for leaflet
Other
263 stars 31 forks source link

Retina Issue with Points & File Sizes for Self Contained Maps? #73

Open mrworthington opened 2 years ago

mrworthington commented 2 years ago

Hi y'all,

Currently reworking a map I made that's going to have at least ~50k points in total, with the potential for more layers. Right now, I'm trying to evaluate {rdeck} and {leafgl} and I'm currently leaning toward {leafgl} because y'all have a lot of native integration with leaflet, which enables the map to have more functionality, but I've got two issues I'm thinking through that stand out to me (Also, I'm happy to file these as two separate issues:

  1. Point Pixelation and Resolution
  2. File Size for Standalone Maps

For reference, here's links to each map:

Links to Maps

Point Pixelation and Resolution

As I've been testing out {leafgl} and {rdeck}, I've noticed a blurriness and pixelation with the points rendered by leafgl. I'm wondering what options there are to increase the resolution of the points? Here's a screenshot:

{leafgl} screenshot

Screen Shot 2022-03-29 at 11 22 31 AM

{rdeck} screenshot

Screen Shot 2022-03-29 at 12 26 33 PM

Code for leafgl point rendering

Right now, this is how I'm drawing the points with leafgl:

```r leafgl_map <- leaflet(health_orgs, options = leafletOptions(zoomControl = TRUE, preferCanvas = TRUE, minZoom = 4, maxZoom = 13, doubleClickZoom= FALSE)) |> addProviderTiles(providers$Stamen.TonerLite, options = providerTileOptions(updateWhenZooming = FALSE, updateWhenIdle = TRUE)) |> addProviderTiles(providers$Stamen.TopOSMRelief, options = providerTileOptions(updateWhenZooming = FALSE, updateWhenIdle = TRUE, opacity = 0.25)) |> addProviderTiles(providers$Stamen.TopOSMFeatures, options = providerTileOptions(updateWhenZooming = FALSE, updateWhenIdle = TRUE, opacity = 0.25)) |> leafgl::addGlPoints(data = h2a_df_cnty, fillColor = "red", fillOpacity = 0.5, src = TRUE, popup = ~housing_tooltip, group = "H-2A Housing Sites") |> leafgl::addGlPoints(data = h2a_df_cnty_work, fillColor = "blue", fillOpacity = 0.5, src = TRUE, popup = ~worksite_tooltip, group = "H-2A Work Sites") |> leafgl::addGlPoints(data = community_health_sites, fillColor = "black", fillOpacity = 0.5, popup = popupTable(community_health_sites, row.numbers = FALSE, feature.id = FALSE, className = "health-orgs"), group = "Community Health Clinic Sites") ```

File Size for Standalone Maps

The last thing I'm wondering about is the difference between file sizes produced for a standalone HTML version when using {leafgl} vs {rdeck}. Using the same data for each map, I used htmlwidgets::saveWidget() to create self-contained versions of the maps, like this:

htmlwidgets::saveWidget(widgetframe::frameableWidget(leafgl_map), 
                        file = "leafgl_map_explorer.html", 
                        selfcontained = TRUE, 
                        background = "white")

When I did, the {leafgl} map was roughly 56.8 MB while the {rdeck} map was 4.4 MB. Is there a way to reduce the file size of the leafgl map?

Session Info

```r R version 4.1.1 (2021-08-10) Platform: aarch64-apple-darwin20 (64-bit) Running under: macOS Monterey 12.3 Matrix products: default LAPACK: /Library/Frameworks/R.framework/Versions/4.1-arm64/Resources/lib/libRlapack.dylib locale: [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8 attached base packages: [1] stats graphics grDevices utils datasets methods base other attached packages: [1] reactablefmtr_2.0.0 reactable_0.2.3 patchwork_1.1.1 rcartocolor_2.0.0 [5] viridis_0.6.2 viridisLite_0.4.0 tippy_0.1.0 mapboxapi_0.3.1 [9] scales_1.1.1 leaflet.extras_1.0.0 leafpop_0.1.0 leaflet_2.1.1 [13] rdeck_0.3.0.91000 sf_1.0-7 purrr_0.3.4 tidyr_1.2.0 [17] dplyr_1.0.8 readr_2.1.2 sever_0.0.7 ggiraph_0.8.2 [21] waiter_0.2.5 gfonts_0.1.3 ggplot2_3.3.5 sass_0.4.1 [25] bslib_0.3.1 shiny_1.6.0 loaded via a namespace (and not attached): [1] httr_1.4.2 tools_4.1.1 utf8_1.2.2 R6_2.5.1 [5] KernSmooth_2.23-20 DBI_1.1.2 colorspace_2.0-3 raster_3.5-15 [9] withr_2.5.0 sp_1.4-6 tidyselect_1.1.2 gridExtra_2.3 [13] curl_4.3.2 compiler_4.1.1 cli_3.2.0 geojsonsf_2.0.2 [17] xml2_1.3.3 classInt_0.4-3 proxy_0.4-26 stringr_1.4.0 [21] systemfonts_1.0.4 digest_0.6.29 svglite_2.1.0 base64enc_0.1-3 [25] jpeg_0.1-9 pkgconfig_2.0.3 htmltools_0.5.2 fastmap_1.1.0 [29] htmlwidgets_1.5.4 rlang_1.0.2 rstudioapi_0.13 httpcode_0.3.0 [33] jquerylib_0.1.4 generics_0.1.2 jsonlite_1.8.0 crosstalk_1.2.0 [37] magrittr_2.0.2 tidyassert_0.3.4 leafgl_0.2.1.9002 Rcpp_1.0.8.3 [41] munsell_0.5.0 fansi_1.0.3 lifecycle_1.0.1 terra_1.5-21 [45] stringi_1.7.6 yaml_2.3.5 snakecase_0.11.0 widgetframe_0.3.1 [49] grid_4.1.1 promises_1.2.0.1 crayon_1.5.1 lattice_0.20-45 [53] hms_1.1.1 magick_2.7.3 knitr_1.37 pillar_1.7.0 [57] uuid_1.0-4 codetools_0.2-18 crul_1.2.0 glue_1.6.2 [61] protolite_2.1.1 vctrs_0.3.8 png_0.1-7 tzdb_0.2.0 [65] httpuv_1.6.5 gtable_0.3.0 aws.s3_0.3.21 slippymath_0.3.1 [69] assertthat_0.2.1 xfun_0.30 mime_0.12 xtable_1.8-4 [73] e1071_1.7-9 later_1.3.0 class_7.3-20 stylebox_0.2.0 [77] tibble_3.1.6 aws.signature_0.6.0 units_0.8-0 ellipsis_0.3.2 [81] brew_1.0-7 ```
trafficonese commented 3 months ago

I cannot reproduce the File Size problem. When I use the following example, the rdeck map is bigger (3.7MB) and leafgl is around 1.8MB.

Concerning the "blurriness".. I guess this is because Leaflet.glify rescales the points depending on the zoom level and rdeck has a "static" size it seems. And maybe these open PR's could also improve this: https://github.com/robertleeplummerjr/Leaflet.glify/pull/138 https://github.com/robertleeplummerjr/Leaflet.glify/pull/127

library(leaflet)
library(leafgl)
library(sf)
library(rdeck)
library(dplyr)
library(sf)
library(viridis)
library(RcppSimdJson)

url <- file.path(
  "https://raw.githubusercontent.com/visgl/deck.gl-data/master",
  "examples/scatterplot/manhattan.json",
  fsep = "/"
)
manhattan_data <- fload(url) %>%
  as_tibble(.name_repair = ~ c("lon", "lat", "species")) %>%
  mutate(
    position = sfc_point(lon, lat),
    species = as.factor(species),
    species_name = if_else(species == 1, "dog", "cat")
  )

rdeckmap <- rdeck(
  map_style = mapbox_dark(), initial_bounds = st_bbox(manhattan_data$position)) %>%
  add_scatterplot_layer(radius_scale = 30,
    data = manhattan_data, get_position = position,
    get_fill_color = scale_color_category(
      col = species, palette = cividis(2)))

pts = st_as_sf(manhattan_data, coords = c("lat", "lon"), crs = 4326)
leafglmap <- leaflet() %>%
  addProviderTiles(provider = providers$CartoDB.DarkMatter) %>%
  addGlPoints(data = pts, 
              group = "pts", fillColor = "species")

htmlwidgets::saveWidget(widgetframe::frameableWidget(rdeckmap), 
                        file = "rdeckmap_map.html", 
                        selfcontained = TRUE, 
                        background = "white")

htmlwidgets::saveWidget(widgetframe::frameableWidget(leafglmap), 
                        file = "leafglmap_map.html", 
                        selfcontained = TRUE, 
                        background = "white")