Search code examples
rleaflet

R Leaflet not mapping polylines to datarame


I use Leaflet with R quite frequently, but I've not used addPolylines before.

I have a series of lines with origin and destination locations that I'm attempting to plot on a map, and I'm noticing some weird behaviour:

I'm not entirely sure what I'm doing wrong here - any help would be appreciated. I've included a reproducible example below.


dummy <- data.frame(
    Line_name = c("line1", "line2", "line3"),
    origin_lng = c(145.1234, 147.223, 153.225),
    origin_lat = c(-17, -19.4, -27.6),
    Destination_lng = c(147.223, 153.225, 156.1123),
    Destination_lat = c(-19.4, -27.6, -30.5),
    Line_weight = c(1, 2, 5)
  )
  
  leaflet() %>%
    addProviderTiles(provider = providers$Esri.WorldImagery) %>%
    setView(lng = 146.612020, lat = -21.628836, zoom = 5) %>%
    addMarkers(lng = dummy$origin_lng, lat = dummy$origin_lat, label = "origins") %>%
    addPolylines(
      lng = c(dummy$origin_lng, dummy$Destination_lng),
      lat = c(dummy$Origin_lat, dummy$Destination_lat),
      weight = dummy$Line_weight,
      label = paste0(
        "Line name: ", dummy$Line_name, "<br>",
        "Origin coords: ", dummy$origin_lng, " ", dummy$origin_lat, "<br>",
        "Destination coords: ", dummy$Destination_lng, " ", dummy$Destination_lat
      ) %>% lapply(htmltools::HTML)
    )

Solution

  • You have to group the lines. You used the columns of dummy as independent vectors but sent no groups. Leaflet doesn't 'know' which labels go with which line segments. Additionally, you did get a popup, but you have to hover. (You only had one, as well.)

    So, in short—grouping the data... There is probably an easier way of doing this, but this works. I pivoted longer to going the lat/long. Then I pivoted wider. Essentially, I needed the longs in a column and the lats in a column.

    library(leaflet)
    library(tidyverse)
    
    dum2 <- dummy %>% pivot_longer(cols = names(.)[2:5], names_to = c("ft", "val"), 
                           names_sep = "_", values_to = "lng_lat") %>% 
      pivot_wider(id_cols = c("Line_name", "ft", "Line_weight"),
                              names_from = "val", values_from = "lng_lat")
    

    Then I separated the call for addPolyLines. You need one call for each group.

    mp <- leaflet() %>%
      addProviderTiles(provider = providers$Esri.WorldImagery) %>%
      setView(lng = 146.612020, lat = -21.628836, zoom = 5) %>%
      addMarkers(lng = dummy$origin_lng, lat = dummy$origin_lat, label = "origins")
    
    map(dummy$Line_name,
        function(group){
          mp <<- addPolylines(
            mp,
            data = dum2[dum2$Line_name == group, ],
            lng = ~lng,
            lat = ~lat,
            weight = ~Line_weight,
            labelOptions = list(noHide = T, sticky = T, permanent = T),
            label = paste0(
              "Line name: ", group, "<br>",
              "Origin coords: ", dummy[dummy$Line_name == group, ]$origin_lng, 
              " ", dummy[dummy$Line_name == group, ]$origin_lat, "<br>",
              "Destination coords: ", dummy[dummy$Line_name == group, ]$Destination_lng, 
              " ", dummy[dummy$Line_name == group, ]$Destination_lat) %>% 
              lapply(htmltools::HTML))
        }
    )
    

    enter image description here