Coder Social home page Coder Social logo

r5r's People

Contributors

actions-user avatar dhersz avatar github-actions[bot] avatar kauebraga avatar luyuliu avatar mattwigway avatar mvpsaraiva avatar olivroy avatar rafapereirabr avatar robinlovelace avatar stupidpupil avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

r5r's Issues

Parameter max_walking_distance only applies to public transport trips

R5's maxWalkTime parameter, that is set in R5R via max_walking_distance, only applies to walking segments of trips with public transportation options. Hence, for direct trips, R5 returns a walking option if one is available within the time set by max_trip_duration. Example:

library("r5r")
library("ggplot2")

# Start R5R core
r5r_core <- setup_r5(system.file("extdata", package = "r5r"), verbose = FALSE)

# Load points of interest
points <- read.csv(system.file("extdata/poa_points_of_interest.csv", package = "r5r"))

# Configuring trip
origin <- points[10,] # Farrapos train station
destination <- points[12,] # Praia de Belas shopping mall

trip_date_time <- lubridate::as_datetime("2019-03-20 14:00:00")

max_walk_distance = 0.8
max_trip_duration = 120L

paths_df <- detailed_itineraries(r5r_core = r5r_core,
                                 origins = origin, destinations = destination,
                                 departure_datetime = trip_date_time,
                                 max_walk_dist = max_walk_distance,
                                 max_trip_duration = max_trip_duration,
                                 mode = c("WALK", "BUS"),
                                 shortest_path = FALSE, verbose = FALSE)

paths_df %>%
  ggplot() +
  geom_sf(aes(colour=mode)) +
  facet_wrap(~option)

I'm leaving this issue here so we can discuss if this is an expected/desirable outcome.

Need to ask to print travel_time_matrix result twice to actually print it

The title is confusing, but I don't really know how to express that in words in a more clearer way.
Everytime I run travel_time_matrix example I can't print it the first time I try to. See example below (note the df typed twice):

# build transport network
path <- system.file("extdata", package = "r5r")
r5r_obj <- setup_r5(data_path = path)

# load origin/destination points
points <- read.csv(system.file("extdata/poa_hexgrid.csv", package = "r5r"))[1:5,]

# estimate travel time matrix
df <- travel_time_matrix( r5r_obj,
                          origins = points,
                          destinations = points,
                          departure_datetime = as.POSIXct("13-03-2019 14:00:00",
                                               format = "%d-%m-%Y %H:%M:%S"),
                          mode = c('WALK', 'TRANSIT'),
                          max_walk_dist = 5,
                          max_trip_duration = 7200
                          )
> df
> df
             fromId   fromLat   fromLon            toId     toLat     toLon travel_time
 1: 89a901291abffff -30.05385 -51.15825 89a901291abffff -30.05385 -51.15825           2
 2: 89a901291abffff -30.05385 -51.15825 89a901295b7ffff -30.07544 -51.16521          54
 3: 89a901291abffff -30.05385 -51.15825 89a901284a3ffff -30.09005 -51.20535         117
 4: 89a901291abffff -30.05385 -51.15825 89a9012809bffff -30.07839 -51.19575          80
 5: 89a9012a3cfffff -30.10058 -51.21187 89a9012a3cfffff -30.10058 -51.21187           3
 6: 89a9012a3cfffff -30.10058 -51.21187 89a901284a3ffff -30.09005 -51.20535          58
 7: 89a9012a3cfffff -30.10058 -51.21187 89a9012809bffff -30.07839 -51.19575         112
 8: 89a901295b7ffff -30.07544 -51.16521 89a901291abffff -30.05385 -51.15825          54
 9: 89a901295b7ffff -30.07544 -51.16521 89a901295b7ffff -30.07544 -51.16521           0
10: 89a901295b7ffff -30.07544 -51.16521 89a901284a3ffff -30.09005 -51.20535         117
11: 89a901295b7ffff -30.07544 -51.16521 89a9012809bffff -30.07839 -51.19575          61
12: 89a901284a3ffff -30.09005 -51.20535 89a9012a3cfffff -30.10058 -51.21187          58
13: 89a901284a3ffff -30.09005 -51.20535 89a901284a3ffff -30.09005 -51.20535           2
14: 89a901284a3ffff -30.09005 -51.20535 89a9012809bffff -30.07839 -51.19575          45
15: 89a9012809bffff -30.07839 -51.19575 89a9012a3cfffff -30.10058 -51.21187          87
16: 89a9012809bffff -30.07839 -51.19575 89a901295b7ffff -30.07544 -51.16521          61
17: 89a9012809bffff -30.07839 -51.19575 89a901284a3ffff -30.09005 -51.20535          46
18: 89a9012809bffff -30.07839 -51.19575 89a9012809bffff -30.07839 -51.19575           0
                                                                   mode
 1: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
 2: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
 3: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
 4: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
 5: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
 6: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
 7: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
 8: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
 9: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
10: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
11: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
12: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
13: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
14: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
15: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
16: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
17: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
18: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR

Submit to CRAN

We're very close to CRAN submission but before that we need to make suer r5r passes all checks (no error, no wanings and if possible no notes)

### CMD Check ----------------
# Check package errors
Sys.setenv(NOT_CRAN = "false")
devtools::check(pkg = ".",  cran = TRUE)

Select number of cores for parallel computing

Currently, r5r uses implement parallel computation in Java and by default it uses the max number of available cores or threads. Ideally, the detailed_itineraries and travel_time_matrix functions should have somehting like an nThread argument so the user can choose how many cores/threads will be used.

