How to plot a large rasterfile quickly in R leaflet with shiny - r

I obtianed a large rasterfile (.asc file), which I can import in R and plot on a leaflet map. Because the file is pretty big, it takes about 40 seconds before the rasterimage is plotted on the basemap. This in comparison to shapefiles, which are plotted almost instantly.
I am wondering if there is a way to have the rasterfile plotted on the basemap more quickly?
The code I use to plot the file on the map is the following:
r = raster("file.asc")
leaflet() %>% addSearchOSM() %>%
addProviderTiles(providers$CartoDB.Positron,
options = providerTileOptions(noWrap = TRUE),
group = "kaart") %>%
addRasterImage(r, opacity = 0.5)

Related

Generating a map like Arcmaps in R

I want to generate a map of various locations. I want to generate it in R using leaflet package. I have latitude and longtitude of each locations. I have used following code but not able to generate. I am attaching a picture. I want this kind of graph.
library(leaflet)
library(dplyr)
library(tidyr)
jin_map=leaflet() %>%
addProviderTiles("Esri") %>%
addMarkers(lng = jinesh_location_1_$Longitude, lat = jinesh_location_1_$Latitude)
jin_map_circle<-jin_map%>%
clearMarkers()%>%
addCircleMarkers(data=jinesh_location_1_,radius = 2,color = "red",opacity = 0.70)

Add "rgb" legend to R leaflet heatmap

I made some interactive heatmaps using leaflet (particularly the addHeatmap() command from the leaflet.extras package) and shiny. Having created a desired map, I would like to add a legend to it.
What I am interested in is a "rgb" legend, based on density values deduced by addHeatmap() from pure long/lat coords.
What I need is something like this map - https://www.patrick-wied.at/static/heatmapjs/example-legend-tooltip.html - unfortunately I have no knowledge of JS and can't rewrite this code in terms of R/include the right fragment of JS code for my problem.
What I tried so far is the addLegend() command, which does not give the desired result, as in this case I would need to specify a variable for which the legend would be prepared. I also tried to extract the color range and assigned values from created leaflet object, however with no success.
Here's link to full data to run the reproducible example on:
https://drive.google.com/file/d/1h3jL_PU6DGTtdIWBK02Tt37R7IB2ArH9/view
And here's top 20 records:
structure(list(latitude = c(30.309522, 30.24429616, 30.30038194,
30.27752338, 30.23294081, 30.23038507,
30.34285933, 30.24962237, 30.26594744,
30.20515821, 30.22363485, 30.2759184,
30.28283226, 30.33816909, 30.26611565,
30.18835401, 30.26704789, 30.27456699,
30.19237135, 30.1925213),
longitude = c(-97.73171047, -97.77446858, -97.77885789,
-97.71919076, -97.58937812, -97.76581095,
-97.73598704, -97.72215443, -97.74144275,
-97.8782895, -97.78329845, -97.71321066,
-97.70820152, -97.82413058, -97.7327258,
-97.81606795, -97.68989589, -97.7580592,
-97.7816127, -97.73138523)),
.Names = c("latitude", "longitude"), row.names =
c(NA, 20L), class = "data.frame")
Here's an example code, which I'd like to extend by the mentioned functionality:
library(magrittr)
library(leaflet)
library(leaflet.extras)
data <- read.csv('DATA.csv')
leaflet(data) %>%
addTiles(group="OSM") %>%
addHeatmap(group="heat", lng = ~longitude, lat = ~latitude, max=.5, blur = 60)
And here is the result of that code (on whole dataset):
https://i.stack.imgur.com/6VFNC.jpg
So to sum up what I would like to do: based on such picture I would like to extract the range of the drawn colors along with values assigned to them, and draw legend using that information.
Is there something I am missing? It looks like a pretty simple issue, but I've been struggling to find a solution for past few hours.
Thanks in advance for any help!
EDIT: extended the reproducible example.
Your sample data does not have any values to it to actually map a density overlay.
You can specify the number of bins with colorBin() and then specify those bins with your pal function. You can set the bins differently depending on your needs at the data_values distributions. The help section of colorBin() is helpful in identifying the correct parameters for your needs.
bins <- c(0,1,2,3,4)
pal <- colorBin("Spectral", domain = data_value, bins = bins, na.color = "transparent")
m <-leaflet() %>%
addTiles() %>%
addHeatmap(lng= long_cords, lat = lat_cords, intensity = data_value,
blur = 20, max = 400, radius = 15, cellSize = 3) %>%
addLegend(pal = pal, values = data_value,
title="Heat map legend")
You'll have to play around with the addHeatmap arguments to get an the right transparency and density settings.

Crosstalk: filter Polylines in Leaflet

