r5py 1.0.1__tar.gz → 1.0.3.dev0__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 (121) hide show
  1. r5py-1.0.3.dev0/MANIFEST.in +3 -0
  2. {r5py-1.0.1/src/r5py.egg-info → r5py-1.0.3.dev0}/PKG-INFO +3 -2
  3. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/__init__.py +1 -1
  4. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/r5/__init__.py +0 -2
  5. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/r5/regional_task.py +4 -33
  6. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/r5/transit_layer.py +18 -39
  7. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/r5/transport_network.py +28 -2
  8. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/util/exceptions.py +4 -0
  9. {r5py-1.0.1 → r5py-1.0.3.dev0/src/r5py.egg-info}/PKG-INFO +3 -2
  10. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py.egg-info/SOURCES.txt +41 -3
  11. r5py-1.0.3.dev0/tests/__init__.py +3 -0
  12. r5py-1.0.3.dev0/tests/conftest.py +13 -0
  13. r5py-1.0.3.dev0/tests/conftest_d/__init__.py +152 -0
  14. r5py-1.0.3.dev0/tests/conftest_d/data_directory.py +8 -0
  15. r5py-1.0.3.dev0/tests/conftest_d/destinations.py +83 -0
  16. r5py-1.0.3.dev0/tests/conftest_d/file_digest.py +48 -0
  17. r5py-1.0.3.dev0/tests/conftest_d/garbage_collection.py +14 -0
  18. r5py-1.0.3.dev0/tests/conftest_d/origins.py +72 -0
  19. r5py-1.0.3.dev0/tests/conftest_d/r5_jar.py +57 -0
  20. r5py-1.0.3.dev0/tests/conftest_d/routing_parameters.py +33 -0
  21. r5py-1.0.3.dev0/tests/conftest_d/routing_results.py +141 -0
  22. r5py-1.0.3.dev0/tests/conftest_d/sample_data.py +25 -0
  23. r5py-1.0.3.dev0/tests/conftest_d/transport_network.py +117 -0
  24. r5py-1.0.3.dev0/tests/conftest_d/upstream_r5.py +19 -0
  25. r5py-1.0.3.dev0/tests/data/test_broken_gtfs.zip +0 -0
  26. r5py-1.0.3.dev0/tests/data/test_detailed_itineraries_bicycle.gpkg.zip +0 -0
  27. r5py-1.0.3.dev0/tests/data/test_detailed_itineraries_car.gpkg.zip +0 -0
  28. r5py-1.0.3.dev0/tests/data/test_detailed_itineraries_transit.gpkg.zip +0 -0
  29. r5py-1.0.3.dev0/tests/data/test_detailed_itineraries_walk.gpkg.zip +0 -0
  30. r5py-1.0.3.dev0/tests/data/test_invalid_points_duplicate_ids.geojson +10 -0
  31. r5py-1.0.3.dev0/tests/data/test_invalid_points_no_id_column.geojson +11 -0
  32. r5py-1.0.3.dev0/tests/data/test_isochrones_bicycle.gpkg.zip +0 -0
  33. r5py-1.0.3.dev0/tests/data/test_isochrones_car.gpkg.zip +0 -0
  34. r5py-1.0.3.dev0/tests/data/test_isochrones_from_multiple_origins.gpkg.zip +0 -0
  35. r5py-1.0.3.dev0/tests/data/test_isochrones_transit.gpkg.zip +0 -0
  36. r5py-1.0.3.dev0/tests/data/test_isochrones_walk.gpkg.zip +0 -0
  37. r5py-1.0.3.dev0/tests/data/test_multiple_origins.geojson +10 -0
  38. r5py-1.0.3.dev0/tests/data/test_snapped_population_grid_centroids.geojson +98 -0
  39. r5py-1.0.3.dev0/tests/data/test_travel_times_bicycle.csv +362 -0
  40. r5py-1.0.3.dev0/tests/data/test_travel_times_car.csv +362 -0
  41. r5py-1.0.3.dev0/tests/data/test_travel_times_transit.csv +362 -0
  42. r5py-1.0.3.dev0/tests/data/test_travel_times_walk.csv +362 -0
  43. r5py-1.0.3.dev0/tests/data/test_valid_points_data.geojson +11 -0
  44. r5py-1.0.3.dev0/tests/data/test_valid_single_point_data.geojson +7 -0
  45. r5py-1.0.3.dev0/tests/data/test_walking_details_not_snapped.csv +362 -0
  46. r5py-1.0.3.dev0/tests/data/test_walking_details_snapped.csv +362 -0
  47. r5py-1.0.3.dev0/tests/data/test_walking_times_not_snapped.csv +8465 -0
  48. r5py-1.0.3.dev0/tests/data/test_walking_times_snapped.csv +8465 -0
  49. r5py-1.0.3.dev0/tests/temporary_directory.py +32 -0
  50. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_detailed_itineraries.py +4 -4
  51. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_isochrones.py +4 -0
  52. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_regional_task.py +17 -11
  53. r5py-1.0.3.dev0/tests/test_transit_layer.py +5 -0
  54. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_transport_network.py +31 -2
  55. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_travel_time_matrix.py +14 -2
  56. r5py-1.0.1/src/r5py/r5/breakdown_stat.py +0 -26
  57. r5py-1.0.1/tests/test_breakdownstats.py +0 -30
  58. r5py-1.0.1/tests/test_transit_layer.py +0 -18
  59. {r5py-1.0.1 → r5py-1.0.3.dev0}/LICENSE +0 -0
  60. {r5py-1.0.1 → r5py-1.0.3.dev0}/README.md +0 -0
  61. {r5py-1.0.1 → r5py-1.0.3.dev0}/pyproject.toml +0 -0
  62. {r5py-1.0.1 → r5py-1.0.3.dev0}/setup.cfg +0 -0
  63. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/__main__.py +0 -0
  64. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/r5/access_leg.py +0 -0
  65. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/r5/base_travel_time_matrix.py +0 -0
  66. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/r5/detailed_itineraries.py +0 -0
  67. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/r5/direct_leg.py +0 -0
  68. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/r5/egress_leg.py +0 -0
  69. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/r5/isochrones.py +0 -0
  70. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/r5/scenario.py +0 -0
  71. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/r5/street_layer.py +0 -0
  72. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/r5/street_segment.py +0 -0
  73. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/r5/transfer_leg.py +0 -0
  74. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/r5/transit_leg.py +0 -0
  75. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/r5/transport_mode.py +0 -0
  76. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/r5/travel_time_matrix.py +0 -0
  77. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/r5/trip.py +0 -0
  78. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/r5/trip_leg.py +0 -0
  79. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/r5/trip_planner.py +0 -0
  80. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/util/__init__.py +0 -0
  81. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/util/camel_to_snake_case.py +0 -0
  82. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/util/classpath.py +0 -0
  83. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/util/config.py +0 -0
  84. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/util/contains_gtfs_data.py +0 -0
  85. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/util/data_validation.py +0 -0
  86. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/util/environment.py +0 -0
  87. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/util/file_digest.py +0 -0
  88. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/util/good_enough_equidistant_crs.py +0 -0
  89. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/util/jvm.py +0 -0
  90. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/util/memory_footprint.py +0 -0
  91. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/util/parse_int_date.py +0 -0
  92. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/util/sample_data_set.py +0 -0
  93. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/util/snake_to_camel_case.py +0 -0
  94. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/util/spatially_clustered_geodataframe.py +0 -0
  95. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/util/validating_requests_session.py +0 -0
  96. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/util/warnings.py +0 -0
  97. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py/util/working_copy.py +0 -0
  98. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py.egg-info/dependency_links.txt +0 -0
  99. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py.egg-info/requires.txt +0 -0
  100. {r5py-1.0.1 → r5py-1.0.3.dev0}/src/r5py.egg-info/top_level.txt +0 -0
  101. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_camel_to_snake_case.py +0 -0
  102. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_classpath.py +0 -0
  103. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_config.py +0 -0
  104. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_contains_gtfs_data.py +0 -0
  105. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_data_validation.py +0 -0
  106. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_deterministic_behaviour.py +0 -0
  107. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_file_digest.py +0 -0
  108. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_good_enough_equidistant_crs.py +0 -0
  109. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_java_casting.py +0 -0
  110. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_memory_footprint.py +0 -0
  111. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_parse_int_date.py +0 -0
  112. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_sample_data_set.py +0 -0
  113. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_snake_to_camel_case.py +0 -0
  114. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_street_layer.py +0 -0
  115. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_transport_mode.py +0 -0
  116. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_trip.py +0 -0
  117. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_trip_leg.py +0 -0
  118. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_trip_planner.py +0 -0
  119. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_validating_request_session.py +0 -0
  120. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_verbose_warnings.py +0 -0
  121. {r5py-1.0.1 → r5py-1.0.3.dev0}/tests/test_working_directory.py +0 -0