Not sure, but this could possibly be done via -Dthread.pool.size.

Not passing r5r_core as an argument in functions to set options, but working anyway

I just realized that the functions that set r5r_core options (set_speed, set_n_threads, etc) the core itself is not an argument. Thus, when using i.e r5r_core$setWalkSpeed(speed) R should raise an "object not found" error. At least that's what I suppose, because it's not raising an error and, in fact, the options set are being changed. Check the example below, with different walks speeds:

data_path <- system.file("extdata", package = "r5r")
r5r_core <- setup_r5(data_path = data_path)

# load and set origin/destination points
points <- read.csv(file.path(data_path, "poa_points_of_interest.csv"))

origins <- points[10,]
destinations <- points[12,]

# inputs
mode = c("WALK", "BUS")
max_walk_dist <- 1
departure_datetime <- as.POSIXct("13-03-2019 14:00:00",
                                 format = "%d-%m-%Y %H:%M:%S")

df <- detailed_itineraries(r5r_core,
                           origins,
                           destinations,
                           departure_datetime,
                           max_walk_dist,
                           mode,
                           walk_speed = 3.6,
                           shortest_path = FALSE)
> df
Simple feature collection with 3 features and 13 fields
geometry type:  LINESTRING
dimension:      XY
bbox:           xmin: -51.22972 ymin: -30.07325 xmax: -51.17479 ymax: -29.99884
geographic CRS: WGS 84
            fromId                           toId   fromLat   fromLon     toLat     toLon option segment mode duration distance  route wait
1 farrapos_station praia_de_belas_shopping_center -29.99772 -51.19762 -30.04995 -51.22875     10       1 WALK      523   551820           0
2 farrapos_station praia_de_belas_shopping_center -29.99772 -51.19762 -30.04995 -51.22875     10       2  BUS     2760       -1 poa:T2  377
3 farrapos_station praia_de_belas_shopping_center -29.99772 -51.19762 -30.04995 -51.22875     10       3 WALK      493   483959           0
                        geometry
1 LINESTRING (-51.19807 -29.9...
2 LINESTRING (-51.1995 -30.00...
3 LINESTRING (-51.22846 -30.0...
df <- detailed_itineraries(r5r_core,
                           origins,
                           destinations,
                           departure_datetime,
                           max_walk_dist,
                           mode,
                           walk_speed = 4,
                           shortest_path = FALSE)
> df
Simple feature collection with 3 features and 13 fields
geometry type:  LINESTRING
dimension:      XY
bbox:           xmin: -51.23012 ymin: -30.07325 xmax: -51.17479 ymax: -29.99884
geographic CRS: WGS 84
            fromId                           toId   fromLat   fromLon     toLat     toLon option segment mode duration distance  route wait
1 farrapos_station praia_de_belas_shopping_center -29.99772 -51.19762 -30.04995 -51.22875     10       1 WALK      480   551820           0
2 farrapos_station praia_de_belas_shopping_center -29.99772 -51.19762 -30.04995 -51.22875     10       2  BUS     2760       -1 poa:T2  420
3 farrapos_station praia_de_belas_shopping_center -29.99772 -51.19762 -30.04995 -51.22875     10       3 WALK      443   483959           0
                        geometry
1 LINESTRING (-51.19807 -29.9...
2 LINESTRING (-51.1995 -30.00...
3 LINESTRING (-51.22846 -30.0...

As you can see, the duration of the walking legs are lower when using a higher walk speed, which makes sense.

Do you have any ideas why this is working? In my opinion, the correct thing to do here would be to make these options setting functions input and return a r5r_core (and I'll try to tackle this tomorrow), but how this is working is what really puzzles me right now.

New function to get all possible combinations of origin destination pairs

In case we should develop a new support function in the future to help users to run detailed_itineraries on all possible combinations of origin destination pairs, this could be a handy function. Something to consider.

library(r5r)
library(data.table)

# function
get_all_od_combinations <- function(origins, destinations){

        # all possible id combinations
        base <- expand.grid(origins$id, destinations$id)
        
        # rename df
        setDT(base)
        setnames(base, 'Var1', 'idorig')
        setnames(base, 'Var2', 'iddest')
        
        # bring spatial coordinates from origin and destination
        base[origins, on=c('idorig'='id'), c('lon_orig', 'lat_orig') := list(i.lon, i.lat)]
        base[destinations, on=c('iddest'='id'), c('lon_dest', 'lat_dest') := list(i.lon, i.lat)]
        
        return(base)
        }

# example
origins <- read.csv(system.file("extdata/poa_hexgrid.csv", package = "r5r"))[1:800,]
destinations <- read.csv(system.file("extdata/poa_hexgrid.csv", package = "r5r"))[400:1200,]

df <- get_all_od_combinations(origins, destinations)

do not run vignette code

We cannot build the vignette on CRAN nor TRAVIS because of the Java dependency. Until we solve this problem, we need to add eval=FALSE to all code blocks in the vignette , and add a few images of the ouputs

Update setup_r5 to use .jpackage instead of .jinit

According to rJava documentation, .jpackage is the recommended way of starting the JVM in R packages:

Starting with version 0.5 rJava provides a custom class loader that can automatically track classes and native libraries that are provided in R packages. Therefore R packages should NOT use .jinit, but call .jpackage instead. In addition this allows the use of class path modifying function .jaddClassPath.

From here

Odd combinations of transport modes

Our heuristic for turning one parameter mode into the 4 parameters R5 uses (direct_mode, transit_mode, access_mode and egress_mode) sometimes generates odd path options. For example, should we consider options such as driving to the bus stop, then taking the bus, and then driving again to the destination?

Example:

library("r5r")
library("ggplot2")

# Start R5R core
r5r_core <- setup_r5(system.file("extdata", package = "r5r"), verbose = FALSE)

# Load points of interest
points <- read.csv(system.file("extdata/poa_points_of_interest.csv", package = "r5r"))


# Configuring trip
origin <- points[10,] # Farrapos train station
destination <- points[12,] # Praia de Belas shopping mall

trip_date_time <- lubridate::as_datetime("2019-03-20 14:00:00")

max_walk_distance = 0.8
max_trip_duration = 120L

paths_df <- detailed_itineraries(r5r_core = r5r_core,
                                 origins = origin, destinations = destination,
                                 departure_datetime = trip_date_time,
                                 max_walk_dist = max_walk_distance,
                                 max_trip_duration = max_trip_duration,
                                 mode = c("WALK", "BICYCLE", "CAR", "BUS"),
                                 shortest_path = FALSE, verbose = FALSE)

paths_df %>%
  ggplot() +
  geom_sf(aes(colour=mode)) +
  facet_wrap(~option)

Include drop_segment_geometry argument in detailed_itineraries

Nowadays there is no option to drop the segment geometry if the user doesn't want it.

I imagine that retrieving the geometry is a somewhat slow and memory consuming task (at least compared to other, such as retrieving segment duration), so I think this argument could be handy.

Error in detailed_itineraries: No suitable method for the given parameters

I'm getting this error when I try to run detailed_itineraries.

Error in .jcall("RJavaTools", "Ljava/lang/Object;", "invokeMethod", cl, :
java.lang.NoSuchMethodException: No suitable method for the given parameters

Reproducible example

 library(r5r)
 library(data.table)
 library(dplyr)
 library(sf)
 
 # build transport network
 path <- system.file("extdata", package = "r5r")
 r5_core <- setup_r5(data_path = path)

 # load origin/destination points
 points <- read.csv(system.file("extdata/poa_hexgrid.csv", package = "r5r"))

 # input
 fromLat <- points[1,]$lat
 fromLon <- points[1,]$lon
 toLat <- points[100,]$lat
 toLon <- points[100,]$lon
 trip_date <- "2019-05-20"
 departure_time <- "14:00:00"
 street_time = 15L
 direct_modes <- c("WALK", "BICYCLE", "CAR")
 transit_modes <-"BUS"
 max_street_time = 30

 trip <- detailed_itineraries( r5_core,
                              fromLat = fromLat,
                              fromLon = fromLon,
                              toLat = toLat,
                              toLon = toLon,
                              trip_date = trip_date,
                              departure_time = departure_time,
                              direct_modes = direct_modes,
                              transit_modes = transit_modes,
                              max_street_time = max_street_time
                             )

check for pbf/gtfs files on otp_setup

Check for .pbf or .gtfs files when setting data_path on the otp_setup function

Provide message with the folder name, number and names of gtfs and pbf files

Itineraries calculated between two identical points

If you send the same dataset to origins and destinations in detailed_itineraries you still get itineraries, even though origins and destinations are literally the same points.

In OTP, at least using the API, if you try to calculate a route between two identical points it returns an error "origin and destination is within trivial distance". Apparently R5 doesn't do so. Should we account for that within the jar?

Reproducible code:

# build transport network
data_path <- system.file("extdata", package = "r5r")
r5r_core <- setup_r5(data_path = data_path)

# load and set origin/destination points
points <- read.csv(file.path(data_path, "poa_hexgrid.csv"))

origins <- head(points, 5)
destinations <- origins 

# input
mode = c('WALK', 'TRANSIT')
departure_time <- "14:00:00"
trip_date <- "2019-03-15"
max_street_time <- 30L

df <- detailed_itineraries(r5r_core,
                           origins,
                           destinations,
                           mode,
                           trip_date,
                           departure_time,
                           max_street_time)
> df
Simple feature collection with 5 features and 6 fields
geometry type:  LINESTRING
dimension:      XY
bbox:           xmin: -51.21271 ymin: -30.1031 xmax: -51.15632 ymax: -30.0542
geographic CRS: WGS 84
                          request option segment mode duration route                       geometry
1 89a901291abffff_89a901291abffff      1       1 WALK      258       LINESTRING (-51.15632 -30.0...
2 89a9012a3cfffff_89a9012a3cfffff      1       1 WALK      696       LINESTRING (-51.20871 -30.0...
3 89a901295b7ffff_89a901295b7ffff      1       1 WALK       50       LINESTRING (-51.16491 -30.0...
4 89a901284a3ffff_89a901284a3ffff      1       1 WALK       64       LINESTRING (-51.20779 -30.0...
5 89a9012809bffff_89a9012809bffff      1       1 WALK       80       LINESTRING (-51.19664 -30.0...

stop_r5 doesn't collect garbage properly

Right now what stop_r5() basically does is to remove r5r_core objects and freeing up the memory previously allocated to it. However, not all free memory is actually reallocated when calling rJava::.jgc inside stop_r5. Check below (I'm using Rio's data and network, which is much more memory intensive than out sample data):

> data_path <- "rio/data/path"
> r5r_obj <- setup_r5(data_path, verbose = FALSE)
Using cached version from C:/Users/Usuario/Documents/R/win-library/4.0/r5r/jar/r5r_v4.9.0_20200822.jar

Using cached network.dat from C:/Users/Usuario/Documents/Mestrado/Dissertaรงรฃo/otp2/graphs/rio/network.dat

Memory usage:
mem1

After manually removing and garbage collecting:

> rm(r5r_obj)
> rJava::.jgc(R.gc = TRUE)

mem2

Setting up again:
mem3

Removing and garbage collecting within stop_r5():
stop_r5(r5r_obj)

mem4

Doesn't free everything. After another garbage collecting, out of stop_r5:
rJava::.jgc(R.gc = TRUE)
mem5

So... Not sure why it behaves like this.

A temporary fix to this is to always use the code below after finishing with r5r, but ideally stop_r5 alone should be enough.

stop_r5(r5r_obj)
rJava::.jgc(R.gc = TRUE)

Any ideas?

Tidying input checking and r5r option setting

Each one of us were writing error and warning messages in our own way. I started using checkmate:: where possible and where not possible I'm trying to emulate their messages as closely as possible.

I also created some more utils function to standardise the way we set r5r options (sometimes it would happen in the body of the main functions, as with number of threads and speeds, sometimes with the aid of utils functions, such as with verbose).

I have already made big progress with this in detailed_itineraries. I'll later do it with travel_time_matrix if you don't make any objections (feel free to do so, though).

Create a very small sample data to save inside the project

Get very small sample data sets that we will be using to test, develop and demonstrate the package.

  • A 1 Km by 1 Km .pbf of a city
  • A small GTFS.zip, perhaps only three or 4 routes
  • A few points that will be used as origin and destination
  • Save these files in the inst/extdata directory.

automatic message to check Java version

It would be good to include a quick automatic check of the Java version. This below is a piece of code suggested by Simon Urbanek, one of the core authors of rJava. I think we could included it as a first check within the setup_r5 function. If the person does not have the necessary jdk installed, then the function should throw a clear error with the reason.

library(r5r)
library(rJava)

# get installed version of Java
.jinit()
ver <- .jcall("java.lang.System","S","getProperty","java.version")
ver

# check version >= 11
ver <- as.numeric(gsub("\\..*","",ver))
if (ver < 11) error("This package requires Java 11 or higher. Please update your Java installation.")

Error in setup_r5: object 'path' not found

Sometimes I get this error below when I test setup_r5.

library(r5r)
library(covr)
library(testthat)

covr::function_coverage(fun=r5r::setup_r5, test_file("tests/testthat/test-setup_r5.R"))

-- 1. Error: setup_r5 - expected behavior (@test-setup_r5.R#9) --------
object 'path' not found
Backtrace:

  1. testthat::expect_message(setup_r5(data_path = path))
  2. r5r::setup_r5(data_path = path)
  3. base::file.path(path, "network.dat")

"TRANSIT" wrapper for all transit options not working

I tried calculating a route with modes = c("WALK", "TRANSIT") but only walking routes were being returned. I then changed "TRANSIT" to "BUS" and some routes appeared. Reproducible code below.

With "TRANSIT":

data_path <- system.file("extdata", package = "r5r")
r5r_core <- setup_r5(data_path = data_path)

origins <- data.frame(id = "10", lat = -29.997721, lon = -51.197618)
destinations <- data.frame(id = "12", lat = -30.049951, lon = -51.228752)

mode = c('WALK', 'TRANSIT')
departure_time <- "14:00:00"
trip_date <- "2019-03-15"
max_street_time <- 120L

df <- detailed_itineraries(r5r_core,
                           origins,
                           destinations,
                           mode,
                           trip_date,
                           departure_time,
                           max_street_time)
> df
Simple feature collection with 1 feature and 6 fields
geometry type:  LINESTRING
dimension:      XY
bbox:           xmin: -51.22955 ymin: -30.05002 xmax: -51.19807 ymax: -29.99884
geographic CRS: WGS 84
  request option segment mode duration route                       geometry
1   10_12      1       1 WALK     7164       LINESTRING (-51.19807 -29.9...

With "BUS":

data_path <- system.file("extdata", package = "r5r")
r5r_core <- setup_r5(data_path = data_path)

origins <- data.frame(id = "10", lat = -29.997721, lon = -51.197618)
destinations <- data.frame(id = "12", lat = -30.049951, lon = -51.228752)

mode = c('WALK', 'BUS')
departure_time <- "14:00:00"
trip_date <- "2019-03-15"
max_street_time <- 120L

df <- detailed_itineraries(r5r_core,
                           origins,
                           destinations,
                           mode,
                           trip_date,
                           departure_time,
                           max_street_time)
> df
Simple feature collection with 49 features and 6 fields
geometry type:  LINESTRING
dimension:      XY
bbox:           xmin: -51.22972 ymin: -30.07325 xmax: -51.17479 ymax: -29.99884
geographic CRS: WGS 84
First 10 features:
   request option segment mode duration  route                       geometry
1    10_12      1       1 WALK     7164        LINESTRING (-51.19807 -29.9...
2    10_12      2       1 WALK     1042        LINESTRING (-51.19807 -29.9...
3    10_12      2       2  BUS     2694 poa:T2 LINESTRING (-51.20197 -30.0...
4    10_12      2       3 WALK      733        LINESTRING (-51.22891 -30.0...
5    10_12      3       1 WALK     1042        LINESTRING (-51.19807 -29.9...
6    10_12      3       2  BUS     2739 poa:T2 LINESTRING (-51.20197 -30.0...
7    10_12      3       3 WALK      493        LINESTRING (-51.22846 -30.0...
8    10_12      4       1 WALK     1042        LINESTRING (-51.19807 -29.9...
9    10_12      4       2  BUS     2731 poa:T2 LINESTRING (-51.20197 -30.0...
10   10_12      4       3 WALK      535        LINESTRING (-51.22853 -30.0...

Using a max_walk_dist that equals a max_street_time of 0L is equivalent to using max_walk_dist = Inf

The title says it all.

Below I'm using max_walk_dist = 30, which is the highest value before max_street_time assumes the value 1L, max_walk_dist = 31 and max_walk_dist = Inf.

I just noticed while writing this issue that it actually returns even more routes than with max_walk_dist = Inf, but I haven't investigated further.

Is that a behaviour we want? How does that work within Java?

data_path <- system.file("extdata", package = "r5r")
r5r_core <- setup_r5(data_path = data_path)
points <- read.csv(file.path(data_path, "poa_points_of_interest.csv"))

origins <- points
destinations <- points[15:1,]
mode = c("WALK", "BUS")
departure_datetime <- as.POSIXct("13-03-2019 14:00:00",
                                 format = "%d-%m-%Y %H:%M:%S")
max_walk_dist <- 30

df <- detailed_itineraries(r5r_core,
                           origins,
                           destinations,
                           mode,
                           departure_datetime,
                           max_walk_dist)
> df
Simple feature collection with 46 features and 13 fields
geometry type:  LINESTRING
dimension:      XY
bbox:           xmin: -51.2409 ymin: -30.07325 xmax: -51.16276 ymax: -29.99884
geographic CRS: WGS 84
First 10 features:
                fromId   fromLat   fromLon              toId     toLat     toLon option segment mode duration distance   route wait
1        public_market -30.02756 -51.22781             pucrs -30.05797 -51.17607      2       1 WALK    10.32      621            0
2        public_market -30.02756 -51.22781             pucrs -30.05797 -51.17607      2       2  BUS     8.65     3586 poa:R10  221
3        public_market -30.02756 -51.22781             pucrs -30.05797 -51.17607      2       3 WALK    70.45     4206            0
4  bus_central_station -30.02329 -51.21886             ufrgs -30.03340 -51.22028      4       1 WALK     3.53      205            0
5  bus_central_station -30.02329 -51.21886             ufrgs -30.03340 -51.22028      4       2  BUS     2.95     1191 poa:176 1171
6  bus_central_station -30.02329 -51.21886             ufrgs -30.03340 -51.22028      4       3 WALK    23.13     1367            0
7     gasometer_museum -30.03404 -51.24095 beira_rio_stadium -30.06494 -51.23659     17       1 WALK    25.25     1491            0
8     gasometer_museum -30.03404 -51.24095 beira_rio_stadium -30.06494 -51.23659     17       2  BUS     9.72     4643 poa:R10  114
9     gasometer_museum -30.03404 -51.24095 beira_rio_stadium -30.06494 -51.23659     17       3 WALK     2.63      154            0
10    gasometer_museum -30.03404 -51.24095 beira_rio_stadium -30.06494 -51.23659     17       4  BUS     5.53     1793  poa:T2  104
                         geometry
1  LINESTRING (-51.22784 -30.0...
2  LINESTRING (-51.22785 -30.0...
3  LINESTRING (-51.21318 -30.0...
4  LINESTRING (-51.21879 -30.0...
5  LINESTRING (-51.21989 -30.0...
6  LINESTRING (-51.22904 -30.0...
7  LINESTRING (-51.2409 -30.03...
8  LINESTRING (-51.22822 -30.0...
9  LINESTRING (-51.21214 -30.0...
10 LINESTRING (-51.21198 -30.0...
max_walk_dist <- 31
> df
Simple feature collection with 1 feature and 13 fields
geometry type:  LINESTRING
dimension:      XY
bbox:           xmin: -51.21632 ymin: -30.03664 xmax: -51.21614 ymax: -30.03653
geographic CRS: WGS 84
            fromId   fromLat   fromLon             toId     toLat     toLon option segment mode duration distance route wait
1 farroupilha_park -30.03675 -51.21611 farroupilha_park -30.03675 -51.21611      1       1 WALK     0.47       42          0
                        geometry
1 LINESTRING (-51.21632 -30.0...
max_walk_dist <- Inf
Simple feature collection with 42 features and 13 fields
geometry type:  LINESTRING
dimension:      XY
bbox:           xmin: -51.2409 ymin: -30.07325 xmax: -51.16276 ymax: -29.99884
geographic CRS: WGS 84
First 10 features:
                fromId   fromLat   fromLon                           toId     toLat     toLon option segment mode duration distance   route wait
1        public_market -30.02756 -51.22781                          pucrs -30.05797 -51.17607      3       1 WALK    10.32      621            0
2        public_market -30.02756 -51.22781                          pucrs -30.05797 -51.17607      3       2  BUS     8.65     3586 poa:R10  221
3        public_market -30.02756 -51.22781                          pucrs -30.05797 -51.17607      3       3 WALK    70.45     4206            0
4  bus_central_station -30.02329 -51.21886                          ufrgs -30.03340 -51.22028      1       1 WALK    23.43     1399            0
5     gasometer_museum -30.03404 -51.24095              beira_rio_stadium -30.06494 -51.23659     18       1 WALK    25.25     1491            0
6     gasometer_museum -30.03404 -51.24095              beira_rio_stadium -30.06494 -51.23659     18       2  BUS     9.72     4643 poa:R10  114
7     gasometer_museum -30.03404 -51.24095              beira_rio_stadium -30.06494 -51.23659     18       3 WALK     2.63      154            0
8     gasometer_museum -30.03404 -51.24095              beira_rio_stadium -30.06494 -51.23659     18       4  BUS     5.53     1793  poa:T2  104
9     gasometer_museum -30.03404 -51.24095              beira_rio_stadium -30.06494 -51.23659     18       5 WALK    17.67     1050            0
10 santa_casa_hospital -30.03043 -51.22240 praia_de_belas_shopping_center -30.04995 -51.22875      2       1 WALK    11.32      710            0
                         geometry
1  LINESTRING (-51.22784 -30.0...
2  LINESTRING (-51.22785 -30.0...
3  LINESTRING (-51.21318 -30.0...
4  LINESTRING (-51.21879 -30.0...
5  LINESTRING (-51.2409 -30.03...
6  LINESTRING (-51.22822 -30.0...
7  LINESTRING (-51.21214 -30.0...
8  LINESTRING (-51.21198 -30.0...
9  LINESTRING (-51.22852 -30.0...
10 LINESTRING (-51.222 -30.029...

Issues with setup_r5()

I noticed that after the creation of R5 core some new files were created in inst/extdata (when running it with the sample data). These are: network.dat, poa_osm.pbf.mapdb and poa_osm.pbf.mapdb.p. Any ideas what that might be?

Also, when running setup_r5 with a .pbf file but no gtfs an error arises (I just copied the pbf file to ~ in this example):

> setup_r5("~")
Using cached version from C:/Users/Usuario/Documents/R/win-library/4.0/r5r/jar/r5r_v4.9.0.jar
12 [main] INFO com.conveyal.r5.transit.TransportNetwork - File '~\build-config.json' is not present. Using default configuration.
 Error in rJava::.jnew("com.conveyal.r5.R5RCore", data_path) : 
  java.lang.NullPointerException 

Edit: Actually, I tried creating a test folder inside ~ with the exact same files as inst/extdata" and run setup_r5("~/test") and I get the same error message as above.

Error detailed_itineraries

@dhersz , I'm curently getting this error in the detailed_itineraries. Thia might be related to recent changes in the function/package. Could you please update the test script?

library(r5r)
library(covr)
library(testthat)

# test
test_file("tests/testthat/test-detailed_itineraries.R")

# code coverage
covr::function_coverage(fun=r5r::detailed_itineraries, 
                        test_file("tests/testthat/test-detailed_itineraries.R"))

test-detailed_itineraries.R:47: error: detailed_itineraries adequately raises warnings and errors
Eror: 2019-03-13 14:00:00 is not a valid 'mode'.
Please use one of the following: TRANSIT, TRAM, SUBWAY, RAIL, BUS, FERRY, CABLE_CAR, GONDOLA, FUNICULAR, WALK, BICYCLE, CAR, BICYCLE_RENT, CAR_PARK

Create function to stop r5_core

I tried stopping the process with system("Taskkill /IM java.exe /F", intern = TRUE) but wasn't able to.

For reference, when I logoff my computer after setting r5 up i get the following warnings:

ago 15, 2020 3:16:35 PM org.geotools.referencing.factory.DeferredAuthorityFactory disposeBackingStore
INFO: Disposing class org.geotools.referencing.factory.epsg.hsql.ThreadedHsqlEpsgFactory backing store
ago 15, 2020 3:16:35 PM org.hsqldb.persist.Logger logInfoEvent
INFO: Database closed

Actually I don't even know what task I should be trying to kill here, I tried java because that's how you'd stop a OTP server, but not sure how it works with r5.

Units of inputs and outputs

Can we please confirm what units are used the inputs and outputs of the package functions?

input:

  • max_walk_dist
  • max_trip_duration
  • walk_speed
  • bike_speed

output:

  • travel_time_matrix

    • travel_time
  • detailed_itineraries

    • duration
    • distance

Functions to export

I glimpsed through NAMESPACE and we're exporting some functions (assert_points_input, posix_to_string, select_mode and set_...) which are used only internally. Should those be exported or kept for internal use only?

Fatal Java error when running setup_r5

When I try to run setup_r5, I run into the following warnings and error:

WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by org.mapdb.Volume$ByteBufferVol (file:/Library/Frameworks/R.framework/Versions/4.0/Resources/library/r5r/jar/r5r_v4.9.0_20200825.jar) to method java.nio.DirectByteBuffer.cleaner() WARNING: Please consider reporting this to the maintainers of org.mapdb.Volume$ByteBufferVol WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release Error in rJava::.jnew("org.ipea.r5r.R5RCore", data_path, verbose) : java.io.IOError: java.io.IOException: Wrong index checksum, store was not closed properly and could be corrupted.

I'm on macOS 10.15.6, with the Java SE Development Kit 11.0.8 installed. Happy to provide any additional info necessary to nail down the bug!

Return travel matrices each minute over a time window

One of the advantages os R5 is how it uses searches from previous departure times to bound the path searches of other departure times later. This gives a big boost to performance and allows us to estimave travel times departing every minute within a time window. There are various advantages of this approach from a sampling perspective (see some works by Marcin Stepniak, Andrew Owen and Steve Farber). I will just reproduce below the suggestion from Matthew Conway (one of the core developers of R5).

Have you considered expanding your travel time matrix function to return all travel times over a time window (say, every minute from 8 am to 10 am)? By setting fromTime and toTime to be further than 60 seconds apart, R5 will calculate the full OD matrix for an origin to all destinations for every departure minute in that time window, a lot quicker than a naive loop would because it re-uses paths that were found a later minutes (because the slowest possible trip departing at 9:00 is by definition no slower than the trip departing at 9:01 + 1 minute, we can bound the search process and make it really fast). Details of these optimizations are in this paper: https://repository.asu.edu/items/54162

Java memory allocation

By default, R allocates only 512MB of memory for Java processes, which is not enough for large queries using r5r.

To increase available memory to 10GB, for example, we need to set the java.parameters option as follows:

options(java.parameters = "-Xmx10G")

Ideally, memory size should be passed as a parameter to the setup_r5 function, so it can be passed along to the .jinit function. However, this does not seem to work, at least in RStudio. It also does not work in RStudio markdown documents. In my tests, it only worked when set as the very first line in an R script, and running on a fresh R session.

For now, the only solution I can think of is letting people know in the package's readme file that they need to set the -Xmx parameter at the beginning of their scripts.

Outputting both actual results and a list with the parameters passed to functions?

Nowadays travel_time_matrix outputs a data.table with a mode column that could be used to remind the users what modes were sent as parameters.

Since the "TRANSIT" wrapper is not natively working from R5, if "TRANSIT" has been used it appends a huge string to the column (see example in the end of post).

What worries me a bit here is not that it's ugly, but we are adding a column to a potentially huge dataset to get just a single information. Also, if we're appending mode we could also be appending any other parameters sent to the function (departure time, max trip duration, etc.).

So I thought that maybe we could output a list that contains both a nested list with the parameters sent to the function and a datatable with the matrix per se. What do you think? At least that could be a useful parameter (something in the lines of include_parameters)?

Example mentioned:

> df
             fromId   fromLat   fromLon            toId     toLat     toLon travel_time
 1: 89a901291abffff -30.05385 -51.15825 89a901291abffff -30.05385 -51.15825           2
 2: 89a901291abffff -30.05385 -51.15825 89a901295b7ffff -30.07544 -51.16521          54
 3: 89a901291abffff -30.05385 -51.15825 89a901284a3ffff -30.09005 -51.20535         117
 4: 89a901291abffff -30.05385 -51.15825 89a9012809bffff -30.07839 -51.19575          80
 5: 89a9012a3cfffff -30.10058 -51.21187 89a9012a3cfffff -30.10058 -51.21187           3
 6: 89a9012a3cfffff -30.10058 -51.21187 89a901284a3ffff -30.09005 -51.20535          58
 7: 89a9012a3cfffff -30.10058 -51.21187 89a9012809bffff -30.07839 -51.19575         112
 8: 89a901295b7ffff -30.07544 -51.16521 89a901291abffff -30.05385 -51.15825          54
 9: 89a901295b7ffff -30.07544 -51.16521 89a901295b7ffff -30.07544 -51.16521           0
10: 89a901295b7ffff -30.07544 -51.16521 89a901284a3ffff -30.09005 -51.20535         117
11: 89a901295b7ffff -30.07544 -51.16521 89a9012809bffff -30.07839 -51.19575          61
12: 89a901284a3ffff -30.09005 -51.20535 89a9012a3cfffff -30.10058 -51.21187          58
13: 89a901284a3ffff -30.09005 -51.20535 89a901284a3ffff -30.09005 -51.20535           2
14: 89a901284a3ffff -30.09005 -51.20535 89a9012809bffff -30.07839 -51.19575          45
15: 89a9012809bffff -30.07839 -51.19575 89a9012a3cfffff -30.10058 -51.21187          87
16: 89a9012809bffff -30.07839 -51.19575 89a901295b7ffff -30.07544 -51.16521          61
17: 89a9012809bffff -30.07839 -51.19575 89a901284a3ffff -30.09005 -51.20535          46
18: 89a9012809bffff -30.07839 -51.19575 89a9012809bffff -30.07839 -51.19575           0
                                                                   mode
 1: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
 2: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
 3: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
 4: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
 5: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
 6: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
 7: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
 8: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
 9: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
10: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
11: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
12: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
13: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
14: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
15: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
16: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
17: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR
18: WALK TRANSIT;TRAM;SUBWAY;RAIL;BUS;FERRY;CABLE_CAR;GONDOLA;FUNICULAR

Different times, same results

I notice that the results from r5r::travel_time_matrix are the same for all times that I choose. I use the line specified in the vignette (with different times):

departure_datetime = lubridate::as_datetime("2019-03-20 14:00:00")

Is this supposed to happen?

Add a "quiet" argument to setup_r5

setup_r5() right now outputs all the network building logs in the console. This can be a bit overwhelming and in the case of large networks I guess it won't be possible to scroll all the way up to where the log starts because the console has a limit of rows.

The "quiet" argument could be used to, instead of outputting the logs in the console, saving it in a log file in the provided path.

Run Travis with correct Java version

The package is failling on devtools::check_win_release(pkg = ".") and on Travis due to the Java version. This is the error we get:

java.lang.UnsupportedClassVersioncom/conveyal/r5/R5RCore has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0

I'm investigating whether we can force Travis and CRAN tests to run on an specific version of Java by adding and specification on the .travis.yml file. There are some clues here but this will involve a long trial and error process.

total_duration sums up to 0 when an option is composed of only one segment

Check the example below. Also note that total_duration is different than the sum of segment_duration + wait almost always by an integer.

You can see that the first two options, direct trips by car and walk, have total_duration = 0, even though segment_duration is there.

Also, check the second option (CAR-BUS-WALK). The sum fo segment_duration + wait is 29.22, while the total_duration is 30.22. Same with the following option, which sums to 37.18 when total returns 38.18.
Perhaps it's useful to include the fields segment_start_time and segment_end_time. We could use these to calculate the segment duration and to check whether the trip is actually starting at the time we are passing on departure_datetime or if there's some initial wait going on.

data_path <- system.file("extdata", package = "r5r")
r5r_obj <- setup_r5(data_path = data_path)
points <- read.csv(file.path(data_path, "poa_points_of_interest.csv"))

origins      <- points[10,]
destinations <- points[12,]

df <- detailed_itineraries(
   r5r_obj,
   origins,
   destinations,
   mode = c("WALK", "CAR", "BUS"),
   departure_datetime = as.POSIXct("13-03-2019 14:00:00", format = "%d-%m-%Y %H:%M:%S"),
   max_walk_dist = Inf,
   max_trip_duration = 120L,
   walk_speed = 3.6,
   bike_speed = 12,
   shortest_path = FALSE,
   n_threads = Inf,
   verbose = FALSE,
   drop_geometry = FALSE
 )

stop_r5(r5r_obj)
rJava::.jgc(R.gc = TRUE)
> df
Simple feature collection with 8 features and 14 fields
geometry type:  LINESTRING
dimension:      XY
bbox:           xmin: -51.22976 ymin: -30.05522 xmax: -51.19807 ymax: -29.99884
geographic CRS: WGS 84
            fromId   fromLat   fromLon                           toId     toLat     toLon option segment mode total_duration segment_duration wait
1 farrapos_station -29.99772 -51.19762 praia_de_belas_shopping_center -30.04995 -51.22875      1       1 WALK           0.00           119.40 0.00
2 farrapos_station -29.99772 -51.19762 praia_de_belas_shopping_center -30.04995 -51.22875      2       1  CAR           0.00            20.60 0.00
3 farrapos_station -29.99772 -51.19762 praia_de_belas_shopping_center -30.04995 -51.22875     38       1  CAR          30.22            17.72 0.00
4 farrapos_station -29.99772 -51.19762 praia_de_belas_shopping_center -30.04995 -51.22875     38       2  BUS          30.22             0.13 3.15
5 farrapos_station -29.99772 -51.19762 praia_de_belas_shopping_center -30.04995 -51.22875     38       3 WALK          30.22             8.22 0.00
6 farrapos_station -29.99772 -51.19762 praia_de_belas_shopping_center -30.04995 -51.22875     29       1  CAR          38.18            13.35 0.00
7 farrapos_station -29.99772 -51.19762 praia_de_belas_shopping_center -30.04995 -51.22875     29       2  BUS          38.18             0.60 1.98
8 farrapos_station -29.99772 -51.19762 praia_de_belas_shopping_center -30.04995 -51.22875     29       3 WALK          38.18            21.25 0.00
  distance   route                       geometry
1     7002         LINESTRING (-51.19807 -29.9...
2     7779         LINESTRING (-51.19981 -29.9...
3     8803         LINESTRING (-51.20018 -30.0...
4       41  poa:T2 LINESTRING (-51.22853 -30.0...
5      483         LINESTRING (-51.22846 -30.0...
6     5791         LINESTRING (-51.20018 -30.0...
7      248 poa:R10 LINESTRING (-51.22822 -30.0...
8     1263         LINESTRING (-51.22972 -30.0...

Send trip_date and departure_time as the same argument trip_departure_time?

Right now both detailed itineraries and travel time matrix functions have two separate arguments trip_date and departure_time, strings with specific formatting options.

We could maybe unify these two string arguments into a single POSIX one, and make any necessary conversions to suit R5 usage inside the functions. What do you think?
I think it would lower the chances of the users passing invalid arguments to the functions and would simplify validity checks as well.

Different data structures to represent no itineraries between a pair of points

Sometimes the objects used to represent no itineraries between a pair of points (by java?) are different. They are either NULL or a list of empty lists. Check below:

image

df here is the result of r5r_core$planMultipleTrips after converted to R using jdx::convertToR.
Note that while df[[1]] is a list of empty lists, df[[5]] is NULL.

This breaks the processing of df, which eventually is turned into a sf data.table, because you get the following error after turning df into a data.table:

Error in `[.data.table`(path_options, , `:=`(temp_duration, sum(duration)),  : 
  column or expression 1 of 'by' or 'keyby' is type list. Do not quote column names. Usage: DT[,sum(colC),by=list(colA,month(colB))]

While that is fixable, it wasn't happening before, so it may be something with the new jar?
To replicate the error, try the code below:

data_path <- system.file("extdata", package = "r5r")
r5r_core <- setup_r5(data_path = data_path)
points <- read.csv(file.path(data_path, "poa_points_of_interest.csv")

origins <- points
destinations <- points[15:1,]
mode = c("WALK", "BUS")
max_walk_dist <- 1000
departure_datetime <- as.POSIXct("13-03-2019 14:00:00",
                                 format = "%d-%m-%Y %H:%M:%S")

df <- detailed_itineraries(r5r_core,
                           origins,
                           destinations,
                           mode,
                           departure_datetime,
                           max_walk_dist)

To replicate df, please place return(path_options) in line 221 of detailed_itineraries.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.