Reputation: 1529
I have a point for which I would like to calculate the distance to the closest polygon.
library(sf)
#> Linking to GEOS 3.9.0, GDAL 3.2.1, PROJ 7.2.1
library(rnaturalearth)
library(ggplot2)
pts <- st_as_sf(
data.frame(longitude = 3.7, latitude = 52.3667),
coords = c("longitude", "latitude"),
crs = 4326
)
ne_land <- ne_download(
category = "physical",
type = "land",
returnclass = "sf",
scale = "small"
)
#> OGR data source with driver: ESRI Shapefile
#> Source: "/tmp/Rtmplq0wPd", layer: "ne_110m_land"
#> with 127 features
#> It has 3 fields
This graph shows where the point is located in relation to the land polygon.
ggplot() +
geom_sf(data = ne_land) +
geom_sf(data = pts) +
coord_sf(xlim = c(2, 5), ylim = c(50, 54))
Then I am trying to get the distance to the closest polygon with:
nearest <- st_nearest_feature(pts, ne_land)
#> although coordinates are longitude/latitude, st_nearest_points assumes that they are planar
nearest
#> [1] 113
dist <- st_distance(pts, ne_land[nearest, ], by_element=TRUE)
dist
#> 0 [m]
As seen, the dist
is equal to 0 meter. Based on the previous graph, this is not the result I was expecting. Any help is appreciated.
EDITS:
Based on the last answer, I have tried with some other locations and higher land resolution and also get 0 meters distance.
ne_land <-
rnaturalearth::ne_download(
category = "physical",
type = "land",
returnclass = "sf",
scale = "large"
)
#> OGR data source with driver: ESRI Shapefile
#> Source: "/tmp/Rtmplq0wPd", layer: "ne_10m_land"
#> with 10 features
#> It has 3 fields
pts <- st_as_sf(
data.frame(longitude = 4.1833, latitude = 52.1833),
coords = c("longitude", "latitude"),
crs = 4326
)
st_distance(pts, st_union(ne_land))
#> although coordinates are longitude/latitude, st_union assumes that they are planar
#> Units: [m]
#> [,1]
#> [1,] 0
ggplot() +
geom_sf(data = st_nearest_points(pts, st_union(ne_land))) +
geom_sf(data = ne_land) +
geom_sf(data = pts) +
coord_sf(xlim = c(2, 5), ylim = c(50, 54))
#> although coordinates are longitude/latitude, st_union assumes that they are planar
#> although coordinates are longitude/latitude, st_nearest_points assumes that they are planar
Created on 2021-04-06 by the reprex package (v2.0.0)
Upvotes: 1
Views: 2357
Reputation: 5489
You need to use st_union()
on the ne_land
data to find the single closest point.
st_distance(pts, st_union(ne_land))
although coordinates are longitude/latitude, st_union assumes that they are planar
Units: [m]
[,1]
[1,] 36319.29
ggplot() +
geom_sf(data = st_nearest_points(pts, st_union(ne_land))) +
geom_sf(data = ne_land) +
geom_sf(data = pts) +
coord_sf(xlim = c(2, 5), ylim = c(50, 54))
Edit:
The following distances are much different from the above distance since pts
has changed as in the edited question.
I don't know why it isn't working with the large naturalearth data, but here is a workaround:
st_nearest_points(pts, ne_land) %>%
st_length()
#although coordinates are longitude/latitude, st_nearest_points assumes #that they are planar
#11481.03 [m]
edit2: This also works, but returns a different distance. This probably has to do with the projection (crs) used or the simplification of polygons to lines.
st_combine(ne_land) %>% st_cast('MULTILINESTRING') %>% st_distance(pts)
Units: [m]
[,1]
[1,] 10136.87
Upvotes: 2