@@ -0,0 +1,3 @@
1
+ recursive-include tests *.py
2
+ recursive-include tests/data *
3
+ global-exclude *.pyc
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: r5py
3
- Version: 1.0.1
3
+ Version: 1.0.3.dev0
4
4
  Summary: Python wrapper for the R5 routing analysis engine
5
5
  Author: Christoph Fink, Willem Klumpenhouwer, Marcus Sairava, Rafael Pereira, Henrikki Tenkanen
6
6
  License: GPL-3.0-or-later or MIT
@@ -58,6 +58,7 @@ Requires-Dist: pytest-lazy-fixtures; extra == "tests"
58
58
  Requires-Dist: r5py.sampledata.helsinki>=0.1.1; extra == "tests"
59
59
  Requires-Dist: r5py.sampledata.sao_paulo>=0.1.1; extra == "tests"
60
60
  Requires-Dist: typing-extensions; extra == "tests"
61
+ Dynamic: license-file
61
62
 
62
63
  <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;">
63
64
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  """Python wrapper for the R5 routing analysis engine."""
4
4
 
5
- __version__ = "1.0.1"
5
+ __version__ = "1.0.3.dev0"
6
6
 
7
7
 
8
8
  from .r5 import (
@@ -3,7 +3,6 @@
3
3
  """R5 classes."""
4
4
 
5
5
  from .access_leg import AccessLeg
6
- from .breakdown_stat import BreakdownStat
7
6
  from .detailed_itineraries import DetailedItineraries, DetailedItinerariesComputer
8
7
  from .direct_leg import DirectLeg
9
8
  from .egress_leg import EgressLeg
@@ -21,7 +20,6 @@ from .trip_planner import TripPlanner
21
20
 
22
21
  __all__ = [
23
22
  "AccessLeg",
24
- "BreakdownStat",
25
23
  "DetailedItineraries",
26
24
  "DetailedItinerariesComputer",
27
25
  "DirectLeg",
@@ -45,7 +45,6 @@ class RegionalTask:
45
45
  speed_cycling=12.0,
46
46
  max_public_transport_rides=8,
47
47
  max_bicycle_traffic_stress=3,
48
- breakdown=False,
49
48
  ):
50
49
  """
51
50
  Create a RegionalTask, a computing request for R5.
@@ -110,8 +109,6 @@ class RegionalTask:
110
109
  max_bicycle_traffic_stress : int
111
110
  Maximum stress level for cyclist routing, ranges from 1-4 see
112
111
  https://docs.conveyal.com/learn-more/traffic-stress Default: 3
113
- breakdown : bool
114
- Compute a more detailed breakdown of the routes. Default: False
115
112
  """
116
113
  self._regional_task = com.conveyal.r5.analyst.cluster.RegionalTask()
117
114
  self.scenario = Scenario()
@@ -149,8 +146,6 @@ class RegionalTask:
149
146
 
150
147
  # always record travel times
151
148
  self._regional_task.recordTimes = True
152
- # also report paths, if `breakdown`
153
- self.breakdown = breakdown
154
149
 
155
150
  # a few settings we don’t expose (yet?)
156
151
  self._regional_task.makeTauiSite = False
@@ -185,32 +180,6 @@ class RegionalTask:
185
180
  access_modes, com.conveyal.r5.api.util.LegMode
186
181
  )
