Search code examples
rr-sfr-leafletmultilinestring

Separate long/lat columns for multilinestrings and plotting in colours


I am plotting a shapefile with multilinestrings into R with leaflet. Is there a way I can extract from the geometry column separate columns for lat and long coordinates? I have looked at this answer and this one, but I can't get the right result and it's a mixture of long/lat co-ordinates in each column.

The end result I would like to get is a map where the lines are coloured based on a variable (like this), but in order to run the loop I need to have long/lat co-ordinates separated.


Solution

  • I have two comments: to export lat & long coordinates of a multilinestring you could use sf::st_coordinates(), provided your multilinestring is in an unprojected CRS (otherwise you would get eastings & northings instead).

    But I believe that - provided that I understand your question correctly - you are making it unnecessarily complicated.

    Color coding multilines based on a variable can be done by the means of leaflet::colorFactor(). You first declare a palette by the means of a named lookup table - linking values to colors - and then apply it in your leaflet::addPolylines() call.

    To illustrate on an example consider this piece of code; as your shapefile is not reproducible I am using a dataset of 13 rivers from Natural Earth to get a multiliestring (any multilinestring).

    library(rnaturalearth) # to get some multilinestrings / any multilinestrings :)
    library(dplyr)
    library(sf)
    
    rivers <- ne_download(category = 'physical', 
                          scale = 110, 
                          type = 'rivers_lake_centerlines',
                          returnclass = 'sf') %>% 
      mutate(color_source = case_when(name %in% c('Mississippi',
                                                  'Peace',
                                                  'Amazonas',
                                                  'Paraná') ~ "Americas",
                                      T ~ "Rest of World")) %>% 
      group_by(color_source) %>% 
      summarise()
      
    library(leaflet)
    
    # prepare a palette - manual colors according to color_source column
    palPwr <- leaflet::colorFactor(palette = c("Americas" = "red", 
                                               "Rest of World" = "blue"), 
                                   domain = rivers$color_source)
    
    # first prepare a leaflet plot ...
    lplot <- leaflet(rivers) %>% 
      addProviderTiles("CartoDB.Positron") %>% # or any other basemap...
      addPolylines(color = ~palPwr(color_source), # note the tilde notation!
                   opacity = 2/3) %>% # opacity = alpha
      leaflet::addLegend(position = "bottomright",
                         values = ~color_source, # data frame column for legend
                         opacity = .7, # alpha of the legend
                         pal = palPwr, # palette declared earlier
                         title = "Rivers of the World")
    
    lplot #  ... then display it
    

    map of the world with rivers in red & blue