Skip to content
Draft
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
22 changes: 19 additions & 3 deletions java-r5rcore/src/org/ipea/r5r/R5RCore.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
import com.conveyal.r5.analyst.Grid;
import com.conveyal.r5.analyst.cluster.PathResult;
import com.conveyal.r5.analyst.decay.*;
import com.conveyal.r5.analyst.scenario.PickupDelay;
import com.conveyal.r5.analyst.scenario.ShapefileLts;
import com.conveyal.r5.api.util.SearchType;
import com.conveyal.r5.analyst.scenario.RoadCongestion;
import com.conveyal.r5.profile.StreetMode;
import com.conveyal.r5.transit.TransportNetwork;
import com.fasterxml.jackson.core.JsonProcessingException;

Expand All @@ -28,9 +30,7 @@
import java.nio.file.Paths;
import java.text.ParseException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;

Expand Down Expand Up @@ -642,6 +642,22 @@ public String applyLtsOsm(HashMap<Long, Integer> ltsMap){
return lts.errors.toString();
}

public String applyPickupDelay(String filePath, Map<String, Set<String>> stopsMap, String streetMode, double defaultWait){
Path fileJPath = Paths.get(filePath).toAbsolutePath().normalize();

PickupDelay pickDel = new PickupDelay();
pickDel.streetMode = StreetMode.valueOf(streetMode);
pickDel.waitTimeAttribute = "wait_time";
pickDel.idAttribute = "poly_id";
pickDel.stopsForZone = stopsMap;
pickDel.defaultWait = defaultWait;
pickDel.zonePolygons = fileJPath.toString();

pickDel.resolve(routingProperties.transportNetworkWorking);
pickDel.apply(routingProperties.transportNetworkWorking);
return pickDel.errors.toString();
}

// ------------------------------ STREET AND TRANSIT NETWORKS ----------------------------------------

