【问题标题】:create density raster and extract sum by polygon feature创建密度栅格并按多边形特征提取总和
【发布时间】:2020-01-22 15:06:29
【问题描述】:

我有一个多边形 (zones) 和一组坐标 (points)。我想为整个多边形创建一个空间核密度栅格,并按区域提取密度总和。多边形之外的点应该被丢弃。

library(raster)
library(tidyverse)
library(sf)
library(spatstat)
library(maptools)

load(url("https://www.dropbox.com/s/iv1s5butsx2v01r/example.RData?dl=1"))
# alternatively, links to gists for each object
# https://gist.github.com/ericpgreen/d80665d22dfa1c05607e75b8d2163b84
# https://gist.github.com/ericpgreen/7f4d3cee3eb5efed5486f7f713306e96

ggplot() +
  geom_sf(data = zones) +
  geom_sf(data = points) +
  theme_minimal()

我尝试使用 {spatstat} 转换为 ppp,然后使用 density(),但我对结果中的单位感到困惑。我认为问题与地图的单位有关,但我不确定如何进行。

更新

这是重现我创建的密度图的代码:

zones_owin <- as.owin(as_Spatial(zones))
pts <- st_coordinates(points)
p <- ppp(pts[,1], pts[,2], window=zones_owin, unitname=c("metre","metres"))
ds <- density(p) 
r <- raster(ds)
plot(r)

【问题讨论】:

  • 能否包含所有相关代码?您是如何转换为栅格的?如果您将数据样本添加到帖子中而不是通过第三方,那就更好了
  • 如果人们喜欢以这种方式获取数据,我会添加指向每个对象的要点的链接。我的光栅代码遵循复杂的 shapefile 转换过程,因此我将示例简化为 sf 对象以在本文中重新开始。但我之前的尝试基本上是raster(density(ppp()))
  • @camille 我玩了一下,得到了重现我创建的密度图的代码。我不知道这些单位是什么。也许我需要完全采取不同的方法。

标签: r spatial raster sf


【解决方案1】:

当您直接使用地理坐标(经度、纬度)时,单位很困难。如果可能,您应该转换为平面坐标(这是spatstat 的要求)并从那里开始。平面坐标通常以米为单位,但我想这取决于特定的投影和底层椭球等。您可以查看this answer,了解如何使用sf 投影到平面坐标并使用spatstat 格式导出maptools注意:您必须手动选择一个合理的投影(您可以使用http://epsg.io 找到一个),并且您必须同时投影多边形和点。

一旦所有内容都采用spatstat 格式,您就可以使用density.ppp 进行内核平滑。生成的网格值(im 类的对象)是点的强度,即每平方单位(例如平方米)的点数。如果您想聚合某个区域,您可以使用integral.im(..., domain = ...) 来获取该区域中具有给定强度的点过程模型的预期点数。

【讨论】:

  • 非常有帮助!我错过了平面的st_transform() 步骤。您能建议如何更改单位吗? zones 现在是 +units=m。如果我想将单位设置为公里怎么办?
  • 这些单位是特定于投影的。您可以找到使用您正在寻找的单位的投影,或者进行计算并在最后转换单位(我更喜欢)。
  • 谢谢。转换比简单的乘法或除法更复杂,对吗?
  • 一旦你有了平面坐标和单位,例如m 转换为 km 只是简单地除以 1000 - 没什么特别的。您可以使用 rescale 函数在 spatstat 中执行此操作,您还可以在其中为单位命名,但它对单位本身一无所知,因此您不能只要求 spatstat 将 m 转换为 km。您必须告诉缩放因子是 1000,新名称是 km。祝你好运!
【解决方案2】:

我不确定这是否能回答您的所有问题,但应该是一个好的开始。如果您需要不同类型的输出,请在评论或您的问题中澄清。

它会删除不在“区域”多边形之一内的所有点,按区域对它们进行计数,并根据落在其中的点数绘制区域。

library(raster)
library(tidyverse)
library(sf)
#> Linking to GEOS 3.6.2, GDAL 2.2.3, PROJ 4.9.3
library(spatstat)

library(maptools)
#> Checking rgeos availability: TRUE

load(url("https://www.dropbox.com/s/iv1s5butsx2v01r/example.RData?dl=1"))
# alternatively, links to gists for each object
# https://gist.github.com/ericpgreen/d80665d22dfa1c05607e75b8d2163b84
# https://gist.github.com/ericpgreen/7f4d3cee3eb5efed5486f7f713306e96

p1 <- ggplot() +
  geom_sf(data = zones) +
  geom_sf(data = points) +
  theme_minimal()

#Remove points outside of zones
points_inside <- st_intersection(points, zones)
#> although coordinates are longitude/latitude, st_intersection assumes that they are planar
#> Warning: attribute variables are assumed to be spatially constant throughout all
#> geometries
nrow(points)
#> [1] 308
nrow(points_inside)
#> [1] 201

p2 <- ggplot() + 
  geom_sf(data = zones) + 
  geom_sf(data = points_inside)

points_per_zone <- st_join(zones, points_inside) %>%
  count(LocationID.x)
#> although coordinates are longitude/latitude, st_intersects assumes that they are planar

p3 <- ggplot() + 
  geom_sf(data = points_per_zone, 
          aes(fill = n)) + 
  scale_fill_viridis_c(option = 'C')

points_per_zone
#> Simple feature collection with 4 features and 2 fields
#> geometry type:  POLYGON
#> dimension:      XY
#> bbox:           xmin: 34.0401 ymin: -1.076718 xmax: 34.17818 ymax: -0.9755066
#> epsg (SRID):    4326
#> proj4string:    +proj=longlat +ellps=WGS84 +no_defs
#> # A tibble: 4 x 3
#>   LocationID.x     n                                                    geometry
#> *        <dbl> <int>                                               <POLYGON [°]>
#> 1           10   129 ((34.08018 -0.9755066, 34.0803 -0.9757393, 34.08046 -0.975…
#> 2           20    19 ((34.05622 -0.9959458, 34.05642 -0.9960835, 34.05665 -0.99…
#> 3           30    29 ((34.12994 -1.026372, 34.12994 -1.026512, 34.12988 -1.0266…
#> 4           40    24 ((34.11962 -1.001829, 34.11956 -1.002018, 34.11966 -1.0020…

cowplot::plot_grid(p1, p2, p3, nrow = 2, ncol = 2)

看来我低估了你的问题的难度。您正在寻找类似于下图(和基础数据)的内容吗?

它使用具有 ~50x50 网格的 raster、具有 9x9 窗口的 raster::focal 使用均值插值数据。

【讨论】:

  • 谢谢@mrhellmann。我认为这可以很好地计算每个功能的点数。我正在寻找的是空间上的一些插值。内核密度、IDW 等。我尝试了密度,但我很难理解这些单位。
  • 我会看看我能不能想出更接近你正在寻找的东西。
  • 更新后的剧情很有意思。非常符合我的想法。可以分享一下如何操作参数吗?
  • @EricGreen 今天晚上我会清理并编辑帖子。引以为豪的代码目前是 rstudio 历史日志中的一个失误雷区。
猜你喜欢
  • 2017-12-16
  • 1970-01-01
  • 2012-03-08
  • 1970-01-01
  • 2021-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多