r5py 0.1.1.dev2__tar.gz → 1.0.0__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-1.0.0}/PKG-INFO +14 -13
- {r5py-0.1.1.dev2 → r5py-1.0.0}/README.md +1 -1
- {r5py-0.1.1.dev2 → r5py-1.0.0}/pyproject.toml +20 -15
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/__init__.py +8 -1
- r5py-1.0.0/src/r5py/__main__.py +3 -0
- r5py-1.0.0/src/r5py/r5/__init__.py +42 -0
- r5py-0.1.1.dev2/src/r5py/r5/base_travel_time_matrix_computer.py → r5py-1.0.0/src/r5py/r5/base_travel_time_matrix.py +28 -8
- r5py-0.1.1.dev2/src/r5py/r5/detailed_itineraries_computer.py → r5py-1.0.0/src/r5py/r5/detailed_itineraries.py +82 -20
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/r5/direct_leg.py +1 -3
- r5py-1.0.0/src/r5py/r5/isochrones.py +351 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/r5/regional_task.py +12 -9
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/r5/street_layer.py +8 -3
- r5py-1.0.0/src/r5py/r5/street_segment.py +41 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/r5/transfer_leg.py +2 -6
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/r5/transit_layer.py +6 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/r5/transit_leg.py +1 -5
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/r5/transport_mode.py +5 -3
- r5py-1.0.0/src/r5py/r5/transport_network.py +236 -0
- r5py-1.0.0/src/r5py/r5/travel_time_matrix.py +209 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/r5/trip.py +13 -8
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/r5/trip_leg.py +76 -15
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/r5/trip_planner.py +109 -54
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/util/__init__.py +8 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/util/classpath.py +9 -5
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/util/config.py +32 -7
- r5py-1.0.0/src/r5py/util/environment.py +34 -0
- r5py-1.0.0/src/r5py/util/file_digest.py +42 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/util/good_enough_equidistant_crs.py +8 -4
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/util/memory_footprint.py +3 -5
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/util/sample_data_set.py +17 -6
- r5py-1.0.0/src/r5py/util/spatially_clustered_geodataframe.py +78 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/util/validating_requests_session.py +2 -2
- r5py-1.0.0/src/r5py/util/working_copy.py +44 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0/src/r5py.egg-info}/PKG-INFO +14 -13
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py.egg-info/SOURCES.txt +15 -7
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py.egg-info/requires.txt +10 -8
- {r5py-0.1.1.dev2 → r5py-1.0.0}/tests/test_breakdownstats.py +1 -1
- {r5py-0.1.1.dev2 → r5py-1.0.0}/tests/test_camel_to_snake_case.py +1 -1
- {r5py-0.1.1.dev2 → r5py-1.0.0}/tests/test_classpath.py +1 -1
- r5py-1.0.0/tests/test_config.py +48 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/tests/test_contains_gtfs_data.py +4 -3
- {r5py-0.1.1.dev2 → r5py-1.0.0}/tests/test_data_validation.py +5 -4
- r5py-0.1.1.dev2/tests/test_detailed_itineraries_computer.py → r5py-1.0.0/tests/test_detailed_itineraries.py +232 -145
- {r5py-0.1.1.dev2 → r5py-1.0.0}/tests/test_deterministic_behaviour.py +10 -13
- r5py-1.0.0/tests/test_file_digest.py +65 -0
- r5py-1.0.0/tests/test_isochrones.py +237 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/tests/test_java_casting.py +1 -1
- {r5py-0.1.1.dev2 → r5py-1.0.0}/tests/test_memory_footprint.py +1 -1
- {r5py-0.1.1.dev2 → r5py-1.0.0}/tests/test_regional_task.py +1 -1
- {r5py-0.1.1.dev2 → r5py-1.0.0}/tests/test_snake_to_camel_case.py +1 -1
- {r5py-0.1.1.dev2 → r5py-1.0.0}/tests/test_transport_mode.py +1 -1
- {r5py-0.1.1.dev2 → r5py-1.0.0}/tests/test_transport_network.py +11 -58
- r5py-0.1.1.dev2/tests/test_travel_time_matrix_computer.py → r5py-1.0.0/tests/test_travel_time_matrix.py +150 -87
- {r5py-0.1.1.dev2 → r5py-1.0.0}/tests/test_trip.py +37 -29
- {r5py-0.1.1.dev2 → r5py-1.0.0}/tests/test_trip_leg.py +21 -14
- {r5py-0.1.1.dev2 → r5py-1.0.0}/tests/test_validating_request_session.py +19 -13
- {r5py-0.1.1.dev2 → r5py-1.0.0}/tests/test_verbose_warnings.py +17 -11
- r5py-1.0.0/tests/test_working_directory.py +39 -0
- r5py-0.1.1.dev2/src/r5py/__main__.py +0 -16
- r5py-0.1.1.dev2/src/r5py/r5/__init__.py +0 -24
- r5py-0.1.1.dev2/src/r5py/r5/transport_network.py +0 -314
- r5py-0.1.1.dev2/src/r5py/r5/travel_time_matrix_computer.py +0 -134
- r5py-0.1.1.dev2/src/r5py/sampledata/_keep/__init__.py +0 -3
- r5py-0.1.1.dev2/tests/test_config.py +0 -27
- {r5py-0.1.1.dev2 → r5py-1.0.0}/LICENSE +0 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/setup.cfg +0 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/r5/access_leg.py +0 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/r5/breakdown_stat.py +0 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/r5/egress_leg.py +0 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/r5/scenario.py +0 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/util/camel_to_snake_case.py +0 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/util/contains_gtfs_data.py +0 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/util/data_validation.py +0 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/util/exceptions.py +0 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/util/jvm.py +0 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/util/parse_int_date.py +0 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/util/snake_to_camel_case.py +0 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py/util/warnings.py +0 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py.egg-info/dependency_links.txt +0 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/src/r5py.egg-info/top_level.txt +0 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/tests/test_good_enough_equidistant_crs.py +0 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/tests/test_parse_int_date.py +0 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/tests/test_sample_data_set.py +0 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/tests/test_street_layer.py +0 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/tests/test_transit_layer.py +0 -0
- {r5py-0.1.1.dev2 → r5py-1.0.0}/tests/test_trip_planner.py +0 -0
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: r5py
|
|
3
|
-
Version:
|
|
3
|
+
Version: 1.0.0
|
|
4
4
|
Summary: Python wrapper for the R5 routing analysis engine
|
|
5
|
-
Author: Willem Klumpenhouwer, Marcus Sairava, Rafael Pereira, Henrikki Tenkanen
|
|
6
|
-
Author-email: Christoph Fink <christoph.fink@helsinki.fi>
|
|
5
|
+
Author: Christoph Fink, Willem Klumpenhouwer, Marcus Sairava, Rafael Pereira, Henrikki Tenkanen
|
|
7
6
|
License: GPL-3.0-or-later or MIT
|
|
8
7
|
Project-URL: Documentation, https://r5py.readthedocs.org/
|
|
9
8
|
Project-URL: Repository, https://github.com/r5py/r5py.git
|
|
@@ -19,9 +18,8 @@ Description-Content-Type: text/markdown
|
|
|
19
18
|
License-File: LICENSE
|
|
20
19
|
Requires-Dist: ConfigArgParse
|
|
21
20
|
Requires-Dist: filelock
|
|
22
|
-
Requires-Dist:
|
|
21
|
+
Requires-Dist: geohexgrid
|
|
23
22
|
Requires-Dist: geopandas
|
|
24
|
-
Requires-Dist: importlib_resources
|
|
25
23
|
Requires-Dist: joblib
|
|
26
24
|
Requires-Dist: jpype1
|
|
27
25
|
Requires-Dist: numpy
|
|
@@ -29,7 +27,9 @@ Requires-Dist: pandas>=2.1.0
|
|
|
29
27
|
Requires-Dist: psutil
|
|
30
28
|
Requires-Dist: pyproj
|
|
31
29
|
Requires-Dist: requests
|
|
30
|
+
Requires-Dist: scikit-learn
|
|
32
31
|
Requires-Dist: shapely>=2.0
|
|
32
|
+
Requires-Dist: simplification
|
|
33
33
|
Provides-Extra: docs
|
|
34
34
|
Requires-Dist: contextily; extra == "docs"
|
|
35
35
|
Requires-Dist: folium; extra == "docs"
|
|
@@ -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
|
-
Requires-Dist: pytest-asyncio; extra == "tests"
|
|
55
55
|
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
|
|
56
|
+
Requires-Dist: pytest-lazy-fixtures; extra == "tests"
|
|
57
|
+
Requires-Dist: r5py.sampledata.helsinki>=0.1.1; extra == "tests"
|
|
58
|
+
Requires-Dist: r5py.sampledata.sao_paulo>=0.1.1; extra == "tests"
|
|
59
|
+
Requires-Dist: typing-extensions; 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
|
|
|
@@ -155,7 +156,7 @@ your project better.
|
|
|
155
156
|
<!-- (2) other links -->
|
|
156
157
|
[conda-create-env-from-yml]: https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html#creating-an-environment-from-an-environment-yml-file
|
|
157
158
|
[conveyal]: https://www.conveyal.com/
|
|
158
|
-
[env-file]: https://github.com/r5py/r5py/blob/main/ci/
|
|
159
|
+
[env-file]: https://github.com/r5py/r5py/blob/main/ci/r5py.yaml
|
|
159
160
|
[geopandas]: https://geopandas.org/
|
|
160
161
|
[r5-github]: https://github.com/conveyal/r5/
|
|
161
162
|
[r5r-github]: https://github.com/ipeaGIT/r5r/
|
|
@@ -96,7 +96,7 @@ your project better.
|
|
|
96
96
|
<!-- (2) other links -->
|
|
97
97
|
[conda-create-env-from-yml]: https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html#creating-an-environment-from-an-environment-yml-file
|
|
98
98
|
[conveyal]: https://www.conveyal.com/
|
|
99
|
-
[env-file]: https://github.com/r5py/r5py/blob/main/ci/
|
|
99
|
+
[env-file]: https://github.com/r5py/r5py/blob/main/ci/r5py.yaml
|
|
100
100
|
[geopandas]: https://geopandas.org/
|
|
101
101
|
[r5-github]: https://github.com/conveyal/r5/
|
|
102
102
|
[r5r-github]: https://github.com/ipeaGIT/r5r/
|
|
@@ -8,7 +8,7 @@ description = "Python wrapper for the R5 routing analysis engine"
|
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
|
|
10
10
|
authors = [
|
|
11
|
-
{ name = "Christoph Fink"
|
|
11
|
+
{ name = "Christoph Fink" },
|
|
12
12
|
{ name = "Willem Klumpenhouwer" },
|
|
13
13
|
{ name = "Marcus Sairava" },
|
|
14
14
|
{ name = "Rafael Pereira" },
|
|
@@ -18,9 +18,8 @@ authors = [
|
|
|
18
18
|
dependencies = [
|
|
19
19
|
"ConfigArgParse",
|
|
20
20
|
"filelock",
|
|
21
|
-
"
|
|
21
|
+
"geohexgrid",
|
|
22
22
|
"geopandas",
|
|
23
|
-
"importlib_resources",
|
|
24
23
|
"joblib",
|
|
25
24
|
"jpype1",
|
|
26
25
|
"numpy",
|
|
@@ -28,7 +27,9 @@ dependencies = [
|
|
|
28
27
|
"psutil",
|
|
29
28
|
"pyproj",
|
|
30
29
|
"requests",
|
|
31
|
-
"
|
|
30
|
+
"scikit-learn",
|
|
31
|
+
"shapely>=2.0",
|
|
32
|
+
"simplification"
|
|
32
33
|
]
|
|
33
34
|
requires-python = ">=3.9"
|
|
34
35
|
|
|
@@ -46,13 +47,12 @@ dynamic = ["version"]
|
|
|
46
47
|
[project.optional-dependencies]
|
|
47
48
|
docs = ["contextily", "folium", "GitPython", "h3>=4.0.0b2", "jupyterlab_myst",
|
|
48
49
|
"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"]
|
|
50
|
+
"r5py.sampledata.helsinki>=0.1.1", "r5py.sampledata.sao_paulo>=0.1.1",
|
|
51
|
+
"shapely", "sphinx", "sphinx-book-theme", "sphinx-design",
|
|
52
|
+
"sphinxcontrib-bibtex", "sphinxcontrib-images"]
|
|
53
|
+
tests = ["pyarrow", "pytest", "pytest-cov", "pytest-lazy-fixtures",
|
|
54
|
+
"r5py.sampledata.helsinki>=0.1.1", "r5py.sampledata.sao_paulo>=0.1.1",
|
|
55
|
+
"typing-extensions"]
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
[project.urls]
|
|
@@ -61,22 +61,27 @@ Repository = "https://github.com/r5py/r5py.git"
|
|
|
61
61
|
"Change log" = "https://github.com/r5py/r5py/blob/main/CHANGELOG.md"
|
|
62
62
|
"Bug tracker" = "https://github.com/r5py/r5py/issues"
|
|
63
63
|
|
|
64
|
-
[tool.coverage.
|
|
65
|
-
|
|
64
|
+
[tool.coverage.paths]
|
|
65
|
+
equivalent_sources = [
|
|
66
|
+
"src/r5py/",
|
|
67
|
+
".virtualenv/lib/python*/site-packages/r5py/",
|
|
68
|
+
"/opt/hostedtoolcache/Python/*/x64/lib/python*/site-packages/r5py/",
|
|
69
|
+
"/Library/Frameworks/Python.framework/Versions/*/lib/python*/site-packages/r5py/",
|
|
70
|
+
"C:/hostedtoolcache/windows/Python/*/x64/Lib/site-packages/r5py/"
|
|
71
|
+
]
|
|
66
72
|
|
|
67
73
|
[tool.jupytext.formats]
|
|
68
74
|
"docs/notebooks/" = "ipynb"
|
|
69
75
|
"docs/md/" = "md"
|
|
70
76
|
|
|
71
77
|
[tool.pytest.ini_options]
|
|
72
|
-
addopts = "-p no:faulthandler --cov --cov-report term-missing --cov-report xml"
|
|
78
|
+
addopts = "-p no:faulthandler --cov=r5py --cov-report term-missing --cov-report xml --import-mode=importlib"
|
|
73
79
|
filterwarnings = [
|
|
74
80
|
"error",
|
|
75
81
|
"ignore:Could not find R5 jar, trying to download it from upstream",
|
|
76
82
|
"ignore:Successfully downloaded r5-"
|
|
77
83
|
]
|
|
78
84
|
testpaths = ["tests"]
|
|
79
|
-
asyncio_mode = "auto"
|
|
80
85
|
|
|
81
86
|
[tool.setuptools.dynamic]
|
|
82
87
|
version = {attr = "r5py.__version__"}
|
|
@@ -2,21 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
"""Python wrapper for the R5 routing analysis engine."""
|
|
4
4
|
|
|
5
|
-
__version__ = "
|
|
5
|
+
__version__ = "1.0.0"
|
|
6
|
+
|
|
6
7
|
|
|
7
8
|
from .r5 import (
|
|
9
|
+
DetailedItineraries,
|
|
8
10
|
DetailedItinerariesComputer,
|
|
11
|
+
Isochrones,
|
|
9
12
|
RegionalTask,
|
|
10
13
|
TransportMode,
|
|
11
14
|
TransportNetwork,
|
|
15
|
+
TravelTimeMatrix,
|
|
12
16
|
TravelTimeMatrixComputer,
|
|
13
17
|
)
|
|
14
18
|
|
|
15
19
|
__all__ = [
|
|
20
|
+
"DetailedItineraries",
|
|
16
21
|
"DetailedItinerariesComputer",
|
|
22
|
+
"Isochrones",
|
|
17
23
|
"RegionalTask",
|
|
18
24
|
"TransportMode",
|
|
19
25
|
"TransportNetwork",
|
|
26
|
+
"TravelTimeMatrix",
|
|
20
27
|
"TravelTimeMatrixComputer",
|
|
21
28
|
"__version__",
|
|
22
29
|
]
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
"""R5 classes."""
|
|
4
|
+
|
|
5
|
+
from .access_leg import AccessLeg
|
|
6
|
+
from .breakdown_stat import BreakdownStat
|
|
7
|
+
from .detailed_itineraries import DetailedItineraries, DetailedItinerariesComputer
|
|
8
|
+
from .direct_leg import DirectLeg
|
|
9
|
+
from .egress_leg import EgressLeg
|
|
10
|
+
from .isochrones import Isochrones
|
|
11
|
+
from .regional_task import RegionalTask
|
|
12
|
+
from .scenario import Scenario
|
|
13
|
+
from .street_layer import StreetLayer
|
|
14
|
+
from .transfer_leg import TransferLeg
|
|
15
|
+
from .transit_leg import TransitLeg
|
|
16
|
+
from .transport_mode import TransportMode
|
|
17
|
+
from .transport_network import TransportNetwork
|
|
18
|
+
from .travel_time_matrix import TravelTimeMatrix, TravelTimeMatrixComputer
|
|
19
|
+
from .trip import Trip
|
|
20
|
+
from .trip_planner import TripPlanner
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
"AccessLeg",
|
|
24
|
+
"BreakdownStat",
|
|
25
|
+
"DetailedItineraries",
|
|
26
|
+
"DetailedItinerariesComputer",
|
|
27
|
+
"DirectLeg",
|
|
28
|
+
"EgressLeg",
|
|
29
|
+
"Isochrones",
|
|
30
|
+
"RegionalTask",
|
|
31
|
+
"Scenario",
|
|
32
|
+
"SpeedConfig",
|
|
33
|
+
"StreetLayer",
|
|
34
|
+
"TransferLeg",
|
|
35
|
+
"TransitLeg",
|
|
36
|
+
"TransportMode",
|
|
37
|
+
"TransportNetwork",
|
|
38
|
+
"TravelTimeMatrix",
|
|
39
|
+
"TravelTimeMatrixComputer",
|
|
40
|
+
"Trip",
|
|
41
|
+
"TripPlanner",
|
|
42
|
+
]
|
|
@@ -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__ = ["
|
|
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
|
|
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,8 +105,16 @@ 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):
|
|
117
|
+
"""The destinations of this travel time matrix (`geopandas.GeoDataFrame`)."""
|
|
94
118
|
return self._destinations
|
|
95
119
|
|
|
96
120
|
@destinations.setter
|
|
@@ -120,10 +144,7 @@ class BaseTravelTimeMatrixComputer:
|
|
|
120
144
|
return data_set.map(lambda x: numpy.nan if x == MAX_INT32 else x)
|
|
121
145
|
|
|
122
146
|
def _prepare_origins_destinations(self):
|
|
123
|
-
"""
|
|
124
|
-
Make sure we received enough information to route from origins to
|
|
125
|
-
destinations.
|
|
126
|
-
"""
|
|
147
|
+
"""Make sure we received enough information to route from origins to destinations."""
|
|
127
148
|
try:
|
|
128
149
|
self.origins
|
|
129
150
|
except AttributeError as exception:
|
|
@@ -161,10 +182,9 @@ class BaseTravelTimeMatrixComputer:
|
|
|
161
182
|
|
|
162
183
|
setattr(self, f"_{which_end}", points.copy())
|
|
163
184
|
|
|
164
|
-
self.snap_to_network = False # prevent repeated snapping on same point sets
|
|
165
|
-
|
|
166
185
|
@property
|
|
167
186
|
def origins(self):
|
|
187
|
+
"""The origins of this travel time matrix (`geopandas.GeoDataFrame`)."""
|
|
168
188
|
return self._origins
|
|
169
189
|
|
|
170
190
|
@origins.setter
|
|
@@ -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 .
|
|
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
|
|
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, ``
|
|
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 ``
|
|
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
|
|
@@ -70,7 +84,7 @@ class DetailedItinerariesComputer(BaseTravelTimeMatrixComputer):
|
|
|
70
84
|
``access_modes``, ``egress_modes``, ``max_time``, ``max_time_walking``,
|
|
71
85
|
``max_time_cycling``, ``max_time_driving``, ``speed_cycling``, ``speed_walking``,
|
|
72
86
|
``max_public_transport_rides``, ``max_bicycle_traffic_stress``
|
|
73
|
-
|
|
87
|
+
Note that not all arguments might make sense in this context, and the
|
|
74
88
|
underlying R5 engine might ignore some of them.
|
|
75
89
|
"""
|
|
76
90
|
super().__init__(
|
|
@@ -106,7 +120,23 @@ class DetailedItinerariesComputer(BaseTravelTimeMatrixComputer):
|
|
|
106
120
|
else:
|
|
107
121
|
self.all_to_all = force_all_to_all
|
|
108
122
|
|
|
109
|
-
|
|
123
|
+
data = self._compute()
|
|
124
|
+
with warnings.catch_warnings():
|
|
125
|
+
warnings.filterwarnings(
|
|
126
|
+
"ignore",
|
|
127
|
+
message=(
|
|
128
|
+
"You are adding a column named 'geometry' to a GeoDataFrame "
|
|
129
|
+
"constructed without an active geometry column"
|
|
130
|
+
),
|
|
131
|
+
category=FutureWarning,
|
|
132
|
+
)
|
|
133
|
+
for column in data.columns:
|
|
134
|
+
self[column] = data[column]
|
|
135
|
+
self.set_geometry("geometry")
|
|
136
|
+
|
|
137
|
+
del self.transport_network
|
|
138
|
+
|
|
139
|
+
def _compute(self):
|
|
110
140
|
"""
|
|
111
141
|
Compute travel times from all origins to all destinations.
|
|
112
142
|
|
|
@@ -114,17 +144,21 @@ class DetailedItinerariesComputer(BaseTravelTimeMatrixComputer):
|
|
|
114
144
|
-------
|
|
115
145
|
geopandas.GeoDataFrame
|
|
116
146
|
The resulting detailed routes. For each origin/destination pair,
|
|
147
|
+
multiple route alternatives (‘options’) might be reported that each
|
|
148
|
+
consist of one or more segments. Each segment represents one row.
|
|
117
149
|
multiple route alternatives (‘options’) might be reported that each consist of
|
|
118
150
|
one or more segments. Each segment represents one row.
|
|
151
|
+
|
|
119
152
|
The data frame comprises of the following columns: `from_id`,
|
|
120
153
|
`to_id`, `option` (`int`), `segment` (`int`), `transport_mode`
|
|
121
154
|
(`r5py.TransportMode`), `departure_time` (`datetime.datetime`),
|
|
122
155
|
`distance` (`float`, metres), `travel_time` (`datetime.timedelta`),
|
|
123
|
-
`wait_time` (`datetime.timedelta`), `
|
|
124
|
-
|
|
125
|
-
|
|
156
|
+
`wait_time` (`datetime.timedelta`), `feed` (`str`, the feed name
|
|
157
|
+
used), `agency_id` (`str` the public transport agency identifier),
|
|
158
|
+
`route_id` (`str`, public transport route ID), `start_stop_id`
|
|
159
|
+
(`str`, the GTFS stop_id for boarding), `end_stop_id` (`str`, the
|
|
160
|
+
GTFS stop_id for alighting), `geometry` (`shapely.LineString`)
|
|
126
161
|
"""
|
|
127
|
-
|
|
128
162
|
self._prepare_origins_destinations()
|
|
129
163
|
|
|
130
164
|
# warn if public transport routes are requested, but R5 has been
|
|
@@ -150,11 +184,12 @@ class DetailedItinerariesComputer(BaseTravelTimeMatrixComputer):
|
|
|
150
184
|
verbose=(10 * self.verbose), # joblib has a funny verbosity scale
|
|
151
185
|
n_jobs=self.NUM_THREADS,
|
|
152
186
|
) as parallel:
|
|
187
|
+
matrices = parallel(
|
|
188
|
+
joblib.delayed(self._travel_details_per_od_pair)(from_id, to_id)
|
|
189
|
+
for _, (from_id, to_id) in self.od_pairs.iterrows()
|
|
190
|
+
)
|
|
153
191
|
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
|
-
),
|
|
192
|
+
[matrix.astype(matrices[0].dtypes) for matrix in matrices],
|
|
158
193
|
ignore_index=True,
|
|
159
194
|
)
|
|
160
195
|
|
|
@@ -162,11 +197,7 @@ class DetailedItinerariesComputer(BaseTravelTimeMatrixComputer):
|
|
|
162
197
|
return od_matrix
|
|
163
198
|
|
|
164
199
|
def _prepare_origins_destinations(self):
|
|
165
|
-
"""
|
|
166
|
-
Make sure we received enough information to route from origins to
|
|
167
|
-
destinations.
|
|
168
|
-
"""
|
|
169
|
-
|
|
200
|
+
"""Make sure we received enough information to route from origins to destinations."""
|
|
170
201
|
super()._prepare_origins_destinations()
|
|
171
202
|
|
|
172
203
|
if self.all_to_all:
|
|
@@ -208,3 +239,34 @@ class DetailedItinerariesComputer(BaseTravelTimeMatrixComputer):
|
|
|
208
239
|
# fmt: on
|
|
209
240
|
|
|
210
241
|
return pandas.DataFrame(trips, columns=self.COLUMNS)
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
@deprecated(
|
|
245
|
+
"Use `DetailedItineraries` instead, `DetailedItinerariesComputer will be deprecated in a future release."
|
|
246
|
+
)
|
|
247
|
+
class DetailedItinerariesComputer:
|
|
248
|
+
"""Compute detailed itineraries between many origins and destinations."""
|
|
249
|
+
|
|
250
|
+
def __init__(self, *args, **kwargs):
|
|
251
|
+
"""Compute detailed itineraries between many origins and destinations."""
|
|
252
|
+
self._detailed_itineraries = DetailedItineraries(*args, **kwargs)
|
|
253
|
+
|
|
254
|
+
def compute_travel_details(self):
|
|
255
|
+
"""
|
|
256
|
+
Compute travel times from all origins to all destinations.
|
|
257
|
+
|
|
258
|
+
Returns
|
|
259
|
+
-------
|
|
260
|
+
geopandas.GeoDataFrame
|
|
261
|
+
The resulting detailed routes. For each origin/destination pair,
|
|
262
|
+
multiple route alternatives (‘options’) might be reported that each consist of
|
|
263
|
+
one or more segments. Each segment represents one row.
|
|
264
|
+
The data frame comprises of the following columns: `from_id`,
|
|
265
|
+
`to_id`, `option` (`int`), `segment` (`int`), `transport_mode`
|
|
266
|
+
(`r5py.TransportMode`), `departure_time` (`datetime.datetime`),
|
|
267
|
+
`distance` (`float`, metres), `travel_time` (`datetime.timedelta`),
|
|
268
|
+
`wait_time` (`datetime.timedelta`), `route` (`str`, public transport
|
|
269
|
+
route number or name), `geometry` (`shapely.LineString`)
|
|
270
|
+
TODO: Add description of output data frame columns and format
|
|
271
|
+
"""
|
|
272
|
+
return self._detailed_itineraries
|