187
182
 
188
- @property
189
- def breakdown(self):
190
- """Compute a more detailed breakdown of the routes."""
191
- return self._breakdown
192
-
193
- @breakdown.setter
194
- def breakdown(self, breakdown):
195
- self._breakdown = breakdown
196
- self._regional_task.includePathResults = breakdown
197
-
198
- # R5 has a maximum number of destinations for which it returns detailed
199
- # information, and it’s set to 5000 by default.
200
- # The value is a static property of com.conveyal.r5.analyst.cluster.PathResult;
201
- # static properites of Java classes can be modified in a singleton kind of way
202
- try:
203
- num_destinations = len(self.destinations)
204
- except AttributeError:
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
- )
213
-
214
183
  @property
215
184
  def departure(self):
216
185
  """Find public transport connections leaving within ``departure_time_window`` after ``departure`` (datetime.datetime)."""
@@ -225,8 +194,10 @@ class RegionalTask:
225
194
  ):
226
195
  # fmt: on
227
196
  warnings.warn(
228
- f"Departure time {departure} is outside of the time range "
229
- "covered by currently loaded GTFS data sets.",
197
+ (
198
+ "The currently loaded GTFS data sets do not define "
199
+ f"any services on {departure.date()}."
200
+ ),
230
201
  RuntimeWarning,
231
202
  )
232
203
 
@@ -4,13 +4,12 @@
4
4
  """Wraps a com.conveyal.r5.transit.TransitLayer."""
5
5
 
6
6
 
7
- import datetime
8
7
  import functools
9
8
 
10
9
  import jpype
11
10
  import jpype.types
12
11
 
13
- from ..util import parse_int_date
12
+ import java.time
14
13
 
15
14
 
16
15
  __all__ = ["TransitLayer"]
@@ -32,44 +31,24 @@ class TransitLayer:
32
31
  instance._transit_layer = transit_layer
33
32
  return instance
34
33
 
35
- @functools.cached_property
36
- def start_date(self):
37
- """The earliest date the loaded GTFS data covers."""
38
- try:
39
- start_date = min(
40
- [
41
- parse_int_date(service.calendar.start_date)
42
- for service in self._transit_layer.services
43
- ]
44
- )
45
- except (AttributeError, ValueError) as exception:
46
- raise ValueError("No GTFS data set loaded") from exception
47
- return start_date
34
+ def covers(self, date):
35
+ """
36
+ Check whether `date` is covered by GTFS data sets.
48
37
 
49
- @functools.cached_property
50
- def end_date(self):
51
- """The latest date the loaded GTFS data covers."""
52
- try:
53
- end_date = max(
54
- [
55
- parse_int_date(service.calendar.end_date)
56
- for service in self._transit_layer.services
57
- ]
58
- )
59
- end_date += datetime.timedelta(
60
- hours=23, minutes=59, seconds=59
61
- ) # *end* of day
62
- except (AttributeError, ValueError) as exception:
63
- raise ValueError("No GTFS data set loaded") from exception
64
- return end_date
65
-
66
- def covers(self, point_in_time):
67
- """Check whether `point_in_time` is covered by GTFS data sets."""
68
- try:
69
- covers = self.start_date <= point_in_time <= self.end_date
70
- except ValueError: # no GTFS data loaded
71
- covers = False
72
- return covers
38
+ Arguments:
39
+ ----------
40
+ date : datetime.date
41
+ date for which to check whether a GTFS service exists.
42
+
43
+ Returns:
44
+ --------
45
+ bool
46
+ Whether or not any services exist on `date`.
47
+ """
48
+ date = java.time.LocalDate.of(date.year, date.month, date.day)
49
+ return True in set(
50
+ [service.activeOn(date) for service in self._transit_layer.services]
51
+ )
73
52
 
74
53
  def get_street_vertex_for_stop(self, stop):
75
54
  """
@@ -16,6 +16,7 @@ from .street_layer import StreetLayer
16
16
  from .transit_layer import TransitLayer
17
17
  from .transport_mode import TransportMode
18
18
  from ..util import Config, contains_gtfs_data, FileDigest, start_jvm, WorkingCopy
19
+ from ..util.exceptions import GtfsFileError
19
20
 
20
21
  import com.conveyal.gtfs
21
22
  import com.conveyal.osmlib
@@ -35,7 +36,7 @@ start_jvm()
35
36
  class TransportNetwork:
36
37
  """Wrap a com.conveyal.r5.transit.TransportNetwork."""
37
38
 
38
- def __init__(self, osm_pbf, gtfs=[]):
39
+ def __init__(self, osm_pbf, gtfs=[], allow_errors=False):
39
40
  """
40
41
  Load a transport network.
41
42
 
@@ -45,6 +46,9 @@ class TransportNetwork:
45
46
  file path of an OpenStreetMap extract in PBF format
46
47
  gtfs : str | pathlib.Path | list[str] | list[pathlib.Path]
47
48
  path(s) to public transport schedule information in GTFS format
49
+ allow_errors : bool
50
+ try to proceed with loading the transport network even if input data
51
+ contain errors
48
52
  """
49
53
  osm_pbf = WorkingCopy(osm_pbf)
50
54
  if isinstance(gtfs, (str, pathlib.Path)):
@@ -79,9 +83,31 @@ class TransportNetwork:
79
83
  transport_network.transitLayer = com.conveyal.r5.transit.TransitLayer()
80
84
  transport_network.transitLayer.parentNetwork = transport_network
81
85
  for gtfs_file in gtfs:
82
- gtfs_feed = com.conveyal.gtfs.GTFSFeed.readOnlyTempFileFromGtfs(
86
+ gtfs_feed = com.conveyal.gtfs.GTFSFeed.writableTempFileFromGtfs(
83
87
  f"{gtfs_file}"
84
88
  )
89
+ if gtfs_feed.errors.size() > 0:
90
+ errors = [
91
+ f"{error.errorType}: {error.getMessageWithContext()}"
92
+ for error in gtfs_feed.errors
93
+ ]
94
+ if allow_errors:
95
+ warnings.warn(
96
+ (
97
+ "R5 reported the following issues with "
98
+ f"GTFS file {gtfs_file.name}: \n"
99
+ + ("\n- ".join(errors))
100
+ ),
101
+ RuntimeWarning,
102
+ )
103
+ else:
104
+ raise GtfsFileError(
105
+ (
106
+ f"Could not load GTFS file {gtfs_file.name}. \n"
107
+ + ("\n- ".join(errors))
108
+ )
109
+ )
110
+
85
111
  transport_network.transitLayer.loadFromGtfs(gtfs_feed)
86
112
  gtfs_feed.close()
87
113
 
@@ -12,6 +12,10 @@ class R5pyError(Exception):
12
12
 
13
13
 
14
14
  # more specific exceptions
15
+ class GtfsFileError(R5pyError):
16
+ """GTFS file contained errors."""
17
+
18
+
15
19
  class ChecksumFailed(requests.RequestException, R5pyError):
16
20
  """Requested resource did not pass checksum test."""
17
21
 
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: r5py
3
- Version: 1.0.1
3
+ Version: 1.0.3.dev0
4
4
  Summary: Python wrapper for the R5 routing analysis engine
5
5
  Author: Christoph Fink, Willem Klumpenhouwer, Marcus Sairava, Rafael Pereira, Henrikki Tenkanen
6
6
  License: GPL-3.0-or-later or MIT
@@ -58,6 +58,7 @@ Requires-Dist: pytest-lazy-fixtures; extra == "tests"
58
58
  Requires-Dist: r5py.sampledata.helsinki>=0.1.1; extra == "tests"
59
59
  Requires-Dist: r5py.sampledata.sao_paulo>=0.1.1; extra == "tests"
60
60
  Requires-Dist: typing-extensions; extra == "tests"
61
+ Dynamic: license-file
61
62
 
62
63
  <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;">
63
64
 
@@ -1,4 +1,5 @@
1
1
  LICENSE
2
+ MANIFEST.in
2
3
  README.md
3
4
  pyproject.toml
4
5
  src/r5py/__init__.py
@@ -11,7 +12,6 @@ src/r5py.egg-info/top_level.txt
11
12
  src/r5py/r5/__init__.py
12
13
  src/r5py/r5/access_leg.py
13
14
  src/r5py/r5/base_travel_time_matrix.py
14
- src/r5py/r5/breakdown_stat.py
15
15
  src/r5py/r5/detailed_itineraries.py
16
16
  src/r5py/r5/direct_leg.py
17
17
  src/r5py/r5/egress_leg.py
@@ -48,7 +48,9 @@ src/r5py/util/spatially_clustered_geodataframe.py
48
48
  src/r5py/util/validating_requests_session.py
49
49
  src/r5py/util/warnings.py
50
50
  src/r5py/util/working_copy.py
51
- tests/test_breakdownstats.py
51
+ tests/__init__.py
52
+ tests/conftest.py
53
+ tests/temporary_directory.py
52
54
  tests/test_camel_to_snake_case.py
53
55
  tests/test_classpath.py
54
56
  tests/test_config.py
@@ -75,4 +77,40 @@ tests/test_trip_leg.py
75
77
  tests/test_trip_planner.py
76
78
  tests/test_validating_request_session.py
77
79
  tests/test_verbose_warnings.py
78
- tests/test_working_directory.py
80
+ tests/test_working_directory.py
81
+ tests/conftest_d/__init__.py
82
+ tests/conftest_d/data_directory.py
83
+ tests/conftest_d/destinations.py
84
+ tests/conftest_d/file_digest.py
85
+ tests/conftest_d/garbage_collection.py
86
+ tests/conftest_d/origins.py
87
+ tests/conftest_d/r5_jar.py
88
+ tests/conftest_d/routing_parameters.py
89
+ tests/conftest_d/routing_results.py
90
+ tests/conftest_d/sample_data.py
91
+ tests/conftest_d/transport_network.py
92
+ tests/conftest_d/upstream_r5.py
93
+ tests/data/test_broken_gtfs.zip
94
+ tests/data/test_detailed_itineraries_bicycle.gpkg.zip
95
+ tests/data/test_detailed_itineraries_car.gpkg.zip
96
+ tests/data/test_detailed_itineraries_transit.gpkg.zip
97
+ tests/data/test_detailed_itineraries_walk.gpkg.zip
98
+ tests/data/test_invalid_points_duplicate_ids.geojson
99
+ tests/data/test_invalid_points_no_id_column.geojson
100
+ tests/data/test_isochrones_bicycle.gpkg.zip
101
+ tests/data/test_isochrones_car.gpkg.zip
102
+ tests/data/test_isochrones_from_multiple_origins.gpkg.zip
103
+ tests/data/test_isochrones_transit.gpkg.zip
104
+ tests/data/test_isochrones_walk.gpkg.zip
105
+ tests/data/test_multiple_origins.geojson
106
+ tests/data/test_snapped_population_grid_centroids.geojson
107
+ tests/data/test_travel_times_bicycle.csv
108
+ tests/data/test_travel_times_car.csv
109
+ tests/data/test_travel_times_transit.csv
110
+ tests/data/test_travel_times_walk.csv
111
+ tests/data/test_valid_points_data.geojson
112
+ tests/data/test_valid_single_point_data.geojson
113
+ tests/data/test_walking_details_not_snapped.csv
114
+ tests/data/test_walking_details_snapped.csv
115
+ tests/data/test_walking_times_not_snapped.csv
116
+ tests/data/test_walking_times_snapped.csv
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env python3
2
+
3
+ """Test the r5py package."""
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env python3
2
+
3
+ """Configuration and fixtures for testing r5py."""
4
+
5
+ # This is a init file common to all tests. It is automatically sourced
6
+ # by pytest et al.
7
+
8
+ # This file imports all files in the conftest.d directory
9
+
10
+ # Define common constants (e.g., paths to test data) and fixtures (e.g.,
11
+ # transport network) there and import the fixtures into conftest_d/__init__.py.
12
+
13
+ from .conftest_d import * # noqa: F401,F403
@@ -0,0 +1,152 @@
1
+ #!/usr/bin/env python3
2
+
3
+
4
+ """Fixtures to be used in r5py tests."""
5
+
6
+
7
+ from .destinations import (
8
+ population_grid,
9
+ population_grid_points,
10
+ population_grid_points_first_three,
11
+ population_grid_points_second_three,
12
+ population_grid_points_four,
13
+ snapped_population_grid_points,
14
+ unreachable_stops,
15
+ unsnappable_points,
16
+ )
17
+
18
+ from .file_digest import (
19
+ file_digest_test_file_as_pathlib_path,
20
+ file_digest_test_file_as_str,
21
+ file_digest_sha256,
22
+ file_digest_blake2b,
23
+ file_digest_blake2s,
24
+ )
25
+
26
+ from .garbage_collection import java_garbage_collection
27
+
28
+ from .origins import (
29
+ multiple_origins,
30
+ origin_point,
31
+ origins_invalid_duplicate_ids,
32
+ origins_invalid_no_id,
33
+ origins_valid_ids,
34
+ )
35
+
36
+ from .r5_jar import (
37
+ r5_jar_cached,
38
+ r5_jar_cached_invalid,
39
+ r5_jar_sha256,
40
+ r5_jar_sha256_github_error_message_when_posting,
41
+ r5_jar_sha256_invalid,
42
+ r5_jar_url,
43
+ )
44
+
45
+ from .routing_parameters import (
46
+ departure_datetime,
47
+ regional_task,
48
+ )
49
+
50
+ from .routing_results import (
51
+ detailed_itineraries_bicycle,
52
+ detailed_itineraries_car,
53
+ detailed_itineraries_transit,
54
+ detailed_itineraries_walk,
55
+ isochrones_from_multiple_origins,
56
+ isochrones_bicycle,
57
+ isochrones_car,
58
+ isochrones_transit,
59
+ isochrones_walk,
60
+ travel_times_bicycle,
61
+ travel_times_car,
62
+ travel_times_transit,
63
+ travel_times_walk,
64
+ walking_details_not_snapped,
65
+ walking_details_snapped,
66
+ walking_times_not_snapped,
67
+ walking_times_snapped,
68
+ )
69
+
70
+ from .sample_data import (
71
+ sample_data_set_sha256,
72
+ sample_data_set_url,
73
+ )
74
+
75
+ from .transport_network import (
76
+ broken_gtfs_file_path,
77
+ gtfs_file_path,
78
+ gtfs_timezone_helsinki,
79
+ helsinki_osm_pbf_file_path,
80
+ not_a_gtfs_file,
81
+ sao_paulo_osm_pbf_file_path,
82
+ transport_network,
83
+ transport_network_files_tuple,
84
+ transport_network_from_test_directory,
85
+ transport_network_from_test_files,
86
+ transport_network_from_test_files_without_gtfs,
87
+ )
88
+
89
+ from .upstream_r5 import (
90
+ can_compute_detailed_route_geometries,
91
+ )
92
+
93
+ __all__ = [
94
+ "broken_gtfs_file_path",
95
+ "can_compute_detailed_route_geometries",
96
+ "departure_datetime",
97
+ "detailed_itineraries_bicycle",
98
+ "detailed_itineraries_car",
99
+ "detailed_itineraries_transit",
100
+ "detailed_itineraries_walk",
101
+ "file_digest_blake2b",
102
+ "file_digest_blake2s",
103
+ "file_digest_sha256",
104
+ "file_digest_test_file_as_pathlib_path",
105
+ "file_digest_test_file_as_str",
106
+ "gtfs_file_path",
107
+ "gtfs_timezone_helsinki",
108
+ "helsinki_osm_pbf_file_path",
109
+ "isochrones_bicycle",
110
+ "isochrones_car",
111
+ "isochrones_from_multiple_origins",
112
+ "isochrones_transit",
113
+ "isochrones_walk",
114
+ "java_garbage_collection",
115
+ "multiple_origins",
116
+ "not_a_gtfs_file",
117
+ "origin_point",
118
+ "origins_invalid_duplicate_ids",
119
+ "origins_invalid_no_id",
120
+ "origins_valid_ids",
121
+ "population_grid",
122
+ "population_grid_points",
123
+ "population_grid_points_first_three",
124
+ "population_grid_points_four",
125
+ "population_grid_points_second_three",
126
+ "r5_jar_cached",
127
+ "r5_jar_cached_invalid",
128
+ "r5_jar_sha256",
129
+ "r5_jar_sha256_github_error_message_when_posting",
130
+ "r5_jar_sha256_invalid",
131
+ "r5_jar_url",
132
+ "regional_task",
133
+ "sample_data_set_sha256",
134
+ "sample_data_set_url",
135
+ "sao_paulo_osm_pbf_file_path",
136
+ "snapped_population_grid_points",
137
+ "transport_network",
138
+ "transport_network_files_tuple",
139
+ "transport_network_from_test_directory",
140
+ "transport_network_from_test_files",
141
+ "transport_network_from_test_files_without_gtfs",
142
+ "travel_times_bicycle",
143
+ "travel_times_car",
144
+ "travel_times_transit",
145
+ "travel_times_walk",
146
+ "unreachable_stops",
147
+ "unsnappable_points",
148
+ "walking_details_not_snapped",
149
+ "walking_details_snapped",
150
+ "walking_times_not_snapped",
151
+ "walking_times_snapped",
152
+ ]
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env python3
2
+
3
+
4
+ """Path to test data sets."""
5
+ import pathlib
6
+
7
+
8
+ DATA_DIRECTORY = pathlib.Path(__file__).resolve().parent.parent / "data"
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env python3
2
+
3
+
4
+ """Fixtures related to the destinations used in routing."""
5
+
6
+
7
+ import geopandas
8
+ import pytest
9
+ import shapely
10
+
11
+ from .data_directory import DATA_DIRECTORY
12
+
13
+
14
+ SNAPPED_POPULATION_GRID_POINTS = (
15
+ DATA_DIRECTORY / "test_snapped_population_grid_centroids.geojson"
16
+ )
17
+
18
+
19
+ @pytest.fixture(scope="session")
20
+ def population_grid():
21
+ """Load the grid point data set."""
22
+ import r5py.sampledata.helsinki
23
+
24
+ yield geopandas.read_file(r5py.sampledata.helsinki.population_grid)
25
+
26
+
27
+ @pytest.fixture(scope="session")
28
+ def population_grid_points(population_grid):
29
+ """Return the grid point data set in EPSG:4326."""
30
+ population_grid_points = population_grid.copy()
31
+ population_grid_points.geometry = population_grid_points.geometry.to_crs(
32
+ "EPSG:3067"
33
+ ).centroid.to_crs("EPSG:4326")
34
+ yield population_grid_points
35
+
36
+
37
+ @pytest.fixture(scope="session")
38
+ def population_grid_points_first_three(population_grid_points):
39
+ """Return the first set of three grid points."""
40
+ yield population_grid_points[0:3]
41
+
42
+
43
+ @pytest.fixture(scope="session")
44
+ def population_grid_points_second_three(population_grid_points):
45
+ """Return the second set of three grid points."""
46
+ yield population_grid_points[4:7]
47
+
48
+
49
+ @pytest.fixture(scope="session")
50
+ def population_grid_points_four(population_grid_points):
51
+ """Return four grid points."""
52
+ yield population_grid_points[10:14]
53
+
54
+
55
+ @pytest.fixture(scope="session")
56
+ def snapped_population_grid_points():
57
+ """Return a `geopandas.GeoDataFrame` that contains grid points snapped to the street network."""
58
+ yield geopandas.read_file(SNAPPED_POPULATION_GRID_POINTS)
59
+
60
+
61
+ @pytest.fixture
62
+ def unreachable_stops():
63
+ """Return a list of public transport stops that cannot be reached."""
64
+ yield [
65
+ 1294132,
66
+ 1174101,
67
+ 1452601,
68
+ ]
69
+
70
+
71
+ @pytest.fixture
72
+ def unsnappable_points():
73
+ """Retrieve a set of points that cannot be snapped to the sample data network."""
74
+ yield geopandas.GeoDataFrame(
75
+ {
76
+ "id": [1, 2],
77
+ "geometry": [
78
+ shapely.Point(48.20, 16.36), # far away from Helsinki
79
+ shapely.Point(-0.22, -78.51), # even further
80
+ ],
81
+ },
82
+ crs="EPSG:4326",
83
+ )
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env python3
2
+
3
+
4
+ """Fixtures describing the expected routing results."""
5
+
6
+
7
+ import pytest
8
+
9
+ from .routing_results import ISOCHRONES_WALK
10
+
11
+
12
+ ISOCHRONES_WALK_BLAKE2B = "163f6b2bc985e7eb347020320392a151ba1c156a09e82f87c0149273de2714516a098984e581bf99742c075232e18d69f5171370589cb5ec64d70f42f539f76c"
13
+ ISOCHRONES_WALK_BLAKE2S = (
14
+ "9f0af2c9946982b2e7d17a0b2205b596cbef01b1037874f5ad72348407ad381e"
15
+ )
16
+ ISOCHRONES_WALK_SHA256 = (
17
+ "b632d148ca5d9875482197461809f25fe790d71827e821983cefe2394841b417"
18
+ )
19
+
20
+
21
+ @pytest.fixture
22
+ def file_digest_test_file_as_pathlib_path():
23
+ """Return the path of a test file as a pathlib.Path."""
24
+ yield ISOCHRONES_WALK
25
+
26
+
27
+ @pytest.fixture
28
+ def file_digest_test_file_as_str(file_digest_test_file_as_pathlib_path):
29
+ """Return the path of a test file as a str."""
30
+ yield f"{file_digest_test_file_as_pathlib_path}"
31
+
32
+
33
+ @pytest.fixture()
34
+ def file_digest_sha256():
35
+ """Return the expected SHA256 hash for the test file."""
36
+ yield ISOCHRONES_WALK_SHA256
37
+
38
+
39
+ @pytest.fixture()
40
+ def file_digest_blake2b():
41
+ """Return the expected BLAKE2B hash for the test file."""
42
+ yield ISOCHRONES_WALK_BLAKE2B
43
+
44
+
45
+ @pytest.fixture()
46
+ def file_digest_blake2s():
47
+ """Return the expected BLAKE2S hash for the test file."""
48
+ yield ISOCHRONES_WALK_BLAKE2S
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env python3
2
+
3
+
4
+ """An auto-use fixture that calls Java garbage collection before every function."""
5
+
6
+
7
+ import jpype
8
+ import pytest
9
+
10
+
11
+ @pytest.fixture(autouse=True, scope="function")
12
+ def java_garbage_collection():
13
+ """Call Java GC before every function."""
14
+ jpype.java.lang.System.gc()