簡體   English   中英

R 中具有兩個幾何的 sf 上的幾何運算

[英]Geometric operations on sf with two geometries in R

我有一個帶有兩個幾何列的 sf 數據集。 這是它的樣子:

> trip_geo

   dstid sourceid                    dest_geom                    source_geom
1    1        1   MULTIPOLYGON (((-2.607985 5... MULTIPOLYGON (((-2.607985 5...
2    1        2   MULTIPOLYGON (((-2.607985 5... MULTIPOLYGON (((-2.57022 51...
3    1        3   MULTIPOLYGON (((-2.607985 5... MULTIPOLYGON (((-2.593213 5...
4    1        4   MULTIPOLYGON (((-2.607985 5... MULTIPOLYGON (((-2.608686 5...
5    1        5   MULTIPOLYGON (((-2.607985 5... MULTIPOLYGON (((-2.512852 5...

活動幾何體是dest_geom

每一行對應於鄰里之間的一次旅行。 對於每次旅行,我想知道旅行途中有哪些街區。 也就是說,如果要在每一行的 source_geom 和 dest_geom 之間畫一條直線,哪些幾何圖形會碰到這條直線? 我想獲得該行的所有接觸幾何圖形,然后將它們合並。

我有另一個數據集,其幾何形狀與每個 id 相對應:

> id_geo

   dstid                       geometry
1      1 MULTIPOLYGON (((-2.607985 5...
2      2 MULTIPOLYGON (((-2.57022 51...
3      3 MULTIPOLYGON (((-2.593213 5...
4      4 MULTIPOLYGON (((-2.608686 5...
5      5 MULTIPOLYGON (((-2.512852 5...

我想第一步是為每次旅行在 source_geom 和 dest_geom 的質心之間定義一條線。 然后,創建一個 sf,其中幾何列包含接觸該線的多邊形列表(我不知道是否可以在 sf 的一列中包含多個幾何圖形)。 然后,合並包含在同一行/列表中的幾何圖形。

我不認為我處理問題的方式是正確的,因為據我所知,不能對 sf 的兩個幾何圖形進行操作,例如定義一條線。 此外,我不知道如何將列表集成到數據框/sf。

如果您能提出一種更現實的解決問題的方法,我將不勝感激。

在一個 sf 數據框中有兩個幾何圖形並沒有錯,但是當它與采用隱式幾何圖形的函數一起使用時,只有其中一個可以是幾何圖形,例如st_centroid(foo)獲取設置幾何圖形的質心。

對於其他幾何圖形,您可以處理該命名列,例如st_centroid(foo$source_geom)

對於具有兩個多邊形幾何圖形的數據框nc ,您可以通過首先合並點以創建 MULTIPOINT 然后將它們轉換為 LINESTRING 來計算質心之間的線。 例如,對於第一行:

> st_cast(st_union(c(st_centroid(nc$source_geom[1]), st_centroid(nc$dest_geom[1]))),"LINESTRING")
Geometry set for 1 feature 
geometry type:  LINESTRING
dimension:      XY
bbox:           xmin: -81.49826 ymin: 36.42228 xmax: -77.41056 ymax: 36.4314
epsg (SRID):    NA
proj4string:    NA
LINESTRING (-81.49826 36.4314, -77.41056 36.42228)

您必須逐行執行此操作,否則最終會在整個幾何向量上進行操作。

完整的例子。 執行library(spdep)example(poly2nb)以獲取nc.sids

首先將其縮減為兩列和 5 個隨機行:

> nc = nc.sids[,c("NAME","FIPS")]
> nc = nc[sample(1:nrow(nc.sids),5),]
> nc
Simple feature collection with 5 features and 2 fields
geometry type:  MULTIPOLYGON
dimension:      XY
bbox:           xmin: -83.73952 ymin: 34.36442 xmax: -78.16968 ymax: 36.54607
epsg (SRID):    NA
proj4string:    NA
         NAME  FIPS                       geometry
82 Cumberland 37051 MULTIPOLYGON (((-78.49929 3...
96     Bladen 37017 MULTIPOLYGON (((-78.2615 34...
13  Granville 37077 MULTIPOLYGON (((-78.74912 3...
78      Macon 37113 MULTIPOLYGON (((-83.10629 3...
14     Person 37145 MULTIPOLYGON (((-78.8068 36...

假設功能 1 轉到功能 2、2 到 3 等。創建新的幾何列:

> nc$dest_geom = nc$geometry[c(2,3,4,5,1)]

現在制作連接質心的線:

> nc$join_geom = st_sfc(sapply(1:nrow(nc),function(i)st_cast(st_union(c(st_centroid(nc$geometry[i]), st_centroid(nc$dest_geom[i]))),"LINESTRING")))

陰謀:

質心連接

> plot(nc$geom)
> plot(nc$join_geom,add=TRUE,lty=2)

@Spacedman 的響應非常適合在感興趣的多邊形之間畫線。 下面是 (1) 繪制線條和 (2) 選擇與每條線相交的多邊形並合並選擇的代碼。

#Draw a line between each source and destination
library(sf)
trip_geo$join_geom = st_sfc(sapply(1:nrow(trip_geo),function(j)
+ st_cast(st_union(c(st_centroid(trip_geo$dest_geom[j]),
+ st_centroid(trip_geo$source_geom[j]))),"LINESTRING")), crs=4326)

#For each trip, select the polygons that intersect the line, then union them together
df=data.frame()
for (i in 1:nrow(trip_geo)){
    id_geo$touch=apply(st_intersects(id_geo, trip_geo$join_geom[i]), 1, any)
    touch=subset(id_geo, touch==T)
    touch=st_union(touch)
    df[i,1]=touch #append the unioned polygons to an empty dataframe
  }

#Add the unioned polygons to the original dataset
sf=st_sf(df, crs=4326) 
bound=cbind(trip_geo, sf)

計算需要一些時間(畫線大約需要 1 分鍾,循環大約需要 1 分鍾,有 3,500 個多邊形),我確信我的代碼可以改進。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM