scgraph 2.7.0__tar.gz → 2.8.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.
Files changed (24) hide show
  1. {scgraph-2.7.0/scgraph.egg-info → scgraph-2.8.0}/PKG-INFO +5 -4
  2. {scgraph-2.7.0 → scgraph-2.8.0}/README.md +5 -4
  3. {scgraph-2.7.0 → scgraph-2.8.0}/pyproject.toml +1 -1
  4. {scgraph-2.7.0 → scgraph-2.8.0}/scgraph/__init__.py +8 -5
  5. scgraph-2.8.0/scgraph/core.py +7 -0
  6. scgraph-2.7.0/scgraph/core.py → scgraph-2.8.0/scgraph/geograph.py +50 -420
  7. scgraph-2.8.0/scgraph/graph.py +551 -0
  8. {scgraph-2.7.0 → scgraph-2.8.0}/scgraph/grid.py +84 -10
  9. {scgraph-2.7.0 → scgraph-2.8.0/scgraph.egg-info}/PKG-INFO +5 -4
  10. {scgraph-2.7.0 → scgraph-2.8.0}/scgraph.egg-info/SOURCES.txt +2 -0
  11. {scgraph-2.7.0 → scgraph-2.8.0}/setup.cfg +1 -1
  12. {scgraph-2.7.0 → scgraph-2.8.0}/LICENSE +0 -0
  13. {scgraph-2.7.0 → scgraph-2.8.0}/scgraph/cache.py +0 -0
  14. {scgraph-2.7.0 → scgraph-2.8.0}/scgraph/geographs/__init__.py +0 -0
  15. {scgraph-2.7.0 → scgraph-2.8.0}/scgraph/geographs/marnet.py +0 -0
  16. {scgraph-2.7.0 → scgraph-2.8.0}/scgraph/geographs/north_america_rail.py +0 -0
  17. {scgraph-2.7.0 → scgraph-2.8.0}/scgraph/geographs/oak_ridge_maritime.py +0 -0
  18. {scgraph-2.7.0 → scgraph-2.8.0}/scgraph/geographs/us_freeway.py +0 -0
  19. {scgraph-2.7.0 → scgraph-2.8.0}/scgraph/helpers/__init__.py +0 -0
  20. {scgraph-2.7.0 → scgraph-2.8.0}/scgraph/helpers/shape_mover_utils.py +0 -0
  21. {scgraph-2.7.0 → scgraph-2.8.0}/scgraph/spanning.py +0 -0
  22. {scgraph-2.7.0 → scgraph-2.8.0}/scgraph/utils.py +0 -0
  23. {scgraph-2.7.0 → scgraph-2.8.0}/scgraph.egg-info/dependency_links.txt +0 -0
  24. {scgraph-2.7.0 → scgraph-2.8.0}/scgraph.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scgraph
3
- Version: 2.7.0
3
+ Version: 2.8.0
4
4
  Summary: Determine an approximate route between two points on earth.
5
5
  Author-email: Connor Makowski <conmak@mit.edu>
6
6
  Project-URL: Homepage, https://github.com/connor-makowski/scgraph
@@ -41,9 +41,10 @@ Low Level: https://connor-makowski.github.io/scgraph/scgraph/core.html
41
41
  - Algorithms:
42
42
  - Dijkstra's algorithm (Modified for sparse networks)
43
43
  - Modified to support sparse network data structures
44
- - Makowski's Modified Sparse Dijkstra algorithm
45
- - Modified for O(n) performance on particularly sparse networks
46
- - A* algorithm (Extension of Makowski's Modified Sparse Dijkstra)
44
+ - Modified Sparse Dijkstra algorithm
45
+ - Modified for O((n+m)log(n)) performance where n is the number of nodes and m is the number of edges
46
+ - Uses a priority queue to improve performance on large graphs
47
+ - A* algorithm (Extension of the Modified Sparse Dijkstra)
47
48
  - Uses a heuristic function to improve performance on large graphs
48
49
  - Note: The heuristic function is optional and defaults to Dijkstra's algorithm
49
50
  - Possible future support for other algorithms
@@ -25,9 +25,10 @@ Low Level: https://connor-makowski.github.io/scgraph/scgraph/core.html
25
25
  - Algorithms:
26
26
  - Dijkstra's algorithm (Modified for sparse networks)
27
27
  - Modified to support sparse network data structures
28
- - Makowski's Modified Sparse Dijkstra algorithm
29
- - Modified for O(n) performance on particularly sparse networks
30
- - A* algorithm (Extension of Makowski's Modified Sparse Dijkstra)
28
+ - Modified Sparse Dijkstra algorithm
29
+ - Modified for O((n+m)log(n)) performance where n is the number of nodes and m is the number of edges
30
+ - Uses a priority queue to improve performance on large graphs
31
+ - A* algorithm (Extension of the Modified Sparse Dijkstra)
31
32
  - Uses a heuristic function to improve performance on large graphs
32
33
  - Note: The heuristic function is optional and defaults to Dijkstra's algorithm
33
34
  - Possible future support for other algorithms
@@ -363,4 +364,4 @@ Make sure Docker is installed and running on a Unix system (Linux, MacOS, WSL2).
363
364
 
364
365
 
365
366
  ## Attributions and Thanks
366
- Originally inspired by [searoute](https://github.com/genthalili/searoute-py) including the use of one of their [datasets](https://github.com/genthalili/searoute-py/blob/main/searoute/data/marnet_densified_v2_old.geojson) that has been modified to work properly with this package.
367
+ Originally inspired by [searoute](https://github.com/genthalili/searoute-py) including the use of one of their [datasets](https://github.com/genthalili/searoute-py/blob/main/searoute/data/marnet_densified_v2_old.geojson) that has been modified to work properly with this package.
@@ -12,7 +12,7 @@ build-backend = "setuptools.build_meta"
12
12
 
13
13
  [project]
14
14
  name = "scgraph"
15
- version = "2.7.0"
15
+ version = "2.8.0"
16
16
  description = "Determine an approximate route between two points on earth."
17
17
  authors = [
18
18
  {name="Connor Makowski", email="conmak@mit.edu"}
@@ -26,9 +26,10 @@ Low Level: https://connor-makowski.github.io/scgraph/scgraph/core.html
26
26
  - Algorithms:
27
27
  - Dijkstra's algorithm (Modified for sparse networks)
28
28
  - Modified to support sparse network data structures
29
- - Makowski's Modified Sparse Dijkstra algorithm
30
- - Modified for O(n) performance on particularly sparse networks
31
- - A* algorithm (Extension of Makowski's Modified Sparse Dijkstra)
29
+ - Modified Sparse Dijkstra algorithm
30
+ - Modified for O((n+m)log(n)) performance where n is the number of nodes and m is the number of edges
31
+ - Uses a priority queue to improve performance on large graphs
32
+ - A* algorithm (Extension of the Modified Sparse Dijkstra)
32
33
  - Uses a heuristic function to improve performance on large graphs
33
34
  - Note: The heuristic function is optional and defaults to Dijkstra's algorithm
34
35
  - Possible future support for other algorithms
@@ -364,7 +365,9 @@ Make sure Docker is installed and running on a Unix system (Linux, MacOS, WSL2).
364
365
 
365
366
 
366
367
  ## Attributions and Thanks
367
- Originally inspired by [searoute](https://github.com/genthalili/searoute-py) including the use of one of their [datasets](https://github.com/genthalili/searoute-py/blob/main/searoute/data/marnet_densified_v2_old.geojson) that has been modified to work properly with this package."""
368
+ Originally inspired by [searoute](https://github.com/genthalili/searoute-py) including the use of one of their [datasets](https://github.com/genthalili/searoute-py/blob/main/searoute/data/marnet_densified_v2_old.geojson) that has been modified to work properly with this package.
369
+ """
368
370
 
369
- from .core import Graph, GeoGraph
371
+ from .graph import Graph
372
+ from .geograph import GeoGraph
370
373
  from .grid import GridGraph
@@ -0,0 +1,7 @@
1
+ # This file just imports the necessary modules to allow for backwards compatibility
2
+ from scgraph.graph import Graph
3
+ from scgraph.geograph import (
4
+ GeoGraph,
5
+ load_geojson_as_geograph,
6
+ get_multi_path_geojson,
7
+ )
@@ -1,424 +1,7 @@
1
1
  from .utils import haversine, distance_converter, get_line_path, cheap_ruler
2
2
  import json
3
- from heapq import heappop, heappush
4
3
 
5
-
6
- class Graph:
7
- @staticmethod
8
- def validate_graph(
9
- graph: list[dict[int, int | float]],
10
- check_symmetry: bool = True,
11
- check_connected: bool = True,
12
- ) -> None:
13
- """
14
- Function:
15
-
16
- - Validate that a graph is properly formatted
17
-
18
- Required Arguments:
19
-
20
- - `graph`:
21
- - Type: list of dictionaries with integer keys and integer or float values
22
- - What: A list of dictionaries where the indicies are origin node ids and the values are dictionaries of destination node indices and graph weights
23
- - Note: All nodes must be included as origins in the graph regardless of if they have any connected destinations
24
- - EG:
25
- ```
26
- [
27
- # From London (index 0)
28
- {
29
- # To Paris (index 1)
30
- 1: 311,
31
- },
32
- # From Paris (index 1)
33
- {
34
- # To London (index 0)
35
- 0: 311,
36
- # To Berlin (index 2)
37
- 2: 878,
38
- # To Rome (index 3)
39
- 3: 1439,
40
- # To Madrid (index 4)
41
- 4: 1053
42
- },
43
- # From Berlin (index 2)
44
- {
45
- # To Paris (index 1)
46
- 1: 878,
47
- # To Rome (index 3)
48
- 3: 1181,
49
- },
50
- # From Rome (index 3)
51
- {
52
- # To Paris (index 1)
53
- 1: 1439,
54
- # To Berlin (index 2)
55
- 2: 1181,
56
- },
57
- # From Madrid (index 4)
58
- {
59
- # To Paris (index 1)
60
- 1: 1053,
61
- # To Lisbon (index 5)
62
- 5: 623
63
- },
64
- # From Lisbon (index 5)
65
- {
66
- # To Madrid (index 4)
67
- 4: 623
68
- }
69
- ]
70
- ```
71
-
72
- Optional Arguments:
73
-
74
- - `check_symmetry`
75
- - Type: bool
76
- - What: Whether to check that the graph is symmetric
77
- - Default: True
78
- - Note: This is forced to True if `check_connected` is True
79
- - `check_connected`
80
- - Type: bool
81
- - What: Whether to check that the graph is fully connected
82
- - Default: True
83
- - Note: For computational efficiency, only symmetric graphs are checked for connectivity
84
- - Note: If this is True, `check_symmetry` is forced to True and the graph will be checked for symmetry prior to checking for connectivity
85
- """
86
- check_symmetry = check_symmetry or check_connected
87
- assert isinstance(graph, list), "Your graph must be a list"
88
- len_graph = len(graph)
89
- for origin_id, origin_dict in enumerate(graph):
90
- assert isinstance(
91
- origin_dict, dict
92
- ), f"Your graph must be a list of dictionaries but the value for origin {origin_id} is not a dictionary"
93
- destinations = list(origin_dict.keys())
94
- lengths = list(origin_dict.values())
95
- assert all(
96
- [
97
- (isinstance(i, int) and i >= 0 and i < len_graph)
98
- for i in destinations
99
- ]
100
- ), f"Destination ids must be non-negative integers and equivalent to an existing index, but graph[{origin_id}] has an error in the destination ids"
101
- assert all(
102
- [(isinstance(i, (int, float)) and i >= 0) for i in lengths]
103
- ), f"Distances must be integers or floats, but graph[{origin_id}] contains a non-integer or non-float distance"
104
- if check_symmetry:
105
- for destination_id, distance in origin_dict.items():
106
- assert (
107
- graph[destination_id].get(origin_id) == distance
108
- ), f"Your graph is not symmetric, the distance from node {origin_id} to node {destination_id} is {distance} but the distance from node {destination_id} to node {origin_id} is {graph.get(destination_id, {}).get(origin_id)}"
109
- if check_connected:
110
- assert Graph.validate_connected(
111
- graph
112
- ), "Your graph is not fully connected"
113
-
114
- @staticmethod
115
- def validate_connected(
116
- graph: list[dict[int, int | float]], origin_id: int = 0
117
- ) -> bool:
118
- """
119
- Function:
120
-
121
- - Validate that a graph is fully connected
122
- - This means that every node in the graph has a path to every other node in the graph
123
- - Note: This assumes that the graph is symmetric
124
- - Return True if the graph is fully connected and False if it is not
125
-
126
- Required Arguments:
127
-
128
- - `graph`:
129
- - Type: list of dictionaries
130
- - See: https://connor-makowski.github.io/scgraph/scgraph/core.html#Graph.validate_graph
131
-
132
- Optional Arguments:
133
-
134
- - `origin_id`
135
- - Type: int
136
- - What: The id of the origin node from which to start the connectivity check
137
- - Default: 0
138
- """
139
- visited = [0] * len(graph)
140
- open_leaves = [origin_id]
141
-
142
- while open_leaves:
143
- current_id = open_leaves.pop()
144
- visited[current_id] = 1
145
- for connected_id, connected_distance in graph[current_id].items():
146
- if visited[connected_id] == 0:
147
- open_leaves.append(connected_id)
148
- return min(visited) == 1
149
-
150
- @staticmethod
151
- def input_check(
152
- graph: list[dict[int, int | float]], origin_id: int, destination_id: int
153
- ) -> None:
154
- """
155
- Function:
156
-
157
- - Check that the inputs passed to the shortest path algorithm are valid
158
- - Raises an exception if the inputs passed are not valid
159
-
160
- Required Arguments:
161
-
162
- - `graph`:
163
- - Type: list of dictionaries
164
- - See: https://connor-makowski.github.io/scgraph/scgraph/core.html#Graph.validate_graph
165
- - `origin_id`
166
- - Type: int
167
- - What: The id of the origin node from the graph dictionary to start the shortest path from
168
- - `destination_id`
169
- - Type: int
170
- - What: The id of the destination node from the graph dictionary to end the shortest path at
171
-
172
- Optional Arguments:
173
-
174
- - None
175
- """
176
- if (
177
- not isinstance(origin_id, int)
178
- and origin_id < len(graph)
179
- and origin_id >= 0
180
- ):
181
- raise Exception(f"Origin node ({origin_id}) is not in the graph")
182
- if (
183
- not isinstance(destination_id, int)
184
- and origin_id < len(graph)
185
- and origin_id >= 0
186
- ):
187
- raise Exception(
188
- f"Destination node ({destination_id}) is not in the graph"
189
- )
190
-
191
- @staticmethod
192
- def dijkstra(
193
- graph: list[dict[int, int | float]], origin_id: int, destination_id: int
194
- ) -> dict:
195
- """
196
- Function:
197
-
198
- - Identify the shortest path between two nodes in a sparse network graph using a modified dijkstra algorithm
199
- - Modifications allow for a sparse distance matrix to be used instead of a dense distance matrix
200
- - This can dramatically reduce the memory and compute requirements of the algorithm
201
- - This algorithm runs in O(n^2) time where n is the number of nodes in the graph
202
- - Return a dictionary of various path information including:
203
- - `id_path`: A list of node ids in the order they are visited
204
- - `path`: A list of node dictionaries (lat + long) in the order they are visited
205
-
206
- Required Arguments:
207
-
208
- - `graph`:
209
- - Type: list of dictionaries
210
- - See: https://connor-makowski.github.io/scgraph/scgraph/core.html#Graph.validate_graph
211
- - `origin_id`
212
- - Type: int
213
- - What: The id of the origin node from the graph dictionary to start the shortest path from
214
- - `destination_id`
215
- - Type: int
216
- - What: The id of the destination node from the graph dictionary to end the shortest path at
217
-
218
- Optional Arguments:
219
-
220
- - None
221
- """
222
- Graph.input_check(
223
- graph=graph, origin_id=origin_id, destination_id=destination_id
224
- )
225
- distance_matrix = [float("inf")] * len(graph)
226
- branch_tip_distances = [float("inf")] * len(graph)
227
- predecessor = [-1] * len(graph)
228
-
229
- distance_matrix[origin_id] = 0
230
- branch_tip_distances[origin_id] = 0
231
-
232
- while True:
233
- current_distance = min(branch_tip_distances)
234
- if current_distance == float("inf"):
235
- raise Exception(
236
- "Something went wrong, the origin and destination nodes are not connected."
237
- )
238
- current_id = branch_tip_distances.index(current_distance)
239
- branch_tip_distances[current_id] = float("inf")
240
- if current_id == destination_id:
241
- break
242
- for connected_id, connected_distance in graph[current_id].items():
243
- possible_distance = current_distance + connected_distance
244
- if possible_distance < distance_matrix[connected_id]:
245
- distance_matrix[connected_id] = possible_distance
246
- predecessor[connected_id] = current_id
247
- branch_tip_distances[connected_id] = possible_distance
248
-
249
- output_path = [current_id]
250
- while predecessor[current_id] != -1:
251
- current_id = predecessor[current_id]
252
- output_path.append(current_id)
253
-
254
- output_path.reverse()
255
-
256
- return {
257
- "path": output_path,
258
- "length": distance_matrix[destination_id],
259
- }
260
-
261
- @staticmethod
262
- def dijkstra_makowski(
263
- graph: list[dict[int, int | float]], origin_id: int, destination_id: int
264
- ) -> dict:
265
- """
266
- Function:
267
-
268
- - Identify the shortest path between two nodes in a sparse network graph using Makowski's modified Dijkstra algorithm
269
- - Modifications allow for a sparse distance matrix to be used instead of a dense distance matrix
270
- - Improvements include only computing future potential nodes based on the open leaves for each branch
271
- - Open leaves are nodes that have not been visited yet but are adjacent to other visited nodes
272
- - This can dramatically reduce the memory and compute requirements of the algorithm
273
- - For particularly sparse graphs, this algorithm runs close to O(n log n) time
274
- - Where n is the number of nodes in the graph
275
- - For dense graphs, this algorithm runs closer to O(n^2) time (similar to the standard Dijkstra algorithm)
276
- - Where n is the number of nodes in the graph
277
- - Return a dictionary of various path information including:
278
- - `id_path`: A list of node ids in the order they are visited
279
- - `path`: A list of node dictionaries (lat + long) in the order they are visited
280
-
281
- Required Arguments:
282
-
283
- - `graph`:
284
- - Type: list of dictionaries
285
- - See: https://connor-makowski.github.io/scgraph/scgraph/core.html#Graph.validate_graph
286
- - `origin_id`
287
- - Type: int
288
- - What: The id of the origin node from the graph dictionary to start the shortest path from
289
- - `destination_id`
290
- - Type: int
291
- - What: The id of the destination node from the graph dictionary to end the shortest path at
292
-
293
- Optional Arguments:
294
-
295
- - None
296
- """
297
- # Input Validation
298
- Graph.input_check(
299
- graph=graph, origin_id=origin_id, destination_id=destination_id
300
- )
301
- # Variable Initialization
302
- distance_matrix = [float("inf")] * len(graph)
303
- distance_matrix[origin_id] = 0
304
- open_leaves = []
305
- heappush(open_leaves, (0, origin_id))
306
- predecessor = [-1] * len(graph)
307
-
308
- while open_leaves:
309
- current_distance, current_id = heappop(open_leaves)
310
- if current_id == destination_id:
311
- break
312
- for connected_id, connected_distance in graph[current_id].items():
313
- possible_distance = current_distance + connected_distance
314
- if possible_distance < distance_matrix[connected_id]:
315
- distance_matrix[connected_id] = possible_distance
316
- predecessor[connected_id] = current_id
317
- heappush(open_leaves, (possible_distance, connected_id))
318
- if current_id != destination_id:
319
- raise Exception(
320
- "Something went wrong, the origin and destination nodes are not connected."
321
- )
322
-
323
- output_path = [current_id]
324
- while predecessor[current_id] != -1:
325
- current_id = predecessor[current_id]
326
- output_path.append(current_id)
327
-
328
- output_path.reverse()
329
-
330
- return {
331
- "path": output_path,
332
- "length": distance_matrix[destination_id],
333
- }
334
-
335
- @staticmethod
336
- def a_star(
337
- graph: list[dict[int, int | float]],
338
- origin_id: int,
339
- destination_id: int,
340
- heuristic_fn=None,
341
- ) -> dict:
342
- """
343
- Function:
344
-
345
- - Identify the shortest path between two nodes in a sparse network graph using an A* extension of Makowski's modified Dijkstra algorithm
346
- - Return a dictionary of various path information including:
347
- - `id_path`: A list of node ids in the order they are visited
348
- - `path`: A list of node dictionaries (lat + long) in the order they are visited
349
-
350
- Required Arguments:
351
-
352
- - `graph`:
353
- - Type: list of dictionaries
354
- - See: https://connor-makowski.github.io/scgraph/scgraph/core.html#Graph.validate_graph
355
- - `origin_id`
356
- - Type: int
357
- - What: The id of the origin node from the graph dictionary to start the shortest path from
358
- - `destination_id`
359
- - Type: int
360
- - What: The id of the destination node from the graph dictionary to end the shortest path at
361
- - `heuristic_fn`
362
- - Type: function
363
- - What: A heuristic function that takes two node ids and returns an estimated distance between them
364
- - Note: If None, returns the shortest path using Makowski's modified Dijkstra algorithm
365
- - Default: None
366
-
367
- Optional Arguments:
368
-
369
- - None
370
- """
371
- if heuristic_fn is None:
372
- return Graph.dijkstra_makowski(
373
- graph=graph,
374
- origin_id=origin_id,
375
- destination_id=destination_id,
376
- )
377
- # Input Validation
378
- Graph.input_check(
379
- graph=graph, origin_id=origin_id, destination_id=destination_id
380
- )
381
- # Variable Initialization
382
- distance_matrix = [float("inf")] * len(graph)
383
- distance_matrix[origin_id] = 0
384
- open_leaves = []
385
- heappush(open_leaves, (0, origin_id))
386
- predecessor = [-1] * len(graph)
387
-
388
- while open_leaves:
389
- current_id = heappop(open_leaves)[1]
390
- if current_id == destination_id:
391
- break
392
- current_distance = distance_matrix[current_id]
393
- for connected_id, connected_distance in graph[current_id].items():
394
- possible_distance = current_distance + connected_distance
395
- if possible_distance < distance_matrix[connected_id]:
396
- distance_matrix[connected_id] = possible_distance
397
- predecessor[connected_id] = current_id
398
- heappush(
399
- open_leaves,
400
- (
401
- possible_distance
402
- + heuristic_fn(connected_id, destination_id),
403
- connected_id,
404
- ),
405
- )
406
- if current_id != destination_id:
407
- raise Exception(
408
- "Something went wrong, the origin and destination nodes are not connected."
409
- )
410
-
411
- output_path = [current_id]
412
- while predecessor[current_id] != -1:
413
- current_id = predecessor[current_id]
414
- output_path.append(current_id)
415
-
416
- output_path.reverse()
417
-
418
- return {
419
- "path": output_path,
420
- "length": distance_matrix[destination_id],
421
- }
4
+ from scgraph.graph import Graph
422
5
 
423
6
 
424
7
  class GeoGraph:
@@ -540,6 +123,24 @@ class GeoGraph:
540
123
  origin_id: int,
541
124
  destination_id: int,
542
125
  ):
126
+ """
127
+ Function:
128
+
129
+ - Calculate the haversine distance between two points on the Earth.
130
+
131
+ Required Arguments:
132
+
133
+ - `origin_id`
134
+ - Type: int
135
+ - What: The id of the origin node in the graph
136
+ - `destination_id`
137
+ - Type: int
138
+ - What: The id of the destination node in the graph
139
+
140
+ Optional Arguments:
141
+
142
+ - None
143
+ """
543
144
  return haversine(
544
145
  origin=self.nodes[origin_id],
545
146
  destination=self.nodes[destination_id],
@@ -552,6 +153,26 @@ class GeoGraph:
552
153
  origin_id: int,
553
154
  destination_id: int,
554
155
  ):
156
+ """
157
+ Function:
158
+
159
+ - Calculate the distance between two points on the Earth using the cheap ruler algorithm.
160
+ - This is based off of Mapbox's cheap ruler algorithm which is a fast approximation of the haversine distance
161
+ - It has modifications to support distances across the antimeridian
162
+
163
+ Required Arguments:
164
+
165
+ - `origin_id`
166
+ - Type: int
167
+ - What: The id of the origin node in the graph
168
+ - `destination_id`
169
+ - Type: int
170
+ - What: The id of the destination node in the graph
171
+
172
+ Optional Arguments:
173
+
174
+ - None
175
+ """
555
176
  return cheap_ruler(
556
177
  origin=self.nodes[origin_id],
557
178
  destination=self.nodes[destination_id],
@@ -719,7 +340,7 @@ class GeoGraph:
719
340
  **algorithm_kwargs,
720
341
  )
721
342
  output["coordinate_path"] = self.get_coordinate_path(output["path"])
722
- output["length"] = self.adujust_circuity_length(
343
+ output["length"] = self.adjust_circuity_length(
723
344
  output=output,
724
345
  node_addition_circuity=node_addition_circuity,
725
346
  off_graph_circuity=off_graph_circuity,
@@ -749,7 +370,7 @@ class GeoGraph:
749
370
  self.remove_appended_node()
750
371
  raise e
751
372
 
752
- def adujust_circuity_length(
373
+ def adjust_circuity_length(
753
374
  self,
754
375
  output: dict,
755
376
  node_addition_circuity: [float | int],
@@ -789,6 +410,15 @@ class GeoGraph:
789
410
  4,
790
411
  )
791
412
 
413
+ def adujust_circuity_length(self, *args, **kwargs):
414
+ """
415
+ Maintain backwards compatibility with the old method that had a typo.
416
+
417
+ This is now just an alias for `adjust_circuity_length`.
418
+ """
419
+ # TODO: Remove in next major release
420
+ return self.adjust_circuity_length(*args, **kwargs)
421
+
792
422
  def get_coordinate_path(self, path: list[int]) -> list[dict[float | int]]:
793
423
  """
794
424
  Function: