r语言 - 从传单/闪亮中绘制的特征构建空间线



我想从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"’

但是无论我以何种方式形成这个,我都有"无法从非数字矩阵中导出坐标"或"无法找到签名"数字"的函数"坐标"的继承方法

我认为mapeditsf相结合可以在这里为您提供帮助。这是一个小例子(显然不是严格可复制的,因为您可以绘制任何您想要的东西(。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( 对象,最终形成空间对象,并在底层栅格表面上执行提取等。

无论如何,我希望这对将来的其他人有所帮助。

最新更新