public List<RDataFrame> getStreetNetwork() {
Expand Down
33 changes: 30 additions & 3 deletions java-r5rcore/src/org/ipea/r5r/Utils/RMapBuilder.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package org.ipea.r5r.Utils;

import java.util.HashMap;
import java.util.*;
import java.util.stream.Collectors;

public class RMapBuilder {
public static HashMap<Long, Float> buildSpeedMap(String osmIds, String scale){
String[] osmIdsArray = osmIds.split(",");
String[] scaleArray = scale.split(",");

HashMap<Long, Float> map = new HashMap<>();
if (osmIdsArray.length != scaleArray.length) {
throw new IllegalArgumentException("osmIds and scale must have the same number of items.");
}

HashMap<Long, Float> map = new HashMap<>((int) Math.ceil(osmIdsArray.length / 0.74));
for (int i = 0; i < osmIdsArray.length; i++) {
long osmId = Long.parseLong(osmIdsArray[i]);
float jScale = Float.parseFloat(scaleArray[i]);
Expand All @@ -20,12 +25,34 @@ public static HashMap<Long, Integer> buildLtsMap(String osmIds, String lts){
String[] osmIdsArray = osmIds.split(",");
String[] ltsArray = lts.split(",");

HashMap<Long, Integer> map = new HashMap<>();
if (osmIdsArray.length != ltsArray.length) {
throw new IllegalArgumentException("osmIds and lts must have the same number of items.");
}

HashMap<Long, Integer> map = new HashMap<>((int) Math.ceil(osmIdsArray.length / 0.74));
for (int i = 0; i < osmIdsArray.length; i++) {
long osmId = Long.parseLong(osmIdsArray[i]);
int jLts = Integer.parseInt(ltsArray[i]);
map.put(osmId, jLts);
}
return map;
}

public static Map<String, Set<String>> buildStopsMap(String polyIds, String stops) {
String[] polyIdsArray = polyIds.split(",");
String[] stopsArray = stops.split(";");

if (polyIdsArray.length != stopsArray.length) {
throw new IllegalArgumentException("polyIds and stopsGroups must have the same number of items.");
}

Map<String, Set<String>> map = new HashMap<>((int) Math.ceil(polyIdsArray.length / 0.74));

for (int i = 0; i < polyIdsArray.length; i++) {
String[] ids = stopsArray[i].split(",");
Set<String> set = new HashSet<>(List.of(ids));
map.put(polyIdsArray[i], set);
}
return map;
}
}
2 changes: 2 additions & 0 deletions r-package/R/accessibility.R
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ accessibility <- function(r5r_network,
new_carspeeds = NULL,
carspeed_scale = 1,
new_lts = NULL,
pickup_zones = NULL,
draws_per_minute = 5L,
n_threads = Inf,
verbose = FALSE,
Expand Down Expand Up @@ -256,6 +257,7 @@ accessibility <- function(r5r_network,
# SCENARIOS -------------------------------------------
set_new_congestion(r5r_network, new_carspeeds, carspeed_scale)
set_new_lts(r5r_network, new_lts)
set_pickup_delay(r5r_network, pickup_zones)


# call r5r_network method and process results ------------------------------
Expand Down
2 changes: 2 additions & 0 deletions r-package/R/arrival_travel_time_matrix.R
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ arrival_travel_time_matrix <- function(r5r_network,
new_carspeeds = NULL,
carspeed_scale = 1,
new_lts = NULL,
pickup_zones = NULL,
draws_per_minute = 5L,
n_threads = Inf,
verbose = FALSE,
Expand Down Expand Up @@ -191,6 +192,7 @@ arrival_travel_time_matrix <- function(r5r_network,
# SCENARIOS -------------------------------------------
set_new_congestion(r5r_network, new_carspeeds, carspeed_scale)
set_new_lts(r5r_network, new_lts)
set_pickup_delay(r5r_network, pickup_zones)


# call r5r_network method and process result -------------------------------
Expand Down
54 changes: 54 additions & 0 deletions r-package/R/assign.R
Original file line number Diff line number Diff line change
Expand Up @@ -425,3 +425,57 @@ assign_osm_link_ids <- function(osm_link_ids, drop_geometry) {
return(osm_link_ids)
}


#' Returns which routing mode to apply pickup delay polygons on.
#'
#' @param pickup_polygons An sf polygon
#'
#' @family assigning functions
#'
#' @return Character. One of street routing modes.
#'
#' @keywords internal
assign_pickup_mode <- function(pickup_polygons){

# check input class
checkmate::assert_class(pickup_polygons, "sf")

# check input colnames
checkmate::assert_names(
x = names(pickup_polygons),
must.include = c("mode")
)

checkmate::assert_true(length(unique(pickup_polygons$mode)) == 1 &&
pickup_polygons$mode[1] %in% c("CAR", "BIKE", "WALK"))

return(pickup_polygons$mode[1])
}


#' Returns default_wait time to use when no delay polygon is found.
#' -1 means area is not served at all.
#'
#' @param pickup_polygons An sf polygon
#'
#' @family assigning functions
#'
#' @return Numeric. Default wait
#'
#' @keywords internal
assign_pickup_default_wait <- function(pickup_polygons){

# check input class
checkmate::assert_class(pickup_polygons, "sf")

# check input colnames
checkmate::assert_names(
x = names(pickup_polygons),
must.include = c("default_wait")
)

checkmate::assert_true(length(unique(pickup_polygons$default_wait)) == 1)
checkmate::assert_numeric(pickup_polygons$default_wait, any.missing = FALSE, lower = -1)

return(pickup_polygons$default_wait[1])
}
2 changes: 2 additions & 0 deletions r-package/R/detailed_itineraries.R
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ detailed_itineraries <- function(r5r_network,
new_carspeeds = NULL,
carspeed_scale = 1,
new_lts = NULL,
pickup_zones = NULL,
n_threads = Inf,
verbose = FALSE,
progress = FALSE,
Expand Down Expand Up @@ -225,6 +226,7 @@ detailed_itineraries <- function(r5r_network,
# SCENARIOS -------------------------------------------
set_new_congestion(r5r_network, new_carspeeds, carspeed_scale)
set_new_lts(r5r_network, new_lts)
set_pickup_delay(r5r_network, pickup_zones)

# call r5r_network method and process result -------------------------------

Expand Down
2 changes: 2 additions & 0 deletions r-package/R/expanded_travel_time_matrix.R
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ expanded_travel_time_matrix <- function(r5r_network,
new_carspeeds = NULL,
carspeed_scale = 1,
new_lts = NULL,
pickup_zones = NULL,
draws_per_minute = 5L,
n_threads = Inf,
verbose = FALSE,
Expand Down Expand Up @@ -199,6 +200,7 @@ expanded_travel_time_matrix <- function(r5r_network,
# SCENARIOS -------------------------------------------
set_new_congestion(r5r_network, new_carspeeds, carspeed_scale)
set_new_lts(r5r_network, new_lts)
set_pickup_delay(r5r_network, pickup_zones)


# call r5r_network method and process result -------------------------------
Expand Down
30 changes: 28 additions & 2 deletions r-package/R/java_utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ dt_to_speed_map <- function(dt) {

checkmate::assert_names(names(dt), must.include = c("osm_id", "max_speed", "speed_type"))
checkmate::assert_numeric(dt$osm_id, any.missing = FALSE, all.missing = FALSE)
checkmate::assert_numeric(dt$max_speed, any.missing = FALSE, all.missing = FALSE)
checkmate::assert_numeric(dt$max_speed, any.missing = FALSE, all.missing = FALSE, lower = 0)
checkmate::assert_true(length(unique(dt$speed_type)) == 1 && dt$speed_type[1] %in% c("km/h", "scale"))

# Create new HashMap<long, float>
Expand Down Expand Up @@ -91,7 +91,7 @@ get_java_version <- function(){
dt_to_lts_map <- function(dt) {
checkmate::assert_names(names(dt), must.include = c("osm_id", "lts"))
checkmate::assert_numeric(dt$osm_id, any.missing = FALSE, all.missing = FALSE)
checkmate::assert_integer(dt$lts, any.missing = FALSE, all.missing = FALSE)
checkmate::assert_integer(dt$lts, any.missing = FALSE, all.missing = FALSE, lower = 1, upper = 4)

# Create new HashMap<Long, Integer>
map_builder <- rJava::.jnew("org.ipea.r5r.Utils.RMapBuilder")
Expand All @@ -100,3 +100,29 @@ dt_to_lts_map <- function(dt) {

return(lts_map)
}


#' data.table to stopsMap
#'
#' @description Converts a `data.frame` with pickup polygons and and respective
#' drop off stops to a Java Map<String, Set<String>>.
#'
#' @param dt data.frame/data.table. Table specifying the
#' polygon ID and stops it links to. The table must contain columns
#' \code{poly_id} and \code{stops_ids}.
#' @return A stopsMap (Java Map<String, Set<String>>)
#' @family java support functions
#' @keywords internal
dt_to_stops_map <- function(dt) {
checkmate::assert_names(names(dt), must.include = c("poly_id", "stops_ids"))
checkmate::assert_character(dt$poly_id, any.missing = FALSE, all.missing = FALSE)
checkmate::assert_list(dt$stops_ids, types = "numeric", any.missing = FALSE, all.missing = FALSE)

# Create new HashMap<Long, Integer>
map_builder <- rJava::.jnew("org.ipea.r5r.Utils.RMapBuilder")
stops_str <- sapply(dt$stops_ids, function(x) paste(x, collapse = ","))
stops_map <- map_builder$buildStopsMap(paste(as.character(dt$poly_id), collapse = ","),
paste(as.character(stops_str), collapse = ";"))

return(stops_map)
}
36 changes: 35 additions & 1 deletion r-package/R/set.R
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,7 @@ set_new_congestion <- function(r5r_network, new_carspeeds, carspeed_scale) {
#' Verifies if and which LTS mode to use and applies it.
#'
#' @template r5r_network
#' @param new_carspeeds A df or sf polygon.
#' @param new_lts A df or sf polygon.
#'
#' @return Invisibly returns `TRUE`.
#' @family setting functions
Expand All @@ -647,3 +647,37 @@ set_new_lts <- function(r5r_network, new_lts) {
}
}
}


#' Set Pickup Delay
#'
#' Verifies if to set a pickup delay and sets it
#'
#' @template r5r_network
#' @param pickup_poly A sf polygon.
#'
#' @return Invisibly returns `TRUE`.
#' @family setting functions
#'
#' @keywords internal
set_pickup_delay <- function(r5r_network, pickup_poly) {
checkmate::assert_class(pickup_poly, "sf", null.ok = TRUE)
if (!is.null(pickup_poly)){
cli::cli_inform(c(i = "Modifying pickup delay..."))

geojson_path <- pickup_poly2geojson(pickup_poly)
stops_map <- dt_to_stops_map(pickup_poly)
street_mode <- assign_pickup_mode(pickup_poly)
default_wait <- assign_pickup_default_wait(pickup_poly)
errors <- r5r_network$applyPickupDelay(geojson_path,
stops_map,
street_mode,
default_wait)

if (errors != "[]"){
cli::cli_inform(c(
"!" = "Encountered the following errors modifying pickup delay:",
" " = errors ))
}
}
}
3 changes: 2 additions & 1 deletion r-package/R/travel_time_matrix.R
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ travel_time_matrix <- function(r5r_network,
new_carspeeds = NULL,
carspeed_scale = 1,
new_lts = NULL,
pickup_zones = NULL,
draws_per_minute = 5L,
n_threads = Inf,
verbose = FALSE,
Expand Down Expand Up @@ -224,7 +225,7 @@ travel_time_matrix <- function(r5r_network,
# SCENARIOS -------------------------------------------
set_new_congestion(r5r_network, new_carspeeds, carspeed_scale)
set_new_lts(r5r_network, new_lts)

set_pickup_delay(r5r_network, pickup_zones)

# call r5r_network method and process result -------------------------------

Expand Down
Loading
Loading