r5py 0.1.2__tar.gz → 1.0.0.dev1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of r5py might be problematic. Click here for more details.

Files changed (73) hide show
  1. {r5py-0.1.2/src/r5py.egg-info → r5py-1.0.0.dev1}/PKG-INFO +3 -4
  2. {r5py-0.1.2 → r5py-1.0.0.dev1}/pyproject.toml +12 -8
  3. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/__init__.py +5 -1
  4. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/r5/__init__.py +4 -2
  5. r5py-0.1.2/src/r5py/r5/base_travel_time_matrix_computer.py → r5py-1.0.0.dev1/src/r5py/r5/base_travel_time_matrix.py +25 -4
  6. r5py-0.1.2/src/r5py/r5/detailed_itineraries_computer.py → r5py-1.0.0.dev1/src/r5py/r5/detailed_itineraries.py +66 -9
  7. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/r5/regional_task.py +2 -2
  8. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/r5/transit_layer.py +4 -0
  9. r5py-0.1.2/src/r5py/r5/travel_time_matrix_computer.py → r5py-1.0.0.dev1/src/r5py/r5/travel_time_matrix.py +95 -10
  10. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/r5/trip.py +5 -4
  11. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/r5/trip_leg.py +32 -10
  12. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/r5/trip_planner.py +22 -8
  13. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/util/classpath.py +2 -2
  14. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/util/config.py +3 -3
  15. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/util/sample_data_set.py +4 -1
  16. {r5py-0.1.2 → r5py-1.0.0.dev1/src/r5py.egg-info}/PKG-INFO +3 -4
  17. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py.egg-info/SOURCES.txt +5 -6
  18. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py.egg-info/requires.txt +1 -2
  19. r5py-0.1.2/tests/test_detailed_itineraries_computer.py → r5py-1.0.0.dev1/tests/test_detailed_itineraries.py +85 -63
  20. {r5py-0.1.2 → r5py-1.0.0.dev1}/tests/test_deterministic_behaviour.py +1 -5
  21. r5py-0.1.2/tests/test_travel_time_matrix_computer.py → r5py-1.0.0.dev1/tests/test_travel_time_matrix.py +114 -61
  22. {r5py-0.1.2 → r5py-1.0.0.dev1}/tests/test_trip.py +37 -29
  23. {r5py-0.1.2 → r5py-1.0.0.dev1}/tests/test_trip_leg.py +21 -14
  24. {r5py-0.1.2 → r5py-1.0.0.dev1}/tests/test_verbose_warnings.py +7 -7
  25. r5py-0.1.2/src/r5py/sampledata/_keep/__init__.py +0 -3
  26. {r5py-0.1.2 → r5py-1.0.0.dev1}/LICENSE +0 -0
  27. {r5py-0.1.2 → r5py-1.0.0.dev1}/README.md +0 -0
  28. {r5py-0.1.2 → r5py-1.0.0.dev1}/setup.cfg +0 -0
  29. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/__main__.py +0 -0
  30. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/r5/access_leg.py +0 -0
  31. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/r5/breakdown_stat.py +0 -0
  32. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/r5/direct_leg.py +0 -0
  33. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/r5/egress_leg.py +0 -0
  34. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/r5/scenario.py +0 -0
  35. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/r5/street_layer.py +0 -0
  36. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/r5/transfer_leg.py +0 -0
  37. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/r5/transit_leg.py +0 -0
  38. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/r5/transport_mode.py +0 -0
  39. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/r5/transport_network.py +0 -0
  40. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/util/__init__.py +0 -0
  41. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/util/camel_to_snake_case.py +0 -0
  42. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/util/contains_gtfs_data.py +0 -0
  43. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/util/data_validation.py +0 -0
  44. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/util/environment.py +0 -0
  45. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/util/exceptions.py +0 -0
  46. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/util/good_enough_equidistant_crs.py +0 -0
  47. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/util/jvm.py +0 -0
  48. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/util/memory_footprint.py +0 -0
  49. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/util/parse_int_date.py +0 -0
  50. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/util/snake_to_camel_case.py +0 -0
  51. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/util/validating_requests_session.py +0 -0
  52. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py/util/warnings.py +0 -0
  53. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py.egg-info/dependency_links.txt +0 -0
  54. {r5py-0.1.2 → r5py-1.0.0.dev1}/src/r5py.egg-info/top_level.txt +0 -0
  55. {r5py-0.1.2 → r5py-1.0.0.dev1}/tests/test_breakdownstats.py +0 -0
  56. {r5py-0.1.2 → r5py-1.0.0.dev1}/tests/test_camel_to_snake_case.py +0 -0
  57. {r5py-0.1.2 → r5py-1.0.0.dev1}/tests/test_classpath.py +0 -0
  58. {r5py-0.1.2 → r5py-1.0.0.dev1}/tests/test_config.py +0 -0
  59. {r5py-0.1.2 → r5py-1.0.0.dev1}/tests/test_contains_gtfs_data.py +0 -0
  60. {r5py-0.1.2 → r5py-1.0.0.dev1}/tests/test_data_validation.py +0 -0
  61. {r5py-0.1.2 → r5py-1.0.0.dev1}/tests/test_good_enough_equidistant_crs.py +0 -0
  62. {r5py-0.1.2 → r5py-1.0.0.dev1}/tests/test_java_casting.py +0 -0
  63. {r5py-0.1.2 → r5py-1.0.0.dev1}/tests/test_memory_footprint.py +0 -0
  64. {r5py-0.1.2 → r5py-1.0.0.dev1}/tests/test_parse_int_date.py +0 -0
  65. {r5py-0.1.2 → r5py-1.0.0.dev1}/tests/test_regional_task.py +0 -0
  66. {r5py-0.1.2 → r5py-1.0.0.dev1}/tests/test_sample_data_set.py +0 -0
  67. {r5py-0.1.2 → r5py-1.0.0.dev1}/tests/test_snake_to_camel_case.py +0 -0
  68. {r5py-0.1.2 → r5py-1.0.0.dev1}/tests/test_street_layer.py +0 -0
  69. {r5py-0.1.2 → r5py-1.0.0.dev1}/tests/test_transit_layer.py +0 -0
  70. {r5py-0.1.2 → r5py-1.0.0.dev1}/tests/test_transport_mode.py +0 -0
  71. {r5py-0.1.2 → r5py-1.0.0.dev1}/tests/test_transport_network.py +0 -0
  72. {r5py-0.1.2 → r5py-1.0.0.dev1}/tests/test_trip_planner.py +0 -0
  73. {r5py-0.1.2 → r5py-1.0.0.dev1}/tests/test_validating_request_session.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: r5py
