在R中从传单获取边界框

时间:2017-05-25 11:17:43

标签: r leaflet

我使用R,RStudio和leaflet包来显示地图。

我想得到传单对象的边界框的最小和最大纬度。我认为这可以使用Shiny(使用类似input$mapobj_bounds之类的东西)完成,但是有一种非闪亮的方法可以做到这一点。

m <- leaflet(width=500,height=400) %>% 
   addTiles() %>% 
   setView(lng = -0.106831, lat = 51.515328, zoom = 18) %>%
   addCircleMarkers(lng = -0.106831, lat = 51.515328)

我需要的是一个使用输入参数m来获取边界框的函数。

可以这样做吗?

此外,查看对象m时的参数值看起来不正确。

e.g。

> m$x$limits
$lat
[1] 51.51533 51.51533

$lng
[1] -0.106831 -0.106831

编辑

我认为javascript函数map.getBounds()在这里可能会有所帮助......正如此处所建议的那样(Get the bounding box of the visible leaflet map?),但不知道如何将此问题应用于我们的问题。对此有任何帮助将非常感激。

2 个答案:

答案 0 :(得分:3)

这是一个javscript版本(初始解决方法)。有关更好的版本,请参阅下文。

  leaflet() %>% addTiles()  %>% 
  setView(lng = -0.106831, lat = 51.515328, zoom = 18) %>%
  addEasyButton(easyButton(
    states = list(
      easyButtonState(
        stateName="unfrozen-markers",
        icon="ion-toggle",
        title="Get Bounding box",
        onClick = JS("
                     function(btn, map) {
                        alert(map.getBounds().getEast());
                        alert(map.getBounds().getWest());
                        alert(map.getBounds().getNorth());
                        alert(map.getBounds().getSouth());
                     }")
      )
    )
  )
)

编辑:

如果你对Jeremys的回答有所帮助,你可以在没有javascript的情况下实际做到这一点。

getBox <- function(m){
  view <- m$x$setView
  lat <- view[[1]][1]
  lng <- view[[1]][2]
  zoom <- view[[2]]
  zoom_width <- 360 / 2^zoom
  lng_width <- m$width / 256 * zoom_width
  lat_height <- m$height / 256 * zoom_width
  return(c(lng - lng_width/2, lng + lng_width/2, lat - lat_height/2, lat + lat_height/2))
}
getBox(m)

答案 1 :(得分:3)

感谢@ BigDataScientist的回答指出,宽度和宽度&amp;高度可用!

只要您知道传单小部件的尺寸,就可以计算边界框。见leafletjs.com/examples/zoom-levels

鉴于这是使用leaflet(width=500,height=400)指定的,这将有效。

if (is.null(m$width) | is.null(m$height)) {
    print("Leaflet width and height must be speciied")
} else {
       width <- m$width 
       height <- m$height 
       zoom <- m$x$setView[[2]]
       lng <- m$x$setView[[1]][2]
       lat <- m$x$setView[[1]][1]
       lng_width <- 360 * width / 2^(zoom + 8)
       lng_east <- lng - lng_width/2
       lng_west <- lng + lng_width/2
       lat_height <- 360 * height * cos(lat/180 * pi) / 2^(zoom + 8)
       lat_north <- lat + lat_height/2
       lat_south <- lat - lat_height/2
}

> lng_east
[1] -0.1081721
> lng_west
[1] -0.1054899
> lat_north
[1] 51.516
> lat_south
[1] 51.51466

与@BigDataScientist相比,它给出与map.getBounds相同的答案,小数点后3位。

enter image description here

修改 我的答案基于参考的传单的文档。这似乎是一种简化。我添加了cos(lat/180 * pi)术语,可以提高准确性。例如,现在这给出了北边界51.516,这与传单51.51599707的差异仅为0.0000029。

我在几个不同的纬度和变焦处测试了这个。缩放级别越低,精度越低。