简体   繁体   English

检查点是否落在多边形 Shapefile 中

[英]Checking if a point falls within polygon Shapefile

I have a shapefile about NYC Yellow cab service zones: taxi_zones.shp.我有一个关于纽约市黄色出租车服务区的 shapefile:taxi_zones.shp。 It can be download here: https://s3.amazonaws.com/nyc-tlc/misc/taxi_zones.zip可以在这里下载: https://s3.amazonaws.com/nyc-tlc/misc/taxi_zones.zip

I want to check whether certain locations fall into any of the zones.我想检查某些位置是否属于任何区域。 Here is the R code I use:这是我使用的 R 代码:

library(sf)
tt <- read_sf('taxi_zones.shp')

pnts <- data.frame(
  "x" = c(-73.97817,-74.00668,0,500),
  "y" = c(40.75798, 40.73178,0,400))

pnts_sf <- do.call("st_sfc",c(lapply(1:nrow(pnts), 
                                     function(i) {st_point(as.numeric(pnts[i, ]))}), list("crs" = 4326))) 

pnts_trans <- st_transform(pnts_sf, 2163) 
tt_trans <- st_transform(tt, 2163)   
   
zones <- apply(st_intersects(tt_trans, pnts_trans, sparse = FALSE), 2, 
                     function(col) { 
                       tt_trans[which(col), ]$LocationID 
                     })

The first two points are within the zones defined by the shapefile.前两个点位于 shapefile 定义的区域内。 However, the third point is not.然而,第三点不是。 And the fourth point has incorrect coordinates.第四点的坐标不正确。 How should I modify the code so that for points outside the zones and points with incorrect coordinates, it returns 'NA'?我应该如何修改代码,以便对于区域外的点和坐标不正确的点,它返回“NA”?

I have my own approach.我有我自己的方法。 Would that fulfill your requirements?那能满足你的要求吗? I can't tell you what specifically is wrong with your code, but this one is also a bit cleaner:我不能告诉你你的代码具体有什么问题,但是这个代码也更简洁一些:

library(sf)
tt <- read_sf('./Downloads/taxi_zones/taxi_zones.shp')


pnts <- data.frame(
  "x" = c(-73.97817, -74.00668, 0, 500),
  "y" = c(40.75798, 40.73178, 0, 400)
)

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

pnts_trans <- st_transform(pnts_sf, 2163)
tt_trans <- st_transform(tt, 2163)


pnts_trans <- pnts_sf %>% mutate(
  intersection = as.integer(st_intersects( pnts_trans,tt_trans)))

The result would be结果将是

                    geometry intersection
1 POINT (-73.97817 40.75798)          161
2 POINT (-74.00668 40.73178)          158
3                POINT (0 0)           NA
4            POINT (500 400)           NA

I suggest you consider joining your spatial objects via sf::st_join() , as shown bellow;我建议您考虑通过sf::st_join()加入您的空间对象,如下所示; what it does is that it combines the attributes of your polygon objects and points objects.它的作用是结合多边形对象和点对象的属性。

The default behaviour is "left" join = points lacking polygons will get NA .默认行为是“左”连接=缺少多边形的点将获得NA It can be tweaked by setting left = FALSE in join parameters, resulting in "inner" join behaviour = points not contained in polygons will be omitted from result.可以通过在连接参数中设置left = FALSE来调整它,从而导致“内部”连接行为 = 不包含在多边形中的点将从结果中省略。

library(sf)
tt <- read_sf('taxi_zones.shp')

pnts <- data.frame(
  "x" = c(-73.97817,-74.00668,0,500),
  "y" = c(40.75798, 40.73178,0,400))

pnts_sf <- sf::st_as_sf(pnts, coords = c("x", "y"), crs = 4326)


pnts_trans <- st_transform(pnts_sf, 2163) 
tt_trans <- st_transform(tt, 2163)  

res <- sf::st_join(pnts_trans, tt_trans)

print(res)

Simple feature collection with 4 features and 6 fields (with 1 geometry empty)
geometry type:  POINT
dimension:      XY
bbox:           xmin: 2152087 ymin: -130624.1 xmax: 9480615 ymax: 1178046
projected CRS:  NAD27 / US National Atlas Equal Area
  OBJECTID Shape_Leng   Shape_Area                          zone LocationID   borough                  geometry
1      161 0.03580391 7.191307e-05                Midtown Center        161 Manhattan POINT (2153474 -127064.5)
2      158 0.05480999 1.855683e-04 Meatpacking/West Village West        158 Manhattan POINT (2152087 -130624.1)
3       NA         NA           NA                          <NA>         NA      <NA>   POINT (9480615 1178046)
4       NA         NA           NA                          <NA>         NA      <NA>               POINT EMPTY

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM