Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find which polygon a point belong to via sf

Tags:

r

gis

sp

tidyverse

sf

I have a sf object that contains polygon information (precincts) for a metro area, obtained through a .shp file. For a given lat/lon pair, I want to determine which precinct it belongs to. I'm thinking I can utilize sf::st_contains() but am having trouble getting the lat/lon in the right format.

like image 311
kevinykuo Avatar asked Apr 17 '17 17:04

kevinykuo


People also ask

What is an sf object in R?

At its most basic, an sf object is a collection of simple features that includes attributes and geometries in the form of a data frame. In other words, it is a data frame (or tibble) with rows of features, columns of attributes, and a special geometry column that contains the spatial aspects of the features.

Is a point inside a polygon?

A point is inside the polygon if either count of intersections is odd or point lies on an edge of polygon. If none of the conditions is true, then point lies outside.

What is sf package?

The sf package encodes spatial vector data according to the Simple Features standard described by the Open Geospatial Consortium (OGC) and International Organization for Standardization (ISO). The sf package provides bindings to GDAL for reading and writing data, to GEOS for geometrical operations, and to proj.


2 Answers

Use st_point() on the lon/lat then it can work with other sf functions.

Example:

find_precinct <- function(precincts, point) {
  precincts %>%
    filter(st_contains(geometry, point) == 1) %>%
    `[[`("WARDS_PREC")
}


ggmap::geocode("nicollet mall, st paul") %>%
  rowwise() %>%
  mutate(point = c(lon, lat) %>%
           st_point() %>%
           list(),
         precinct = find_precinct(msvc_precincts, point)
         )
like image 68
kevinykuo Avatar answered Sep 21 '22 21:09

kevinykuo


If you have a data.frame of coordinates (mydf), convert them to an sf object and then intersect with an sf map of polygons:

mydf_sf <- sf::st_as_sf(mydf, coords=c("lon","lat"), crs=4326)
int <- sf::st_intersects(mydf_sf , map)
mydf$country <- map$country_name[unlist(int)]

There's a complete working example at https://gis.stackexchange.com/a/318629/36710

like image 36
Berry Boessenkool Avatar answered Sep 19 '22 21:09

Berry Boessenkool