Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R leaflet: addPolygons by group

Tags:

r

leaflet

I am not able to make the group variable work in leaflet to create polygons for each group.

My data:

data <- data.frame(group = c("p_pladser.1", "p_pladser.1", "p_pladser.2","p_pladser.2", "p_pladser.3", "p_pladser.3", "p_pladser.4", "p_pladser.4","p_pladser.6", "p_pladser.6", "p_pladser.6"), lat = c(55.67179, 55.67171, 55.67143, 55.67135, 55.67110, 55.67099, 55.67173, 55.67158, 55.67155, 55.67154, 55.67145), long = c(12.55825, 12.55853, 12.55956, 12.55984, 12.56041, 12.56082, 12.55819, 12.55873, 12.55913, 12.55914, 12.55946))

What I have tried

leaflet(data) %>%
  addTiles() %>%
  addPolygons(lat = ~ lat, lng = ~ long, group = ~ group)

This results in:

enter image description here

What I need is the parking spaces to be individually connected, underneath done with the same data in ggplot2.

ggplot() + 
geom_line(data=data, aes(lat, long, group=group)) +
theme(legend.position="none")

enter image description here

Edit: Sample data for creating polygons by group.

df <- data.frame(group = c(9,9,9,9,3,3,4,10,4,4,6,6,9,9,6,7,8,6,6,6,4,10,10,10,10,5,5,5,5,6,2,6,8,10,4,1,1,8,2,2,8,1,1,2,3,3,1,2,3,5,5,7,7,7,7,7), lat = c(12.51324264,12.513305365,12.513460965,12.513471705,12.51323028,12.51343869,12.51002744,12.50998803,12.50981405,12.50976721,12.511631235,12.513047085,12.513872565,12.51284178,12.512897255,12.51491698,12.51098456,12.51271646,12.512567055,12.51193457,12.510672405,12.509586335,12.509513235,12.509228595,12.51019304,12.514326785,12.51430267,12.51431847,12.514476435,12.512163885,12.51235039,12.51238198,12.51063921,12.51044102,12.510237215,12.510051915,12.51031317,12.511275515,12.51133816,12.51112378,12.51150496,12.50974082,12.51063222,12.51169496,12.512893665,12.51391899,12.510612445,12.51168118,12.5127838,12.5139199,12.515012135,12.51503213,12.515610885,12.515487105,12.515415995,12.51546271), long = c(55.662148595,55.66274813,55.662200085,55.662681285,55.6618097,55.66187776,55.66261815,55.66273954,55.66191013,55.66203335,55.66224483,55.66231779,55.662361495,55.662510495,55.662309905,55.66241728,55.66220386,55.662301165,55.6622937,55.662261925,55.66218702,55.663355645,55.663463555,55.66335952,55.663351875,55.661814145,55.66214884,55.661928915,55.662022445,55.66189588,55.66176534,55.662082195,55.66289834,55.663009465,55.66231188,55.661666315,55.66180155,55.662641355,55.661861295,55.661826095,55.662688875,55.66121794,55.66126692,55.66132434,55.661389205,55.66144555,55.66141339,55.661468365,55.661532485,55.66159399,55.66165429,55.661505195,55.662096835,55.6617923,55.662226165,55.661944765))
like image 486
Esben Eickhardt Avatar asked Jul 21 '17 12:07

Esben Eickhardt


1 Answers

So you need to turn your coordinates into a SpatialLines object and use addPolylines.

Below I've converted the data into a SpatialLines object, its important to have the columns appearing as long and then lat.

Essentially, the data is split by group, turned into a matrix of the long/lat and then converted into a Line, which is pushed into an ID'd Lines object. Which is all wrapped up into SpatialLines.

Lines

library(leaflet)
library(sp)

# data
data <- data.frame(group = c("p_pladser.1", "p_pladser.1", "p_pladser.2","p_pladser.2", "p_pladser.3", "p_pladser.3", "p_pladser.4", "p_pladser.4","p_pladser.6", "p_pladser.6", "p_pladser.6"), lat = c(55.67179, 55.67171, 55.67143, 55.67135, 55.67110, 55.67099, 55.67173, 55.67158, 55.67155, 55.67154, 55.67145), long = c(12.55825, 12.55853, 12.55956, 12.55984, 12.56041, 12.56082, 12.55819, 12.55873, 12.55913, 12.55914, 12.55946))

# turn into SpatialLines
split_data = lapply(unique(data$group), function(x) {
  df = as.matrix(data[data$group == x, c("long", "lat")])
  lns = Lines(Line(df), ID = x)
  return(lns)
})

data_lines = SpatialLines(split_data)

leaflet(data_lines) %>%
  addTiles() %>%
  addPolylines()

enter image description here


Polygons

if you want to use polygons then you will create a SpatialPolygons object, which is done in much the same way lines are done.

Expect to see some warning messages as there are not more than four sets of coordinates in the polygons, it will recycle the first pair until it reaches four.

split_data_poly = lapply(unique(data$group), function(x) {
  df = as.matrix(data[data$group == x, c("long", "lat")])
  polys = Polygons(list(Polygon(df)), ID = x)
  return(polys)
})

data_polys = SpatialPolygons(split_data_poly)

leaflet(data_polys) %>%
  addTiles() %>%
  addPolygons()

Unordered Polygon & Colour

This isn't as simple, and is becomes more complicated the more points there are. The real 'easy' solution would be to get the data from a source where it is appropriately ordered. A quick alternative is to use convex hull chull. This IS NOT guaranteed to maintain shape.

Adding colour is easier, you can turn the SpatialPolygon into a SpatialPolygonDataFrame which has meta information on the group and its colour.

The example below contains the colour in the SpatialPolygonDataFrame as a column, this is just alternating between red and blue in this example.

data <- data.frame(group = c(9,9,9,9,3,3,4,10,4,4,6,6,9,9,6,7,8,6,6,6,4,10,10,10,10,5,5,5,5,6,2,6,8,10,4,1,1,8,2,2,8,1,1,2,3,3,1,2,3,5,5,7,7,7,7,7), lat = c(12.51324264,12.513305365,12.513460965,12.513471705,12.51323028,12.51343869,12.51002744,12.50998803,12.50981405,12.50976721,12.511631235,12.513047085,12.513872565,12.51284178,12.512897255,12.51491698,12.51098456,12.51271646,12.512567055,12.51193457,12.510672405,12.509586335,12.509513235,12.509228595,12.51019304,12.514326785,12.51430267,12.51431847,12.514476435,12.512163885,12.51235039,12.51238198,12.51063921,12.51044102,12.510237215,12.510051915,12.51031317,12.511275515,12.51133816,12.51112378,12.51150496,12.50974082,12.51063222,12.51169496,12.512893665,12.51391899,12.510612445,12.51168118,12.5127838,12.5139199,12.515012135,12.51503213,12.515610885,12.515487105,12.515415995,12.51546271), long = c(55.662148595,55.66274813,55.662200085,55.662681285,55.6618097,55.66187776,55.66261815,55.66273954,55.66191013,55.66203335,55.66224483,55.66231779,55.662361495,55.662510495,55.662309905,55.66241728,55.66220386,55.662301165,55.6622937,55.662261925,55.66218702,55.663355645,55.663463555,55.66335952,55.663351875,55.661814145,55.66214884,55.661928915,55.662022445,55.66189588,55.66176534,55.662082195,55.66289834,55.663009465,55.66231188,55.661666315,55.66180155,55.662641355,55.661861295,55.661826095,55.662688875,55.66121794,55.66126692,55.66132434,55.661389205,55.66144555,55.66141339,55.661468365,55.661532485,55.66159399,55.66165429,55.661505195,55.662096835,55.6617923,55.662226165,55.661944765))

split_data_poly = lapply(unique(data$group), function(x) {
  df = as.matrix(data[data$group == x, c("long", "lat")])
  ch = chull(df) # remove me if not wanted
  df = df[ch, ] # remove me if not wanted
  polys = Polygons(list(Polygon(df)), ID = x)
  return(polys)
  return(df)
})

data_polys = SpatialPolygonsDataFrame(SpatialPolygons(split_data_poly),
                                      data.frame(group = 1:10, colour = c("red", "blue")))

leaflet(data_polys) %>%
  addTiles() %>%
  addPolygons(color = ~colour)
like image 134
zacdav Avatar answered Nov 01 '22 00:11

zacdav