我想从Leaflet&Shiny中的绘制事件中构建一个SpatialLine对象(以评估栅格(。我正在使用 leaflet.extras 中的 addDrawToolbar。
我已经用多边形完成了此操作,并认为过渡会很简单,但显然不是,我尝试使用(和以下变体(:
# get the coordinates of the drawn line
line_coordinates <- input$mymap_draw_new_feature$geometry$coordinates[[1]]
# transform them to an sp line
drawn_line <- Line(do.call(rbind,lapply(line_coordinates,function(x){c(x[[1]][1],x[[2]][1])})))
但该错误与 NA 错误或下标越界
。以下内容不会在应用程序中产生错误:
# remove the [[1]] subscript
line_coordinates <- input$rasmap_draw_new_feature$geometry$coordinates
# list to matrix of coordinates for Line
raw <- as.numeric(as.character(do.call(rbind,line_coordinates)))
raw <- do.call(rbind,lapply(line_coordinates,function(x){c(x[1],x[2])}))
但是当我推进到:
# make Line object
drawn_line <- Line(raw)
Warning: Error in .local: cannot derive coordinates from non-numeric matrix
# or
drawn_line <- Line(as.numeric(raw))
Warning: Error in <Anonymous>: unable to find an inherited method for function ‘coordinates’ for signature ‘"numeric"’
但是无论我以何种方式形成这个,我都有"无法从非数字矩阵中导出坐标"或"无法找到签名"数字"的函数"坐标"的继承方法
我认为mapedit与sf相结合可以在这里为您提供帮助。这是一个小例子(显然不是严格可复制的,因为您可以绘制任何您想要的东西(。editMap
返回类sf
的简单功能对象,然后可以将其转换为 sp 对象。
library(mapedit)
library(sf)
drawn = editMap() # zoom to where you wanna draw and draw a line
head(drawn) # a sf LINESTRING object
Simple feature collection with 1 feature and 2 fields
geometry type: LINESTRING
dimension: XY
bbox: xmin: 3.8232 ymin: 46.4076 xmax: 9.0088 ymax: 48.8936
epsg (SRID): 4326
proj4string: +proj=longlat +datum=WGS84 +no_defs
X_leaflet_id feature_type geometry
1 81 polyline LINESTRING(4.5483 46.9803, ...
drawn_sp = as(drawn, "Spatial") # to convert the LINESTRING to a SpatialLinesDataFrame object.
如果您想在自己的 shiny 应用程序中利用此功能,请查看 http://r-spatial.org/r/2017/06/09/mapedit_0-2-0.html#shiny-modules 其中@timelyportfolio提供了在 shiny 中使用editMap
的示例。
leaflet.extras 作者在这里。返回到 Shiny 事件的对象是 JavaScript 端的 GeoJSON,我认为它作为列表来到 R 端。如果你想从中得到一个空间对象,请考虑 geojson/geojsonio pkgs 将列表转换为 sp/sf 格式。 Tim关于使用mapedit的建议也是一个很好的建议。mapedit是专门为帮助交互式GIS操作而开发的,就像您正在尝试执行的操作一样。 Leaflet.extras为其提供了低级基础,但mapedit提供了更丰富的UX。
好吧,我取得了一些成功;
来自 leaflet.extras 的 addDrawToolbar 中的绘制功能如下所示:
# line feature of 3 vertices
line_coords <- input$rasmap_draw_new_feature$geometry$coordinates
print(line_coords)
[[1]]
[[1]][[1]]
[1] -3.214188
[[1]][[2]]
[1] 54.55634
[[2]]
[[2]][[1]]
[1] -3.213501
[[2]][[2]]
[1] 54.53383
[[3]]
[[3]][[1]]
[1] -3.185349
[[3]][[2]]
[1] 54.53323
class(line_coords)
"list"
# then rbind the list into a matrix, all fine
raw <- do.call(rbind,line_coords)
print(raw)
[,1] [,2]
[1,] -3.214188 54.55634
[2,] -3.213501 54.53383
[3,] -3.185349 54.53323
class(raw)
[1] "matrix"
一切似乎都很好,但是如果您在上述矩阵上执行 Line(raw(,仍然会发生错误".local 中的错误:无法从非数字矩阵中获取坐标"。
看看 str(raw( 就会发现:
str(raw)
List of 6
$ : num -3.21
$ : num -3.21
$ : num -3.19
$ : num 54.6
$ : num 54.5
$ : num 54.5
- attr(*, "dim")= int [1:2] 3 2
NULL
现在,我真的不知道为什么会发生这种情况,一个列表矩阵。当在标准列表列表上执行上述操作时,它不会发生;
g <- list(list(322000,512000),list(323000,512000),list(325000,514000))
co <- do.call(rbind,g)
str(co)
num [1:3, 1:2] 322000 323000 325000 512000 512000 514000
将其更改回数字(按列(,将修复它;
raw <- apply(raw, 2,as.numeric)
str(raw)
num [1:3, 1:2] -3.19 -3.2 -3.17 54.54 54.52 54.51
我可以继续形成 Line(raw( 对象,最终形成空间对象,并在底层栅格表面上执行提取等。
无论如何,我希望这对将来的其他人有所帮助。