I can't get crosstalk to work with leaflet and Polylines - here is an MWE:
library(crosstalk)
library(leaflet)
theta <- seq(0, 2*pi, len = 100)
dat <- data.frame(
lon = cos(theta),
lat = sin(theta),
t = 1:100
)
sd <- SharedData$new(dat)
map <- leaflet() %>%
addTiles() %>%
addCircleMarkers(data = sd, lat = ~lat, lng = ~lon, color = "blue") %>%
addPolylines(data = sd, lat = ~lat, lng = ~lon, color = "blue")
bscols(
filter_slider("t", "Time", sd, column = ~t),
map
)
The time filter_slider applies to the circle markers but not the polylines.
Happy to having a go at fixing this in the R leaflet package if someone can point me in the right direction. I.e. what would be required to change / implement? I assume the support is missing on the javascript side as of now?
UPDATE: Good News!
#dmurdoch has submitted a pull request to add support for polylines and polygons.
Using his version of crosstalk, you can now filter leaflet lines/polygons if they're sp objects (note, it doesn't seem to work with sf yet).
First you will need to install this version of crosstalk:
devtools::install_github("dmurdoch/leaflet#crosstalk4")
Then you will need to make sure your features are Spatial objects, easy using rgdal or raster:
shapes_to_filter <- raster::shapefile("data/features.shp") # raster import to 'Spatial Object'
shapes_to_filter <- rgdal::readOGR("data/features.shp") # rgdal import to 'Spatial Object'
Or, if you use sf and dplyr for most spatial tasks (like me) convert an sf object to Spatial:
library(dplyr)
library(sf)
shapes_to_filter <- st_read("data/features.shp") %>% as('Spatial') # sf import to 'Spatial Object'
Then create an sd object for leaflet, and a data frame copy for the filters (IMPORTANT: note how the group for sd_df is set using the group names from the sd_map) :
library(crosstalk)
sd_map <- SharedData$new(shapes_to_filter)
sd_df <- SharedData$new(as.data.frame(shapes_to_filter#data), group = sd_map $groupName())
Create crosstalk filters using sd_df:
filter_select("filterid", "Select Filter Label", sd_df, ~SomeColumn)
Create the map using the sd_map object:
library(leaflet)
leaflet() %>%
addProviderTiles("OpenStreetMap") %>%
addPolygons(data = sd_map)
And any linked tables/charts need to also use the sd_df object:
library(DT)
datatable(sd_df)
Here's all of the sources for the solution:
GitHub Issue
Github pull request from dmurdoch to add support for polygons/lines
Original solution - with outdated method "sd$transform"
Updated example - with the new "group" method, but I couldnt get their RMD to work
As previously mentioned by Bhaskar Karambelkar:
"crosstalk for now works only with markers and not polylines/polygons"
I hope this changes soon.

R Leaflet change layer order

I'm trying to produce a leaflet map in R with a layer (e.g. WMS tile or raster) and some circles. Since there are many circles in my application, I need to change the order, i.e. the layer should be shown on top of the circles.
Is there a way in R to change the order such that I can bring the WMS tile to the front or sent the circles to the background?
My code looks like the following (in a simplified way):
library(leaflet)
leaflet() %>% addTiles() %>% setView(-93.65, 42.0285, zoom = 4) %>%
addCircles(lng=-98,lat=40,radius=100000,color = "red",stroke=FALSE,fillOpacity=1) %>%
addWMSTiles(
baseUrl="http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi",
layers ="nexrad-n0r-900913",
options = WMSTileOptions(format = "image/png", transparent = TRUE),
attribution = "Weather data © 2012 IEM Nexrad"
)

TopoJSON choropleth in R/Leaflet?

Is it possible to style a TopoJSON file from its features for a choropleth using R/leaflet? Tried a few things, and I'm not sure if this is impossible with the leaflet package or if I just don't have the syntax right, especially accessing the properties to enter in the pal() function. Here's what I have:
pal<-colorNumeric(palette ="YlOrRd",domain = USAdata$GINI) #USAdata data frame I merged with the spdf before converting it to shp/topojson
map<-leaflet() %>%
addTiles(options=tileOptions(minZoom = 3)) %>%
setMaxBounds(-167.276413,5.499550,-52.233040, 83.162102) %>%
setView(93.85,37.45,zoom =3) %>%
#addGeoJSON(geojson = jso5)
addTopoJSON(topojson=jso, fillColor = ~pal("GINI"))
#addPolygons(data=poly)
this throws up an error:
"Error in UseMethod("doResolveFormula") :
no applicable method for 'doResolveFormula' applied to an object of class "NULL""
I also tried converting it to an R object the topojson with fromJSON() and adding style elements, but this won't load after I try send it back with toJSON().
Not sure if relevant, but the topojson was created from a shapefile made following the instructions here:
with cl:
topojson -o 'USApuma.json' --shapefile-encoding utf8 --id-property=+GEOID10 -p GINI,+STATEFP10,+GEOID10 -- 'usaetest.shp'
then read in with readLines().
Eventually trying to throw this into a shiny app. Here's some examples I've been following.
Do you need to use TopoJSON? If not consider using the tigris package (disclosure: I created and maintain the package). It'll get you access to just about any Census geographic dataset you need, and plays nicely with leaflet. Here's a brief example in line with what you are doing. For example, you can get all PUMAs in the continental US with the following code:
library(readr)
library(tigris)
library(leaflet)
us_states <- unique(fips_codes$state)[1:51]
continental_states <- us_states[!us_states %in% c("AK", "HI")]
pumas_list <- lapply(continental_states, function(x) {
pumas(state = x, cb = TRUE)
})
us_pumas <- rbind_tigris(pumas_list)
I've generated a sample dataset that measures PUMA median household income for this example; the geo_join function from the tigris package can merge the dataset to the spatial data frame us_pumas:
puma_income <- read_csv('http://personal.tcu.edu/kylewalker/data/puma_income.csv')
joined_pumas <- geo_join(us_pumas, puma_income, 'GEOID10', 'GEOID')
We can then plot with Leaflet:
pal <- colorQuantile(palette = 'YlOrRd', domain = joined_pumas$hhincome, n = 7)
leaflet(joined_pumas) %>%
addProviderTiles('CartoDB.Positron') %>%
addPolygons(weight = 0.5, fillColor = ~pal(hhincome),
color = 'lightgrey', fillOpacity = 0.75,
smoothFactor = 0.2) %>%
addLegend(pal = pal,
values = joined_pumas$hhincome)
If you are planning to build a Shiny app, I'd recommend saving out the PUMAs you obtain from tigris first as a .rda file and reading it in with your Shiny script so you don't have to rbind_tigris every time.

Resources