我想知道,如何根据其中的图标为群集着色.
我的数据:
remorque time.stamp lat long geolocalisation maintenance temperature appairage
1 21/11/2017 10:36 48.86272 2.2875920 OnMouv noir
2 21/11/2017 10:36 43.60776 1.4421606 StartMouv rouge
3 21/11/2017 10:36 46.58619 0.3388710 OnMouv rouge
4 21/11/2017 10:36 45.76695 3.0556216 Life orange
5 21/11/2017 10:36 45.14555 1.4751652 EndMouv rouge
6 21/11/2017 10:36 46.81157 1.6936336 Life orange
7 21/11/2017 10:36 47.36223 0.6751146 alerte rouge
8 21/11/2017 10:36 47.36032 1.7441244 StartMouv
9 21/11/2017 10:36 48.85333 1.8215332 StartMouv
10 21/11/2017 10:36 48.84429 1.7913208 alerte
11 21/11/2017 10:36 48.81356 1.6759643 EndMouv
Run Code Online (Sandbox Code Playgroud)
示例:
如果我的群集中有一个图标,并且appairage = rouge,则群集的颜色应为红色.
如果没有红色图标,如果我的群集中有一个图标,温度=橙色,则群集的颜色应为橙色.
...对于每个变量(温度,应用,维护).如果culster中的所有图标都有其变量,则群集应为绿色.
我的地图看起来像:
我找到了一种方法来改变互联网上群集着色的范围.但我不想为群集中的每个标记数着色.
可以根据聚集在一起的图标的属性为聚类图标着色.最简单的方法可能是使用htmlwidgets并在地图渲染上调用javascript函数.
但是,在进入htmlwidget之前,需要为集群层设置clusterId:
addAwesomeMarkers(clusterId = "cluster" ...
现在我们可以在htmlwidget中找到这个图层:
function(el, x) {
map = this; // the map object
var cluster = map.layerManager.getLayer('cluster','cluster'); // the cluster layer
Run Code Online (Sandbox Code Playgroud)
在集群层中,我们要为icon属性创建一个函数iconCreateFunction:
cluster.options.iconCreateFunction = function(d) {
// generate icon
}
Run Code Online (Sandbox Code Playgroud)
这个功能应该:
1.通过子标记迭代
对于第一,并在上面构建,我们可以迭代每个子标记:
cluster.options.iconCreateFunction = function(c) {
var markers = c.getAllChildMarkers();
markers.forEach(function(m) {
// do something for each marker
})
}
Run Code Online (Sandbox Code Playgroud)
我c用来表示一个簇,m代表每个孩子的标记
2.获得最高排名的标记
列表中的主要挑战是确定子图标的最高等级 - 因为数据未绑定到我们在选项中受限的图标.假设图标的颜色对应于数据框中项目的颜色代码,我将使用图标的颜色来确定其优先级/等级.在确定排名最高的孩子之后,我将根据孩子的等级为群集着色.
我将按如下方式为群集着色(因为我相信这是您的预期结果):
为了获得颜色,我需要访问适当的属性.(真棒)标记的颜色(填充)位于:
marker.options.icon.options.markerColor
Run Code Online (Sandbox Code Playgroud)
为了比较颜色,我将使用一个对象来表示每种颜色的等级,这将允许简单的颜色比较:
var priority = {
'green':0,
'orange':1,
'red':2
}
Run Code Online (Sandbox Code Playgroud)
这允许:
cluster.options.iconCreateFunction = function(c) {
var markers = c.getAllChildMarkers();
var priority = {
'green': 0,
'orange': 1,
'red': 2
};
var highestRank = 0; // defaults to the lowest level to start
markers.forEach(function(m) {
var color = m.options.icon.options.markerColor;
// check each marker to see if it is the highest value
if(priority[color] > highestRank) {
highestRank = priority[color];
}
})
}
Run Code Online (Sandbox Code Playgroud)
3.返回一个图标
现在我们有一个代表颜色的值,我们可以返回一个图标.Leaflet集群图标具有有限的样式选项.他们使用L.divIcon(),这有点限制选项.当与群集标签的CSS样式结合使用时,它们会创建熟悉的绿色,黄色和橙色圆圈.
这些默认样式具有以下css类:
.marker-cluster-small // green
.marker-cluster-medium // yellow
.marker-cluster-large // orange
Run Code Online (Sandbox Code Playgroud)
如果我们对使用这些类感到满意,我们可以轻松地设置聚簇多边形的样式:
var styles = [
'marker-cluster-small', // green
'marker-cluster-medium', // yellow
'marker-cluster-large' // orange
]
var style = styles[highestRank];
var count = markers.length;
return L.divIcon({ html: '<div><span>'+count+'</span></div>', className: 'marker-cluster ' + style, iconSize: new L.Point(40, 40) });
Run Code Online (Sandbox Code Playgroud)
因此整个小部件看起来像:
function(el,x) {
map = this;
var cluster = map.layerManager.getLayer('cluster','cluster');
cluster.options.iconCreateFunction = function(c) {
var markers = c.getAllChildMarkers();
var priority = {
'green': 0,
'orange': 1,
'red': 2
};
var highestRank = 0; // defaults to the lowest level to start
markers.forEach(function(m) {
var color = m.options.icon.options.markerColor;
// check each marker to see if it is the highest value
if(priority[color] > highestRank) {
highestRank = priority[color];
}
})
var styles = [
'marker-cluster-small', // green
'marker-cluster-medium', // yellow
'marker-cluster-large' // orange
]
var style = styles[highestRank];
var count = markers.length;
return L.divIcon({ html: '<div><span>'+count+'</span></div>', className: 'marker-cluster ' + style, iconSize: new L.Point(40, 40) });
}
}
Run Code Online (Sandbox Code Playgroud)
改变颜色
您可能希望高优先级图标显示为红色.这可以完成,但您需要为地图添加CSS样式.
在更改上面的图标功能的同时执行此操作的一种方法是在窗口小部件中使用javascript将样式附加到页面.你需要制作两种样式,一种用于拿着图标的div,另一种用于图标,你可以同时做两种:
var style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = '.red, .red div { background-color: rgba(255,0,0,0.6); }'; // set both at the same time
document.getElementsByTagName('head')[0].appendChild(style);
Run Code Online (Sandbox Code Playgroud)
不要忘记更新样式数组中使用的类:
var styles = [
'marker-cluster-small', // green
'marker-cluster-medium', // yellow
'red' // red
]
Run Code Online (Sandbox Code Playgroud)
在图标中显示更多信息
你是不是仅限于在该图标上的号码,你能告诉1-3-5,代表一个高优先级,三个中型等,你只需要保持多少孩子每个优先级的图标在每个集群轨迹:
var children = [0,0,0];
markers.forEach(function(m) {
var color = m.options.icon.options.markerColor;
children[priority[color]]++; // increment the appropriate value in the children array.
...
Run Code Online (Sandbox Code Playgroud)
然后显示:
return L.divIcon({ html: '<div><span>'+children.reverse()+'</span>...
Run Code Online (Sandbox Code Playgroud)
给这样的东西:
测试例
这应该是copy和pastable,以显示除图标中的其他文本之外的所有内容(使用这些文档示例中的代码作为基础):
library(leaflet)
# first 20 quakes
df.20 <- quakes[1:50,]
getColor <- function(quakes) {
sapply(quakes$mag, function(mag) {
if(mag <= 4) {
"green"
} else if(mag <= 5) {
"orange"
} else {
"red"
} })
}
icons <- awesomeIcons(
icon = 'ios-close',
iconColor = 'black',
library = 'ion',
markerColor = getColor(df.20)
)
leaflet(df.20) %>% addTiles() %>%
addAwesomeMarkers(~long, ~lat, icon=icons, label=~as.character(mag), clusterOptions = markerClusterOptions(), group = "clustered", clusterId = "cluster") %>%
htmlwidgets::onRender("function(el,x) {
map = this;
var style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = '.red, .red div { background-color: rgba(255,0,0,0.6); }'; // set both at the same time
document.getElementsByTagName('head')[0].appendChild(style);
var cluster = map.layerManager.getLayer('cluster','cluster');
cluster.options.iconCreateFunction = function(c) {
var markers = c.getAllChildMarkers();
var priority = {
'green': 0,
'orange': 1,
'red': 2
};
var highestRank = 0; // defaults to the lowest level to start
markers.forEach(function(m) {
var color = m.options.icon.options.markerColor;
// check each marker to see if it is the highest value
if(priority[color] > highestRank) {
highestRank = priority[color];
}
})
var styles = [
'marker-cluster-small', // green
'marker-cluster-large', // orange
'red' // red
]
var style = styles[highestRank];
var count = markers.length;
return L.divIcon({ html: '<div><span>'+count+'</span></div>', className: 'marker-cluster ' + style, iconSize: new L.Point(40, 40) });
}
}")
Run Code Online (Sandbox Code Playgroud)