r5py 0.1.1.dev2__tar.gz → 0.1.2__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.
- {r5py-0.1.1.dev2/src/r5py.egg-info → r5py-0.1.2}/PKG-INFO +7 -6
- {r5py-0.1.1.dev2 → r5py-0.1.2}/pyproject.toml +6 -7
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/__init__.py +2 -1
- r5py-0.1.2/src/r5py/__main__.py +3 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/r5/__init__.py +14 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/r5/base_travel_time_matrix_computer.py +3 -4
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/r5/detailed_itineraries_computer.py +6 -10
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/r5/direct_leg.py +1 -3
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/r5/regional_task.py +10 -7
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/r5/street_layer.py +1 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/r5/transfer_leg.py +2 -6
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/r5/transit_layer.py +2 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/r5/transit_leg.py +1 -5
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/r5/transport_mode.py +5 -3
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/r5/transport_network.py +16 -7
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/r5/travel_time_matrix_computer.py +4 -15
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/r5/trip.py +8 -4
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/r5/trip_leg.py +44 -5
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/r5/trip_planner.py +81 -39
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/util/__init__.py +2 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/util/classpath.py +9 -5
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/util/config.py +11 -2
- r5py-0.1.2/src/r5py/util/environment.py +34 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/util/good_enough_equidistant_crs.py +0 -1
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/util/memory_footprint.py +3 -5
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/util/sample_data_set.py +13 -5
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/util/validating_requests_session.py +2 -2
- {r5py-0.1.1.dev2 → r5py-0.1.2/src/r5py.egg-info}/PKG-INFO +7 -6
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py.egg-info/SOURCES.txt +1 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py.egg-info/requires.txt +6 -5
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_breakdownstats.py +1 -1
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_camel_to_snake_case.py +1 -1
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_classpath.py +1 -1
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_contains_gtfs_data.py +4 -3
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_data_validation.py +5 -4
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_detailed_itineraries_computer.py +36 -46
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_java_casting.py +1 -1
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_memory_footprint.py +1 -1
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_regional_task.py +1 -1
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_snake_to_camel_case.py +1 -1
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_transport_mode.py +1 -1
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_transport_network.py +13 -12
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_travel_time_matrix_computer.py +36 -26
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_validating_request_session.py +19 -13
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_verbose_warnings.py +10 -4
- r5py-0.1.1.dev2/src/r5py/__main__.py +0 -16
- {r5py-0.1.1.dev2 → r5py-0.1.2}/LICENSE +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/README.md +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/setup.cfg +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/r5/access_leg.py +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/r5/breakdown_stat.py +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/r5/egress_leg.py +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/r5/scenario.py +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/sampledata/_keep/__init__.py +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/util/camel_to_snake_case.py +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/util/contains_gtfs_data.py +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/util/data_validation.py +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/util/exceptions.py +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/util/jvm.py +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/util/parse_int_date.py +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/util/snake_to_camel_case.py +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py/util/warnings.py +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py.egg-info/dependency_links.txt +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/src/r5py.egg-info/top_level.txt +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_config.py +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_deterministic_behaviour.py +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_good_enough_equidistant_crs.py +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_parse_int_date.py +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_sample_data_set.py +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_street_layer.py +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_transit_layer.py +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_trip.py +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_trip_leg.py +0 -0
- {r5py-0.1.1.dev2 → r5py-0.1.2}/tests/test_trip_planner.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: r5py
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
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>
|
|
@@ -41,8 +41,8 @@ Requires-Dist: matplotlib; extra == "docs"
|
|
|
41
41
|
Requires-Dist: myst-nb; extra == "docs"
|
|
42
42
|
Requires-Dist: nbsphinx; extra == "docs"
|
|
43
43
|
Requires-Dist: pybtex-apa7-style; extra == "docs"
|
|
44
|
-
Requires-Dist: r5py.sampledata.helsinki>=0.1.1
|
|
45
|
-
Requires-Dist: r5py.sampledata.sao_paulo>=0.1.1
|
|
44
|
+
Requires-Dist: r5py.sampledata.helsinki>=0.1.1; extra == "docs"
|
|
45
|
+
Requires-Dist: r5py.sampledata.sao_paulo>=0.1.1; extra == "docs"
|
|
46
46
|
Requires-Dist: shapely; extra == "docs"
|
|
47
47
|
Requires-Dist: sphinx; extra == "docs"
|
|
48
48
|
Requires-Dist: sphinx-book-theme; extra == "docs"
|
|
@@ -50,12 +50,13 @@ Requires-Dist: sphinx-design; extra == "docs"
|
|
|
50
50
|
Requires-Dist: sphinxcontrib-bibtex; extra == "docs"
|
|
51
51
|
Requires-Dist: sphinxcontrib-images; extra == "docs"
|
|
52
52
|
Provides-Extra: tests
|
|
53
|
+
Requires-Dist: pyarrow; extra == "tests"
|
|
53
54
|
Requires-Dist: pytest; extra == "tests"
|
|
54
55
|
Requires-Dist: pytest-asyncio; extra == "tests"
|
|
55
56
|
Requires-Dist: pytest-cov; extra == "tests"
|
|
56
|
-
Requires-Dist: pytest-lazy-
|
|
57
|
-
Requires-Dist: r5py.sampledata.helsinki>=0.1.1
|
|
58
|
-
Requires-Dist: r5py.sampledata.sao_paulo>=0.1.1
|
|
57
|
+
Requires-Dist: pytest-lazy-fixtures; extra == "tests"
|
|
58
|
+
Requires-Dist: r5py.sampledata.helsinki>=0.1.1; extra == "tests"
|
|
59
|
+
Requires-Dist: r5py.sampledata.sao_paulo>=0.1.1; extra == "tests"
|
|
59
60
|
|
|
60
61
|
<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;">
|
|
61
62
|
|
|
@@ -46,13 +46,12 @@ dynamic = ["version"]
|
|
|
46
46
|
[project.optional-dependencies]
|
|
47
47
|
docs = ["contextily", "folium", "GitPython", "h3>=4.0.0b2", "jupyterlab_myst",
|
|
48
48
|
"mapclassify", "matplotlib", "myst-nb", "nbsphinx", "pybtex-apa7-style",
|
|
49
|
-
"r5py.sampledata.helsinki>=0.1.1.
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
"r5py.sampledata.sao_paulo>=0.1.1.dev2"]
|
|
49
|
+
"r5py.sampledata.helsinki>=0.1.1", "r5py.sampledata.sao_paulo>=0.1.1",
|
|
50
|
+
"shapely", "sphinx", "sphinx-book-theme", "sphinx-design",
|
|
51
|
+
"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"]
|
|
56
55
|
|
|
57
56
|
|
|
58
57
|
[project.urls]
|
|
@@ -2,23 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
"""R5 classes."""
|
|
4
4
|
|
|
5
|
+
from .access_leg import AccessLeg
|
|
5
6
|
from .breakdown_stat import BreakdownStat
|
|
6
7
|
from .detailed_itineraries_computer import DetailedItinerariesComputer
|
|
8
|
+
from .direct_leg import DirectLeg
|
|
9
|
+
from .egress_leg import EgressLeg
|
|
7
10
|
from .regional_task import RegionalTask
|
|
8
11
|
from .scenario import Scenario
|
|
9
12
|
from .street_layer import StreetLayer
|
|
13
|
+
from .transfer_leg import TransferLeg
|
|
14
|
+
from .transit_leg import TransitLeg
|
|
10
15
|
from .transport_mode import TransportMode
|
|
11
16
|
from .transport_network import TransportNetwork
|
|
12
17
|
from .travel_time_matrix_computer import TravelTimeMatrixComputer
|
|
18
|
+
from .trip import Trip
|
|
19
|
+
from .trip_planner import TripPlanner
|
|
13
20
|
|
|
14
21
|
__all__ = [
|
|
22
|
+
"AccessLeg",
|
|
15
23
|
"BreakdownStat",
|
|
16
24
|
"DetailedItinerariesComputer",
|
|
25
|
+
"DirectLeg",
|
|
26
|
+
"EgressLeg",
|
|
17
27
|
"RegionalTask",
|
|
18
28
|
"Scenario",
|
|
19
29
|
"SpeedConfig",
|
|
20
30
|
"StreetLayer",
|
|
31
|
+
"TransferLeg",
|
|
32
|
+
"TransitLeg",
|
|
21
33
|
"TransportMode",
|
|
22
34
|
"TransportNetwork",
|
|
23
35
|
"TravelTimeMatrixComputer",
|
|
36
|
+
"Trip",
|
|
37
|
+
"TripPlanner",
|
|
24
38
|
]
|
|
@@ -91,6 +91,7 @@ class BaseTravelTimeMatrixComputer:
|
|
|
91
91
|
|
|
92
92
|
@property
|
|
93
93
|
def destinations(self):
|
|
94
|
+
"""The destinations of this travel time matrix (`geopandas.GeoDataFrame`)."""
|
|
94
95
|
return self._destinations
|
|
95
96
|
|
|
96
97
|
@destinations.setter
|
|
@@ -120,10 +121,7 @@ class BaseTravelTimeMatrixComputer:
|
|
|
120
121
|
return data_set.map(lambda x: numpy.nan if x == MAX_INT32 else x)
|
|
121
122
|
|
|
122
123
|
def _prepare_origins_destinations(self):
|
|
123
|
-
"""
|
|
124
|
-
Make sure we received enough information to route from origins to
|
|
125
|
-
destinations.
|
|
126
|
-
"""
|
|
124
|
+
"""Make sure we received enough information to route from origins to destinations."""
|
|
127
125
|
try:
|
|
128
126
|
self.origins
|
|
129
127
|
except AttributeError as exception:
|
|
@@ -165,6 +163,7 @@ class BaseTravelTimeMatrixComputer:
|
|
|
165
163
|
|
|
166
164
|
@property
|
|
167
165
|
def origins(self):
|
|
166
|
+
"""The origins of this travel time matrix (`geopandas.GeoDataFrame`)."""
|
|
168
167
|
return self._origins
|
|
169
168
|
|
|
170
169
|
@origins.setter
|
|
@@ -124,7 +124,6 @@ class DetailedItinerariesComputer(BaseTravelTimeMatrixComputer):
|
|
|
124
124
|
route number or name), `geometry` (`shapely.LineString`)
|
|
125
125
|
TODO: Add description of output data frame columns and format
|
|
126
126
|
"""
|
|
127
|
-
|
|
128
127
|
self._prepare_origins_destinations()
|
|
129
128
|
|
|
130
129
|
# warn if public transport routes are requested, but R5 has been
|
|
@@ -150,11 +149,12 @@ class DetailedItinerariesComputer(BaseTravelTimeMatrixComputer):
|
|
|
150
149
|
verbose=(10 * self.verbose), # joblib has a funny verbosity scale
|
|
151
150
|
n_jobs=self.NUM_THREADS,
|
|
152
151
|
) as parallel:
|
|
152
|
+
matrices = parallel(
|
|
153
|
+
joblib.delayed(self._travel_details_per_od_pair)(from_id, to_id)
|
|
154
|
+
for _, (from_id, to_id) in self.od_pairs.iterrows()
|
|
155
|
+
)
|
|
153
156
|
od_matrix = pandas.concat(
|
|
154
|
-
|
|
155
|
-
joblib.delayed(self._travel_details_per_od_pair)(from_id, to_id)
|
|
156
|
-
for _, (from_id, to_id) in self.od_pairs.iterrows()
|
|
157
|
-
),
|
|
157
|
+
[matrix.astype(matrices[0].dtypes) for matrix in matrices],
|
|
158
158
|
ignore_index=True,
|
|
159
159
|
)
|
|
160
160
|
|
|
@@ -162,11 +162,7 @@ class DetailedItinerariesComputer(BaseTravelTimeMatrixComputer):
|
|
|
162
162
|
return od_matrix
|
|
163
163
|
|
|
164
164
|
def _prepare_origins_destinations(self):
|
|
165
|
-
"""
|
|
166
|
-
Make sure we received enough information to route from origins to
|
|
167
|
-
destinations.
|
|
168
|
-
"""
|
|
169
|
-
|
|
165
|
+
"""Make sure we received enough information to route from origins to destinations."""
|
|
170
166
|
super()._prepare_origins_destinations()
|
|
171
167
|
|
|
172
168
|
if self.all_to_all:
|
|
@@ -200,12 +200,16 @@ class RegionalTask:
|
|
|
200
200
|
# The value is a static property of com.conveyal.r5.analyst.cluster.PathResult;
|
|
201
201
|
# static properites of Java classes can be modified in a singleton kind of way
|
|
202
202
|
try:
|
|
203
|
-
|
|
204
|
-
com.conveyal.r5.analyst.cluster.PathResult.maxDestinations,
|
|
205
|
-
len(self.destinations) + 1,
|
|
206
|
-
)
|
|
203
|
+
num_destinations = len(self.destinations)
|
|
207
204
|
except AttributeError:
|
|
208
|
-
|
|
205
|
+
num_destinations = 0
|
|
206
|
+
if (
|
|
207
|
+
num_destinations
|
|
208
|
+
> com.conveyal.r5.analyst.cluster.PathResult.MAX_PATH_DESTINATIONS
|
|
209
|
+
):
|
|
210
|
+
com.conveyal.r5.analyst.cluster.PathResult.MAX_PATH_DESTINATIONS = (
|
|
211
|
+
num_destinations + 1
|
|
212
|
+
)
|
|
209
213
|
|
|
210
214
|
@property
|
|
211
215
|
def departure(self):
|
|
@@ -246,8 +250,7 @@ class RegionalTask:
|
|
|
246
250
|
|
|
247
251
|
@property
|
|
248
252
|
def departure_time_window(self):
|
|
249
|
-
"""Find public transport connections leaving within
|
|
250
|
-
``departure_time_window`` after ``departure`` (datetime.timedelta).
|
|
253
|
+
"""Find public transport connections leaving within ``departure_time_window`` after ``departure`` (datetime.timedelta).
|
|
251
254
|
|
|
252
255
|
**Note:** The value of ``departure_time_window`` should be set with some
|
|
253
256
|
caution. Specifically, setting values near or below the typical headways
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
"""Represent one leg of a trip, specifically transfers between public transport
|
|
5
|
-
vehicles."""
|
|
4
|
+
"""Represent one leg of a trip, specifically transfers between public transport vehicles."""
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
from .direct_leg import DirectLeg
|
|
@@ -12,7 +11,4 @@ __all__ = ["TransferLeg"]
|
|
|
12
11
|
|
|
13
12
|
|
|
14
13
|
class TransferLeg(DirectLeg):
|
|
15
|
-
"""
|
|
16
|
-
Represent one leg of a trip, specifically transfers between public transport
|
|
17
|
-
vehicles.
|
|
18
|
-
"""
|
|
14
|
+
"""Represent one leg of a trip, specifically transfers between public transport vehicles."""
|
|
@@ -90,10 +90,12 @@ class TransitLayer:
|
|
|
90
90
|
|
|
91
91
|
@functools.cached_property
|
|
92
92
|
def routes(self):
|
|
93
|
+
"""Return a list of GTFS routes."""
|
|
93
94
|
return list(self._transit_layer.routes)
|
|
94
95
|
|
|
95
96
|
@functools.cached_property
|
|
96
97
|
def trip_patterns(self):
|
|
98
|
+
"""Return a list of GTFS trip patterns."""
|
|
97
99
|
return list(self._transit_layer.tripPatterns)
|
|
98
100
|
|
|
99
101
|
|
|
@@ -68,6 +68,7 @@ class TransportMode(enum.Enum):
|
|
|
68
68
|
return None
|
|
69
69
|
|
|
70
70
|
def __add__(self, other):
|
|
71
|
+
"""Combine two transport modes."""
|
|
71
72
|
if isinstance(other, self.__class__):
|
|
72
73
|
return [self, other]
|
|
73
74
|
elif isinstance(other, list):
|
|
@@ -78,6 +79,7 @@ class TransportMode(enum.Enum):
|
|
|
78
79
|
)
|
|
79
80
|
|
|
80
81
|
def __radd__(self, other):
|
|
82
|
+
"""Combine two transport modes."""
|
|
81
83
|
if other == 0: # first iteration of sum()
|
|
82
84
|
return self
|
|
83
85
|
elif isinstance(other, list):
|
|
@@ -87,17 +89,17 @@ class TransportMode(enum.Enum):
|
|
|
87
89
|
|
|
88
90
|
@property
|
|
89
91
|
def is_leg_mode(self):
|
|
90
|
-
"""Can this TransportMode function as a LegMode
|
|
92
|
+
"""Can this TransportMode function as a LegMode?."""
|
|
91
93
|
return self.name in LEG_MODES
|
|
92
94
|
|
|
93
95
|
@property
|
|
94
96
|
def is_street_mode(self):
|
|
95
|
-
"""Can this TransportMode function as a StreetMode
|
|
97
|
+
"""Can this TransportMode function as a StreetMode?."""
|
|
96
98
|
return self.name in STREET_MODES
|
|
97
99
|
|
|
98
100
|
@property
|
|
99
101
|
def is_transit_mode(self):
|
|
100
|
-
"""Can this TransportMode function as a TransitMode
|
|
102
|
+
"""Can this TransportMode function as a TransitMode?."""
|
|
101
103
|
return self.name in TRANSIT_MODES
|
|
102
104
|
|
|
103
105
|
AIR = "AIR"
|
|
@@ -89,9 +89,7 @@ class TransportNetwork:
|
|
|
89
89
|
self._transport_network = transport_network
|
|
90
90
|
|
|
91
91
|
def __del__(self):
|
|
92
|
-
"""
|
|
93
|
-
Delete all temporary files upon destruction.
|
|
94
|
-
"""
|
|
92
|
+
"""Delete all temporary files upon destruction."""
|
|
95
93
|
MAX_TRIES = 10
|
|
96
94
|
|
|
97
95
|
# first, close the open osm_file,
|
|
@@ -110,13 +108,23 @@ class TransportNetwork:
|
|
|
110
108
|
del self.transit_layer
|
|
111
109
|
except AttributeError:
|
|
112
110
|
pass
|
|
113
|
-
|
|
111
|
+
try:
|
|
112
|
+
del self._transport_network
|
|
113
|
+
except AttributeError:
|
|
114
|
+
pass
|
|
114
115
|
|
|
115
|
-
time.sleep(0
|
|
116
|
-
|
|
116
|
+
time.sleep(1.0)
|
|
117
|
+
try:
|
|
118
|
+
jpype.java.lang.System.gc()
|
|
119
|
+
except jpype.JVMNotRunning:
|
|
120
|
+
pass
|
|
117
121
|
|
|
118
122
|
# then, try to delete all files in cache directory
|
|
119
|
-
|
|
123
|
+
try:
|
|
124
|
+
temporary_files = [child for child in self._cache_directory.iterdir()]
|
|
125
|
+
except FileNotFoundError: # deleted in the meantime/race condition
|
|
126
|
+
temporary_files = []
|
|
127
|
+
|
|
120
128
|
for _ in range(MAX_TRIES):
|
|
121
129
|
for temporary_file in temporary_files:
|
|
122
130
|
try:
|
|
@@ -206,6 +214,7 @@ class TransportNetwork:
|
|
|
206
214
|
|
|
207
215
|
@property
|
|
208
216
|
def extent(self):
|
|
217
|
+
"""The geographic area covered, as a `shapely.box`."""
|
|
209
218
|
# TODO: figure out how to get the extent of the GTFS schedule,
|
|
210
219
|
# then find the smaller extent of the two (or the larger one?)
|
|
211
220
|
return self.street_layer.extent
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
import copy
|
|
6
6
|
|
|
7
|
-
import joblib
|
|
8
7
|
import pandas
|
|
9
8
|
|
|
10
9
|
from .base_travel_time_matrix_computer import BaseTravelTimeMatrixComputer
|
|
@@ -40,20 +39,10 @@ class TravelTimeMatrixComputer(BaseTravelTimeMatrixComputer):
|
|
|
40
39
|
self._prepare_origins_destinations()
|
|
41
40
|
self.request.destinations = self.destinations
|
|
42
41
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
verbose=(10 * self.verbose), # joblib has a funny verbosity scale
|
|
48
|
-
n_jobs=self.NUM_THREADS,
|
|
49
|
-
) as parallel:
|
|
50
|
-
od_matrix = pandas.concat(
|
|
51
|
-
parallel(
|
|
52
|
-
joblib.delayed(self._travel_times_per_origin)(from_id)
|
|
53
|
-
for from_id in self.origins.id
|
|
54
|
-
),
|
|
55
|
-
ignore_index=True,
|
|
56
|
-
)
|
|
42
|
+
od_matrix = pandas.concat(
|
|
43
|
+
[self._travel_times_per_origin(from_id) for from_id in self.origins.id],
|
|
44
|
+
ignore_index=True,
|
|
45
|
+
)
|
|
57
46
|
|
|
58
47
|
try:
|
|
59
48
|
od_matrix = od_matrix.to_crs(self._origins_crs)
|
|
@@ -15,9 +15,7 @@ __all__ = ["Trip"]
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
class Trip:
|
|
18
|
-
"""
|
|
19
|
-
Represent one trip, consisting of one or more `TripLeg`s.
|
|
20
|
-
"""
|
|
18
|
+
"""Represent one trip, consisting of one or more `r5py.r5.TripLeg`."""
|
|
21
19
|
|
|
22
20
|
COLUMNS = [
|
|
23
21
|
"segment",
|
|
@@ -25,7 +23,7 @@ class Trip:
|
|
|
25
23
|
|
|
26
24
|
def __init__(self, legs=[]):
|
|
27
25
|
"""
|
|
28
|
-
Represent one trip, consisting of one of more `TripLeg
|
|
26
|
+
Represent one trip, consisting of one of more `r5py.r5.TripLeg`.
|
|
29
27
|
|
|
30
28
|
Arguments
|
|
31
29
|
=========
|
|
@@ -34,7 +32,13 @@ class Trip:
|
|
|
34
32
|
"""
|
|
35
33
|
self.legs = legs
|
|
36
34
|
|
|
35
|
+
def __eq__(self, other):
|
|
36
|
+
"""Check whether `self` and `other` are equal."""
|
|
37
|
+
if isinstance(other, self.__class__):
|
|
38
|
+
return self.legs == other.legs
|
|
39
|
+
|
|
37
40
|
def __repr__(self):
|
|
41
|
+
"""Return a string representation of `self`."""
|
|
38
42
|
legs = ", ".join([str(leg) for leg in self.legs])
|
|
39
43
|
return (
|
|
40
44
|
f"<{self.__class__.__name__}: "
|
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
"""Represent one leg of a trip."""
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
import datetime
|
|
8
|
+
import numpy
|
|
9
|
+
import shapely
|
|
10
|
+
|
|
11
|
+
|
|
7
12
|
__all__ = ["TripLeg"]
|
|
8
13
|
|
|
9
14
|
|
|
@@ -28,12 +33,12 @@ class TripLeg:
|
|
|
28
33
|
def __init__(
|
|
29
34
|
self,
|
|
30
35
|
transport_mode=None,
|
|
31
|
-
departure_time=
|
|
36
|
+
departure_time=numpy.datetime64("NaT"),
|
|
32
37
|
distance=None,
|
|
33
|
-
travel_time=
|
|
34
|
-
wait_time=
|
|
38
|
+
travel_time=datetime.timedelta(seconds=0),
|
|
39
|
+
wait_time=datetime.timedelta(seconds=0),
|
|
35
40
|
route=None,
|
|
36
|
-
geometry=
|
|
41
|
+
geometry=shapely.LineString(),
|
|
37
42
|
):
|
|
38
43
|
"""
|
|
39
44
|
Represent one leg of a trip.
|
|
@@ -66,6 +71,7 @@ class TripLeg:
|
|
|
66
71
|
self.geometry = geometry
|
|
67
72
|
|
|
68
73
|
def __add__(self, other):
|
|
74
|
+
"""Trip-chain `other` to `self`."""
|
|
69
75
|
from .trip import Trip
|
|
70
76
|
|
|
71
77
|
if isinstance(other, self.__class__):
|
|
@@ -80,6 +86,7 @@ class TripLeg:
|
|
|
80
86
|
)
|
|
81
87
|
|
|
82
88
|
def __radd__(self, other):
|
|
89
|
+
"""Trip-chain `self` to `other`."""
|
|
83
90
|
from .trip import Trip
|
|
84
91
|
|
|
85
92
|
if other == 0: # first iteration of sum()
|
|
@@ -90,31 +97,43 @@ class TripLeg:
|
|
|
90
97
|
else:
|
|
91
98
|
return self.__add__(other)
|
|
92
99
|
|
|
100
|
+
def __eq__(self, other):
|
|
101
|
+
"""Check if `other` is an equal `TripLeg`."""
|
|
102
|
+
if isinstance(other, self.__class__):
|
|
103
|
+
return False not in [
|
|
104
|
+
self._are_columns_equal(other, column) for column in self.COLUMNS
|
|
105
|
+
]
|
|
106
|
+
|
|
93
107
|
def __gt__(self, other):
|
|
108
|
+
"""Check if `other` has a longer travel time."""
|
|
94
109
|
if isinstance(other, TripLeg):
|
|
95
110
|
return (self.travel_time + self.wait_time) > (
|
|
96
111
|
other.travel_time + other.wait_time
|
|
97
112
|
)
|
|
98
113
|
|
|
99
114
|
def __ge__(self, other):
|
|
115
|
+
"""Check if `other` has a longer or equal travel time."""
|
|
100
116
|
if isinstance(other, TripLeg):
|
|
101
117
|
return (self.travel_time + self.wait_time) >= (
|
|
102
118
|
other.travel_time + other.wait_time
|
|
103
119
|
)
|
|
104
120
|
|
|
105
121
|
def __lt__(self, other):
|
|
122
|
+
"""Check if `other` has a shorter travel time."""
|
|
106
123
|
if isinstance(other, TripLeg):
|
|
107
124
|
return (self.travel_time + self.wait_time) < (
|
|
108
125
|
other.travel_time + other.wait_time
|
|
109
126
|
)
|
|
110
127
|
|
|
111
128
|
def __le__(self, other):
|
|
129
|
+
"""Check if `other` has a shorter or equal travel time."""
|
|
112
130
|
if isinstance(other, TripLeg):
|
|
113
131
|
return (self.travel_time + self.wait_time) <= (
|
|
114
132
|
other.travel_time + other.wait_time
|
|
115
133
|
)
|
|
116
134
|
|
|
117
135
|
def __repr__(self):
|
|
136
|
+
"""Return a string representation."""
|
|
118
137
|
try:
|
|
119
138
|
first_point = self.geometry.coords[0]
|
|
120
139
|
last_point = self.geometry.coords[-1]
|
|
@@ -127,10 +146,30 @@ class TripLeg:
|
|
|
127
146
|
f"{first_point} -> {last_point}"
|
|
128
147
|
">"
|
|
129
148
|
)
|
|
130
|
-
except AttributeError:
|
|
149
|
+
except (AttributeError, IndexError):
|
|
131
150
|
_repr = f"<{self.__class__.__name__}>"
|
|
132
151
|
return _repr
|
|
133
152
|
|
|
153
|
+
def _are_columns_equal(self, other, column):
|
|
154
|
+
"""
|
|
155
|
+
Check if a column equals the same column of a different `Trip`.
|
|
156
|
+
|
|
157
|
+
Compare if attribute `column` of self equals attribute `column` of
|
|
158
|
+
other. Also True if both values are None or NaN or NaT.
|
|
159
|
+
"""
|
|
160
|
+
self_column = getattr(self, column)
|
|
161
|
+
other_column = getattr(other, column)
|
|
162
|
+
|
|
163
|
+
return (
|
|
164
|
+
self_column == other_column
|
|
165
|
+
or (self_column is None and other_column is None)
|
|
166
|
+
or (self_column == numpy.nan and other_column == numpy.nan)
|
|
167
|
+
or (
|
|
168
|
+
self_column == numpy.datetime64("NaT")
|
|
169
|
+
and other_column == numpy.datetime64("NaT")
|
|
170
|
+
)
|
|
171
|
+
)
|
|
172
|
+
|
|
134
173
|
def as_table_row(self):
|
|
135
174
|
"""
|
|
136
175
|
Return a table row (list) of this trip leg’s details.
|