5

I am trying to create lines on a map with Leaflet between latitude/longitude points. Here is a sample input data:

  segment_id latitude1 longitude1 latitude2 longitude2      len
1          1  48.15387   17.07388  48.15396   17.07387 10.98065
2          1  48.15396   17.07387  48.15404   17.07377 11.31327
3          1  48.15404   17.07377  48.15410   17.07364 11.74550
4          1  48.15410   17.07364  48.15412   17.07349 11.48138
5          1  48.15412   17.07349  48.15412   17.07334 11.63625
6          2  48.15424   17.07307  48.15432   17.07299 10.79304

The result of this should be 6 lines lat1,lng1 -> lat2,lng2. I have a hard time working with addPolylines, it is creating extra unwanted lines and I am not sure why.

enter image description here

This is how it should look like, without the extra lines stacked on top of each other :D

Here's my code so far but it's garbage:

  drawEdges <- function(x) {
    d <- cbind(x$latitude1,x$latitude2)
    s <- rep(1:nrow(x), each = 2) + (0:1) * nrow(x)
    latitudeOut <- d[s]
    e <- cbind(x$longitude1,x$longitude2)
    t <- rep(1:nrow(x), each = 2) + (0:1) * nrow(x)
    longitudeOut <- e[t]
    mymap <<- addPolylines(map = mymap,data = x, lng = ~longitudeOut, lat = ~latitudeOut)
  }

  if (!is.null(edges)){
    segments <- split( edges , f = edges$segment_id )
    segments
    sapply(segments, drawEdges)
}

Thank you for helping

ayshelina
  • 137
  • 1
  • 10
  • take a look at package sp. It worked for me before. If you can share the data set, I can write the code – Dinesh.hmn Dec 17 '16 at 20:37
  • possible duplicate with http://stackoverflow.com/questions/32275213/how-do-i-connect-two-coordinates-with-a-line-using-leaflet-in-r – MLavoie Dec 17 '16 at 20:38
  • @Dinesh.hmn I posted an example data set – ayshelina Dec 17 '16 at 20:43
  • Difficult to copy and import in R. Fine, I will work with it. – Dinesh.hmn Dec 17 '16 at 20:44
  • 1
    x <- read.csv("/home/dinesh/dat.csv", header = F) x <- as.matrix(x) library(sp) lnam <- list() for (i in 1:nrow(x)){ te <- data.frame(matrix(data = c(x[i,1],x[i,3],x[i,2],x[i,4]), nrow = 2)) nam <- paste0("line",i) lnam[i] <- nam assign(nam,Lines(list(Line(te)),ID = paste0(i))) } lnam <- as.character(lnam) mylines.lst <- list() for(tti in 1:length(lnam)) { mylines.lst[[tti]] <- get(lnam[tti]) } splines <- SpatialLines(mylines.lst) m <- leaflet(splines) %>% addTiles() %>% addPolylines() I have messed up the coordinates so I am not adding it as an answer. – Dinesh.hmn Dec 17 '16 at 21:19
  • @Dinesh.hmn i think this might work, it is showing the lines well, but if i use 'mymap <- leaflet(splines) %>% addTiles() %>% addPolylines()', the map is not there, only grey background and the lines are displayed. Without the addPolylines, map background appears without issues. Any idea whats happening? – ayshelina Dec 17 '16 at 23:14
  • may just be a zoom-level issue - have you tried zooming out? – SymbolixAU Dec 18 '16 at 08:50
  • zooming out or in doesn't help :( it's behaving so strange, if i leave only the mymap <- leaflet(splines) mymap <- addTiles(mymap) mymap <- addPolylines(mymap) the lines appear, but background doesn't. If I add my circles and markers then everything is appearing well except the lines disappear.... – ayshelina Dec 18 '16 at 14:33
  • did my answer not help? – SymbolixAU Dec 19 '16 at 07:23

1 Answers1

5

To get the lines joining in sequence you need your data reshaped into a long form, with the points in order.

And to do this without using any spatial objects (e.g. from library(sp)) you need to add the lines using a loop.

library(leaflet)

### --- reshaping the data ----
## keep the order - but because we're going to split the data, only use odd numbers
## and we'll combine the even's on later
df$myOrder <- seq(from = 1, to = ((nrow(df) * 2) - 1), by = 2)

## put the data in long form by splitting into two sets and then rbinding them
## I'm renaming the columns using setNames, as we need to `rbind` them
## together later
df1 <- setNames(df[, c("segment_id","latitude1","longitude1", "myOrder")],
                c("segment_id", "lat","lon", "myOrder"))

df2 <- setNames(df[, c("segment_id","latitude2","longitude2", "myOrder")],
                c("segment_id", "lat","lon", "myOrder"))

## make df2's order even
df2$myOrder <- (df2$myOrder + 1)

df <- rbind(df1, df2)

## can now sort the dataframe
df <- df[with(df, order(myOrder)), ]

## and de-dupelicate it
df <- unique(df[, c("segment_id", "lat","lon")])
### -----------------------------


## ----- plotting ---------------
map <- leaflet(data = df) %>%
  addTiles() %>%
  addCircles()

## without using any spatial objects, you add different lines in a loop
for(i in unique(df$segment_id)){
  map <- addPolylines(map, data = df[df$segment_id == i,], 
                      lat = ~lat, lng = ~lon, group = ~segment_id)
}
map

enter image description here

SymbolixAU
  • 25,502
  • 4
  • 67
  • 139
  • i am worried that this solution has the same issue as my try. Do you notice how the lines and circles in the middle have much higher opacity and are bolder? I think they are duplicated. And my data will have hundreds of lines i think this might be an issue :/ – ayshelina Dec 20 '16 at 09:29
  • @ayshelina You're right - I've added in a step to 'de-duplicate' points `df <- unique(df[, c("segment_id", "lat","lon")])` – SymbolixAU Dec 21 '16 at 11:04
  • I tried running it on a bigger data set and it created line connections where they shouldn't be :( I checked the input data frame and those connections don't exist there, here is the output screenshot: http://imgur.com/XBpJOGm . I used your code, I have no idea how it manages to create those random lines... – ayshelina Dec 21 '16 at 17:00
  • @ayshelina It looks like the lines aren't grouped appropriately. Are you still keeping a `segment_id` for each set of connected lines? – SymbolixAU Dec 22 '16 at 01:54
  • My original data frame has each row for one line that should be drawn. There shouldnt be any more lines than there are rows. I don't know how to debug this unfortunately, but I think it is connecting `lat1/lng1[1]` -> `lat2/lng2[1]`, which we want, but then then also `lat2/lng2[1]` -> `lat1/lng1[2]` (those are in one segment), but we don't want them connected. That might be why the lines are duplicated or there are weird extra connections in big data sets. – ayshelina Dec 22 '16 at 09:32