Checking if a GPS coordinate belong in a defined geo-polygon

I have GPS coordinates in degrees within a data frame that I converted to the class SpatialPointsDataFrame. Also, I have a polygon object of the US border of the class SpatialPolygons. How can I check if the coordinates in the data frame are within the polygon?

This is my US_Border polygon and GPS Coordinates:

States <- raster::getData("GADM", country = "United States", level = 1)
US_Border <- rgeos::gUnaryUnion(States, id = States$ISO)
df <- data.frame(long = c(-64.70165790479105, -127.0546743044134, -123.8361408468202, -78.01064761813421, -64.70165790479105), 
                 lat = c(46.54000819626808, 50.41093540503351, 30.37665910843564, 24.54447072686601, 46.54000819626808))
coordinates(df) <- ~ long + lat
library(ggplot2)
library(sf)
#> Linking to GEOS 3.11.0, GDAL 3.5.3, PROJ 9.1.0; sf_use_s2() is TRUE
library(tigris)
#> To enable caching of data, set `options(tigris_use_cache = TRUE)`
#> in your R script or .Rprofile.

boundary <- nation(resolution = '20m')
#> Retrieving data for the year 2021
#>   |                                                                              |                                                                      |   0%  |                                                                              |======                                                                |   8%  |                                                                              |=========                                                             |  13%  |                                                                              |============                                                          |  18%  |                                                                              |===================                                                   |  27%  |                                                                              |================================                                      |  45%  |                                                                              |======================================                                |  55%  |                                                                              |=============================================                         |  64%  |                                                                              |================================================                      |  69%  |                                                                              |======================================================================| 100%

d <- data.frame(
  long = c(-64.70165790479105, -127.0546743044134, -123.8361408468202, -78.01064761813421, -64.70165790479105),
  lat = c(46.54000819626808, 50.41093540503351, 30.37665910843564, 24.54447072686601, 46.54000819626808)
)

pts <- st_as_sf(d, coords = c("long", "lat"))

# conform coordinate system
st_crs(pts) <- st_crs(boundary)$input

# pts are near corners of contiguous US
ggplot(boundary) + geom_sf() + geom_sf(data = pts)


# none are within
st_intersects(boundary$geometry,pts$geometry, sparse = FALSE)
#>       [,1]  [,2]  [,3]  [,4]  [,5]
#> [1,] FALSE FALSE FALSE FALSE FALSE

# point known to be within contiguous US

pt <- data.frame(long = -82.9987942, lat = 39.9611755)
pt <- st_as_sf(pt, coords = c("long","lat"))
st_crs(pt) <- st_crs(boundary)$input
st_intersects(boundary$geometry,pt$geometry, sparse = FALSE)
#>      [,1]
#> [1,] TRUE

Created on 2023-05-22 with reprex v2.0.2

1 Like

I only know the solution with st_contain from sf package:

library(tidyverse)
library(sf);sf_use_s2(F)

US_Border_sf <- US_Border %>% st_as_sf()

df_points <- st_as_sf(df, coords = c("long","lat"), crs = 4326)

st_contains(df_points, US_Border_sf)

And the result shows that none of the 5 points are in the US domain:

although coordinates are longitude/latitude, st_contains assumes that they are planar
Sparse geometry binary predicate list of length 5, where the predicate was `contains'
 1: (empty)
 2: (empty)
 3: (empty)
 4: (empty)
 5: (empty)
1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.