R: Filtering GPS coordinates based on a BBOX value, a mistake in the implementation

Viewed 95

I would like to filter out the coordinates which are not within given BBOX.

I have the following list of GPS points and to test this problem I know that all of them are within the BBOX:

         V1       V2
 1:  47.8924  11.7018
 2: 47.81252 12.07387
 3: 47.84976 12.08231
 4: 47.89307 11.69957
 5:  47.8497  12.0824
 6:  47.8497 12.08272
 7: 47.89152 11.69514
 8: 47.88932 11.70749
 9: 47.84252 12.11194
10: 47.80853 12.07071

Furthermore I have the following BBOX:

 xmin     ymin     xmax     ymax 
11.71541 47.77093 12.32288 48.17883 

I know that all those points are within the BBOX.

To check that I use the following function:

vec_geofence <- function(left, bottom, right,top, lat, lon) {
  
  # The mask vector represents whether a coordinate is seen in any of the
  #   fences defined by the top, left, bottom and right vectors. In the beginning
  #   all the coordinates haven't been tested, so the respective value in the
  #   mask vector is initialized as False.
  mask <- rep(F, length(lon))
  
  # For each fence...
  for(i in seq_along(top)) {
    
    # ... check for all the coordinates if they are inside of the fence
    if( left[i] > right[i] )
      new_mask <- top[i] >= lat & lat >= bottom[i] & (left[i] <= lon | lon <= right[i])
    else
      new_mask <- top[i] >= lat & lat >= bottom[i] & (left[i] <= lon & lon <= right[i])
    
    # For all the coordinates that hadn't yet been seen in a fence, and that
    #   are inside the current fence, update the respective mask value to True
    mask[!mask][new_mask] <- T
    
    # The coordinates that will pass through to the next fence check are the ones
    #   that still haven't been seen inside a fence
    lat <- lat[!new_mask]
    lon <- lon[!new_mask]
  }
  
  mask
}

This function produces an index vector of true/false values so I can filter out which points are not in the given BBOX. Yet somewhere is a mistake.

It should give me a vector of only true values since all the points are actually in the BBOX. Yet it produces the following result:

 [1] FALSE  TRUE  TRUE FALSE  TRUE  TRUE FALSE FALSE  TRUE  TRUE

That means according to the function not all given points are within the BBOX.

Please help me to find the mistake. Thank you!

############## Example DATA:

    test_data<-structure(list(V1 = c("47.8924", "47.81252", "47.84976", "47.89307", 
                                 "47.8497", "47.8497", "47.89152", "47.88932", 
                                 "47.84252", "47.80853"), 
                          V2 = c("11.7018", "12.07387", "12.08231", "11.69957", 
                                 "12.0824","12.08272", "11.69514", "11.70749", 
                                 "12.11194", "12.07071")), 
                     row.names = c(NA,-10L), class = c("data.table", "data.frame"))

bbox_dimensions <- structure(c(xmin = 11.7154051652041, ymin = 47.7709252414407, 
            xmax = 12.3228827739125, ymax = 48.1788333505125), 
            class = "bbox", crs = structure(list(
              input = "EPSG:4326", wkt = "GEOGCS[\"WGS 84\",\n    
              DATUM[\"WGS_1984\",\n        SPHEROID[\"WGS 84\",6378137,298.257223563,\n 
              AUTHORITY[\"EPSG\",\"7030\"]],\n        AUTHORITY[\"EPSG\",\"6326\"]],\n  
              PRIMEM[\"Greenwich\",0,\n        AUTHORITY[\"EPSG\",\"8901\"]],\n  
              UNIT[\"degree\",0.0174532925199433,\n 
              AUTHORITY[\"EPSG\",\"9122\"]],\n  
              AUTHORITY[\"EPSG\",\"4326\"]]"), class = "crs"))

vec_geofence <- function(left, bottom, right,top, lat, lon) {
  
  # The mask vector represents whether a coordinate is seen in any of the
  #   fences defined by the top, left, bottom and right vectors. In the beginning
  #   all the coordinates haven't been tested, so the respective value in the
  #   mask vector is initialized as False.
  mask <- rep(F, length(lon))
  
  # For each fence...
  for(i in seq_along(top)) {
    
    # ... check for all the coordinates if they are inside of the fence
    if( left[i] > right[i] )
      new_mask <- top[i] >= lat & lat >= bottom[i] & (left[i] <= lon | lon <= right[i])
    else
      new_mask <- top[i] >= lat & lat >= bottom[i] & (left[i] <= lon & lon <= right[i])
    
    # For all the coordinates that hadn't yet been seen in a fence, and that
    #   are inside the current fence, update the respective mask value to True
    mask[!mask][new_mask] <- T
    
    # The coordinates that will pass through to the next fence check are the ones
    #   that still haven't been seen inside a fence
    lat <- lat[!new_mask]
    lon <- lon[!new_mask]
  }
  
  mask
}

test_data_index<-vec_geofence(bbox_dimensions[1],bbox_dimensions[2],bbox_dimensions[3],bbox_dimensions[4],
                              as.numeric(test_data$V1), as.numeric(test_data$V2))
1 Answers

It tuns out my data was incorrect. The algorithm works as intended. Thank you for pointing this out.

Related