К сожалению, довольно сложно использовать maps
данные для пространственной фильтрации точек, потому что данные действительно предназначены для построения графиков, а не для пространственных операций. К счастью, использовать пакет sf
для такой пространственной работы довольно просто.
- Сначала я получаю новозеландскую границу из пакета
rnaturalearth
, который является удобным источником границ страны. Я делаю несколько преобразований, чтобы сохранить только три самых больших полигона в шейп-файле, так как в противном случае мы бы построили множество удаленных островов, которые, вероятно, не имеют отношения к этой карте.
- Затем я генерирую несколько случайных точек вокруг Новой Зеландии. Вы можете видеть, что
tibble
- это просто столбец долгот и столбец широт. Мы превращаем это в точечные геометрии с помощью st_as_sf
и наносим на график, чтобы показать, как это выглядит.
- Наконец, мы можем использовать
st_within
для проверки каждой точки, находится ли она внутри границы nz
. st_within
возвращает список индексов полигонов, в которых находится точка для каждой точки, поэтому мы можем использовать lengths
, чтобы получить желаемый результат. Здесь все, что является 0
, не находится в пределах границы, и все, что является 1
, находится в пределах границы. Графики с этим новым атрибутом on_land
показывают, что морские точки соответствующим образом окрашены.
library(tidyverse)
library(sf)
#> Linking to GEOS 3.6.1, GDAL 2.2.3, proj.4 4.9.3
library(rnaturalearth)
nz <- ne_countries(country = "New Zealand", returnclass = "sf", scale = "large") %>%
st_cast("POLYGON") %>%
mutate(area = st_area(geometry)) %>%
top_n(3, area)
#> Warning in st_cast.sf(., "POLYGON"): repeating attributes for all sub-
#> geometries for which they may not be constant
points <- tibble(
x = runif(1000, st_bbox(nz)[1], st_bbox(nz)[3]),
y = runif(1000, st_bbox(nz)[2], st_bbox(nz)[4])
)
points
#> # A tibble: 1,000 x 2
#> x y
#> <dbl> <dbl>
#> 1 167. -44.5
#> 2 175. -40.9
#> 3 177. -43.8
#> 4 167. -44.8
#> 5 173. -39.3
#> 6 173. -42.1
#> 7 176. -41.9
#> 8 171. -44.9
#> 9 173. -41.2
#> 10 174. -39.5
#> # ... with 990 more rows
points <- st_as_sf(points, coords = c("x", "y"), crs = 4326)
plot(nz$geometry, col = "red")
plot(points, pch = 19, cex = 1, add = TRUE)
points <- points %>% mutate(on_land = lengths(st_within(points, nz)))
#> although coordinates are longitude/latitude, st_within assumes that they are planar
plot(nz$geometry, col = "red")
plot(points, pch = 19, cex = 1, add = TRUE)
Создано в 2018-05-02 пакетом Представить (v0.2.0).