Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

materialize sf example #2

Open
mdsumner opened this issue Jul 21, 2022 · 1 comment
Open

materialize sf example #2

mdsumner opened this issue Jul 21, 2022 · 1 comment

Comments

@mdsumner
Copy link
Member

mdsumner commented Jul 21, 2022

  library(L3bin)
  nr <- 360  ## NUMROWS, i.e. how many steps in latitude seq(-90, 90, length.out = nr) is the basis of the binning

  ## this just stores the information about the scheme
  bins <- L3bin(nr)
  
  ## we can now use the L3bin:: functions to lookup bin by longlat, or generate longlat by bin, etc. 
  ## but here we materialize a relatively small set of global bins and use sf
  
  
  ## matrix of cbind(xmin, xmax, ymin, ymax ) for every bin (don't do this for really large NUMROWS, even 180 is pretty dense at global scale)
  ex <- extent_from_bin(1:bins$totbins, nr)
  #plot(range(ex[,1:2]), range(ex[,3:4]))
  #rect(ex[,1], ex[,3], ex[,2], ex[,4])
  #lbins <- crop_bins(bins, extent = c(100, 180, -90, -20))
  #ex <- extent_from_bin(lbins, nr)
#' Create sf from matrix of xmin, xmax, ymin, ymax
#' @param ex matrix 4-columns
#' @param crs projection string of the coordinates
to_sf <- function(ex, crs = "OGC:CRS84") {
  idx <- c(1, 2, 2, 1, 1, 
           3, 3, 4, 4, 3)
  proto <- sf::st_polygon(list(cbind(0, c(1:4, 1))))
  sf::st_sfc(lapply(split(t(ex), rep(1:nrow(ex), each = 4L)), 
                    function(.x) {
                      proto[[1L]][] <- .x[idx]
                      proto
                    }), crs = crs)
}
sf::sf_use_s2(FALSE)
#> Spherical geometry (s2) switched off
#' Densify segments of sf safely
#' ‘dx’ is in the units of the geometry coordinates, so 1 (111111m) or 0.1 (111111m) maybe lower near the poles
#' @param sf lines or polygons
#' @param dx delta for shortest length of new segments from old (straight-line native to the geometry coordinates)
segit <- function(x, dx) {
  crs <- sf::st_crs(x)
  sf::st_set_crs(sf::st_segmentize(sf::st_set_crs(x, NA), dx), crs)
} 

## 70Mb at 360 rows
sfx <- to_sf(ex)

## we can crop the bins with crop_bins(bins) to get which bins fall in a longlat extent
## but, we've already materialized as polygons so we can use the GIS stuff
## everything within 1000km (beware of unit shenanigans though)
keep <- unclass(sf::st_distance(sfx, sf::st_sfc(sf::st_point(cbind(147, -42)), crs = sf::st_crs(sfx)))) <= 1e6
plot(sfx[keep])
maps::map(add = TRUE)
abline(v = 100:180,h = -50:-10, lty = 2, col = rgb(0, 0, 0, .4))
axis(1); axis(2)

## dx that's sensible, portion of  a degree - will depend on where (and it's only a constant which is not good)
utm <- "+proj=utm +zone=55 +south"
plot(st_transform(segit(sfx[keep], .1), utm))
plot(st_transform(rnaturalearth::ne_countries(country = "Australia", returnclass = "sf"), utm)[1], add = T, colour = NA)

Created on 2022-07-21 by the reprex package (v2.0.1)

@mdsumner
Copy link
Member Author

ping @ozjimbob

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant