绘制或访问Shiny Leaflet中空间子集的绘制形状几何图形 [英] Plot brushing or accessing drawn shape geometry for spatial subsets in Shiny Leaflet

查看:328
本文介绍了绘制或访问Shiny Leaflet中空间子集的绘制形状几何图形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在寻找Leaflet / Shiny中 addDrawToolbar 的漂亮功能,它允许自定义绘制形状等。



但是我想通过访问绘制形状的几何来设置空间数据,这是如何完成的? 此处这里,但我无法让他们以任何速度工作。



我也许认为情节笔刷可能适用于传单地图,但Joe Cheng 去年建议,它没有到位。

那么,是否有任何进展或解决方法?或者有人设法使用addDrawToolbar访问绘制的矩形的几何图形?

您可以使用 addDrawToolbar 来自 leaflet.extras 包。



文档很少,但是< A HREF = https://github.com/bhaskarvk/leaflet.extras/blob/d377e540614b83f06b1316e135cfb4cf583e23af/inst/htmlwidgets/lib/draw/draw-bindings.js 相对= nofollow noreferrer>页具有代码为 Leaflet.draw 闪亮的绑定。您可以查找包含 Shiny.onInputChange 的行,并在您的应用的服务器部分中使用相应的 input $ event 将数据传递给 Shiny.onInputChange



下面是一个简单的例子,您可以绘制

  rm(list = ls())在城市周围的多边形和多边形中的城市名称将显示在地图下方: )
library(shiny)
library(leaflet)
library(leaflet.extras)

cities< - structure(list(AccentCity = c(Saint Petersburg ,哈拉雷,青岛,
亚的斯亚贝巴,西安,鞍山,荣成,金沙萨,纽约,
悉尼, , 杜阿拉, Bayrut, 罗安达, 卢迪亚纳
)所示,经度= C(30.264167,31.0447222,120.371944,38.749226,
108.928611,122.99,116.364159,15.3,-74.0063889, 151.205475,
27.466667 ,9.7,35.5097222,13.233174,75.85),纬度= C(59.894444,
-17.8177778,36.098611,9.024325,34.258333,41.123611,23.528858,
-4.3,40.7141667,-33.861481,-11.666667,4.0502778, 33.8719444,
-8.836804,30.9)),class =data.frame,row.names = c(NA,-15L
),.Names = c(AccentCity,Longitude, Latitude))



cities_coordinates< - SpatialPointsDataFrame(城市[,c(经度,纬度)],城市)

ui< - fluidPage(
leafletOutput(mymap),
textOutput(selected_cities)



服务器< - 函数(输入,输出,会话){

输出$ mymap< - renderLeaflet({
leaflet()%> %
setView(0,0,2)%>%
addProviderTiles(providers $ CartoDB.Positron)%>%
addMarkers(data = cities,lat =〜Latitude,lng = 〜Longitude,label =〜AccentCity)%>%
addDrawToolbar(
targetGroup ='draw',
polylineOptions = FALSE,
markerOptions = FALSE,
circleOptions = TRUE)%>%
addLayersControl(overlayGroups = c('draw'),options =
layersControlOptions(collapsed = FALSE))
})

output $ (输入$ mymap_draw_stop)
打印(输入$ mymap_draw_new_feature)
feature_type< - 使用draw_stop事件来检测用户完成绘图时的输入
req(输入$ mymap_draw_stop)输入$ mymap_draw_new_feature $ properties $ feature_type

if(feature_type%in%c(rectangle,polygon)){

#获取多边形的坐标
polygon_coordinates< - input $ mymap_draw_new_feature $ geometry $ coor (polygon_coordinates,function(x){c(x [ [1]] [1],x [[2]] [1])})))

从sp包中使用以标识选定的城市
selected_cities< - cities_coordinates %over SpatialPolygons(list(Polygons(list(drawn_polygon),drawn_polygon)))

#打印城市名称
cities [which(!is.na(selected_cities) ),AccentCity]
} else if(feature_type ==circle){
#获取cirle中心的坐标
center_coords< - matrix(c(input($ mymap_draw_new_feature $ geometry $ coordinates [[1]],输入$ mymap_draw_new_feature $ geometry $ coordinates [[2]]),ncol = 2)

#计算城市到中心的距离
dist_to_center < - spDistsN1(cities_coordinates,center_coords,longlat = TRUE)

#选择靠近中心的城市比圆圈
个城市[dist_to_center<输入$ mymap_draw_new_feature $ properties $ radius / 1000,AccentCity]
}


})

}

shinyApp(ui,server)

