r - 在 sf 对象中按距离聚合特征
问题描述
我有两个sf
对象:多边形county
(注意:这是一个多多边形,即许多县)和点monitor2
。
county
如下所示。汉字不能正常显示,但问题不大。
Simple feature collection with 6 features and 4 fields
geometry type: MULTIPOLYGON
dimension: XY
bbox: xmin: 113.15 ymin: 20.58265 xmax: 124.5656 ymax: 40.10793
epsg (SRID): 4326
proj4string: +proj=longlat +datum=WGS84 +no_defs
City District Province Code geometry
1 <U+53F0><U+6E7E><U+7701> <U+53F0><U+6E7E><U+7701> <U+53F0><U+6E7E><U+7701> 710000 MULTIPOLYGON (((116.7346 20...
2 <U+5317><U+4EAC><U+5E02> <U+671D><U+9633><U+533A> <U+5317><U+4EAC><U+5E02> 110105 MULTIPOLYGON (((116.4834 40...
3 <U+4E0A><U+6D77><U+5E02> <U+666E><U+9640><U+533A> <U+4E0A><U+6D77><U+5E02> 310107 MULTIPOLYGON (((121.3562 31...
4 <U+4E0A><U+6D77><U+5E02> <U+5B9D><U+5C71><U+533A> <U+4E0A><U+6D77><U+5E02> 230506 MULTIPOLYGON (((121.4855 31...
5 <U+5E7F><U+5DDE><U+5E02> <U+767D><U+4E91><U+533A> <U+5E7F><U+4E1C><U+7701> 440111 MULTIPOLYGON (((113.4965 23...
6 <U+798F><U+5DDE><U+5E02> <U+9F13><U+697C><U+533A> <U+798F><U+5EFA><U+7701> 320106 MULTIPOLYGON (((119.2611 26...
monitor2
如下所示。
Simple feature collection with 6 features and 5 fields
geometry type: POINT
dimension: XY
bbox: xmin: 116.17 ymin: 39.8673 xmax: 116.473 ymax: 40.2865
epsg (SRID): 4326
proj4string: +proj=longlat +datum=WGS84 +no_defs
# A tibble: 6 x 6
code name city ref value geometry
<chr> <chr> <chr> <chr> <dbl> <POINT [°]>
1 1001A 万寿西宫 北京 N 47.8 (116.366 39.8673)
2 1002A 定陵 北京 Y 45.9 (116.17 40.2865)
3 1003A 东四 北京 N 42.2 (116.434 39.9522)
4 1004A 天坛 北京 N 51.2 (116.434 39.8745)
5 1005A 农展馆 北京 N 46.9 (116.473 39.9716)
6 1006A 官园 北京 N 49.5 (116.361 39.9425)
第一个任务是将value
特征加入monitor2
到county
. 我用st_is_within_distance
and做到了这一点st_join
。请参阅下面的代码。我将距离设置为 50 公里。新多边形中的某些县可能具有来自 50 公里缓冲区内多个点的值。
new = st_join(county, monitor2,
join = st_is_within_distance, dist = 50)
第二个任务来了。我需要从 50 公里缓冲区内的不同点到县质心的距离汇总值。我如何完成这项任务?
欢迎任何意见。
解决方案
如果没有可重复的数据,很难确切地知道您想要什么,但这里尝试展示您如何做到这一点。
获取样本数据。我们在这里从纬度/经度重新投影到带有米的东西,这样我们就可以进行基于距离的空间操作。我们将使用样本数据中的 3 个县,并使用中间县作为我们要测量距离的主要多边形,并添加散布在三个县的点的随机样本。
library(sf)
nc <- st_read(system.file("shape/nc.shp", package="sf"))
nc <- st_transform(nc, 32119) # NC state plane projection in metres
county = st_cast(nc[2,],"POLYGON")
p1 = st_as_sf(st_sample(nc[1:3, ], 200)) # random points
# Visualize
plot(st_geometry(nc)[1:3])
plot(county, col = "grey80", add = TRUE)
我们只想关注距目标县一定距离内的点。让我们通过使用st_buffer
.
plot(st_buffer(county, dist = 10000), col = NA, border = "red", lty = 3, add = TRUE)
我们可以对中心县 10000m 范围内的点进行子集化,这与与对象st_is_within_distance
相交的效果相同。st_buffer
p1_10 <- p1[st_is_within_distance(county,p1,dist = 10000, sparse = FALSE),]
测量质心和该子集的每个元素之间的距离是直截了当的。然后,我们可以将距离测量值分配为子空间对象中的变量。
p1_10$distance_to_centroid <- as.vector(st_distance(st_centroid(county), p1_10))
这是完全绘制的样子
plot(st_geometry(nc)[1:3])
plot(county, col = "grey80", add = TRUE)
plot(p1, add = TRUE, pch = 19)
plot(st_buffer(county, dist = 10000), col = NA, border = "red", lty = 3, add = TRUE)
plot(st_centroid(county), col = "red", pch = 15, cex = 1, axes = TRUE, add = TRUE)
plot(p1_10["distance_to_centroid"], add = TRUE, pch = 19)
> p1_10
Simple feature collection with 78 features and 1 field
geometry type: POINT
dimension: XY
bbox: xmin: 389967.6 ymin: 293489.4 xmax: 448197.1 ymax: 315140.7
CRS: EPSG:32119
First 10 features:
x distance_to_centroid
1 POINT (437228.1 294079.7) 21703.5425
2 POINT (425029.8 305656.7) 5868.4917
3 POINT (425131.4 309137.8) 6665.0253
4 POINT (409851.2 294971.7) 14549.0585
5 POINT (393070.6 303879.7) 26207.5651
6 POINT (436666.3 296282.2) 20070.5879
7 POINT (442623.8 295976.3) 25549.5662
8 POINT (400517.2 307897.4) 18746.6918
9 POINT (418763.7 306728) 724.6165
10 POINT (405001.4 294845.7) 18125.0738
因此,您可以从这里使用您想要的任何方法按距离聚合您的特征。在dplyr
中,它非常简单。例如,假设我想以 5 公里的间隔聚合。
library(dplyr)
p1_10 %>%
mutate(dist_group = ceiling(distance_to_centroid/5000)) %>%
group_by(dist_group) %>%
tally() %>% # stop here if you want the result to retain geography
as_tibble() %>%
select(dist_group, n)
# A tibble: 7 x 2
dist_group n
<dbl> <int>
1 1 7
2 2 15
3 3 22
4 4 13
5 5 11
6 6 9
7 7 1
推荐阅读
- python - 已解决 - 为什么两个连续的 for 循环都不执行?
- python - 使用 asyncio 完成对我的 python 脚本进行编码的问题
- python - dokku 中的 Celery 看不到 sqlite 记录
- matlab - 高效计算和重做图形动作
- laravel - Laravel:如何根据条件添加到集合中的每个对象
- python - Python opens executable, but it doesn't close on its own
- r - 在 R 中绘制网格
- c++ - 指向具有私有构造函数的类的类成员的指针
- javascript - 使用 Content-Security-Policy 和 JavaScript 避免 `script-src 'unsafe-inline'`
- javascript - 如何编辑咖喱/箭头函数以包含正则表达式?