簡體   English   中英

在R中使用shapefile過濾緯度點

[英]Filter lat-lon points using shapefile in R

我正在嘗試使用shapefile過濾熱帶氣旋的緯度點:

  1. 鏈接到shapefile

我在以前的帖子中做了類似的問題:

過濾指定網格框上的TC軌跡(緯度點)

但是在這種情況下,我使用的是不規則的shapefile(而不是盒子)。

我只想過濾通過shapefile的具有相同標識符(下面的示例數據中的“ SN”列)的點。 因此,將僅過濾唯一的TC。

這是數據的子集:

dat <- structure(list(SN = c(200608L, 200608L, 200608L, 200608L, 200608L, 
200608L, 200608L, 200608L, 200608L, 200608L, 200608L, 200608L, 
200610L, 200610L, 200610L, 200612L, 200612L, 200612L, 200612L, 
200612L, 200612L, 200612L, 200709L, 200709L, 200709L, 200709L, 
200709L, 200709L, 200709L, 200709L, 200709L, 200709L, 200709L, 
200709L, 200709L, 200709L, 200709L, 200709L, 200709L, 200709L, 
200709L, 200709L, 200709L, 200709L, 200709L, 200709L, 200709L, 
200709L, 200709L, 200709L, 200709L, 200709L), CY = c(8L, 8L, 
8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 10L, 10L, 10L, 12L, 12L, 
12L, 12L, 12L, 12L, 12L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 
9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 
9L, 9L, 9L, 9L, 9L), Year = c(2006L, 2006L, 2006L, 2006L, 2006L, 
2006L, 2006L, 2006L, 2006L, 2006L, 2006L, 2006L, 2006L, 2006L, 
2006L, 2006L, 2006L, 2006L, 2006L, 2006L, 2006L, 2006L, 2007L, 
2007L, 2007L, 2007L, 2007L, 2007L, 2007L, 2007L, 2007L, 2007L, 
2007L, 2007L, 2007L, 2007L, 2007L, 2007L, 2007L, 2007L, 2007L, 
2007L, 2007L, 2007L, 2007L, 2007L, 2007L, 2007L, 2007L, 2007L, 
2007L, 2007L), Month = c(8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 
8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 
8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 
8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L), Day = c(9L, 9L, 
9L, 9L, 10L, 10L, 10L, 10L, 11L, 11L, 11L, 11L, 9L, 9L, 9L, 14L, 
14L, 14L, 15L, 15L, 15L, 15L, 12L, 12L, 12L, 13L, 13L, 13L, 13L, 
14L, 14L, 14L, 14L, 15L, 15L, 15L, 15L, 16L, 16L, 16L, 16L, 17L, 
17L, 17L, 17L, 18L, 18L, 18L, 18L, 19L, 19L, 19L), Hour = c(0L, 
6L, 12L, 18L, 0L, 6L, 12L, 18L, 0L, 6L, 12L, 18L, 0L, 6L, 12L, 
6L, 12L, 18L, 0L, 6L, 12L, 18L, 6L, 12L, 18L, 0L, 6L, 12L, 18L, 
0L, 6L, 12L, 18L, 0L, 6L, 12L, 18L, 0L, 6L, 12L, 18L, 0L, 6L, 
12L, 18L, 0L, 6L, 12L, 18L, 0L, 6L, 12L), Lat = c(23.7, 24.7, 
25.3, 25.9, 26.4, 27, 27.2, 27.4, 27.7, 28.1, 28.5, 28.9, 22.8, 
22.9, 22.4, 18.7, 19.8, 20.2, 21, 22.4, 23.9, 26.9, 17.4, 17, 
16.7, 16.6, 16.5, 16.4, 16.3, 16.2, 16, 15.8, 15.5, 15.6, 15.9, 
16.1, 16.6, 17.2, 17.9, 18.7, 19.4, 20.2, 21, 21.9, 22.7, 23.4, 
24, 24.4, 24.8, 25.2, 25.6, 26), Lon = c(128.4, 126.9, 125.3, 
123.9, 122.5, 121.1, 119.9, 118.7, 117.4, 115.8, 115, 114.4, 
119.8, 118.6, 117.7, 131.3, 132.4, 133.9, 135.6, 137.2, 139.1, 
140.4, 135.4, 135.2, 134.8, 134.3, 133.7, 133, 132.3, 131.5, 
130.7, 129.9, 129.2, 128.5, 128, 127.6, 127.1, 126.6, 126.1, 
125.6, 124.8, 124.2, 123.5, 122.8, 122, 121.2, 119.9, 119.4, 
119, 118.6, 118.3, 118)), class = "data.frame", row.names = c(NA, 
-52L))

