Leaflet maps. Nudging co-incident markers

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Leaflet maps. Nudging co-incident markers

gavinr
I have a dataset showing points, with a category for each point and its location.

I simply want to display my points, in a way that users can toggle the points on and off by category.

Where I have two objects in the same category I'd like to display them nudged to appear as two distinct, but very close points.
I have made reproduceable example (the places are not real), which is loosely based on a tutorial I found recently (https://allthisblog.wordpress.com/2016/10/12/r-311-with-leaflet-tutorial/)

I have three categories of things (cafes, libraries and galleries), at three locations but have four objects in my set. This is because on of my locations has two functions - there is a cafe at a gallery (North St Gallery and the Gallery Cafe on the same site)    

If I make a selection that includes galleries and cafes there are just two points. I would like to nudge the point for the North St Galley and the Gallery Cafe so they appear as two (very close) points on the map and display the name when clicked on.

Also if anyone has any suggestions for generally tidying up the code I'd be grateful as my real version is much more complex with many more points and marker categories.   I believe there are Java libraries out there for managing markers and how they behave, but I'm hoping this can be done in the Leaflet R library somehow.

The only solution I could think of was to interrogate the entire dataframe, identify points that were had the same co-ords and move them diagonally apart by adding and subtracting a fixed amount of longitude and latitude from the co-ordinates.

Thanks in advance.

GavinR

Here is the code:

library(leaflet)

#make data frame of points

idno=c(1,2,3,4)
x=c(-1.9116, -1.9116,-1.9237,-1.91848)
y=c(52.4898,52.4898,52.5015,52.4851)
cat=c('Gallery','Cafe','Library','Cafe')
n=c('North St Gallery','Gallery cafe', 'South St Library', 'Coffee 2 go')
d<-data.frame(idno,x,y,cat,n)

#get a map and zoom into approx area of interest

m=leaflet()%>% setView(lng = -1.935, lat=52.485, zoom=12)
m=addTiles(m)
m

#create groups of objects

c= subset(d,cat=="Cafe")
l= subset(d, cat=="Library")
g= subset(d, cat=="Gallery")  

#add markers
 
m=addCircleMarkers(m,
                     lng = c$x,
                     lat = c$y,
                     popup = c$n,
                     radius = 5,
                     stroke =FALSE,
                     fillOpacity = 0.75,
                     group = "1 - Cafes")
 
m=addCircleMarkers(m,
                   lng = g$x,
                   lat = g$y,
                   popup = g$n,
                   radius = 5,
                   stroke =FALSE,
                   fillOpacity = 0.75,
                   group = "2 - Galleries")

m=addCircleMarkers(m,
                   lng = l$x,
                   lat = l$y,
                   popup = l$n,
                   radius = 5,
                   stroke =FALSE,
                   fillOpacity = 0.75,
                   group = "3 - libraries")

m = addLayersControl(m, overlayGroups = c("1 - Cafes","2 - Galleries","3 - libraries"))

m

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: Leaflet maps. Nudging co-incident markers

Jim Lemon-4
Hi Gavin,
Here's a sort of brute force way to nudge points. Might be helpful.

nudge<-function(x,y,away=0.1,tol=0.01) {
 dimx<-dim(x)
 if(missing(y) && !is.null(dimx)) {
  y<-x[,2]
  x<-x[,1]
 }
 xlen<-length(x)
 if(xlen != length(y)) stop("x and y must be the same length.")
 for(i in 1:xlen) {
  for(j in 1:xlen) {
   if(i != j) {
    dist<-sqrt((x[i]-x[j])^2 + (y[i]-y[j])^2)
    if(dist < tol) {
     if(x[i] >= x[j]) {
      x[i]<-x[i]+away
      x[j]<-x[j]-away
     } else {
      x[i]<-x[i]-away
      x[j]<-x[j]+away
     }
     if(y[i] >= y[j]) {
      y[i]<-y[i]+away
      y[j]<-y[j]-away
     } else {
      y[i]<-y[i]-away
      y[j]<-y[j]+away
     }
    }
   }
  }
 }
 return(list(x=x,y=y))
}
x=c(-1.9116, -1.9116,-1.9237,-1.91848)
y=c(52.4898,52.4898,52.5015,52.4851)
plot(nudge(x,y,0.0001,0.00001))

Jim

On Sat, Jan 20, 2018 at 4:51 AM, Gavin Rudge (Institute of Applied
Health Research) <[hidden email]> wrote:

> I have a dataset showing points, with a category for each point and its location.
>
> I simply want to display my points, in a way that users can toggle the points on and off by category.
>
> Where I have two objects in the same category I'd like to display them nudged to appear as two distinct, but very close points.
> I have made reproduceable example (the places are not real), which is loosely based on a tutorial I found recently (https://allthisblog.wordpress.com/2016/10/12/r-311-with-leaflet-tutorial/)
>
> I have three categories of things (cafes, libraries and galleries), at three locations but have four objects in my set. This is because on of my locations has two functions - there is a cafe at a gallery (North St Gallery and the Gallery Cafe on the same site)
>
> If I make a selection that includes galleries and cafes there are just two points. I would like to nudge the point for the North St Galley and the Gallery Cafe so they appear as two (very close) points on the map and display the name when clicked on.
>
> Also if anyone has any suggestions for generally tidying up the code I'd be grateful as my real version is much more complex with many more points and marker categories.   I believe there are Java libraries out there for managing markers and how they behave, but I'm hoping this can be done in the Leaflet R library somehow.
>
> The only solution I could think of was to interrogate the entire dataframe, identify points that were had the same co-ords and move them diagonally apart by adding and subtracting a fixed amount of longitude and latitude from the co-ordinates.
>
> Thanks in advance.
>
> GavinR
>
> Here is the code:
>
> library(leaflet)
>
> #make data frame of points
>
> idno=c(1,2,3,4)
> x=c(-1.9116, -1.9116,-1.9237,-1.91848)
> y=c(52.4898,52.4898,52.5015,52.4851)
> cat=c('Gallery','Cafe','Library','Cafe')
> n=c('North St Gallery','Gallery cafe', 'South St Library', 'Coffee 2 go')
> d<-data.frame(idno,x,y,cat,n)
>
> #get a map and zoom into approx area of interest
>
> m=leaflet()%>% setView(lng = -1.935, lat=52.485, zoom=12)
> m=addTiles(m)
> m
>
> #create groups of objects
>
> c= subset(d,cat=="Cafe")
> l= subset(d, cat=="Library")
> g= subset(d, cat=="Gallery")
>
> #add markers
>
> m=addCircleMarkers(m,
>                      lng = c$x,
>                      lat = c$y,
>                      popup = c$n,
>                      radius = 5,
>                      stroke =FALSE,
>                      fillOpacity = 0.75,
>                      group = "1 - Cafes")
>
> m=addCircleMarkers(m,
>                    lng = g$x,
>                    lat = g$y,
>                    popup = g$n,
>                    radius = 5,
>                    stroke =FALSE,
>                    fillOpacity = 0.75,
>                    group = "2 - Galleries")
>
> m=addCircleMarkers(m,
>                    lng = l$x,
>                    lat = l$y,
>                    popup = l$n,
>                    radius = 5,
>                    stroke =FALSE,
>                    fillOpacity = 0.75,
>                    group = "3 - libraries")
>
> m = addLayersControl(m, overlayGroups = c("1 - Cafes","2 - Galleries","3 - libraries"))
>
> m
>
> ______________________________________________
> [hidden email] mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.