编辑:
在用户绘制一个圆。


I've been looking at the nice added functionality of addDrawToolbar in Leaflet/Shiny, which allows for custom drawing of shapes etc.

But i'm interested in sub-setting spatial data by accessing the geometry of the drawn shape, how is this done? There are some efforts here and here but I can't get them to work at any rate.

I thought perhaps that the clever functionality of plot brush might work with leaflet maps but Joe Cheng suggested last year that it wasn't in place.

So, are there any developments or workarounds on this? or has anyone managed to access the geometry of a drawn rectangle using addDrawToolbar?

解决方案

You could use the addDrawToolbar from the leaflet.extras package.

The docs are sparse but this page has the code for the Leaflet.draw shiny bindings. You can look for the lines that have Shiny.onInputChange and in your the server part of your app, use the corresponding input$event to get the data passed to the Shiny.onInputChange.

Here's a minimal example, you can draw polygons around cities and the names of the cities in the polygon will be displayed below the map:

rm(list=ls())
library(shiny)
library(leaflet)
library(leaflet.extras)

cities <- structure(list(AccentCity = c("Saint Petersburg", "Harare", "Qingdao", 
                                        "Addis Abeba", "Xian", "Anshan", "Rongcheng", "Kinshasa", "New York", 
                                        "Sydney", "Lubumbashi", "Douala", "Bayrut", "Luanda", "Ludhiana"
), Longitude = c(30.264167, 31.0447222, 120.371944, 38.749226, 
                 108.928611, 122.99, 116.364159, 15.3, -74.0063889, 151.205475, 
                 27.466667, 9.7, 35.5097222, 13.233174, 75.85), Latitude = c(59.894444, 
                                                                             -17.8177778, 36.098611, 9.024325, 34.258333, 41.123611, 23.528858, 
                                                                             -4.3, 40.7141667, -33.861481, -11.666667, 4.0502778, 33.8719444, 
                                                                             -8.836804, 30.9)), class = "data.frame", row.names = c(NA, -15L
                                                                             ), .Names = c("AccentCity", "Longitude", "Latitude"))



cities_coordinates <- SpatialPointsDataFrame(cities[,c("Longitude","Latitude")],cities)

ui <- fluidPage(
  leafletOutput("mymap"),
  textOutput("selected_cities")
)


server <- function(input, output, session) {

  output$mymap <- renderLeaflet({
    leaflet() %>%
      setView(0,0,2) %>%
      addProviderTiles(providers$CartoDB.Positron) %>%
      addMarkers(data=cities,lat=~Latitude,lng=~Longitude,label=~AccentCity) %>%
      addDrawToolbar(
        targetGroup='draw',
        polylineOptions=FALSE,
        markerOptions = FALSE,
        circleOptions = TRUE)  %>%
      addLayersControl(overlayGroups = c('draw'), options =
                         layersControlOptions(collapsed=FALSE)) 
  })

  output$selected_cities <- renderText({
    #use the draw_stop event to detect when users finished drawing
    req(input$mymap_draw_stop)
    print(input$mymap_draw_new_feature)
    feature_type <- input$mymap_draw_new_feature$properties$feature_type

    if(feature_type %in% c("rectangle","polygon")) {

      #get the coordinates of the polygon
      polygon_coordinates <- input$mymap_draw_new_feature$geometry$coordinates[[1]]

      #transform them to an sp Polygon
      drawn_polygon <- Polygon(do.call(rbind,lapply(polygon_coordinates,function(x){c(x[[1]][1],x[[2]][1])})))

      #use over from the sp package to identify selected cities
      selected_cities <- cities_coordinates %over% SpatialPolygons(list(Polygons(list(drawn_polygon),"drawn_polygon")))

      #print the name of the cities
      cities[which(!is.na(selected_cities)),"AccentCity"]
    } else if(feature_type=="circle") {
      #get the coordinates of the center of the cirle
      center_coords <- matrix(c(input$mymap_draw_new_feature$geometry$coordinates[[1]],input$mymap_draw_new_feature$geometry$coordinates[[2]]),ncol=2)

      #calculate the distance of the cities to the center
      dist_to_center <- spDistsN1(cities_coordinates,center_coords,longlat=TRUE)

      #select the cities that are closer to the center than the radius of the circle
      cities[dist_to_center < input$mymap_draw_new_feature$properties$radius/1000,"AccentCity"]
    }


  })

}

shinyApp(ui, server)

Edit: Added support in case the user draws a circle.

这篇关于绘制或访问Shiny Leaflet中空间子集的绘制形状几何图形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