R 具有可变点大小传单的交互式地图

R 具有可变点大小传单的交互式地图,r,leaflet,R,Leaflet,我创建了一个交互式地图,如下所示: library(leafletR) data(quakes) # store data in GeoJSON file (just a subset here) q.dat <- toGeoJSON(data=quakes[1:99,], dest=tempdir(), name="quakes") # make style based on quake magnitude q.style <- styleGrad(prop="mag", br

我创建了一个交互式地图,如下所示:

library(leafletR)
data(quakes)

# store data in GeoJSON file (just a subset here)
q.dat <- toGeoJSON(data=quakes[1:99,], dest=tempdir(), name="quakes")

# make style based on quake magnitude
q.style <- styleGrad(prop="mag", breaks=seq(4, 6.5, by=0.5), style.val=rev(heat.colors(5)), leg="Richter Magnitude", fill.alpha=0.7, rad=8)

# create map
q.map <- leaflet(data=q.dat, dest=tempdir(), title="Fiji Earthquakes", base.map="osm", style=q.style, popup="mag")

# view map in browser
rstudio::viewer(q.map)
function onEachFeature(feature, layer) {
    if (feature.properties && feature.properties.mag && feature.properties.stations) {
        layer.bindPopup("mag: " + feature.properties.mag + "<br> # Stations: " + feature.properties.stations);
    }
} 
库(传单)
数据(地震)
#将数据存储在GeoJSON文件中(这里只是一个子集)
q、 dat我通读了传单包的文档,在我看来(我可能错了),当前版本不支持同一数据集的多种样式。他们给出了一些示例,其中通过列出2个样式单(例如,
style=list(sty.1,sty.2)
)组合了2个样式单,但这只适用于列出2个不同的数据集(有关更多详细信息,请参见文档中的第8页)。我试过各种各样的把戏,但都不管用

然而,我提出了一个你可能想尝试的黑客解决方案。在使用
spool()
函数创建html页面后,您可以编辑处理样式的Javascript代码,以使
radius
属性动态(这也适用于其他样式属性,例如
fill
alpha
等)

您需要知道的内容:

在传单创建的HTML文档中,搜索
style1(功能)
函数的定义。您应该找到以下代码段:

function style1(feature) {
    return {"color": getValue(feature.properties.mag),
            "fillOpacity": 0.7, 
            "radius": 8};
}
此函数基本上返回数据集中每条记录的样式。如您所见,当前形式的函数为
fillOpacity
radius
返回一个静态值。但是,当涉及到颜色时,它调用另一个名为
getValue
的函数,并将
mag
(幅值)属性传递给它。如果我们看一下
getValue
函数的定义,就会发现它只是定义了每种颜色的幅度范围:

function getValue(x) {
    return x >= 6.5 ? "#808080" :
           x >= 6 ? "#FF0000" :
           x >= 5.5 ? "#FF5500" :
           x >= 5 ? "#FFAA00" :
           x >= 4.5 ? "#FFFF00" :
           x >= 4 ? "#FFFF80" :
           "#808080";
}  
函数定义非常简单。如果x(本例中的幅值)大于或等于6.5,则该数据点的颜色将为“#8080”。如果介于6和6.5之间,则颜色将为#FF0000“。依此类推

你能做什么:

现在我们了解了Javascript代码如何处理如何将颜色分配给每个数据点,我们可以非常轻松地为所有其他样式属性执行类似的操作。例如,下面的代码段显示了如何根据区域中的桩号数使半径动态化:

/* The getValue function controls the color of the data points */ 
function getValue(x) {
    return x >= 6.5 ? "#808080" :
           x >= 6 ? "#FF0000" :
           x >= 5.5 ? "#FF5500" :
           x >= 5 ? "#FFAA00" :
           x >= 4.5 ? "#FFFF00" :
           x >= 4 ? "#FFFF80" :
           "#808080";
}

/* The getRadValue function controls the radius of the data points */ 
function getRadValue(x) {
    return x >= 100 ? 24 :
           x >= 80 ? 20 :
           x >= 60 ? 16 :
           x >= 40 ? 12 :
           8;
}

/* The updated definition of the style1 function */
function style1(feature) {
    return {"color": getValue(feature.properties.mag),
            "fillOpacity": 0.7, 
            "radius": getRadValue(feature.properties.stations)
            };
}
因此,使用新定义的
style1(feature)
,现在我们可以控制数据点的颜色和半径。代码修改的结果如下所示:

legend.onAdd = function (map) {
    var div = L.DomUtil.create('div', 'legend');
    var labels = [];
    var grades = [4, 4.5, 5, 5.5, 6, 6.5];

    div.innerHTML += 'Richter Magnitude<br>';
    for (var i = 0; i < grades.length - 1; i++) {
        div.innerHTML += '<i style="background:' + getValue(grades[i]) + '"></i> ' + grades[i] + '&ndash;' + grades[i + 1] + '<br>';
    }

    return div;
};

这种方法的好处在于,它使您能够更细粒度地控制样式属性及其可以拥有的值的范围。主要的缺点是,如果您想为这些属性添加图例,则必须手动添加。添加/编辑图例的逻辑应该是最基本的ttom的HTML文档,如果您知道Javascript/HTML/CSS,编辑该代码段应该不会太困难

更新:

为新的动态变量添加图例(在本例中为半径),您需要编辑连接到图例对象的
.onAdd
处理程序。正如我前面所说,此处理程序的定义通常位于html页面的底部,如果我们运行您在问题中提供的代码,则处理程序应如下所示:

legend.onAdd = function (map) {
    var div = L.DomUtil.create('div', 'legend');
    var labels = [];
    var grades = [4, 4.5, 5, 5.5, 6, 6.5];

    div.innerHTML += 'Richter Magnitude<br>';
    for (var i = 0; i < grades.length - 1; i++) {
        div.innerHTML += '<i style="background:' + getValue(grades[i]) + '"></i> ' + grades[i] + '&ndash;' + grades[i + 1] + '<br>';
    }

    return div;
};
如您所见,我们控制的样式属性的类型将决定我们在图例中指定它的方式。例如,如果要为
alpha
属性添加图例,则可能需要尝试其他方法,而不是使用圆并控制其宽度和高度。代码修改的最终结果上面的ns如下所示:

另外,如果你想在弹出窗口中包含电台的数量,那么你必须编辑
onEachFeature
函数。这将是我们在所有其他修改中采用的相同方法,这是一个非常简单的更改

在原始HTML中,
onEachFeature
函数如下所示:

function onEachFeature(feature, layer) {
    if (feature.properties && feature.properties.mag) {
        layer.bindPopup("mag: " + feature.properties.mag);
    }
}
如果您还想在弹出窗口中包含电台数量,则需要将其包含在
bindPopup
方法的参数中,如下所示:

library(leafletR)
data(quakes)

# store data in GeoJSON file (just a subset here)
q.dat <- toGeoJSON(data=quakes[1:99,], dest=tempdir(), name="quakes")

# make style based on quake magnitude
q.style <- styleGrad(prop="mag", breaks=seq(4, 6.5, by=0.5), style.val=rev(heat.colors(5)), leg="Richter Magnitude", fill.alpha=0.7, rad=8)

# create map
q.map <- leaflet(data=q.dat, dest=tempdir(), title="Fiji Earthquakes", base.map="osm", style=q.style, popup="mag")

# view map in browser
rstudio::viewer(q.map)
function onEachFeature(feature, layer) {
    if (feature.properties && feature.properties.mag && feature.properties.stations) {
        layer.bindPopup("mag: " + feature.properties.mag + "<br> # Stations: " + feature.properties.stations);
    }
} 
功能特性(特性,图层){
if(feature.properties&&feature.properties.mag&&feature.properties.stations){
layer.bindPopup(“mag:+feature.properties.mag+”
#Stations:+feature.properties.Stations”); } }
这一变化的最终结果如下:


希望这能有所帮助。

我读了你的答案。它看起来很完整,已经谢谢了。我会在这个周末尝试,我会让你知道它是如何运作的,如果我想写一个传奇,我会接受并给予奖励,因为这对我来说也很重要(见我的初始问题)。图例实际上就在那里。我在最后指出的一点是,你不会有半径大小的图例。相反,你的图例将只反映颜色范围。但如果你想包括半径大小的范围以及它在图例中的含义,这也是可能的。我更新了我的答案,以显示它是如何完成的。