简体   繁体   中英

Find coordinates of points within overlapping circles

Lets say I have many (lon,lat) points on a globe (eg 1,000,000 points). Then I draw a circle around each point and would like to find a new point within each overlapping area. Now I am interested in the (lon,lat) coordinates of the new points.

The following gives an illustration of what I would like to achieve:

# Original points (3 points)
lon <- c(6.3, 6.9, 6.9)
lat <- c(53, 53.1, 52.4)
df <- data.frame(lat = lat, lon = lon, r = .5) 

Now I would like to create a new data.frame with (lon,lat) points within overlapping circles:

# Example of new points within overlapping areas
df_new <- data.frame(
  lat = c(52.4, 53.1, 53, 53, 52.6, 52.75, 52.75),
  lon = c(6.9, 6.9, 6.3, 6.6, 6.5, 6.65, 7)
)

How can I achieve this? The exact location of the red point doesn't matter, the only constraint is that the red point should be within the intersection. I prefer a data.table solution (and not with sf or sp). Or is it possible to solve this using Voronoi Diagrams?

Created on 2021-04-26 by the reprex package (v1.0.0)

This might not be exactly what you want but it might help you. Code below takes buffer around each point in df of 50 km, finds overlaping geometries and points in df_new that are in:

library(dplyr)
library(purrr)
library(sf)

lon <- c(6.3, 6.9, 6.9)
lat <- c(53, 53.1, 52.4)
df <- data.frame(lat = lat, lon = lon, r = .5) 

df_new <- data.frame(
  lat = c(52.4, 53.1, 53, 53, 52.6, 52.75, 52.75),
  lon = c(6.9, 6.9, 6.3, 6.6, 6.5, 6.65, 7)
) %>%
  st_as_sf(coords = c("lon", "lat"), crs = 4326) 


circle_df <- df %>%
  st_as_sf(coords = c("lon", "lat"), crs = 4326) %>%
  st_transform(3035) %>%
  st_buffer(dist = units::set_units(50, "kilometers"))


in_intersection <- st_intersection(circle_df) %>% 
  filter(n.overlaps == 2) %>%
  st_transform(4326) %>%
  st_within(df_new, .) %>%
  map_lgl(is_empty) %>%
  "!"() %>%
  which() %>%
  slice(df_new, .) 

plot(st_geometry(circle_df %>% st_transform(4326)))
plot(st_geometry(in_intersection), add = TRUE)

在此处输入图像描述

I'm not sure how to make circles around points where distance is difference in longitude and latitude (that woudn't be circle but some kind of ellipse). What you can try to do is to approximate radius by taking distance from points (lon, lat) and (lon, lat-r) (one way of doing it) and passing that distance for buffer.

df <- df %>% mutate(lat1 = lat - r) 
df1 <- df %>% st_as_sf(coords = c("lon", "lat"), crs = 4326)  
df2 <- df %>% st_as_sf(coords = c("lon", "lat1"), crs = 4326)   
d <- st_distance(df1, df2, by_element = TRUE)

circle_df <- df1 %>%
  st_transform(3035) %>%
  st_buffer(dist = d) 

and continuing from here as in upper example. I'm not sure how scalable this is (you have a lot of points).

edit

circle_df <- df %>%
  st_as_sf(coords = c("lon", "lat"), crs = 4326) %>%
  st_transform(3035) %>%
  st_buffer(dist = units::set_units(50, "kilometers"))

points_within <- st_intersection(circle_df) %>%
  st_centroid()

df_new <- points_within %>%
  st_transform(4326) %>%
  st_coordinates() %>%
  as_tibble() %>%
  setNames(c("lon", "lat"))

plot(st_geometry(circle_df))
plot(st_geometry(points_within), add = TRUE)

在此处输入图像描述

If you want points only in intersections add filter(n.overlaps > 1) after st_centroid() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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