Search code examples
rcoordinatesspatiallatitude-longitude

Create grid with equal spacings R from specific latitude and longitude


I would like to create a grid of 4 points with lat lons (1 x 4) each 150m apart using a specific point as the start, e.g., top left of the grid. My starting point is Latitude 51.83985301, Longitude 0.885039037 would be Point 1. Can I do this in R?

Point 1 (x,y)    Point 2 (x,y)
Point 3 (x,y)    Point 4 (x,y)

Solution

  • Yes--You can do this in R!

    # Use this R package
    require( geosphere )
    
    # Example distance and point
    distance <- 150
    tplon    <- 0.885039037
    tplat    <- 51.83985301
    
    ELLIPSOID <- tibble::tribble(
      # Data are from help( 'distVincentyEllipsoid' ) 
       ~name              ,   ~a        ,      ~b       ,     ~f
     , 'WGS84'              , 6378137     , 6356752.3142  , 1/298.257223563
     , 'GRS80'              , 6378137     , 6356752.3141  , 1/298.257222101
     , 'GRS67'              , 6378160     , 6356774.719   , 1/298.25
     , 'Airy 1830'          , 6377563.396 , 6356256.909   , 1/299.3249646
     , 'Bessel 1841'        , 6377397.155 , 6356078.965   , 1/299.1528434
     , 'Clarke 1880'        , 6378249.145 , 6356514.86955 , 1/293.465
     , 'Clarke 1866'        , 6378206.4   , 6356583.8     , 1/294.9786982
     , 'International 1924' , 6378388     , 6356911.946   , 1/297
     , 'Krasovsky 1940'     , 6378245     , 6356863       , 1/298.2997381
    )
    
    # Choose an ellipsoid to use
    cfg      <- ELLIPSOID[ ELLIPSOID$name == 'WGS84', ]
    
    # A function to determine the next point, given
    # the current point, direction, and distance
    
    from_here_this_way_so_far <- function( lon, lat, direction, distance = 150 ){
      geodesic(
            p = cbind( lon, lat )
        , azi = direction
        ,   d = distance
        ,   a = cfg$a
        ,   f = cfg$f
      )[ 1:2 ]
    }
    
    # Demonstrate on the example
    from_here_this_way_so_far( tplon, tplat, 0.00, 150 )
    ## [1]  0.885 51.841
    
    # Get bearings for east, west, north, and south
    bear <- list(
        # Positive longitude change
        east = bearing( c( tplon, tplat ), c( tplon+0.001, tplat ) )
        # Negative longitude change
      , west = bearing( c( tplon, tplat ), c( tplon-0.001, tplat ) )
        # Positive latitude change
      , north = bearing( c( tplon, tplat ), c( tplon, tplat+0.001 ) )
        # Negative latitude change
      , south = bearing( c( tplon, tplat ), c( tplon, tplat-0.001 ) )
    )
    
    # A function to determine the coordinates for each corner of the square
    corners <- function( lon, lat ){
      A <- c( lon, lat )
      B <- from_here_this_way_so_far( lon, lat, bear$east, 150 )
      C <- from_here_this_way_so_far( B[1], B[2], bear$south, 150 )
      D <- from_here_this_way_so_far( lon, lat, bear$south, 150 )
    
      ## E <- from_here_this_way_so_far( C[1], C[2], bear$west, 150 )
      ## all.equal( D, E )
      ## [1] TRUE
    
      result = cbind( A, B, C, D )
      row.names( result ) <-  c('lon','lat')
      result
    }
    
    # Demonstrate using the example
    corners( tplon, tplat )
    ##        A       B       C      D
    ## lon  0.885  0.8872  0.8872  0.885
    ## lat 51.840 51.8399 51.8385 51.839