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

Add a radius argument to find_snap() #402

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions java-r5rcore/src/org/ipea/r5r/R5RCore.java
Original file line number Diff line number Diff line change
Expand Up @@ -522,17 +522,18 @@ public double[] testDecay(String decayFunctionName, double decayValue) {
}

// ---------------------------------- FIND SNAP POINTS -----------------------------------------
public RDataFrame findSnapPoints(String fromId, double fromLat, double fromLon, String mode) throws ExecutionException, InterruptedException {
public RDataFrame findSnapPoints(String fromId, double fromLat, double fromLon, double radius, String mode) throws ExecutionException, InterruptedException {
String[] fromIds = {fromId};
double[] fromLats = {fromLat};
double[] fromLons = {fromLon};

return findSnapPoints(fromIds, fromLats, fromLons, mode);
return findSnapPoints(fromIds, fromLats, fromLons, radius, mode);
}

public RDataFrame findSnapPoints(String[] fromId, double[] fromLat, double[] fromLon, String mode) throws ExecutionException, InterruptedException {
public RDataFrame findSnapPoints(String[] fromId, double[] fromLat, double[] fromLon, double radius, String mode) throws ExecutionException, InterruptedException {
SnapFinder snapFinder = new SnapFinder(r5rThreadPool, this.transportNetwork);
snapFinder.setOrigins(fromId, fromLat, fromLon);
snapFinder.setRadius(radius);
snapFinder.setMode(mode);
return snapFinder.run();
}
Expand Down
8 changes: 6 additions & 2 deletions java-r5rcore/src/org/ipea/r5r/SnapFinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,13 @@ public class SnapFinder {
protected String[] fromIds;
protected double[] fromLats;
protected double[] fromLons;
protected double radius;
private StreetMode mode;

public void setRadius(double radius) {
this.radius = radius;
}

public void setMode(String mode) {
this.mode = StreetMode.valueOf(mode);
}
Expand Down Expand Up @@ -61,8 +66,7 @@ public RDataFrame run() {
snapTable.set("lat", fromLats[index]);
snapTable.set("lon", fromLons[index]);

Split split = transportNetwork.streetLayer.findSplit(fromLats[index], fromLons[index],
StreetLayer.LINK_RADIUS_METERS, this.mode);
Split split = transportNetwork.streetLayer.findSplit(fromLats[index], fromLons[index], this.radius, this.mode);

if (split != null) {
// found split at StreetLayer.INITIAL_LINK_RADIUS_METERS
Expand Down
25 changes: 16 additions & 9 deletions r-package/R/find_snap.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,22 @@
#' created by `R5`. The snapping process in `R5` is composed of two rounds.
#' First, it tries to snap the points within a radius of 300 meters from
#' themselves. If the first round is unsuccessful, then `R5` expands the search
#' radius to 1.6 km. If yet again it is unsuccessful, then the unsnapped points
#' won't be used during the routing process. The snapped location of each point
#' depends on the transport mode set by the user, because some network edges
#' are not available to specific modes (e.g. a pedestrian-only street cannot be
#' used to snap car trips).
#' to the radius specified (by default 1.6km). If yet again it is unsuccessful,
#' then the unsnapped points won't be used during the routing process. The
#' snapped location of each point depends on the transport mode set by the user,
#' because some network edges are not available to specific modes (e.g. a
#' pedestrian-only street cannot be used to snap car trips).
#'
#' @template r5r_core
#' @param points Either a `POINT sf` object with WGS84 CRS, or a `data.frame`
#' containing the columns `id`, `lon` and `lat`.
#' @param radius Numeric. The maximum radius in meters within which to snap.
#' Defaults to 1600m.
#' @param mode A string. Which mode to consider when trying to snap the points
#' to the network. Defaults to `WALK`, also allows `BICYCLE` and `CAR`.
#'
#' @return A `data.table` with the original points, their respective
#' snapped coordinates on the street network and the Euclidean distance ( in
#' snapped coordinates on the street network and the Euclidean distance (in
#' meters) between the original points and their snapped location. Points that
#' could not be snapped show `NA` coordinates and `found = FALSE`.
#'
Expand All @@ -32,14 +34,15 @@
#' r5r_core <- setup_r5(data_path = path)
#' points <- read.csv(file.path(path, "poa_hexgrid.csv"))
#'
#' snap_df <- find_snap(r5r_core, points, mode = "WALK")
#' snap_df <- find_snap(r5r_core, points, radius = 2000, mode = "WALK")
#'
#' stop_r5(r5r_core)
#' @export
find_snap <- function(r5r_core, points, mode = "WALK") {
find_snap <- function(r5r_core, points, radius = 1600, mode = "WALK") {
checkmate::assert_class(r5r_core, "jobjRef")

mode_options <- c("WALK", "BICYCLE", "CAR")
checkmate::assert_numeric(radius, lower = 0, finite = TRUE, max.len = 1)
checkmate::assert(
checkmate::check_string(mode),
checkmate::check_names(mode, subset.of = mode_options),
Expand All @@ -48,7 +51,11 @@ find_snap <- function(r5r_core, points, mode = "WALK") {

points <- assign_points_input(points, "points")

snap_df <- r5r_core$findSnapPoints(points$id, points$lat, points$lon, mode)
snap_df <- r5r_core$findSnapPoints(points$id,
points$lat,
points$lon,
radius,
mode)
snap_df <- java_to_dt(snap_df)

snap_df[found == FALSE, `:=`(snap_lat = NA, snap_lon = NA, distance = NA)]
Expand Down
Binary file modified r-package/inst/jar/r5r.jar
Binary file not shown.
19 changes: 11 additions & 8 deletions r-package/man/find_snap.Rd

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

19 changes: 18 additions & 1 deletion r-package/tests/testthat/test-find_snap.R
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ test_that("adequately raises errors", {
# invalid points
expect_error( find_snap(r5r_core=r5r_core, points = 'a', mode = 'WALK') )

# invalid radius
expect_error( find_snap(r5r_core=r5r_core, points = 'a', radius = -90, mode = 'WALK') )

})


Expand All @@ -26,6 +29,20 @@ test_that("adequately raises errors", {
test_that("output is correct", {

# expected behavior
expect_s3_class( find_snap(r5r_core, points = points, mode = 'WALK'), 'data.table' )
expect_s3_class( find_snap(r5r_core=r5r_core, points = points, mode = 'WALK'), 'data.table')

# 6 points don't get snapped using the default radius after moving them
points_snap <- points
points_snap$lat <- points_snap$lat + 0.01
expect_equal(
sum(!find_snap(r5r_core, points_snap, mode = 'WALK')$found),
6
)

# all points are snapped after increasing the radius
expect_equal(
sum(!find_snap(r5r_core, points_snap, mode = 'WALK', radius = 5000)$found),
0
)

})
Loading