从Leaflet / Shiny中的绘制特征构建SpatialLine

时间:2017-07-20 08:22:52

标签: r shiny leaflet polyline

我想从Leaflet&中的draw事件构建一个SpatialLine对象(以评估栅格)。闪亮的。我正在使用leaflet.extras中的addDrawToolbar。

I have done this with a polygon并认为过渡很简单,但显然不是,我尝试过使用(及其变体):

# 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错误或下标越界错误。

以下内容不会在app中产生错误:

# 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"’

但是我形成这个的每一种方式,我都“无法从非数字矩阵中导出坐标”或“无法找到用于签名的函数'坐标'的继承方法'”数字“'”

3 个答案:

答案 0 :(得分:3)

我认为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.

如果您想在自己的闪亮应用程序中利用此功能,请查看http://r-spatial.org/r/2017/06/09/mapedit_0-2-0.html#shiny-modules,其中@timelyportfolio提供了editMap内部闪亮使用的示例。

答案 1 :(得分:1)

leaflet.extras作者在这里。返回到Shiny事件的对象是JavaScript端的GeoJSON,我认为它作为列表出现在R端。如果你想要一个空间对象,可以考虑使用geojson / geojsonio pkgs将列表转换为sp / sf格式。 蒂姆关于使用mapedit的建议也很好。 mapedit专门用于帮助交互式GIS操作,就像您正在尝试的那样。 leaflet.extras为它提供了低级别的基础,但是mapedit提供了更丰富的用户体验。

答案 2 :(得分:0)

好的,我有一点成功;

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(原始)对象,最终形成空间对象,并在底层栅格表面上执行提取等。

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