Search code examples
rgoogle-mapsrasterterra

How to filter point using a buffer in r


Say that there are 4 monitor site (monitor_site) and 10 family address (family_address).

I want to use monitor_site to draw a circle with specific buffer.

I want to reuturn the family_addresss which are selected by the circles (As long as there is a circle surrounding the family_address is included).

Also, I want to return a map so that I can have a good look at the intersection of family_address and monitor_site.

Example data

monitor_site = data.frame(lat = c(39.93912273, 39.93109353, 39.91091467, 39.92758728),
                          lon = c(116.3492345, 116.3567815, 116.3596614, 116.4166152),
                          site_name = c('A', 'B', 'C', 'D'))
    
    
    
    
family_address = data.frame(lat = c(39.849243, 39.982189, 39.982674, 39.932026,39.952347, 
                                    39.936577, 39.929142, 39.996777, 39.926285,39.848591),
                            lon = c(116.378365, 116.35762, 116.360039, 116.380867, 116.325386,
                                    116.353981, 116.203125, 116.315018, 116.25695, 116.278061),
                            family_name = c('leona', 'jamie', 'celeste', 'Cherry', 'Magee',
                                            'sigrid', 'jessica', 'Julius', 'hulda', 'Bob'))
  
    
    
buffer = 10 # unit: km
# I just wrote a random number, but it could have been any number


Solution

  • Your data

    monitor_site = data.frame(lat = c(39.93912273, 39.93109353, 39.91091467, 39.92758728),
                              lon = c(116.3492345, 116.3567815, 116.3596614, 116.4166152),
                              site_name = c('A', 'B', 'C', 'D'))   
        
    family_address = data.frame(lat = c(39.849243, 39.982189, 39.982674, 39.932026,39.952347, 
                                        39.936577, 39.929142, 39.996777, 39.926285,39.848591),
                                lon = c(116.378365, 116.35762, 116.360039, 116.380867, 116.325386,
                                        116.353981, 116.203125, 116.315018, 116.25695, 116.278061),
                                family_name = c('leona', 'jamie', 'celeste', 'Cherry', 'Magee',
                                                'sigrid', 'jessica', 'Julius', 'hulda', 'Bob'))
      
    
    buffer = 5000   
       
    

    I make two SpatVector objects and show two alternative methods:

    library(terra)
    m <- vect(monitor_site, c("lon", "lat"), crs="+proj=longlat")
    a <- vect(family_address, c("lon", "lat"), crs="+proj=longlat")
    

    Method 1

    d <- distance(m, a)
    colnames(d) = a$family_name
    rownames(d) = m$site_name
    
    d < buffer
    #  leona jamie celeste Cherry Magee sigrid jessica Julius hulda   Bob
    #A FALSE  TRUE    TRUE   TRUE  TRUE   TRUE   FALSE  FALSE FALSE FALSE
    #B FALSE FALSE   FALSE   TRUE  TRUE   TRUE   FALSE  FALSE FALSE FALSE
    #C FALSE FALSE   FALSE   TRUE FALSE   TRUE   FALSE  FALSE FALSE FALSE
    #D FALSE FALSE   FALSE   TRUE FALSE  FALSE   FALSE  FALSE FALSE FALSE
     
    

    Method 2

    b <- buffer(m, buffer)
    plot(a, xlim=c(116.1,116.5))
    lines(b)
    
    x <- intersect(a, b)
    values(x)
    #   family_name site_name
    #1        jamie         A
    #2      celeste         A
    #3       Cherry         A
    #4        Magee         A
    #5       sigrid         A
    #6       Cherry         B
    #7        Magee         B
    #8       sigrid         B
    #9       Cherry         C
    #10      sigrid         C
    #11      Cherry         D