R / leaflet - drawing numerous polygons - r

I am trying to draw numerous polygons with the leaflet package but I can't understand what's going wrong.
The shapefile I use can be found here: https://www.data.gouv.fr/en/datasets/fond-de-carte-des-codes-postaux/
library(leaflet)
library(rgdal)
df <- readOGR("C:/Users/me/codes_postaux","codes_postaux_region")
plot(df)
The shapefile seems ok to me and the code I use is rather simple. However I only get the map as an output and no Polygons. I've been struggling with this issue for quite a long time, I would really appreciate if someone could help me here.
map <- leaflet(df) %>%
addProviderTiles("CartoDB.Positron")%>%
fitBounds(10,38,10,55) %>%
addPolygons(fillOpacity = 0.8, color = "Blue", weight = 1)
map

Look at df#proj4string and the output of plot(df); axis(1); axis(2). Your shapefile uses a specific CRS. You need to transform your SpatialPolygonsDataFrame with a common CRSobj (I got the CRS code from here: Leaflet for R: Raster Images).
library(sp)
pj <- CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs")
df2 <- spTransform(df, pj)
map2 <- leaflet(df2) %>%
addProviderTiles("CartoDB.Positron")%>%
fitBounds(10,38,10,55) %>%
addPolygons(fillOpacity = 0.8, color = "Blue", weight = 1)
map2

Related

Make a choropleth from a non-highmap-collection map

I've been trying to make a choropleth map with hcmap from highcharter package; I obtained the polygons from my own shapefile because it's a map that is not on the list of highmap's collection.
To do so, first I managed to transform my shapefile to a GeoJson file, as described here:
https://blog.exploratory.io/creating-geojson-out-of-shapefile-in-r-40bc0005857d
Later I managed to draw the map using the package geosonio as described here:
http://jkunst.com/highcharter/highmaps.html#geojsonio-package
However, I can't figure out how to merge a dataframe with values into the polygons drawn in my map. All the examples availables are merging to mapdata that is in a data.frame format, which I lose when transforming to GeoJson.
Here's my code so far:
library(rgdal)
library(geojsonio)
library(highcharter)
#Get map from shapefile
Mymap <- readOGR(dsn="Mymap", "Mymap", verbose = FALSE) %>%
spTransform(CRS("+proj=longlat +ellps=GRS80 +datum=WGS84"))
#Transform to geoJson
MymapJSON <- geojson_json(Mymap)
#Use geojsonio to make data compatible with hcmap
Myhcmap <- jsonlite::fromJSON(MymapJSON, simplifyVector = FALSE)
Myhcmap<- geojsonio::as.json(Myhcmap)
#Draw map:
highchart(type = "map") %>%
hc_add_series(mapData = Myhcmap, showInLegend = T)
Result:
¿How can I put additional data into the GeoJson so I can draw a choropleth?
I finally got to a solution by myself some time ago, it's was fairly simple but since it's not well documented how to add data to the GeoJSON, I will show it here:
#Work with the map until this step:
Myhcmap <- jsonlite::fromJSON(MymapJSON, simplifyVector = FALSE)
#This part was unnecessary:
#Myhcmap<- geojsonio::as.json(Myhcmap)
#Then, write your map like this:
highchart() %>%
hc_add_series_map(Myhcmap, df, value = "value", joinBy = "ID")
Where:
dfis the dataframe you want to append
value is the column name of the data you want to color your map by
joinBy is the joining key variable

Using tmap in R shows black background for masked RGB raster

I'm attempting to create a map in R using library(tmap) with a full-color RGB, masked Landsat image. The NAs however appear as black. Here's what I did.
Using library(sf) I calculated the centroids of 5 polygons and buffered them by 5000m. Following this I used library(raster) to mask a Landsat image by the buffered centroids. The code looks like this and works perfectly.
# Read in the data
polys <- st_read("nybb.shp")
rast <- brick("LC08_L1TP_013032_20171027_20171027_01_RT.tif")
# Transform polys, crop raster, calculate centroids
polys <- st_transform(polys, crs = crs(rast, asText = TRUE))
rast <- crop(rast, as(polys, "Spatial"))
cent <- st_centroid(polys) %>% st_buffer(., 5000) %>% as(., "Spatial")
# Mask the raster using buffered centroids
r <- mask(rast, cent)
I can accomplish what I want using base R and library(raster) -- BUT I would prefer to do this using tmap.
# Code that works
plot(polys$geometry, col = "grey", border = "white")
plotRGB(r, bgalpha = 0, add = TRUE)
# Code that does not work
# The NAs in the masked raster appear as black
# even when using the colorNA argument
tm_shape(polys) + tm_polygons() +
tm_shape(r, bbox = polys) +
tm_rgb(colorNA = "red")
Any idea how to show the masked raster using tmap's tm_rgb() function without showing the NAs as black?
To create a basemap with tmap, you can use the read_osm function, from the tmaptools package as follows. Note that you must first transform the data into a geographical CRS: epsg=4326
library(tmaptools)
library(OpenStreetMap)
rast <-projectRaster(rast,crs="+init=epsg:4326",method = "ngb") #(you can use method=method="bilinear")
polys <- spTransform(polys, CRS("+init=epsg:4326"))
background <- read_osm(bbox(rast))
tm_shape(background) + tm_raster() +
tm_shape(polys) + tm_polygons() +
tm_shape(r, bbox = polys) +
tm_rgb(colorNA = "red")

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.

Using markerClusterOptions with SpatialPolygons in Leaflet

I am using the package Leaflet to plot around 25.000 polygons on a map. Because of this large number of polygons I want to make use of markerClusterOptions.
This is what I would like to do:
leaflet() %>%
addTiles() %>%
addPolygons(data=sp_polygons,
clusterOptions = markerClusterOptions())
But addPolygons doesn't know clusterOptions.
What is possible, is to do the following
leaflet() %>%
addTiles() %>%
addMarkers(data=coordinates(sp_polygons),
clusterOptions = markerClusterOptions())
But when I zoom in I only markers and not the polygons. Is there a way to use clusterOptions but still show the polygons when zooming in?
To cut a long story short, you could simply create a SpatialPointsDataFrame from the polygon data (as you did above using coordinates) and subsequently display points and polygons on the same map. Here is an example using the mapview package.
library(sp)
library(mapview)
## create spatial points from Switzerland administrative borders
gadmCHE_pts <- SpatialPointsDataFrame(coordinates(gadmCHE),
data = gadmCHE#data,
proj4string = CRS(proj4string(gadmCHE)))
## display data
mapview(gadmCHE_pts, clusterOptions = markerClusterOptions()) +
gadmCHE

Plotting regions and adding color in leaflet R

I need to plot a map of Denmark divided into regions (there are 5: Region Nordjylland, Midtjylland, Sydjylland, Sjælland and Hovedstaden) and then color the regions such that the different regions stand out clearly. I have to use leaflet, since it has other features, that I will use later. I found a map on naturalearthdata.com, that I think I can use, but I can't figure out how to color (or even indicate) the regions. The code I tried is below
library(rgdal)
library(leaflet)
download.file(file.path('http://www.naturalearthdata.com/http/',
'www.naturalearthdata.com/download/50m/cultural',
'ne_50m_admin_1_states_provinces_lakes.zip'),
f <- tempfile())
unzip(f, exdir=tempdir())
world <- readOGR(tempdir(), 'ne_50m_admin_1_states_provinces_lakes', encoding='UTF-8')
DK <- subset(world, name=="Denmark")
leaflet() %>% addTiles() %>% addTopoJSON(DK, weight = 1, color = "#444444", fill = TRUE)
How does one use the naturalearthdata.com data to plot regions/states/provinces of different countries? I have seen a very nice example at
http://www.56n.dk/kort/dk2050kort_age.html
but there is no sample code available.
I have also found a very nice example here: https://rpubs.com/walkerke/leaflet_choropleth - but I need a map of Denmark.
UPDATE: I have found a shapefile at http://www.kortforsyningen.dk which does the trick. So now my question is how do I combine my own data with a shapefile and plot it in leaflet? If I just put
DK <- readOGR(".../shape", layer="REGION")
leaflet(data=DK)
I get a blank screen...

Resources