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

Expose edge tessellator as a wk filter #115

Merged
merged 11 commits into from
May 21, 2021
4 changes: 4 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ export(s2_perimeter)
export(s2_point)
export(s2_project)
export(s2_project_normalized)
export(s2_projection_filter)
export(s2_projection_mercator)
export(s2_projection_plate_carree)
export(s2_rebuild)
export(s2_rebuild_agg)
export(s2_simplify)
Expand All @@ -164,6 +167,7 @@ export(s2_touches)
export(s2_touches_matrix)
export(s2_union)
export(s2_union_agg)
export(s2_unprojection_filter)
export(s2_within)
export(s2_within_matrix)
export(s2_x)
Expand Down
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# s2 (development version)

* Added `s2_projection_filter()` and `s2_unprojection_filter()` to
expose the S2 edge tessellator, which can be used to make Cartesian
or great circle assumptions of line segments explicit by adding
points where necessary (#115).
* Added an `s2_cell()` vector class to expose a subset of the S2
indexing system to R users (#85, #114).
* Added `s2_closest_edges()` to make k-nearest neighbours calculation
Expand Down
78 changes: 78 additions & 0 deletions R/wk-utils.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@

#' Low-level wk filters and handlers
#'
#' @inheritParams wk::wk_handle
#' @param projection One of [s2_projection_plate_carree()] or
#' [s2_projection_mercator()]
#' @param tessellate_tol An angle in radians. Points will not be added
#' if a line segment is within this distance of a point.
#'
#' @return
#' - `s2_unprojection_filter()`, `s2_projection_filter()`: A `new_wk_handler()`
#' - `s2_projection_plate_carree()`, `s2_projection_mercator()`: An external pointer
#' to an S2 projection.
#' @export
#'
#' @examples
#' library(wk)
#'
#' # simple conversion of individual coordinates *to* unit sphere
#' # space
#' wk_handle(
#' wkt("LINESTRING (0 0, 0 45, -60 45)"),
#' s2_unprojection_filter(wkt_format_handler(5))
#' )
#'
#' # simple conversion of individual coordinates *from* unit sphere
#' # space
#' wk_handle(
#' wkt("LINESTRING Z (1 0 0, 0.7071 0 0.7071, 0.3536 -0.6124 0.7071)"),
#' s2_projection_filter(wkt_format_handler(5))
#' )
#'
#' # use tessellate_tol to force points to be added to an edge
#' # unprojection will ensure an edge maintains its cartesian
#' # assumption when transformed to the unit sphere
#' # (i.e., what you probably want when importing a geography)
#' wk_handle(
#' wkt("LINESTRING (0 0, 0 45, -60 45)"),
#' s2_unprojection_filter(wkt_format_handler(5), tessellate_tol = 0.001)
#' )
#'
#' # projection will ensure an edge maintains its geodesic
#' # assumption when transformed to projected space
#' # (i.e., what you probably want when exporting a geography)
#' wk_handle(
#' wkt("LINESTRING Z (1 0 0, 0.7071 0 0.7071, 0.3536 -0.6124 0.7071)"),
#' s2_projection_filter(wkt_format_handler(5), tessellate_tol = 0.001)
#' )
#'
s2_unprojection_filter <- function(handler, projection = s2_projection_plate_carree(),
tessellate_tol = Inf) {
wk::new_wk_handler(
.Call(c_s2_coord_filter_new, handler, projection, TRUE, tessellate_tol),
subclass = "s2_coord_filter"
)
}

#' @rdname s2_unprojection_filter
#' @export
s2_projection_filter <- function(handler, projection = s2_projection_plate_carree(),
tessellate_tol = Inf) {
wk::new_wk_handler(
.Call(c_s2_coord_filter_new, handler, projection, FALSE, tessellate_tol),
subclass = "s2_coord_filter"
)
}

#' @rdname s2_unprojection_filter
#' @export
s2_projection_plate_carree <- function() {
.Call(c_s2_projection_plate_carree)
}

#' @rdname s2_unprojection_filter
#' @export
s2_projection_mercator <- function() {
.Call(c_s2_projection_mercator)
}
11 changes: 11 additions & 0 deletions _pkgdown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ reference:
contents:
- s2_closest_feature

- title: Linear Referencing
contents:
- s2_interpolate

- title: Utility Functions
contents:
- s2_earth_radius_meters
Expand All @@ -75,3 +79,10 @@ reference:
desc: Useful data for testing and demonstrating s2 functions
contents:
- starts_with("s2_data")

- title: Low-level Details
desc: Interact with spherical geometry at a low level
contents:
- s2_cell
- s2_cell_is_valid
- s2_unprojection_filter
79 changes: 79 additions & 0 deletions man/s2_unprojection_filter.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/Makevars.in
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ OBJECTS = cpp-compat.o \
s2-matrix.o \
s2-point.o \
s2-xptr.o \
wk-impl.o \
wk-c-utils.o \
s2-c-api.o \
s2/base/stringprintf.o \
s2/base/strtoint.o \
s2/encoded_s2cell_id_vector.o \
Expand Down
3 changes: 3 additions & 0 deletions src/Makevars.win
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ OBJECTS = cpp-compat.o \
s2-matrix.o \
s2-point.o \
s2-xptr.o \
wk-impl.o \
wk-c-utils.o \
s2-c-api.o \
s2/base/stringprintf.o \
s2/base/strtoint.o \
s2/encoded_s2cell_id_vector.o \
Expand Down
7 changes: 7 additions & 0 deletions src/RcppExports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1269,6 +1269,10 @@ BEGIN_RCPP
END_RCPP
}

RcppExport SEXP c_s2_coord_filter_new(SEXP, SEXP, SEXP, SEXP);
RcppExport SEXP c_s2_projection_mercator();
RcppExport SEXP c_s2_projection_plate_carree();

static const R_CallMethodDef CallEntries[] = {
{"_s2_cpp_s2_init", (DL_FUNC) &_s2_cpp_s2_init, 0},
{"_s2_cpp_s2_is_collection", (DL_FUNC) &_s2_cpp_s2_is_collection, 1},
Expand Down Expand Up @@ -1375,6 +1379,9 @@ static const R_CallMethodDef CallEntries[] = {
{"_s2_cpp_s2_buffer_cells", (DL_FUNC) &_s2_cpp_s2_buffer_cells, 4},
{"_s2_s2_xptr_test", (DL_FUNC) &_s2_s2_xptr_test, 1},
{"_s2_s2_xptr_test_op", (DL_FUNC) &_s2_s2_xptr_test_op, 1},
{"c_s2_coord_filter_new", (DL_FUNC) &c_s2_coord_filter_new, 4},
{"c_s2_projection_mercator", (DL_FUNC) &c_s2_projection_mercator, 0},
{"c_s2_projection_plate_carree", (DL_FUNC) &c_s2_projection_plate_carree, 0},
{NULL, NULL, 0}
};

Expand Down