如何确定一个点是否在缓冲区内

How to determine if a point is within a buffer

我正在处理一个如下所示的 SpatialPointsDataFrame:

new("SpatialPointsDataFrame", data = structure(list(date = c("01dec2013", 
"01jul2003", "01nov2008", "01dec2017", "01dec2017", "01dec2003"
), company = c("Shwe Taung", "PetroChina Exploration and Development", 
"Repsol SA", "Repsol SA", "Ipsen Pharmaceutical", "Ceva Laval"
), parent_company = c("Shwe Taung", "China National Petroleum (CNPC)", 
"Repsol SA", "Repsol SA", "Ipsen Pharmaceutical", "Ceva Sante Animale"
), Website = c("www.shwetaunggroup.com", "www.cnpc.com.cn", "www.repsol.com", 
"www.repsol.com", "www.ipsen.com", "www.ceva.com"), revenues_usd_ml = c(NA, 
394554.53, 53215.45, 53215.45, 1760.671, 967.152), Headcount = c(NA, 
1396144L, 24634L, 24634L, NA, 3500L), r_d_exp = c(NA, NA, 77.67, 
77.67, NA, NA), est_year = c(NA, 1988L, 1927L, 1927L, 1929L, 
1989L), o_country = c("Myanmar", "China", "Spain", "Spain", "France", 
"France"), o_state = c("Rangoon (Yangon)", "Beijing Municipality", 
"Comunidad de Madrid", "Comunidad de Madrid", "Ile-de-France", 
"Sud-Ouest (FR)"), o_admin = c("Not Specified", "Not Specified", 
"Madrid", "Madrid", "Ile-de-France", "Not Specified"), o_city = c("Rangoon (Yangon)", 
"Beijing", "Madrid", "Madrid", "Paris", "Not Specified"), country = c("Algeria", 
"Algeria", "Algeria", "Algeria", "Algeria", "Algeria"), state = c("Adrar", 
"Adrar", "Adrar", "Adrar", "Adrar", "Adrar"), region = c("Not Specified", 
"Not Specified", "Not Specified", "Not Specified", "Not Specified", 
"Not Specified"), city = c("Adrar", "Adrar", "Reggane", "Reggane", 
"Sidi Abdallah", "Sidi Abdallah"), free_zone = c("", "", "", 
"", "", ""), relocation = c("", "", "", "", "", ""), sector = c("Building materials", 
"Coal, oil & gas", "Coal, oil & gas", "Coal, oil & gas", "Pharmaceuticals", 
"Healthcare"), sub_sector = c("Cement & concrete products", "Oil & gas extraction", 
"Oil & gas extraction", "Oil & gas extraction", "Pharmaceutical preparations", 
"Other (Healthcare)"), cluster = c("Construction", "Energy", 
"Energy", "Energy", "Life sciences", "Life sciences"), activity = c("Manufacturing", 
"Extraction", "Extraction", "Extraction", "Manufacturing", "Manufacturing"
), fdi_jobs = c(351L, 145L, 235L, 227L, 150L, 45L), est_fdi_jobs = c("Yes", 
"Yes", "Yes", "Yes", "No", "No"), capital = c(139.9, 350, 565, 
299.7, 29.55, 2.5), est_capital = c("Yes", "No", "No", "Yes", 
"No", "No"), fdi_type = c("New", "New", "New", "Expansion", "New", 
"New"), fdi_status = c("Announced", "Announced", "Announced", 
"Opened", "Announced", "Opened"), g_lon = c(-0.287488, -0.287488, 
0.1751507, 0.1751507, 5.0152099, 5.0152099), year = c(2013L, 
2003L, 2008L, 2017L, 2017L, 2003L), code_d = c(12L, 12L, 12L, 
12L, 12L, 12L), income_d = c("MIDLW", "MIDLW", "MIDLW", "MIDLW", 
"MIDLW", "MIDLW"), continent_d = c("Africa", "Africa", "Africa", 
"Africa", "Africa", "Africa"), lang_d = c("Arabic", "Arabic", 
"Arabic", "Arabic", "Arabic", "Arabic"), landlocked = c(0L, 0L, 
0L, 0L, 0L, 0L), iso_d = c("DZA", "DZA", "DZA", "DZA", "DZA", 
"DZA"), isic = c(26L, 11L, 11L, 11L, 24L, 85L), isic4 = c(2695L, 
1110L, 1110L, 1110L, 2411L, 8519L), sector_eora = c("Petroleum, Chemical and Non-Metallic Mineral Products", 
"Mining and Quarrying", "Mining and Quarrying", "Mining and Quarrying", 
"Petroleum, Chemical and Non-Metallic Mineral Products", "Mining and Quarrying"
), oc_lat = c(26.4888155, 26.4888155, 26.7207267, 26.7207267, 
32.5966492, 32.5966492), oc_lng = c(-1.3582442, -1.3582442, 0.1751507, 
0.1751507, -7.8308492, -7.8308492), oc_formatted = c("Adrar, Algeria", 
"Adrar, Algeria", "Reggane, Reggane District, Algeria", "Reggane, Reggane District, Algeria", 
"Sidi Abdallah, cercle de Rehamna, Morocco", "Sidi Abdallah, cercle de Rehamna, Morocco"
), oc_lat_st = c(26.4888155, 26.4888155, 26.4888155, 26.4888155, 
26.4888155, 26.4888155), oc_lng_st = c(-1.3582442, -1.3582442, 
-1.3582442, -1.3582442, -1.3582442, -1.3582442), oc_formatted_st = c("Adrar, Algeria", 
"Adrar, Algeria", "Adrar, Algeria", "Adrar, Algeria", "Adrar, Algeria", 
"Adrar, Algeria")), row.names = c(NA, 6L), class = "data.frame"), 
    coords.nrs = numeric(0), coords = structure(c(-1.3582442, 
    -1.3582442, 0.1751507, 0.1751507, -7.8308492, -7.8308492, 
    26.4888155, 26.4888155, 26.7207267, 26.7207267, 32.5966492, 
    32.5966492), .Dim = c(6L, 2L), .Dimnames = list(NULL, c("coords.x1", 
    "coords.x2"))), bbox = structure(c(-7.8308492, 26.4888155, 
    0.1751507, 32.5966492), .Dim = c(2L, 2L), .Dimnames = list(
        c("coords.x1", "coords.x2"), c("min", "max"))), proj4string = new("CRS", 
        projargs = "+proj=longlat +datum=WGS84 +no_defs"))

我的任务是确定用 oc_lat_st oc_lng_st 列标识的质心是否落在用 oc_lat 和 [=15= 列标识的质心周围 50 公里缓冲区内].

我目前生成的代码是:

library(rgdal)
library(ggplot2)
library(dplyr)
library(tidyr)
library(maptools)
library(rgeos)

FDI <- read.csv("FDI_harmonized.csv")

coords <- FDI[,40:41]

plot(coords)

coords <- drop_na(coords)
FDI <- FDI[!is.na(FDI$oc_lat), ]

coordinates(FDI) <- cbind(coords$oc_lng,coords$oc_lat)

#change coordinate reference system
geo_proj = "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"

proj4string(FDI) <- CRS(geo_proj)

#build buffer
distInMeters <- 1000
FDI50km <- gBuffer(FDI, width=100*distInMeters, byid=TRUE )

# Add data, and write to shapefile
FDI50km <- SpatialPolygonsDataFrame(FDI50km, data=FDI50km@data )
writeOGR( FDI50km, "FDI50km", "FDI50km", driver="ESRI Shapefile" )

plot(FDI50km) 

但输出只是一个没有任何 CRS 的大缓冲区。

你有什么建议吗?理想的输出是一个额外的列,其中包含一个 T/F 或 1/0 值,用于表示第一组坐标是否落在缓冲区内。

通过像这样读取平面数据来使用 sf 包:

library(sf)
geo_proj = "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
df_new <- st_as_sf(df, coords = c("oc_lng", "oc_lat"), crs = geo_proj)

或者,将您的数据从 sp 转换为 sf:

library(sf)
df_new <- sf::st_as_sf(yourspatialdataframe)

然后将缓冲区定义为单独的功能 class:

# Define polygons
df_buff <- st_buffer(df_new, dist = 1000)

并按照 ?sf::st_intersects() 中的示例与您的点和缓冲区相交:

# Example data
pts = st_sfc(st_point(c(.5,.5)), st_point(c(1.5, 1.5)), st_point(c(2.5, 2.5)))
pol = st_polygon(list(rbind(c(0,0), c(2,0), c(2,2), c(0,2), c(0,0))))

# View data
plot(x = NA, xlim = c(0,3), ylim = c(0,3), axes = FALSE, ann = FALSE)
plot(pts, col = "blue", add= TRUE)
plot(pol, add= TRUE)

# Intersect
lst = st_intersects(pts, pol)
lst
#> Sparse geometry binary predicate list of length 3, where the predicate
#> was `intersects'
#>  1: 1
#>  2: 1
#>  3: (empty)
mat = st_intersects(pts, pol, sparse = FALSE)
mat
#>       [,1]
#> [1,]  TRUE
#> [2,]  TRUE
#> [3,] FALSE

# which points fall inside a polygon?
apply(mat, 1, any)
#> [1]  TRUE  TRUE FALSE
lengths(lst) > 0
#> [1]  TRUE  TRUE FALSE
# which points fall inside the first polygon?
st_intersects(pol, pts)[[1]]
#> [1] 1 2