【问题标题】:Can't loop with R's leaflet package to produce multiple maps无法使用 R 的传单包循环生成多个地图
【发布时间】:2016-04-11 16:46:41
【问题描述】:

这里是新的,对 R 来说也相对较新,所以请先原谅我,让我知道我在这篇文章中做错了什么,以免将来惹恼其他人:

我正在尝试创建传单地图序列(1971 年 9 月至 1972 年 4 月)。最后,我想将它们加工成闪亮的,并让用户播放/暂停动画(闪亮的循环动画滑块)。

没有适合我的 while 和 for 循环。当我在运行代码后检查我的is 时,增量起作用了,传单不起作用。没有循环,我的“Dynamic Leaflet Fails”(参见下面的代码部分)工作并打开了一张地图。

不能按顺序制作传单吗?

#set working directory
require(leaflet)
require(dplyr)

#Build data.frame with 10 obs + 3 cols
power <- data.frame(Latitude <-c(33.515556, 38.060556, 47.903056, 49.71, 49.041667, 31.934167, 54.140586, 54.140586, 48.494444, 48.494444), Longitude <- c(
129.837222, -77.789444, 7.563056, 8.415278, 9.175, -82.343889, 13.664422, 13.664422, 17.681944, 17.681944), start <- c(as.Date(
"15-Sep-1971", "1-Dec-1971", "1-Feb-1972", "1-Feb-1972", "1-Feb-1972", "1-Feb-1972", "1-Apr-1972", "1-Apr-1972", "24-Apr-1972", "24-Apr-1972", format = "%d-%b-%Y")))

#"Dynamic" leaflet Fails1: While+For combo
i<- as.Date("1971-09-14")
while (i < as.Date("1972-05-01")) {    for(star in start){
if (star > i) {
leaflet(power) %>% addTiles() %>%
  addCircleMarkers(lng = ~Longitude, lat = ~Latitude)
}}
i <- i+60}

#"Dynamic" leaflet Fails2: For+break combo
lap <- seq(as.Date("1971-09-14"), as.Date("1972-05-01"), by = "month")
for(i in lap) {
leaflet (data = power[power$start > i,]) %>%
addTiles() %>%
addCircleMarkers(lng = ~Longitude, lat = ~Latitude)  
if (i > as.Date("1951-01-01")) 
{      break }}

【问题讨论】:

  • 鉴于传单构建动态地图,最好构建一张地图,您可以在其中调整开始日期。 shiny 让它变得非常简单。否则,如果您使用传单制作静态地图(不是一个好主意)构建绘图功能,或者至少存储您正在构建的地图,以便您可以使用它们做一些事情。
  • 感谢阿利斯泰尔! (单个)动态和静态传单地图有什么区别?如果有的话,我错过了一些巨大的东西。在我看来,传单不会让闪亮干扰调整,但我可能错了,我愿意接受建议。有了这一切,我试图创建这样的东西:(seth127.shinyapps.io/slider) 但我无法从以前的任何其他项目中找到代码,其中结合了闪亮的循环动画和传单。如果您有建议如何解决这个问题,请赐教!
  • 呃! -3 研究工作。回到本科,我的心都碎了。说真的,我在网上进行了大量的试验和错误,也许比我的帖子所涉及的要多。请与我分享你的大脑,请
  • 这是我想要绘制的所有坐标的单张传单地图:(homepage.univie.ac.at/a1009991/power.html) 按顺序绘制标记确实讲述了一个惊人的故事,伙计们,让它运行起来真是太棒了!有任何想法吗?我想创建这样的东西:(skeate.github.io/Leaflet.timeline/earthquakes.html)
  • 我不同意 -3 的说法,而且我不知道还有其他人对此提出了解决方案,因此我会尽快尝试回答。

标签: r leaflet


【解决方案1】:

这是一种按照您建议的方式添加leaflet-timeline 的快速方法。出于某种原因,时间线在 RStudio Viewer 中无法完美呈现,但在 Chrome 中似乎可以正常工作。我在代码中注释了内联以描述这些步骤。

library(htmlwidgets)
library(htmltools)
library(leaflet)
library(geojsonio)

#Build data.frame with 10 obs + 3 cols
power <- data.frame(
  "Latitude" = c(33.515556, 38.060556, 47.903056, 49.71, 49.041667, 31.934167, 54.140586, 54.140586, 48.494444, 48.494444),
  "Longitude" = c(129.837222, -77.789444, 7.563056, 8.415278, 9.175, -82.343889, 13.664422, 13.664422, 17.681944, 17.681944),
  "start" = do.call(
    "as.Date",
    list(
      x = c("15-Sep-1971", "1-Dec-1971", "1-Feb-1972", "1-Feb-1972", "1-Feb-1972", "1-Feb-1972", "1-Apr-1972", "1-Apr-1972", "24-Apr-1972", "24-Apr-1972"),
      format = "%d-%b-%Y"
    )
  )
)

# set start same as end
#  adjust however you would like
power$end <- power$start


# use geojsonio to convert our data.frame
#  to GeoJSON which timeline expects
power_geo <- geojson_json(power,lat="Latitude",lon="Longitude")

# create a leaflet map on which we will build
leaf <- leaflet() %>%
  addTiles()