3
- Version: 0.1.2
3
+ Version: 1.0.0.dev1
4
4
  Summary: Python wrapper for the R5 routing analysis engine
5
5
  Author: Willem Klumpenhouwer, Marcus Sairava, Rafael Pereira, Henrikki Tenkanen
6
6
  Author-email: Christoph Fink <christoph.fink@helsinki.fi>
@@ -21,7 +21,6 @@ Requires-Dist: ConfigArgParse
21
21
  Requires-Dist: filelock
22
22
  Requires-Dist: fiona
23
23
  Requires-Dist: geopandas
24
- Requires-Dist: importlib_resources
25
24
  Requires-Dist: joblib
26
25
  Requires-Dist: jpype1
27
26
  Requires-Dist: numpy
@@ -52,11 +51,11 @@ Requires-Dist: sphinxcontrib-images; extra == "docs"
52
51
  Provides-Extra: tests
53
52
  Requires-Dist: pyarrow; extra == "tests"
54
53
  Requires-Dist: pytest; extra == "tests"
55
- Requires-Dist: pytest-asyncio; extra == "tests"
56
54
  Requires-Dist: pytest-cov; extra == "tests"
57
55
  Requires-Dist: pytest-lazy-fixtures; extra == "tests"
58
56
  Requires-Dist: r5py.sampledata.helsinki>=0.1.1; extra == "tests"
59
57
  Requires-Dist: r5py.sampledata.sao_paulo>=0.1.1; extra == "tests"
58
+ Requires-Dist: typing-extensions; extra == "tests"
60
59
 
61
60
  <img class="r5py_logo" align="right" src="https://github.com/r5py/r5py/raw/main/docs/_static/images/r5py_blue.svg" alt="r5py logo" style="width:180px; max-width:30vW;">
62
61
 
