Verifica se i punti rientrano nel poligono Shapefile


19

Zillow ha una serie di shapefile per diversi quartieri delle principali città degli Stati Uniti. Volevo verificare se alcuni edifici erano presenti in alcuni quartieri 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", ]

Posso tracciare senza problemi

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

inserisci qui la descrizione dell'immagine

proj4Abbino la stringa dal file di forma al mio data.frame

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

over(df, sodo)

Questo mi dà solo un sacco di NAvalori. Ho provato questa risposta

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

ma ottiene ancora solo NAvalori. Qualche idea cos'altro dovrei provare?

Risposte:


20

Lo spazio data.framenon è formato correttamente. Questo potrebbe funzionare:

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

Ho appena fatto la stessa cosa. La risposta di Pascal la copre quasi, ma potresti aver bisogno di due passaggi aggiuntivi come di seguito.

#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))

Non mi è chiaro in quali casi sono necessari questi passaggi aggiuntivi. Per me la soluzione della risposta dell'utente32309 è stata abbastanza buona.
djhurio,

3
Dipende dal formato in cui si trovano i tuoi dati. Se è nella proiezione A e vuoi solo dichiarare che usi proj4string e dovresti essere bravo. Ma se è nella proiezione B e devi fare una conversione in modo effettivo alla proiezione A devi usare spTransform.
John Curry,

2

Ho usato un approccio simile alla risposta accettata in questo post, ma non sono mai stato davvero soddisfatto, quindi ho cercato delle alternative e ho trovato la libreria sf .

E usando questa libreria puoi quindi scrivere codice in questo modo:

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

Produzione:

         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 

Ho pubblicato questo codice su un altro post che era una domanda simile, qui: Identificare il poligono contenente il punto con il pacchetto R sf

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.