Verificando se os pontos se enquadram no polígono


19

Zillow tem um conjunto de arquivos de forma para diferentes bairros das principais cidades dos EUA. Eu queria verificar se certos edifícios estavam presentes em determinados bairros usando R:

library(rgeos)
library(sp)
library(rgdal)

df <- data.frame(Latitude =c(47.591351, 47.62212,47.595152),
                 Longitude = c(-122.332271,-122.353985,-122.331639),
                 names = c("Safeco Field", "Key Arena", "Century Link"))
coordinates(df) <- ~ Latitude + Longitude

wa.map <- readOGR("ZillowNeighborhoods-WA.shp", layer="ZillowNeighborhoods-WA")

sodo <- wa.map[wa.map$CITY == "Seattle"  & wa.map$NAME == "Industrial District", ]

Consigo traçar sem problemas

plot(sodo)
points(df$Latitude ~ df$Longitude, col = "red", cex = 1)

insira a descrição da imagem aqui

proj4Combino a string do shapefile com meu data.frame

CRSobj <- CRS("+proj=longlat +datum=NAD83 +no_defs +ellps=GRS80 +towgs84=0,0,0 ")
df@proj4string <- CRSobj

over(df, sodo)

Isso me dá um monte de NAvalores. Eu tentei esta resposta

spp <- SpatialPoints(df)
spp@proj4string <- CRSobj
over(spp, sodo)

mas ainda obtém apenas NAvalores. Alguma idéia do que mais eu deveria tentar?

Respostas:


20

O espacial data.framenão está formado corretamente. Isso pode funcionar:

library(rgeos)
library(sp)
library(rgdal)

wa.map <- readOGR("ZillowNeighborhoods-WA.shp", layer="ZillowNeighborhoods-WA")

sodo <- wa.map[wa.map$CITY == "Seattle"  & wa.map$NAME == "Industrial District", ]

# Don't use df as name, it is an R function
# Better to set longitudes as the first column and latitudes as the second
dat <- data.frame(Longitude = c(-122.332271,-122.353985,-122.331639),
                  Latitude =c(47.591351, 47.62212,47.595152),
                  names = c("Safeco Field", "Key Arena", "Century Link"))
# Assignment modified according
coordinates(dat) <- ~ Longitude + Latitude
# Set the projection of the SpatialPointsDataFrame using the projection of the shapefile
proj4string(dat) <- proj4string(sodo)

over(dat, sodo)
#  STATE COUNTY    CITY                NAME REGIONID
#1    WA   King Seattle Industrial District   271892
#2  <NA>   <NA>    <NA>                <NA>       NA
#3  <NA>   <NA>    <NA>                <NA>       NA

over(sodo, dat)
#           names
#122 Safeco Field

7

Acabei de fazer a mesma coisa. A resposta de Pascal quase cobre, mas você pode precisar de duas etapas extras, como abaixo.

#After you create your list of latlongs you must set the proj4string to longlat
proj4string(dat) <- CRS("+proj=longlat")

#Before you re-set the proj4string to the one from sodo you must actually convert #your coordinates to the new projection
dat <- spTransform(dat, proj4string(sodo))

Não está claro para mim em quais casos essas etapas adicionais são necessárias. Para mim, a solução da resposta do usuário32309 foi boa o suficiente.
djhurio

3
Depende do formato dos seus dados. Se estiver na projeção A e você quiser apenas declarar que usa proj4string e deve ser bom. Mas se estiver na projeção B e você precisar fazer uma conversão para a projeção A, precisará usar o spTransform.
John Curry

2

Eu usei uma abordagem semelhante à resposta aceita neste post, mas nunca fiquei realmente satisfeito com isso, então procurei alternativas e encontrei o sf biblioteca .

E usando esta biblioteca, você pode escrever um código como este:

library(sf)
# Shapefile from ABS: 
# https://www.abs.gov.au/AUSSTATS/abs@.nsf/DetailsPage/1270.0.55.004July%202016?OpenDocument
map = read_sf("data/ABS/shapes/SUA_2016_AUST.shp")

pnts_sf <- st_as_sf(pnts, coords = c('y', 'x'), crs = st_crs(map))

pnts <- pnts_sf %>% mutate(
  intersection = as.integer(st_intersects(geometry, map))
  , area = if_else(is.na(intersection), '', map$SUA_NAME16[intersection])
) 

pnts

Resultado:

         geometry intersection area    
*     <POINT [°]>        <int> <chr>   
1 (138.62 -34.92)           79 Adelaide
2 (138.58 -34.93)           79 Adelaide
3 (138.52 -34.95)           79 Adelaide
4 (152.71 -27.63)           60 Brisbane
5 (153.01 -27.57)           60 Brisbane
6  (150.73 -33.9)           31 Sydney  
7 (150.99 -33.92)           31 Sydney 

Eu publiquei esse código em outro post que era uma pergunta semelhante, aqui: Identificar ponto contendo polígono com o pacote R sf

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.