@@ -20,7 +20,6 @@ dependencies = [
20
20
  "filelock",
21
21
  "fiona",
22
22
  "geopandas",
23
- "importlib_resources",
24
23
  "joblib",
25
24
  "jpype1",
26
25
  "numpy",
@@ -49,9 +48,9 @@ docs = ["contextily", "folium", "GitPython", "h3>=4.0.0b2", "jupyterlab_myst",
49
48
  "r5py.sampledata.helsinki>=0.1.1", "r5py.sampledata.sao_paulo>=0.1.1",
50
49
  "shapely", "sphinx", "sphinx-book-theme", "sphinx-design",
51
50
  "sphinxcontrib-bibtex", "sphinxcontrib-images"]
52
- tests = ["pyarrow", "pytest", "pytest-asyncio", "pytest-cov",
53
- "pytest-lazy-fixtures", "r5py.sampledata.helsinki>=0.1.1",
54
- "r5py.sampledata.sao_paulo>=0.1.1"]
51
+ tests = ["pyarrow", "pytest", "pytest-cov", "pytest-lazy-fixtures",
52
+ "r5py.sampledata.helsinki>=0.1.1", "r5py.sampledata.sao_paulo>=0.1.1",
53
+ "typing-extensions"]
55
54
 
56
55
 
57
56
  [project.urls]
@@ -60,22 +59,27 @@ Repository = "https://github.com/r5py/r5py.git"
60
59
  "Change log" = "https://github.com/r5py/r5py/blob/main/CHANGELOG.md"
61
60
  "Bug tracker" = "https://github.com/r5py/r5py/issues"
62
61
 
63
- [tool.coverage.run]
64
- omit = ["tests/*", ".virtualenv/**/*"]
62
+ [tool.coverage.paths]
63
+ equivalent_sources = [
64
+ "src/r5py/",
65
+ ".virtualenv/lib/python*/site-packages/r5py/",
66
+ "/opt/hostedtoolcache/Python/*/x64/lib/python*/site-packages/r5py/",
67
+ "/Library/Frameworks/Python.framework/Versions/*/lib/python*/site-packages/r5py/",
68
+ "C:/hostedtoolcache/windows/Python/*/x64/Lib/site-packages/r5py/"
69
+ ]
65
70
 
66
71
  [tool.jupytext.formats]
67
72
  "docs/notebooks/" = "ipynb"
68
73
  "docs/md/" = "md"
69
74
 
70
75
  [tool.pytest.ini_options]
71
- addopts = "-p no:faulthandler --cov --cov-report term-missing --cov-report xml"
76
+ addopts = "-p no:faulthandler --cov=r5py --cov-report term-missing --cov-report xml --import-mode=importlib"
72
77
  filterwarnings = [
73
78
  "error",
74
79
  "ignore:Could not find R5 jar, trying to download it from upstream",
75
80
  "ignore:Successfully downloaded r5-"
76
81
  ]
77
82
  testpaths = ["tests"]
78
- asyncio_mode = "auto"
79
83
 
80
84
  [tool.setuptools.dynamic]
81
85
  version = {attr = "r5py.__version__"}
@@ -2,22 +2,26 @@
2
2
 
3
3
  """Python wrapper for the R5 routing analysis engine."""
4
4
 
5
- __version__ = "0.1.2"
5
+ __version__ = "1.0.0.dev1"
6
6
 
7
7
 
8
8
  from .r5 import (
9
+ DetailedItineraries,
9
10
  DetailedItinerariesComputer,
10
11
  RegionalTask,
11
12
  TransportMode,
12
13
  TransportNetwork,
14
+ TravelTimeMatrix,
13
15
  TravelTimeMatrixComputer,
14
16
  )
15
17
 
16
18
  __all__ = [
19
+ "DetailedItineraries",
17
20
  "DetailedItinerariesComputer",
18
21
  "RegionalTask",
19
22
  "TransportMode",
20
23
  "TransportNetwork",
24
+ "TravelTimeMatrix",
21
25
  "TravelTimeMatrixComputer",
22
26
  "__version__",
23
27
  ]
@@ -4,7 +4,7 @@
4
4
 
5
5
  from .access_leg import AccessLeg
6
6
  from .breakdown_stat import BreakdownStat
7
- from .detailed_itineraries_computer import DetailedItinerariesComputer
7
+ from .detailed_itineraries import DetailedItineraries, DetailedItinerariesComputer
8
8
  from .direct_leg import DirectLeg
9
9
  from .egress_leg import EgressLeg
10
10
  from .regional_task import RegionalTask
@@ -14,13 +14,14 @@ from .transfer_leg import TransferLeg
14
14
  from .transit_leg import TransitLeg
15
15
  from .transport_mode import TransportMode
16
16
  from .transport_network import TransportNetwork
17
- from .travel_time_matrix_computer import TravelTimeMatrixComputer
17
+ from .travel_time_matrix import TravelTimeMatrix, TravelTimeMatrixComputer
18
18
  from .trip import Trip
19
19
  from .trip_planner import TripPlanner
20
20
 
21
21
  __all__ = [
22
22
  "AccessLeg",
23
23
  "BreakdownStat",
24
+ "DetailedItineraries",
24
25
  "DetailedItinerariesComputer",
25
26
  "DirectLeg",
26
27
  "EgressLeg",
@@ -32,6 +33,7 @@ __all__ = [
32
33
  "TransitLeg",
33
34
  "TransportMode",
34
35
  "TransportNetwork",
36
+ "TravelTimeMatrix",
35
37
  "TravelTimeMatrixComputer",
36
38
  "Trip",
37
39
  "TripPlanner",
@@ -6,6 +6,7 @@ import math
6
6
  import multiprocessing
7
7
  import warnings
8
8
 
9
+ import geopandas
9
10
  import numpy
10
11
  import shapely
11
12
 
@@ -14,7 +15,7 @@ from .regional_task import RegionalTask
14
15
  from .transport_network import TransportNetwork
15
16
 
16
17
 
17
- __all__ = ["BaseTravelTimeMatrixComputer"]
18
+ __all__ = ["BaseTravelTimeMatrix"]
18
19
 
19
20
 
20
21
  # R5 fills cut-off (NULL) values with MAX_INT32
@@ -26,13 +27,26 @@ MAX_INT32 = (2**31) - 1
26
27
  NUM_THREADS = math.ceil(multiprocessing.cpu_count() * 0.5)
27
28
 
28
29
 
29
- class BaseTravelTimeMatrixComputer:
30
+ class BaseTravelTimeMatrix(geopandas.GeoDataFrame):
30
31
  """Base class for travel time computers between many origins and destinations."""
31
32
 
32
33
  MAX_INT32 = MAX_INT32
33
34
 
34
35
  NUM_THREADS = NUM_THREADS
35
36
 
37
+ _r5py_attributes = [
38
+ "_destinations",
39
+ "_destinations_crs",
40
+ "_origins",
41
+ "_origins_crs",
42
+ "destinations",
43
+ "origins",
44
+ "request",
45
+ "snap_to_network",
46
+ "transport_network",
47
+ "verbose",
48
+ ]
49
+
36
50
  def __init__(
37
51
  self,
38
52
  transport_network,
@@ -71,6 +85,8 @@ class BaseTravelTimeMatrixComputer:
71
85
  ``max_time_cycling``, ``max_time_driving``, ``speed_cycling``, ``speed_walking``,
72
86
  ``max_public_transport_rides``, ``max_bicycle_traffic_stress``
73
87
  """
88
+ geopandas.GeoDataFrame.__init__(self)
89
+
74
90
  if not isinstance(transport_network, TransportNetwork):
75
91
  transport_network = TransportNetwork(*transport_network)
76
92
  self.transport_network = transport_network
@@ -89,6 +105,13 @@ class BaseTravelTimeMatrixComputer:
89
105
 
90
106
  self.verbose = Config().arguments.verbose
91
107
 
108
+ def __setattr__(self, attr, val):
109
+ """Catch our own attributes here so we don’t mess with (geo)pandas columns."""
110
+ if attr in self._r5py_attributes:
111
+ object.__setattr__(self, attr, val)
112
+ else:
113
+ super().__setattr__(attr, val)
114
+
92
115
  @property
93
116
  def destinations(self):
94
117
  """The destinations of this travel time matrix (`geopandas.GeoDataFrame`)."""
@@ -159,8 +182,6 @@ class BaseTravelTimeMatrixComputer:
159
182
 
160
183
  setattr(self, f"_{which_end}", points.copy())
161
184
 
162
- self.snap_to_network = False # prevent repeated snapping on same point sets
163
-
164
185
  @property
165
186
  def origins(self):
166
187
  """The origins of this travel time matrix (`geopandas.GeoDataFrame`)."""
@@ -7,23 +7,33 @@
7
7
  import copy
8
8
  import warnings
9
9
 
10
+ try:
11
+ from warnings import deprecated
12
+ except ImportError: # Python<=3.12
13
+ from typing_extensions import deprecated
14
+
10
15
  import geopandas
11
16
  import joblib
12
17
  import pandas
13
18
 
14
- from .base_travel_time_matrix_computer import BaseTravelTimeMatrixComputer
19
+ from .base_travel_time_matrix import BaseTravelTimeMatrix
15
20
  from .trip import Trip
16
21
  from .trip_planner import ACCURATE_GEOMETRIES, TripPlanner
17
22
 
18
23
 
19
- __all__ = ["DetailedItinerariesComputer"]
24
+ __all__ = ["DetailedItineraries", "DetailedItinerariesComputer"]
20
25
 
21
26
 
22
- class DetailedItinerariesComputer(BaseTravelTimeMatrixComputer):
27
+ class DetailedItineraries(BaseTravelTimeMatrix):
23
28
  """Compute detailed itineraries between many origins and destinations."""
24
29
 
25
30
  COLUMNS = ["from_id", "to_id", "option"] + Trip.COLUMNS
26
31
 
32
+ _r5py_attributes = BaseTravelTimeMatrix._r5py_attributes + [
33
+ "all_to_all",
34
+ "od_pairs",
35
+ ]
36
+
27
37
  def __init__(
28
38
  self,
29
39
  transport_network,
@@ -36,6 +46,10 @@ class DetailedItinerariesComputer(BaseTravelTimeMatrixComputer):
36
46
  """
37
47
  Compute travel times between many origins and destinations.
38
48
 
49
+ ``r5py.DetailedItineraries`` are child classes of
50
+ ``geopandas.GeoDataFrame`` and support all of their methods and
51
+ properties, see https://geopandas.org/en/stable/docs.html
52
+
39
53
  Arguments
40
54
  ---------
41
55
  transport_network : r5py.TransportNetwork | tuple(str, list(str), dict)
@@ -58,10 +72,10 @@ class DetailedItinerariesComputer(BaseTravelTimeMatrixComputer):
58
72
  if `int`, use `snap_to_network` meters as the search radius.
59
73
  force_all_to_all : bool, default False
60
74
  If ``origins`` and ``destinations`` have the same length, by
61
- default, ``DetailedItinerariesComputer`` finds routes between pairs
75
+ default, ``DetailedItineraries`` finds routes between pairs
62
76
  of origins and destinations, i.e., it routes from origin #1 to
63
77
  destination #1, origin #2 to destination #2, ... .
64
- Set ``all_to_all=True`` to route from each origin to all
78
+ Set ``force_all_to_all=True`` to route from each origin to all
65
79
  destinations (this is the default, if ``origins`` and ``destinations``
66
80
  have different lengths, or if ``destinations`` is omitted)
67
81
  **kwargs : mixed
@@ -106,7 +120,14 @@ class DetailedItinerariesComputer(BaseTravelTimeMatrixComputer):
106
120
  else:
107
121
  self.all_to_all = force_all_to_all
108
122
 
109
- def compute_travel_details(self):
123
+ data = self._compute()
124
+ with warnings.catch_warnings():
125
+ warnings.simplefilter("ignore", category=FutureWarning)
126
+ for column in data.columns:
127
+ self[column] = data[column]
128
+ self.set_geometry("geometry")
129
+
130
+ def _compute(self):
110
131
  """
111
132
  Compute travel times from all origins to all destinations.
112
133
 
@@ -114,15 +135,20 @@ class DetailedItinerariesComputer(BaseTravelTimeMatrixComputer):
114
135
  -------
115
136
  geopandas.GeoDataFrame
116
137
  The resulting detailed routes. For each origin/destination pair,
138
+ multiple route alternatives (‘options’) might be reported that each
139
+ consist of one or more segments. Each segment represents one row.
117
140
  multiple route alternatives (‘options’) might be reported that each consist of
118
141
  one or more segments. Each segment represents one row.
142
+
119
143
  The data frame comprises of the following columns: `from_id`,
120
144
  `to_id`, `option` (`int`), `segment` (`int`), `transport_mode`
121
145
  (`r5py.TransportMode`), `departure_time` (`datetime.datetime`),
122
146
  `distance` (`float`, metres), `travel_time` (`datetime.timedelta`),
123
- `wait_time` (`datetime.timedelta`), `route` (`str`, public transport
124
- route number or name), `geometry` (`shapely.LineString`)
125
- TODO: Add description of output data frame columns and format
147
+ `wait_time` (`datetime.timedelta`), `feed` (`str`, the feed name
148
+ used), `agency_id` (`str` the public transport agency identifier),
149
+ `route_id` (`str`, public transport route ID), `start_stop_id`
150
+ (`str`, the GTFS stop_id for boarding), `end_stop_id` (`str`, the
151
+ GTFS stop_id for alighting), `geometry` (`shapely.LineString`)
126
152
  """
127
153
  self._prepare_origins_destinations()
128
154
 
@@ -204,3 +230,34 @@ class DetailedItinerariesComputer(BaseTravelTimeMatrixComputer):
204
230
  # fmt: on
205
231
 
206
232
  return pandas.DataFrame(trips, columns=self.COLUMNS)
233
+
234
+
235
+ @deprecated(
236
+ "Use `DetailedItineraries` instead, `DetailedItinerariesComputer will be deprecated in a future release."
237
+ )
238
+ class DetailedItinerariesComputer:
239
+ """Compute detailed itineraries between many origins and destinations."""
240
+
241
+ def __init__(self, *args, **kwargs):
242
+ """Compute detailed itineraries between many origins and destinations."""
243
+ self._detailed_itineraries = DetailedItineraries(*args, **kwargs)
244
+
245
+ def compute_travel_details(self):
246
+ """
247
+ Compute travel times from all origins to all destinations.
248
+
249
+ Returns
250
+ -------
251
+ geopandas.GeoDataFrame
252
+ The resulting detailed routes. For each origin/destination pair,
253
+ multiple route alternatives (‘options’) might be reported that each consist of
254
+ one or more segments. Each segment represents one row.
255
+ The data frame comprises of the following columns: `from_id`,
256
+ `to_id`, `option` (`int`), `segment` (`int`), `transport_mode`
257
+ (`r5py.TransportMode`), `departure_time` (`datetime.datetime`),
258
+ `distance` (`float`, metres), `travel_time` (`datetime.timedelta`),
259
+ `wait_time` (`datetime.timedelta`), `route` (`str`, public transport
260
+ route number or name), `geometry` (`shapely.LineString`)
261
+ TODO: Add description of output data frame columns and format
262
+ """
263
+ return self._detailed_itineraries
@@ -53,11 +53,11 @@ class RegionalTask:
53
53
  A RegionalTask wraps a `com.conveyal.r5.analyst.cluster.RegionalTask`,
54
54
  which is used to specify the details of a requested computation.
55
55
  RegionalTasks underlie virtually all major computations carried out,
56
- such as, e.g., `TravelTimeMatrixComputer` or `AccessibilityEstimator`.
56
+ such as, e.g., `TravelTimeMatrix` or `AccessibilityEstimator`.
57
57
 
58
58
  In **r5py**, there is usually no need to explicitely create a
59
59
  `RegionalTask`. Rather, the constructors to the computation classes
60
- (`TravelTimeMatrixComputer`, `AccessibilityEstimator`, ...) accept the
60
+ (`TravelTimeMatrix`, `AccessibilityEstimator`, ...) accept the
61
61
  arguments, and pass them through to an internally handled
62
62
  `RegionalTask`.
63
63
 
@@ -98,6 +98,10 @@ class TransitLayer:
98
98
  """Return a list of GTFS trip patterns."""
99
99
  return list(self._transit_layer.tripPatterns)
100
100
 
101
+ def get_stop_id_from_index(self, stop_index):
102
+ """Get the GTFS stop id for the `stop_index`-th stop of this transit layer."""
103
+ return self._transit_layer.stopIdForIndex[stop_index]
104
+
101
105
 
102
106
  @jpype._jcustomizer.JConversion(
103
107
  "com.conveyal.r5.transit.TransitLayer", exact=TransitLayer
@@ -4,24 +4,82 @@
4
4
 
5
5
  import copy
6
6
 
7
+ try:
8
+ from warnings import deprecated
9
+ except ImportError: # Python<=3.12
10
+ from typing_extensions import deprecated
11
+
7
12
  import pandas
8
13
 
9
- from .base_travel_time_matrix_computer import BaseTravelTimeMatrixComputer
14
+ from .base_travel_time_matrix import BaseTravelTimeMatrix
10
15
  from ..util import start_jvm
11
16
 
12
17
  import com.conveyal.r5
13
18
 
14
19
 
15
- __all__ = ["TravelTimeMatrixComputer"]
20
+ __all__ = ["TravelTimeMatrix", "TravelTimeMatrixComputer"]
16
21
 
17
22
 
18
23
  start_jvm()
19
24
 
20
25
 
21
- class TravelTimeMatrixComputer(BaseTravelTimeMatrixComputer):
26
+ class TravelTimeMatrix(BaseTravelTimeMatrix):
22
27
  """Compute travel times between many origins and destinations."""
23
28
 
24
- def compute_travel_times(self):
29
+ def __init__(
30
+ self,
31
+ transport_network,
32
+ origins=None,
33
+ destinations=None,
34
+ snap_to_network=False,
35
+ **kwargs,
36
+ ):
37
+ """
38
+ Compute travel times between many origins and destinations.
39
+
40
+ ``r5py.TravelTimeMatrix`` are child classes of ``pandas.DataFrame`` and
41
+ support all of their methods and properties,
42
+ see https://pandas.pydata.org/docs/
43
+
44
+ Arguments
45
+ ---------
46
+ transport_network : r5py.TransportNetwork | tuple(str, list(str), dict)
47
+ The transport network to route on. This can either be a readily
48
+ initialised r5py.TransportNetwork or a tuple of the parameters
49
+ passed to ``TransportNetwork.__init__()``: the path to an OpenStreetMap
50
+ extract in PBF format, a list of zero of more paths to GTFS transport
51
+ schedule files, and a dict with ``build_config`` options.
52
+ origins : geopandas.GeoDataFrame
53
+ Places to find a route _from_
54
+ Has to have a point geometry, and at least an `id` column
55
+ destinations : geopandas.GeoDataFrame (optional)
56
+ Places to find a route _to_
57
+ Has to have a point geometry, and at least an `id` column
58
+ If omitted, use same data set as for origins
59
+ snap_to_network : bool or int, default False
60
+ Should origin an destination points be snapped to the street network
61
+ before routing? If `True`, the default search radius (defined in
62
+ `com.conveyal.r5.streets.StreetLayer.LINK_RADIUS_METERS`) is used,
63
+ if `int`, use `snap_to_network` meters as the search radius.
64
+ **kwargs : mixed
65
+ Any arguments than can be passed to r5py.RegionalTask:
66
+ ``departure``, ``departure_time_window``, ``percentiles``, ``transport_modes``,
67
+ ``access_modes``, ``egress_modes``, ``max_time``, ``max_time_walking``,
68
+ ``max_time_cycling``, ``max_time_driving``, ``speed_cycling``, ``speed_walking``,
69
+ ``max_public_transport_rides``, ``max_bicycle_traffic_stress``
70
+ """
71
+ super().__init__(
72
+ transport_network,
73
+ origins,
74
+ destinations,
75
+ snap_to_network,
76
+ **kwargs,
77
+ )
78
+ data = self._compute()
79
+ for column in data.columns:
80
+ self[column] = data[column]
81
+
82
+ def _compute(self):
25
83
  """
26
84
  Compute travel times from all origins to all destinations.
27
85
 
@@ -76,17 +134,16 @@ class TravelTimeMatrixComputer(BaseTravelTimeMatrixComputer):
76
134
  travel time.
77
135
  """
78
136
  # First, create an empty DataFrame (this forces column types)
79
- travel_time_columns = {
80
- "from_id": pandas.Series(dtype=str),
81
- "to_id": pandas.Series(dtype=str),
82
- }
83
- travel_time_columns.update(
137
+ od_matrix = pandas.DataFrame(
84
138
  {
139
+ "from_id": pandas.Series(dtype=str),
140
+ "to_id": pandas.Series(dtype=str),
141
+ }
142
+ | {
85
143
  f"travel_time_p{percentile:d}": pandas.Series(dtype=float)
86
144
  for percentile in self.request.percentiles
87
145
  }
88
146
  )
89
- od_matrix = pandas.DataFrame(travel_time_columns)
90
147
 
91
148
  # first assign columns with correct length (`to_id`),
92
149
  # only then fill `from_id` (it’s a scalar)
@@ -121,3 +178,31 @@ class TravelTimeMatrixComputer(BaseTravelTimeMatrixComputer):
121
178
  od_matrix = self._parse_results(from_id, results)
122
179
 
123
180
  return od_matrix
181
+
182
+
183
+ @deprecated(
184
+ "Use `TravelTimeMatrix` instead, `TravelTimeMatrixComputer will be deprecated in a future release."
185
+ )
186
+ class TravelTimeMatrixComputer:
187
+ """Compute travel times between many origins and destinations."""
188
+
189
+ def __init__(self, *args, **kwargs):
190
+ """Compute travel times between many origins and destinations."""
191
+ self._ttm = TravelTimeMatrix(*args, **kwargs)
192
+
193
+ def compute_travel_times(self):
194
+ """
195
+ Compute travel times from all origins to all destinations.
196
+
197
+ Returns
198
+ -------
199
+ pandas.DataFrame
200
+ A data frame containing the columns ``from_id``, ``to_id``, and
201
+ ``travel_time``, where ``travel_time`` is the median calculated
202
+ travel time between ``from_id`` and ``to_id`` or ``numpy.nan``
203
+ if no connection with the given parameters was found.
204
+ If non-default ``percentiles`` were requested: one or more columns
205
+ ``travel_time_p{:02d}`` representing the particular percentile of
206
+ travel time.
207
+ """
208
+ return self._ttm
@@ -54,8 +54,9 @@ class Trip:
54
54
  Returns
55
55
  =======
56
56
  list : detailed information about this trip and its legs (segments):
57
- ``segment``, ``transport_mode``, ``departure_time``, ``distance``,
58
- ``travel_time``, ``wait_time``, ``route``, ``geometry``
57
+ ``segment``, ``transport_mode``, ``departure_time``, ``distance``,
58
+ ``travel_time``, ``wait_time``, ``feed``, ``agency_id``, ``route_id``,
59
+ ``start_stop_id``, ``end_stop_id``, ``geometry``
59
60
  """
60
61
  return [[segment] + leg.as_table_row() for segment, leg in enumerate(self.legs)]
61
62
 
@@ -76,9 +77,9 @@ class Trip:
76
77
  )
77
78
 
78
79
  @property
79
- def routes(self):
80
+ def route_ids(self):
80
81
  """The public transport route(s) used on this trip."""
81
- return [leg.route for leg in self.legs]
82
+ return [leg.route_id for leg in self.legs]
82
83
 
83
84
  @property
84
85
  def transport_modes(self):
@@ -26,7 +26,11 @@ class TripLeg:
26
26
  "distance",
27
27
  "travel_time",
28
28
  "wait_time",
29
- "route",
29
+ "feed",
30
+ "agency_id",
31
+ "route_id",
32
+ "start_stop_id",
33
+ "end_stop_id",
30
34
  "geometry",
31
35
  ]
32
36
 
@@ -37,28 +41,41 @@ class TripLeg:
37
41
  distance=None,
38
42
  travel_time=datetime.timedelta(seconds=0),
39
43
  wait_time=datetime.timedelta(seconds=0),
40
- route=None,
44
+ feed=None,
45
+ agency_id=None,
46
+ route_id=None,
47
+ start_stop_id=None,
48
+ end_stop_id=None,
41
49
  geometry=shapely.LineString(),
42
50
  ):
43
51
  """
44
52
  Represent one leg of a trip.
45
53
 
46
- This is a base class, use one the specific classes,
47
- e.g., TransitLeg, or DirectLeg
54
+ This is a base class, use one of the more specific classes, e.g.,
55
+ TransitLeg, or DirectLeg
48
56
 
49
57
  Arguments
50
58
  =========
51
59
  transport_mode : r5py.TransportMode
52
60
  mode of transport this trip leg was travelled
53
- departure_time : datetime.datetime,
61
+ departure_time : datetime.datetime
62
+ departure time of this trip leg
54
63
  distance : float
55
64
  distance covered by this trip leg, in metres
56
65
  travel_time : datetime.timedelta
57
66
  time spent travelling on this trip leg
58
67
  wait_time : datetime.timedelta
59
68
  time spent waiting for a connection on this trip leg
60
- route : str
61
- public transport route used for this trip leg
69
+ feed : str
70
+ the GTFS feed identifier used for this trip leg
71
+ agency_id : str
72
+ the GTFS id the agency used for this trip leg
73
+ route_id : str
74
+ the GTFS id of the public transport route used for this trip leg
75
+ start_stop_id : str
76
+ the GTFS stop_id of the boarding stop used for this trip leg
77
+ end_stop_id : str
78
+ the GTFS stop_id of the aligning stop used for this trip leg
62
79
  geometry : shapely.LineString
63
80
  spatial representation of this trip leg
64
81
  """
@@ -67,7 +84,11 @@ class TripLeg:
67
84
  self.distance = distance
68
85
  self.travel_time = travel_time
69
86
  self.wait_time = wait_time
70
- self.route = route
87
+ self.feed = feed
88
+ self.agency_id = agency_id
89
+ self.route_id = route_id
90
+ self.start_stop_id = start_stop_id
91
+ self.end_stop_id = end_stop_id
71
92
  self.geometry = geometry
72
93
 
73
94
  def __add__(self, other):
@@ -177,7 +198,8 @@ class TripLeg:
177
198
  Returns
178
199
  =======
179
200
  list : detailed information about this trip leg: ``transport_mode``,
180
- ``departure_time``, ``distance``, ``travel_time``, ``wait_time``,
181
- ``route``, ``geometry``
201
+ ``departure_time``, ``distance``, ``travel_time``, ``wait_time``,
202
+ ``feed``, ``agency_id`` ``route_id``, ``start_stop_id``,
203
+ ``end_stop_id``, ``geometry``
182
204
  """
183
205
  return [getattr(self, column) for column in self.COLUMNS]