Define function in leaflet cluster options

2019-05-31 16:25发布

问题:

How do I custom the cluster options so that the markers aren't clustered by the default Leaflet markerOptions(count of markers), but by a function (mean, maximum or whatelse) that I choose? For Java i could find tons of examples, but for R I couldn't find anything. Only thing I could find is something that has to do with "iconCreateFunction" and "JS()", but I don't know if it's right and how it works..

leaflet(data) %>%
addTiles() %>%
addMarkers(lng=data$lon, lat=data$lat, clusterOptions = list(iconCreateFunction = JS(...

Can somebody help me? Thanks in advance

回答1:

Replying to old question however some users still may find this useful. You need to pass custom iconCreateFunction javascript formula to markerClusterOptions() The main challenge is how you pass data to the markers so that you can apply a formula to data which are in the cluster of markers. I have tried to read the javascript code which is on the example website, but since I don't know js I could only find a workaround. Example website: http://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-custom.html The user is adding data into marker[i].number in populate() function. If anyone knows how this work please add your solution which I assume will be better than what I currently use.

My workaround is to store data into addMarkers(... , title=myData, ...) or addCircleMarkers(... , weight=myData , ...)

library(leaflet)
# sample data to pass to markers
myData <- sample(x=1:1000, size=1000, replace=TRUE)
# add some NaN which may occur in real data
myData[sample(x=1:1000, size=100, replace=FALSE)] <- NaN
circle.colors <- sample(x=c("red","green","gold"),size=1000,replace=TRUE)

avg.formula = 
"function (cluster) {
var markers = cluster.getAllChildMarkers();
var sum = 0;
var count = 0;
var avg = 0;
var mFormat = ' marker-cluster-';
for (var i = 0; i < markers.length; i++) {
if(markers[i].options.weight != undefined){
sum += markers[i].options.weight;
count += 1;
}
}
avg = Math.round(sum/count);
if(avg<333) {mFormat+='small'} else if (avg>667){mFormat+='large'}else{mFormat+='medium'};
return L.divIcon({ html: '<div><span>' + avg + '</span></div>', className: 'marker-cluster'+mFormat, iconSize: L.point(40, 40) });
}"

# in the above we loop through every marker in cluster access the options.weight
# which is our data, if data is not undefined (not NA or NaN) then we sum data
# and count occurrence
# at the end of code we check if average is more/less to assign default
# marker icons marker-cluster-small marker-cluster-medium marker-cluster-large
# for green yellow red respectively

# stroke = FALSE is a must if you store data in weights !!!
leaflet(quakes) %>% addTiles() %>%
 addCircleMarkers(lng=~long,lat=~lat,radius=10,stroke=FALSE,fillOpacity=0.9,
                   fillColor = circle.colors,weight=myData,
                   popup=as.character(myData),
                   clusterOptions = markerClusterOptions(iconCreateFunction=JS(avg.formula)))

for any other custom formula you need to adjust

for (var i = 0; i < markers.length; i++) {
if(markers[i].options.weight != undefined){
sum += markers[i].options.weight;
count += 1;
}
}

Kind regards, Peter



标签: r leaflet