# add leaflet-timeline as a dependency
#  to get the js and css
leaf$dependencies[[length(leaf$dependencies)+1]] <- htmlDependency(
  name = "leaflet-timeline",
  version = "1.0.0",
  src = c("href" = "http://skeate.github.io/Leaflet.timeline/"),
  script = "javascripts/leaflet.timeline.js",
  stylesheet = "stylesheets/leaflet.timeline.css"
)

# use the new onRender in htmlwidgets to run
#  this code once our leaflet map is rendered
#  I did not spend time perfecting the leaflet-timeline
#  options
leaf %>%
  setView(44.0665,23.74667,2) %>%
  onRender(sprintf(
    '
function(el,x){
    var power_data = %s;

    var timeline = L.timeline(power_data, {
      pointToLayer: function(data, latlng){
        var hue_min = 120;
        var hue_max = 0;
        var hue = hue_min;
        return L.circleMarker(latlng, {
          radius: 10,
          color: "hsl("+hue+", 100%%, 50%%)",
          fillColor: "hsl("+hue+", 100%%, 50%%)"
        });
      },
      steps: 1000,
      duration: 10000,
      showTicks: true
    });
    timeline.addTo(HTMLWidgets.find(".leaflet"));
}
    ',
    power_geo
))

【讨论】:

  • timelyportfolio,你是一个巫师,一个真正的绅士。我选择power$end &lt;- power$start + 90 来实际查看标记,我会再玩一些。非常非常感谢。
  • @timelyportfolio。很好的答案。你会怎么做才能使颜色以变量为条件?
  • 如果我理解正确,您可以在sprintfjsonlite::toJSON 中添加颜色图。所以var colors = %s 然后jsonlite::toJSON(list(var1 = list(color = "...", fillColor="...", ...), auto_unbox = TRUE) 最后在JavaScript 中添加查找。很难在评论中解释。
  • 我已经建立了一个传单时间线包leaftime 以使这更容易。
【解决方案2】:

@timelyportfolio 去年帖子的更新版本。我需要添加一个timelineControl 函数才能让它工作。我还需要调用leaflet 元素的getMap() 函数来获取要绑定到地图对象的函数。

library(htmlwidgets)
library(htmltools)
library(leaflet)
library(geojsonio)

#Build data.frame with 10 obs + 3 cols
power <- data.frame(
    "Latitude" = c(33.515556, 38.060556, 47.903056, 49.71, 49.041667, 31.934167, 54.140586, 54.140586, 48.494444, 48.494444),
    "Longitude" = c(129.837222, -77.789444, 7.563056, 8.415278, 9.175, -82.343889, 13.664422, 13.664422, 17.681944, 17.681944),
    "start" = do.call(
        "as.Date",
        list(
            x = c("15-Sep-1971", "1-Dec-1971", "1-Feb-1972", "1-Feb-1972", "1-Feb-1972", "1-Feb-1972", "1-Apr-1972", "1-Apr-1972", "24-Apr-1972", "24-Apr-1972"),
            format = "%d-%b-%Y"
        )
    )
)

# set start same as end
#  adjust however you would like
power$end <- power$start + 30


# use geojsonio to convert our data.frame
#  to GeoJSON which timeline expects
power_geo <- geojson_json(power,lat="Latitude",lon="Longitude", pretty = T)

# create a leaflet map on which we will build
leaf <- leaflet() %>%
    addTiles()

# add leaflet-timeline as a dependency
#  to get the js and css
leaf$dependencies[[length(leaf$dependencies)+1]] <- htmlDependency(
    name = "leaflet-timeline",
    version = "1.0.0",
    src = c("href" = "http://skeate.github.io/Leaflet.timeline/"),
    script = "javascripts/leaflet.timeline.js",
    stylesheet = "stylesheets/leaflet.timeline.css"
)

# use the new onRender in htmlwidgets to run
#  this code once our leaflet map is rendered
#  I did not spend time perfecting the leaflet-timeline
#  options
leaf %>%
    setView(44.0665,23.74667,2) %>%
    onRender(sprintf(
        '
        function(el,x){
        var power_data = %s;

        var timelineControl = L.timelineSliderControl({
          formatOutput: function(date) {
            return new Date(date).toString();
          }
        });

        var timeline = L.timeline(power_data, {
        pointToLayer: function(data, latlng){
        var hue_min = 120;
        var hue_max = 0;
        var hue = hue_min;
        return L.circleMarker(latlng, {
        radius: 10,
        color: "hsl("+hue+", 100%%, 50%%)",
        fillColor: "hsl("+hue+", 100%%, 50%%)"
        });
        },
        steps: 1000,
        duration: 10000,
        showTicks: true
        });
        timelineControl.addTo(HTMLWidgets.find(".leaflet").getMap());
        timelineControl.addTimelines(timeline);
        timeline.addTo(HTMLWidgets.find(".leaflet").getMap());
        }
        ',
        power_geo
    ))

【讨论】:

  • @timelyportfolio:这很好,但是假设您有一个更复杂的 data.frame,您如何指示哪个变量保存时间线信息? geojson_json() 中是否有此论据?
猜你喜欢
  • 2017-11-07
  • 2021-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-25
  • 2017-10-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多