完整的數據鏈接在這里

預期成績:

我的預期結果類似於上面的鏈接。 csv文件中的另外兩列表示TC是否在shapefile中。 每個TC都有一個唯一的標識符:SN列。 因此,如果具有相同SN號的經緯度點在shapefile中,則將它們標記為TRUE(具有相同SN號的所有經緯度點)。

dat[SN %in% dat[inBounds == TRUE, unique(SN)], passesThroughBox := T ]
dat[is.na(passesThroughBox), passesThroughBox := F]

關於如何在R中執行此操作的任何建議?

此致Lyndz

不是最好的樣本數據,因為似乎沒有任何觀察結果通過shapefile的bbox傳遞。盡管如此,她是我的專長。

library( tidyverse )
library( sf )

SF和Tidyverse解決方案

#first, get the boundaries of the shapefile
bbox <- read_sf(dsn = "./Bicol_Region/Bicol_region.shp") %>% st_bbox()

#      xmin      ymin      xmax      ymax 
# 122.29929  11.71056 124.42607  14.50061 


dat %>% 
  #check if measurement is withing boundaries (yes, or not (no))
  mutate( passes_through_box = ifelse( Lat >= bbox[2] & Lat <= bbox[4] & Lon >= bbox[1] & Lon <= bbox[3], "yes", "no" ) ) %>%
  #group by SN
  group_by( SN ) %>%
  #check if any value of 'passes_through_box' in a group is "yes", if so 'yes', else 'no'
  mutate( passes_through_box_anyime = ifelse( any( passes_through_box == "yes"), "yes", "no" ) )

# # A tibble: 52 x 10
# # Groups:   SN [4]
#       SN    CY  Year Month   Day  Hour   Lat   Lon passes_through_box passes_through_box_anyime
#    <int> <int> <int> <int> <int> <int> <dbl> <dbl> <chr>              <chr>                    
# 1 200608     8  2006     8     9     0  23.7  128. no                 no                       
# 2 200608     8  2006     8     9     6  24.7  127. no                 no                       
# 3 200608     8  2006     8     9    12  25.3  125. no                 no                       
# 4 200608     8  2006     8     9    18  25.9  124. no                 no                       
# 5 200608     8  2006     8    10     0  26.4  122. no                 no                       
# 6 200608     8  2006     8    10     6  27    121. no                 no   

全科幻解決方案

library( tidyverse )
library( sf )

#first, get the boundaries of the shapefile
bbox <- read_sf(dsn = "./Bicol_Region/Bicol_region.shp") %>% st_bbox() %>% st_as_sfc( crs = "+proj=longlat +datum=WGS84" )

#      xmin      ymin      xmax      ymax 
# 122.29929  11.71056 124.42607  14.50061 

#create aspatial data.frame
spdf <- st_as_sf( x = dat,
                  coords = c("Lon", "Lat"),
                  crs = "+proj=longlat +datum=WGS84" )

spdf %>% 
  #check if a line the spatial df intersecgt with the defined boundary-box
  mutate( passes_through_box = as.numeric( st_intersects(spdf, bbox) ) ) %>%
  group_by( SN ) %>%
  mutate( passes_through_box_anyime = ifelse( any( passes_through_box == 1), "yes", "no" ) )

為了完整起見,另一種SF方法

library( tidyverse )
library( sf )

#first, get the boundaries of the shapefile and create a box
bbox <- read_sf(dsn = "./Bicol_Region/Bicol_region.shp") %>% st_bbox() %>% st_as_sfc( crs = "+proj=longlat +datum=WGS84" )

#create a spatial points data.frame using the sample data provided
spdf <- st_as_sf( x = dat,
                  coords = c("Lon", "Lat"),
                  crs = "+proj=longlat +datum=WGS84" )

#create a spatial lines data.frame, bases on lat-lon groupes by SN
sldf <- spdf %>%
  group_by( SN ) %>%
  summarise( m = mean( Year ) ) %>%
  st_cast( "LINESTRING" ) %>%
  select( -m )

#let's see the printed results
library(mapview)
mapview( list(bbox, sldf) )

在此處輸入圖片說明

#any intersections? ... #nope, no intersections
st_intersects( bbox, sldf )

# although coordinates are longitude/latitude, st_intersects assumes that they are planar
# Sparse geometry binary predicate list of length 1, where the predicate was `intersects'
# 1: (empty)

暫無
暫無

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

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