multimodalrouter 0.1.0__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 multimodalrouter might be problematic. Click here for more details.

Files changed (32) hide show
  1. {multimodalrouter-0.1.0 → multimodalrouter-0.1.2}/MANIFEST.in +1 -0
  2. {multimodalrouter-0.1.0/src/multiModalRouter.egg-info → multimodalrouter-0.1.2}/PKG-INFO +4 -1
  3. multimodalrouter-0.1.2/docs/cli.md +78 -0
  4. multimodalrouter-0.1.2/docs/examples/demoData.csv +1 -0
  5. multimodalrouter-0.1.2/docs/examples/flightRouter/data/fullDataset.csv +101 -0
  6. multimodalrouter-0.1.2/docs/examples/flightRouter/main.py +37 -0
  7. multimodalrouter-0.1.2/docs/examples/mazePathfinder/data/createMaze.py +64 -0
  8. multimodalrouter-0.1.2/docs/examples/mazePathfinder/data/maze.csv +198 -0
  9. multimodalrouter-0.1.2/docs/examples/mazePathfinder/main.py +59 -0
  10. multimodalrouter-0.1.2/docs/graph.md +514 -0
  11. multimodalrouter-0.1.2/docs/installation.md +44 -0
  12. multimodalrouter-0.1.2/docs/solvedMaze1.png +0 -0
  13. multimodalrouter-0.1.2/docs/utils.md +1 -0
  14. {multimodalrouter-0.1.0 → multimodalrouter-0.1.2}/pyproject.toml +7 -1
  15. {multimodalrouter-0.1.0 → multimodalrouter-0.1.2/src/multiModalRouter.egg-info}/PKG-INFO +4 -1
  16. {multimodalrouter-0.1.0 → multimodalrouter-0.1.2}/src/multiModalRouter.egg-info/SOURCES.txt +11 -0
  17. {multimodalrouter-0.1.0 → multimodalrouter-0.1.2}/src/multiModalRouter.egg-info/requires.txt +3 -0
  18. {multimodalrouter-0.1.0 → multimodalrouter-0.1.2}/LICENSE.md +0 -0
  19. {multimodalrouter-0.1.0 → multimodalrouter-0.1.2}/README.md +0 -0
  20. {multimodalrouter-0.1.0 → multimodalrouter-0.1.2}/setup.cfg +0 -0
  21. {multimodalrouter-0.1.0 → multimodalrouter-0.1.2}/src/multiModalRouter.egg-info/dependency_links.txt +0 -0
  22. {multimodalrouter-0.1.0 → multimodalrouter-0.1.2}/src/multiModalRouter.egg-info/entry_points.txt +0 -0
  23. {multimodalrouter-0.1.0 → multimodalrouter-0.1.2}/src/multiModalRouter.egg-info/top_level.txt +0 -0
  24. {multimodalrouter-0.1.0 → multimodalrouter-0.1.2}/src/multimodalrouter/__init__.py +0 -0
  25. {multimodalrouter-0.1.0 → multimodalrouter-0.1.2}/src/multimodalrouter/graph/__init__.py +0 -0
  26. {multimodalrouter-0.1.0 → multimodalrouter-0.1.2}/src/multimodalrouter/graph/dataclasses.py +0 -0
  27. {multimodalrouter-0.1.0 → multimodalrouter-0.1.2}/src/multimodalrouter/graph/graph.py +0 -0
  28. {multimodalrouter-0.1.0 → multimodalrouter-0.1.2}/src/multimodalrouter/router/__init__.py +0 -0
  29. {multimodalrouter-0.1.0 → multimodalrouter-0.1.2}/src/multimodalrouter/router/build.py +0 -0
  30. {multimodalrouter-0.1.0 → multimodalrouter-0.1.2}/src/multimodalrouter/router/route.py +0 -0
  31. {multimodalrouter-0.1.0 → multimodalrouter-0.1.2}/src/multimodalrouter/utils/__init__.py +0 -0
  32. {multimodalrouter-0.1.0 → multimodalrouter-0.1.2}/src/multimodalrouter/utils/preprocessor.py +0 -0
@@ -1,2 +1,3 @@
1
1
  include LICENSE
2
2
  include README.md
3
+ recursive-include docs *
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: multimodalrouter
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: A graph-based routing library for dynamic routing.
5
5
  Author-email: Tobias Karusseit <karusseittobi@gmail.com>
6
6
  License: MIT License
@@ -14,6 +14,7 @@ License: MIT License
14
14
  THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15
15
 
16
16
 
17
+ Project-URL: Repository, https://github.com/K-T0BIAS/MultiModalRouter
17
18
  Requires-Python: >=3.11
18
19
  Description-Content-Type: text/markdown
19
20
  License-File: LICENSE.md
@@ -41,6 +42,8 @@ Requires-Dist: typing_extensions>=4.15.0
41
42
  Requires-Dist: tzdata>=2025.2
42
43
  Provides-Extra: torch
43
44
  Requires-Dist: torch>=2.8.0; extra == "torch"
45
+ Provides-Extra: dev
46
+ Requires-Dist: pytest>=8.0; extra == "dev"
44
47
  Dynamic: license-file
45
48
 
46
49
  # Multi Modal Router
@@ -0,0 +1,78 @@
1
+ [HOME](../README.md)
2
+
3
+ # command line interface
4
+
5
+ If you don't want to always write new scripts to build the graph or to find routes, you can simply use the command line interface.
6
+
7
+ ## building a graph from the terminal
8
+
9
+ **this assumes that your data has been preprocessed into the correct format**
10
+
11
+ > from your terminal run:
12
+
13
+ ```
14
+ multimodalrouter-build hubType1 transportMode1 pathToDataset1 --maxDist 123 --extraMetrics metric1 metric2 --drivingEnabled --Dir pathToSomeDir
15
+ ```
16
+ ### args
17
+
18
+ - `hub type`,`transport mode`,`dataset path` = the first arguments in your cli should be these three. They must follow this order to be parsed correctly
19
+ - `hub type` = the name the hubs from this dataset will get
20
+ - `transport mode` = the mode of transport unique to this hub
21
+ - `dataset path` = ideally the absolute path to the dataset that contains this `hub type`
22
+ - NOTE: you can add as many hub types and datasets at once as you want just make sure the order is always; type1 mode1 path1 type2 ...
23
+ - `--maxDist` = the float value that limits the maximum length a driving edge can have (this is irrelevant id `--enableDriving` isn't set)
24
+ - `extraMetrics` = a list of keys that the graph will scan your data for and add the values to any edge where the key exists in the data (NOTE: each key should be present in at least one dataset, the number of extra metrics is not limited)
25
+ - `--drivingEnabled` = if this flag is added the graph will try to build connections between hubs for any hub that is closer than the `--maxDist` to anoter hub (check [here](../README.md#important-considerations-for-your-usecase) to see if your data allows this)
26
+ - `--Dir` = put the target directory of the save file here. (if this is not set the graph will be saved to a default dir)
27
+
28
+ ### example
29
+
30
+ > create a new dir for the garph and edit the `--Dir` if you want the graph in a easy to access directory otherwise keep as is
31
+
32
+ > NOTE: this example assumes you are still in the project dir. If not please adapt the dataset path accordingly
33
+
34
+ ```text
35
+ multimodalrouter-build airport plane ./docs/examples/flightRouter/data/fullDataset.csv --maxDist 100 --drivingEnabled
36
+ --extraMetrics source_name destination_name
37
+ ```
38
+
39
+ **output:**
40
+
41
+ ```text
42
+ Building graph...
43
+ Generating airport Hubs: 100hub [00:00, 186995.27hub/s]
44
+ Graph built and saved.
45
+ ```
46
+
47
+ ## finding a route
48
+
49
+ ```text
50
+ multimodalrouter-route --start lat1 lng1 --end lat2 lng2 --allowedModes car plane --maxSegments 123 --verbose
51
+ ```
52
+
53
+ > NOTE: if you have higher dimensional coordinates you can simply add them here aswell
54
+
55
+ ### agrs
56
+
57
+ - `--start` = the start coordinates for the route (doesn't have to be exact to the `Hub` it will find the closest hub to the point. Also the coordinates do not have to be in dgrees, but rather fit with the coordinate system of your data. Read more [here](./graph.md#advanced-options))
58
+ - `--end` = the end coordinates of the route: (same features as for `--start` apply)
59
+ - `--allowedModes` = a filter that discards edges that use a transport mode that is not in this list. (default= ['car'])
60
+ - `--maxSegments` = an interger value of the maximum number of hubs a route can have. (e.g.: to avoid very deep searches when long routes are not logically feasable) (default = 10)
61
+ - `--verbose` = if this flag is set the output route will contain the [edgeMetadata](./graph.md#edgemetadata) for every leg of the route (default=false when flag not set)
62
+
63
+ ### example
64
+
65
+ > NOTE: this example assumes you build the graph from the [previous example](#example).
66
+ > if you changed the save path this script wont find it (**this will hopefully be fixed in the future**).
67
+
68
+ ```text
69
+ multimodalrouter-route --start 60.866699 -162.272996 --end 60.872747 -162.5247 --allowedModes plane car --maxSegments 10 --verbose
70
+ ```
71
+
72
+ **output:**
73
+
74
+ ```text
75
+ Start: ATT
76
+ Edge: (transportMode=plane, metrics={'distance': 13.641155702721523, 'source_name': 'Atmautluak Airport', 'destination_name': 'Kasigluk Airport'})
77
+ -> KUK
78
+ ```
@@ -0,0 +1 @@
1
+ source,destination,distance,source_lat,source_lng,destination_lat,destination_lng
@@ -0,0 +1,101 @@
1
+ type_x,source_name,source_lat,source_lng,source,type_y,destination_name,destination_lat,destination_lng,destination,distance
2
+ small_airport,Nunapitchuk Airport,60.905591,-162.440454,NUP,medium_airport,Bethel Airport,60.77980042,-161.8379974,BET,35.50891861257026
3
+ small_airport,Nunapitchuk Airport,60.905591,-162.440454,NUP,small_airport,Atmautluak Airport,60.866699,-162.272996,ATT,10.038962939026435
4
+ seaplane_base,Port Protection Seaplane Base,56.328800201416,-133.61000061035,PPV,medium_airport,Ketchikan International Airport,55.35559845,-131.7140045,KTN,160.3721674641772
5
+ small_airport,Atmautluak Airport,60.866699,-162.272996,ATT,small_airport,Kasigluk Airport,60.872747,-162.5247,KUK,13.641155702721525
6
+ small_airport,Atmautluak Airport,60.866699,-162.272996,ATT,medium_airport,Bethel Airport,60.77980042,-161.8379974,BET,25.48337320882719
7
+ small_airport,Ouzinkie Airport,57.942094,-152.464314,KOZ,small_airport,Port Lions Airport,57.884905,-152.847719,ORI,23.522288770693002
8
+ small_airport,Ouzinkie Airport,57.942094,-152.464314,KOZ,medium_airport,Kodiak Airport,57.75,-152.4940033,ADQ,21.432013590596263
9
+ small_airport,Tununak Airport,60.569638,-165.246649,TNK,small_airport,Mertarvik Airport,60.81037,-164.499511,WWT,48.68780922120069
10
+ small_airport,Tununak Airport,60.569638,-165.246649,TNK,small_airport,Mertarvik Airport,60.81037,-164.499511,WWT,48.68780922120069
11
+ small_airport,Minto Al Wright Airport,65.147991,-149.368658,MNT,medium_airport,Fairbanks International Airport,64.815102,-147.856003,FAI,80.18507978147673
12
+ seaplane_base,Whale Pass Seaplane Float Harbor Facility,56.116299,-133.121994,WWP,seaplane_base,Naukati Bay Seaplane Base,55.849602,-133.227994,NKI,30.379585733808945
13
+ small_airport,Chuathbaluk Airport,61.579102,-159.216003,CHU,small_airport,Crooked Creek Airport,61.870315,-158.137636,CKD,65.38238505420615
14
+ small_airport,Levelock Airport,59.12606,-156.860906,KLL,small_airport,Igiugig Airport,59.324001,-155.901993,IGG,58.828992456169594
15
+ small_airport,Tuntutuliak Airport,60.351243,-162.654476,WTL,small_airport,Kongiganak Airport,59.9608,-162.880997,KKH,45.188440482713354
16
+ small_airport,Tuntutuliak Airport,60.351243,-162.654476,WTL,medium_airport,Bethel Airport,60.77980042,-161.8379974,BET,65.2786595888185
17
+ small_airport,Chignik Lake Airport,56.2550010681,-158.774993896,KCQ,small_airport,Perryville Airport,55.9065,-159.16091,KPV,45.55296472659558
18
+ small_airport,Ulawa Airport,-9.86054358262,161.979546547,RNA,large_airport,Honiara International Airport,-9.428,160.054993,HIR,216.38820067708903
19
+ small_airport,Ulawa Airport,-9.86054358262,161.979546547,RNA,small_airport,Ngorangora Airport,-10.4497003555,161.897994995,IRA,66.11653988838862
20
+ small_airport,Uru Harbour Airport,-8.87333,161.011002,ATD,large_airport,Honiara International Airport,-9.428,160.054993,HIR,121.73124157936162
21
+ small_airport,Bellona/Anua Airport,-11.3022222222,159.798333333,BNY,large_airport,Honiara International Airport,-9.428,160.054993,HIR,210.28617119708878
22
+ small_airport,Bellona/Anua Airport,-11.3022222222,159.798333333,BNY,small_airport,Rennell/Tingoa Airport,-11.55,160.062778,RNL,39.87237198952627
23
+ small_airport,Choiseul Bay Airport,-6.711944,156.396111,CHY,small_airport,Nusatupe Airport,-8.09778022766,156.863998413,GZO,162.5049617838888
24
+ small_airport,Fera/Maringe Airport,-8.1075,159.576996,FRE,large_airport,Honiara International Airport,-9.428,160.054993,HIR,155.94596147929755
25
+ small_airport,Fera/Maringe Airport,-8.1075,159.576996,FRE,small_airport,Suavanao Airport,-7.58556,158.731003,VAO,109.78386316421907
26
+ large_airport,Honiara International Airport,-9.428,160.054993,HIR,large_airport,Bauerfield International Airport,-17.699301,168.320007,VLI,1281.5410455884694
27
+ large_airport,Honiara International Airport,-9.428,160.054993,HIR,small_airport,Uru Harbour Airport,-8.87333,161.011002,ATD,121.73124157936162
28
+ large_airport,Honiara International Airport,-9.428,160.054993,HIR,large_airport,Brisbane International Airport,-27.38419914245605,153.11700439453125,BNE,2125.197199470748
29
+ large_airport,Honiara International Airport,-9.428,160.054993,HIR,small_airport,Bellona/Anua Airport,-11.3022222222,159.798333333,BNY,210.28617119708878
30
+ large_airport,Honiara International Airport,-9.428,160.054993,HIR,small_airport,Choiseul Bay Airport,-6.711944,156.396111,CHY,503.4301040975509
31
+ large_airport,Honiara International Airport,-9.428,160.054993,HIR,small_airport,Sege Airport,-8.57889,157.876007,EGM,257.25669923971793
32
+ large_airport,Honiara International Airport,-9.428,160.054993,HIR,small_airport,Fera/Maringe Airport,-8.1075,159.576996,FRE,155.94596147929755
33
+ large_airport,Honiara International Airport,-9.428,160.054993,HIR,small_airport,Nusatupe Airport,-8.09778022766,156.863998413,GZO,380.58997472323
34
+ large_airport,Honiara International Airport,-9.428,160.054993,HIR,small_airport,Ngorangora Airport,-10.4497003555,161.897994995,IRA,231.62836439151877
35
+ large_airport,Honiara International Airport,-9.428,160.054993,HIR,small_airport,Kaghau Airport,-7.3305,157.585,KGE,358.07676558742975
36
+ large_airport,Honiara International Airport,-9.428,160.054993,HIR,medium_airport,Munda Airport,-8.32797,157.263,MUA,330.2196835379018
37
+ large_airport,Honiara International Airport,-9.428,160.054993,HIR,medium_airport,Nadi International Airport,-17.755399703979492,177.4429931640625,NAN,2092.93698138901
38
+ large_airport,Honiara International Airport,-9.428,160.054993,HIR,small_airport,Santa Ana Airport,-10.847994,162.454108,NNB,306.4114913331019
39
+ large_airport,Honiara International Airport,-9.428,160.054993,HIR,small_airport,Ramata Airport,-8.168060302734375,157.64300537109375,RBV,299.78875699036024
40
+ large_airport,Honiara International Airport,-9.428,160.054993,HIR,small_airport,Ulawa Airport,-9.86054358262,161.979546547,RNA,216.38820067708903
41
+ large_airport,Honiara International Airport,-9.428,160.054993,HIR,small_airport,Rennell/Tingoa Airport,-11.55,160.062778,RNL,235.95716942961073
42
+ large_airport,Honiara International Airport,-9.428,160.054993,HIR,small_airport,Marau Airport,-9.86166954041,160.824996948,RUS,97.21320359785862
43
+ large_airport,Honiara International Airport,-9.428,160.054993,HIR,small_airport,Santa Cruz/Graciosa Bay/Luova Airport,-10.7203,165.794998,SCZ,644.616728255269
44
+ large_airport,Honiara International Airport,-9.428,160.054993,HIR,small_airport,Suavanao Airport,-7.58556,158.731003,VAO,251.33538811065654
45
+ large_airport,Honiara International Airport,-9.428,160.054993,HIR,large_airport,Bauerfield International Airport,-17.699301,168.320007,VLI,1281.5410455884694
46
+ large_airport,Honiara International Airport,-9.428,160.054993,HIR,large_airport,Bauerfield International Airport,-17.699301,168.320007,VLI,1281.5410455884694
47
+ large_airport,Honiara International Airport,-9.428,160.054993,HIR,medium_airport,Nadi International Airport,-17.755399703979492,177.4429931640625,NAN,2092.93698138901
48
+ large_airport,Honiara International Airport,-9.428,160.054993,HIR,large_airport,Port Moresby Jacksons International Airport,-9.44338035583496,147.22000122070312,POM,1407.7980052392509
49
+ large_airport,Honiara International Airport,-9.428,160.054993,HIR,large_airport,Brisbane International Airport,-27.38419914245605,153.11700439453125,BNE,2125.197199470748
50
+ small_airport,Ngorangora Airport,-10.4497003555,161.897994995,IRA,large_airport,Honiara International Airport,-9.428,160.054993,HIR,231.62836439151877
51
+ small_airport,Ngorangora Airport,-10.4497003555,161.897994995,IRA,small_airport,Santa Ana Airport,-10.847994,162.454108,NNB,75.19751316811372
52
+ small_airport,Ngorangora Airport,-10.4497003555,161.897994995,IRA,small_airport,Ulawa Airport,-9.86054358262,161.979546547,RNA,66.11653988838862
53
+ small_airport,Santa Cruz/Graciosa Bay/Luova Airport,-10.7203,165.794998,SCZ,large_airport,Honiara International Airport,-9.428,160.054993,HIR,644.616728255269
54
+ medium_airport,Munda Airport,-8.32797,157.263,MUA,small_airport,Sege Airport,-8.57889,157.876007,EGM,72.96767843412853
55
+ medium_airport,Munda Airport,-8.32797,157.263,MUA,small_airport,Nusatupe Airport,-8.09778022766,156.863998413,GZO,50.82722405648163
56
+ medium_airport,Munda Airport,-8.32797,157.263,MUA,large_airport,Honiara International Airport,-9.428,160.054993,HIR,330.2196835379018
57
+ medium_airport,Munda Airport,-8.32797,157.263,MUA,small_airport,Kaghau Airport,-7.3305,157.585,KGE,116.44735467761112
58
+ small_airport,Nusatupe Airport,-8.09778022766,156.863998413,GZO,small_airport,Choiseul Bay Airport,-6.711944,156.396111,CHY,162.5049617838888
59
+ small_airport,Nusatupe Airport,-8.09778022766,156.863998413,GZO,small_airport,Sege Airport,-8.57889,157.876007,EGM,123.52564099929795
60
+ small_airport,Nusatupe Airport,-8.09778022766,156.863998413,GZO,large_airport,Honiara International Airport,-9.428,160.054993,HIR,380.58997472323
61
+ small_airport,Nusatupe Airport,-8.09778022766,156.863998413,GZO,medium_airport,Munda Airport,-8.32797,157.263,MUA,50.82722405648163
62
+ small_airport,Rennell/Tingoa Airport,-11.55,160.062778,RNL,small_airport,Bellona/Anua Airport,-11.3022222222,159.798333333,BNY,39.87237198952627
63
+ small_airport,Rennell/Tingoa Airport,-11.55,160.062778,RNL,large_airport,Honiara International Airport,-9.428,160.054993,HIR,235.95716942961073
64
+ small_airport,Sege Airport,-8.57889,157.876007,EGM,small_airport,Nusatupe Airport,-8.09778022766,156.863998413,GZO,123.52564099929795
65
+ small_airport,Sege Airport,-8.57889,157.876007,EGM,large_airport,Honiara International Airport,-9.428,160.054993,HIR,257.25669923971793
66
+ small_airport,Sege Airport,-8.57889,157.876007,EGM,small_airport,Ramata Airport,-8.168060302734375,157.64300537109375,RBV,52.38204651861383
67
+ small_airport,Sege Airport,-8.57889,157.876007,EGM,small_airport,Suavanao Airport,-7.58556,158.731003,VAO,145.1191154079397
68
+ small_airport,Santa Ana Airport,-10.847994,162.454108,NNB,large_airport,Honiara International Airport,-9.428,160.054993,HIR,306.4114913331019
69
+ small_airport,Santa Ana Airport,-10.847994,162.454108,NNB,small_airport,Ngorangora Airport,-10.4497003555,161.897994995,IRA,75.19751316811372
70
+ small_airport,Marau Airport,-9.86166954041,160.824996948,RUS,large_airport,Honiara International Airport,-9.428,160.054993,HIR,97.21320359785862
71
+ small_airport,Suavanao Airport,-7.58556,158.731003,VAO,large_airport,Honiara International Airport,-9.428,160.054993,HIR,251.33538811065654
72
+ small_airport,Kaghau Airport,-7.3305,157.585,KGE,small_airport,Nusatupe Airport,-8.09778022766,156.863998413,GZO,116.57914877867566
73
+ small_airport,Kaghau Airport,-7.3305,157.585,KGE,medium_airport,Munda Airport,-8.32797,157.263,MUA,116.44735467761112
74
+ small_airport,Ramata Airport,-8.168060302734375,157.64300537109375,RBV,large_airport,Honiara International Airport,-9.428,160.054993,HIR,299.78875699036024
75
+ small_airport,Ramata Airport,-8.168060302734375,157.64300537109375,RBV,medium_airport,Munda Airport,-8.32797,157.263,MUA,45.44094741444411
76
+ seaplane_base,Naukati Bay Seaplane Base,55.849602,-133.227994,NKI,seaplane_base,Edna Bay Seaplane Base,55.949653,-133.661012,EDA,29.19724206748465
77
+ seaplane_base,Amook Bay Seaplane Base,57.4715003967,-153.815002441,AOS,seaplane_base,Zachar Bay Seaplane Base,57.553001,-153.746052,KZB,9.954218423033408
78
+ medium_airport,Nauru International Airport,-0.547458,166.919006,INU,large_airport,Brisbane International Airport,-27.38419914245605,153.11700439453125,BNE,3327.7632640151937
79
+ medium_airport,Nauru International Airport,-0.547458,166.919006,INU,medium_airport,Marshall Islands International Airport,7.06476,171.272003,MAJ,974.4960347944631
80
+ medium_airport,Nauru International Airport,-0.547458,166.919006,INU,medium_airport,Bonriki International Airport,1.38164,173.147003,TRW,724.9332999884076
81
+ medium_airport,Buka Airport,-5.422319889068604,154.67300415039062,BUA,medium_airport,Tokua Airport,-4.34046,152.380005,RAB,281.08421413197493
82
+ medium_airport,Buka Airport,-5.422319889068604,154.67300415039062,BUA,small_airport,Londolovit Airport,-3.04361009598,152.628997803,LNV,348.3233345946322
83
+ medium_airport,Buka Airport,-5.422319889068604,154.67300415039062,BUA,large_airport,Port Moresby Jacksons International Airport,-9.44338035583496,147.22000122070312,POM,935.3716267807029
84
+ medium_airport,Buka Airport,-5.422319889068604,154.67300415039062,BUA,medium_airport,Tokua Airport,-4.34046,152.380005,RAB,281.08421413197493
85
+ small_airport,Bulolo Airport,-7.216286671410001,146.649541855,BUL,large_airport,Port Moresby Jacksons International Airport,-9.44338035583496,147.22000122070312,POM,255.4701324460494
86
+ medium_airport,Chimbu Airport,-6.024290084838867,144.9709930419922,CMU,large_airport,Port Moresby Jacksons International Airport,-9.44338035583496,147.22000122070312,POM,453.79316712547796
87
+ medium_airport,Daru Airport,-9.08676,143.207993,DAU,medium_airport,Nadzab Airport,-6.569803,146.725977,LAE,478.00303964492326
88
+ medium_airport,Daru Airport,-9.08676,143.207993,DAU,large_airport,Port Moresby Jacksons International Airport,-9.44338035583496,147.22000122070312,POM,442.0739733579925
89
+ medium_airport,Daru Airport,-9.08676,143.207993,DAU,small_airport,Kiunga Airport,-6.1257100105285645,141.28199768066406,UNG,391.7380630804866
90
+ medium_airport,Daru Airport,-9.08676,143.207993,DAU,large_airport,Port Moresby Jacksons International Airport,-9.44338035583496,147.22000122070312,POM,442.0739733579925
91
+ medium_airport,Goroka Airport,-6.081689834590001,145.391998291,GKA,medium_airport,Mount Hagen Kagamuga Airport,-5.828212,144.299412,HGU,124.07803210978558
92
+ medium_airport,Goroka Airport,-6.081689834590001,145.391998291,GKA,medium_airport,Nadzab Airport,-6.569803,146.725977,LAE,157.10150462058704
93
+ medium_airport,Goroka Airport,-6.081689834590001,145.391998291,GKA,medium_airport,Madang Airport,-5.20707988739,145.789001465,MAG,106.7138992902682
94
+ medium_airport,Goroka Airport,-6.081689834590001,145.391998291,GKA,large_airport,Port Moresby Jacksons International Airport,-9.44338035583496,147.22000122070312,POM,424.5928070950016
95
+ medium_airport,Goroka Airport,-6.081689834590001,145.391998291,GKA,large_airport,Port Moresby Jacksons International Airport,-9.44338035583496,147.22000122070312,POM,424.5928070950016
96
+ medium_airport,Gurney Airport,-10.3114995956,150.333999634,GUR,small_airport,Losuia Airport,-8.505820274353027,151.08099365234375,LSA,216.85910026596767
97
+ medium_airport,Gurney Airport,-10.3114995956,150.333999634,GUR,small_airport,Misima Island Airport,-10.6892004013,152.837997437,MIS,276.9706342250573
98
+ medium_airport,Gurney Airport,-10.3114995956,150.333999634,GUR,medium_airport,Girua Airport,-8.80453968048,148.309005737,PNP,278.16980437426656
99
+ medium_airport,Gurney Airport,-10.3114995956,150.333999634,GUR,large_airport,Port Moresby Jacksons International Airport,-9.44338035583496,147.22000122070312,POM,354.5183966398174
100
+ medium_airport,Gurney Airport,-10.3114995956,150.333999634,GUR,small_airport,Misima Island Airport,-10.6892004013,152.837997437,MIS,276.9706342250573
101
+ medium_airport,Gurney Airport,-10.3114995956,150.333999634,GUR,large_airport,Port Moresby Jacksons International Airport,-9.44338035583496,147.22000122070312,POM,354.5183966398174
@@ -0,0 +1,37 @@
1
+ # demo.py
2
+ # Copyright (c) 2025 Tobias Karusseit
3
+ # Licensed under the MIT License. See LICENSE file in the project root for full license information
4
+
5
+ from multimodalrouter import RouteGraph
6
+ import os
7
+
8
+ def main():
9
+ path = os.path.dirname(os.path.abspath(__file__))
10
+ # initialize the graph
11
+ graph = RouteGraph(
12
+ maxDistance=50,
13
+ transportModes={"airport": "plane", },
14
+ dataPaths={"airport": os.path.join(path, "data", "fullDataset.csv")},
15
+ compressed=False,
16
+ )
17
+ # build the graph
18
+ graph.build()
19
+ # set start and end points
20
+ start = [60.866699,-162.272996] # Atmautluak Airport
21
+ end = [60.872747,-162.5247] #Kasigluk Airport
22
+
23
+ start_hub = graph.findClosestHub(["airport"], start) # find the hubs
24
+ end_hub = graph.findClosestHub(["airport"], end)
25
+ # find the route
26
+ route = graph.find_shortest_path(
27
+ start_hub.id,
28
+ end_hub.id,
29
+ allowed_modes=["plane","car"],
30
+ verbose=True
31
+ )
32
+ # print the route
33
+ print(route.flatPath if route else "No route found")
34
+
35
+
36
+ if __name__ == "__main__":
37
+ main()
@@ -0,0 +1,64 @@
1
+ # demo.py
2
+ # Copyright (c) 2025 Tobias Karusseit
3
+ # Licensed under the MIT License. See LICENSE file in the project root for full license information
4
+
5
+ import random
6
+ import pandas as pd
7
+
8
+ # simple cell class for the maze
9
+ class Cell:
10
+ def __init__(self, x, y):
11
+ self.id = f"cell-{x,y}"
12
+ self.x = x
13
+ self.y = y
14
+ self.visited = False
15
+ self.connected = []
16
+
17
+ def main():
18
+ # init a 10x10 maze
19
+ mazeHeight = 10
20
+ mazeWidth = 10
21
+ # init the cells
22
+ cells = [Cell(x, y) for x, y in [(x, y) for x in range(mazeWidth) for y in range(mazeHeight)]]
23
+ cellStack = []
24
+ # random choose one cell and init the stack
25
+ random.shuffle(cells)
26
+ cellStack.append(cells.pop())
27
+ # build the maze
28
+ while cellStack:
29
+ currentCell = cellStack[-1] # peek at the current cell
30
+ # get all not et visited neighbors
31
+ neighbors = [
32
+ c for c in cells if not c.visited and (
33
+ (c.x == currentCell.x + 1 and c.y == currentCell.y) or
34
+ (c.x == currentCell.x - 1 and c.y == currentCell.y) or
35
+ (c.y == currentCell.y + 1 and c.x == currentCell.x) or
36
+ (c.y == currentCell.y - 1 and c.x == currentCell.x)
37
+ )
38
+ ]
39
+
40
+ if neighbors:
41
+ # select a random neighbor
42
+ random.shuffle(neighbors)
43
+ neighbor = neighbors.pop()
44
+ # connect the cells (remove walls)
45
+ currentCell.connected.append(neighbor)
46
+ neighbor.connected.append(currentCell)
47
+ # mark the neighbor as visited
48
+ neighbor.visited = True
49
+ # add the neighbor to the stack
50
+ cellStack.append(neighbor)
51
+ else:
52
+ # remove the current cell from the stack since no paths exist for it
53
+ cellStack.pop()
54
+
55
+ # init the dataframe
56
+ data = pd.DataFrame(columns=["source", "destination", "distance", "source_lat", "source_lng", "destination_lat", "destination_lng"])
57
+ # add the edges to the dataframe
58
+ for cell in cells:
59
+ for neighbor in cell.connected:
60
+ data.loc[len(data)] = [cell.id, neighbor.id, 1, cell.x, cell.y, neighbor.x, neighbor.y]
61
+ # save the dataframe
62
+ data.to_csv("docs/examples/mazePathfinder/data/maze.csv", index=False)
63
+
64
+ if __name__ == "__main__": main()
@@ -0,0 +1,198 @@
1
+ source,destination,distance,source_lat,source_lng,destination_lat,destination_lng
2
+ "cell-(6, 9)","cell-(5, 9)",1,6,9,5,9
3
+ "cell-(6, 9)","cell-(7, 9)",1,6,9,7,9
4
+ "cell-(6, 6)","cell-(5, 6)",1,6,6,5,6
5
+ "cell-(6, 6)","cell-(7, 6)",1,6,6,7,6
6
+ "cell-(7, 5)","cell-(8, 5)",1,7,5,8,5
7
+ "cell-(7, 5)","cell-(6, 5)",1,7,5,6,5
8
+ "cell-(1, 5)","cell-(2, 5)",1,1,5,2,5
9
+ "cell-(1, 5)","cell-(0, 5)",1,1,5,0,5
10
+ "cell-(8, 5)","cell-(9, 5)",1,8,5,9,5
11
+ "cell-(8, 5)","cell-(7, 5)",1,8,5,7,5
12
+ "cell-(6, 3)","cell-(6, 4)",1,6,3,6,4
13
+ "cell-(6, 3)","cell-(5, 3)",1,6,3,5,3
14
+ "cell-(3, 3)","cell-(2, 3)",1,3,3,2,3
15
+ "cell-(3, 3)","cell-(3, 4)",1,3,3,3,4
16
+ "cell-(9, 6)","cell-(8, 6)",1,9,6,8,6
17
+ "cell-(9, 6)","cell-(9, 5)",1,9,6,9,5
18
+ "cell-(9, 6)","cell-(9, 7)",1,9,6,9,7
19
+ "cell-(6, 5)","cell-(7, 5)",1,6,5,7,5
20
+ "cell-(6, 2)","cell-(7, 2)",1,6,2,7,2
21
+ "cell-(6, 2)","cell-(5, 2)",1,6,2,5,2
22
+ "cell-(8, 3)","cell-(7, 3)",1,8,3,7,3
23
+ "cell-(8, 3)","cell-(8, 2)",1,8,3,8,2
24
+ "cell-(6, 7)","cell-(7, 7)",1,6,7,7,7
25
+ "cell-(6, 7)","cell-(6, 8)",1,6,7,6,8
26
+ "cell-(9, 7)","cell-(9, 6)",1,9,7,9,6
27
+ "cell-(9, 7)","cell-(8, 7)",1,9,7,8,7
28
+ "cell-(2, 9)","cell-(3, 9)",1,2,9,3,9
29
+ "cell-(2, 9)","cell-(2, 8)",1,2,9,2,8
30
+ "cell-(4, 4)","cell-(3, 4)",1,4,4,3,4
31
+ "cell-(4, 4)","cell-(4, 3)",1,4,4,4,3
32
+ "cell-(9, 8)","cell-(9, 9)",1,9,8,9,9
33
+ "cell-(9, 8)","cell-(8, 8)",1,9,8,8,8
34
+ "cell-(2, 7)","cell-(2, 8)",1,2,7,2,8
35
+ "cell-(2, 7)","cell-(1, 7)",1,2,7,1,7
36
+ "cell-(7, 4)","cell-(8, 4)",1,7,4,8,4
37
+ "cell-(7, 4)","cell-(6, 4)",1,7,4,6,4
38
+ "cell-(3, 0)","cell-(2, 0)",1,3,0,2,0
39
+ "cell-(3, 0)","cell-(4, 0)",1,3,0,4,0
40
+ "cell-(8, 0)","cell-(7, 0)",1,8,0,7,0
41
+ "cell-(8, 0)","cell-(9, 0)",1,8,0,9,0
42
+ "cell-(2, 3)","cell-(2, 4)",1,2,3,2,4
43
+ "cell-(2, 3)","cell-(3, 3)",1,2,3,3,3
44
+ "cell-(5, 7)","cell-(5, 8)",1,5,7,5,8
45
+ "cell-(5, 7)","cell-(4, 7)",1,5,7,4,7
46
+ "cell-(1, 3)","cell-(1, 2)",1,1,3,1,2
47
+ "cell-(1, 3)","cell-(0, 3)",1,1,3,0,3
48
+ "cell-(4, 7)","cell-(5, 7)",1,4,7,5,7
49
+ "cell-(4, 7)","cell-(4, 6)",1,4,7,4,6
50
+ "cell-(3, 1)","cell-(4, 1)",1,3,1,4,1
51
+ "cell-(3, 1)","cell-(3, 2)",1,3,1,3,2
52
+ "cell-(2, 2)","cell-(3, 2)",1,2,2,3,2
53
+ "cell-(2, 2)","cell-(1, 2)",1,2,2,1,2
54
+ "cell-(5, 3)","cell-(6, 3)",1,5,3,6,3
55
+ "cell-(5, 3)","cell-(5, 4)",1,5,3,5,4
56
+ "cell-(5, 0)","cell-(4, 0)",1,5,0,4,0
57
+ "cell-(0, 4)","cell-(0, 5)",1,0,4,0,5
58
+ "cell-(0, 4)","cell-(1, 4)",1,0,4,1,4
59
+ "cell-(8, 7)","cell-(9, 7)",1,8,7,9,7
60
+ "cell-(7, 8)","cell-(8, 8)",1,7,8,8,8
61
+ "cell-(7, 8)","cell-(7, 7)",1,7,8,7,7
62
+ "cell-(9, 1)","cell-(9, 0)",1,9,1,9,0
63
+ "cell-(9, 1)","cell-(9, 2)",1,9,1,9,2
64
+ "cell-(4, 9)","cell-(4, 8)",1,4,9,4,8
65
+ "cell-(4, 9)","cell-(3, 9)",1,4,9,3,9
66
+ "cell-(4, 9)","cell-(5, 9)",1,4,9,5,9
67
+ "cell-(0, 2)","cell-(0, 3)",1,0,2,0,3
68
+ "cell-(0, 2)","cell-(0, 1)",1,0,2,0,1
69
+ "cell-(5, 1)","cell-(5, 2)",1,5,1,5,2
70
+ "cell-(5, 1)","cell-(6, 1)",1,5,1,6,1
71
+ "cell-(4, 2)","cell-(4, 3)",1,4,2,4,3
72
+ "cell-(4, 2)","cell-(4, 1)",1,4,2,4,1
73
+ "cell-(2, 0)","cell-(2, 1)",1,2,0,2,1
74
+ "cell-(2, 0)","cell-(3, 0)",1,2,0,3,0
75
+ "cell-(2, 0)","cell-(1, 0)",1,2,0,1,0
76
+ "cell-(2, 8)","cell-(2, 9)",1,2,8,2,9
77
+ "cell-(2, 8)","cell-(2, 7)",1,2,8,2,7
78
+ "cell-(1, 8)","cell-(0, 8)",1,1,8,0,8
79
+ "cell-(1, 8)","cell-(1, 9)",1,1,8,1,9
80
+ "cell-(7, 7)","cell-(7, 8)",1,7,7,7,8
81
+ "cell-(7, 7)","cell-(6, 7)",1,7,7,6,7
82
+ "cell-(8, 9)","cell-(7, 9)",1,8,9,7,9
83
+ "cell-(8, 9)","cell-(9, 9)",1,8,9,9,9
84
+ "cell-(4, 3)","cell-(4, 4)",1,4,3,4,4
85
+ "cell-(4, 3)","cell-(4, 2)",1,4,3,4,2
86
+ "cell-(8, 2)","cell-(8, 3)",1,8,2,8,3
87
+ "cell-(8, 2)","cell-(8, 1)",1,8,2,8,1
88
+ "cell-(6, 0)","cell-(6, 1)",1,6,0,6,1
89
+ "cell-(6, 0)","cell-(7, 0)",1,6,0,7,0
90
+ "cell-(0, 7)","cell-(1, 7)",1,0,7,1,7
91
+ "cell-(0, 7)","cell-(0, 8)",1,0,7,0,8
92
+ "cell-(0, 7)","cell-(0, 6)",1,0,7,0,6
93
+ "cell-(1, 1)","cell-(0, 1)",1,1,1,0,1
94
+ "cell-(1, 1)","cell-(2, 1)",1,1,1,2,1
95
+ "cell-(6, 8)","cell-(6, 7)",1,6,8,6,7
96
+ "cell-(6, 8)","cell-(5, 8)",1,6,8,5,8
97
+ "cell-(0, 6)","cell-(0, 7)",1,0,6,0,7
98
+ "cell-(0, 6)","cell-(1, 6)",1,0,6,1,6
99
+ "cell-(4, 0)","cell-(3, 0)",1,4,0,3,0
100
+ "cell-(4, 0)","cell-(5, 0)",1,4,0,5,0
101
+ "cell-(6, 4)","cell-(7, 4)",1,6,4,7,4
102
+ "cell-(6, 4)","cell-(6, 3)",1,6,4,6,3
103
+ "cell-(4, 8)","cell-(3, 8)",1,4,8,3,8
104
+ "cell-(4, 8)","cell-(4, 9)",1,4,8,4,9
105
+ "cell-(5, 8)","cell-(6, 8)",1,5,8,6,8
106
+ "cell-(5, 8)","cell-(5, 7)",1,5,8,5,7
107
+ "cell-(9, 3)","cell-(9, 2)",1,9,3,9,2
108
+ "cell-(9, 3)","cell-(9, 4)",1,9,3,9,4
109
+ "cell-(0, 3)","cell-(1, 3)",1,0,3,1,3
110
+ "cell-(0, 3)","cell-(0, 2)",1,0,3,0,2
111
+ "cell-(9, 4)","cell-(9, 3)",1,9,4,9,3
112
+ "cell-(9, 4)","cell-(8, 4)",1,9,4,8,4
113
+ "cell-(9, 0)","cell-(8, 0)",1,9,0,8,0
114
+ "cell-(9, 0)","cell-(9, 1)",1,9,0,9,1
115
+ "cell-(1, 6)","cell-(0, 6)",1,1,6,0,6
116
+ "cell-(1, 6)","cell-(2, 6)",1,1,6,2,6
117
+ "cell-(7, 9)","cell-(6, 9)",1,7,9,6,9
118
+ "cell-(7, 9)","cell-(8, 9)",1,7,9,8,9
119
+ "cell-(3, 7)","cell-(3, 6)",1,3,7,3,6
120
+ "cell-(3, 7)","cell-(3, 8)",1,3,7,3,8
121
+ "cell-(7, 6)","cell-(6, 6)",1,7,6,6,6
122
+ "cell-(7, 6)","cell-(8, 6)",1,7,6,8,6
123
+ "cell-(1, 9)","cell-(1, 8)",1,1,9,1,8
124
+ "cell-(1, 9)","cell-(0, 9)",1,1,9,0,9
125
+ "cell-(9, 2)","cell-(9, 1)",1,9,2,9,1
126
+ "cell-(9, 2)","cell-(9, 3)",1,9,2,9,3
127
+ "cell-(8, 4)","cell-(9, 4)",1,8,4,9,4
128
+ "cell-(8, 4)","cell-(7, 4)",1,8,4,7,4
129
+ "cell-(7, 2)","cell-(7, 1)",1,7,2,7,1
130
+ "cell-(7, 2)","cell-(6, 2)",1,7,2,6,2
131
+ "cell-(5, 4)","cell-(5, 3)",1,5,4,5,3
132
+ "cell-(5, 4)","cell-(5, 5)",1,5,4,5,5
133
+ "cell-(4, 5)","cell-(5, 5)",1,4,5,5,5
134
+ "cell-(4, 5)","cell-(3, 5)",1,4,5,3,5
135
+ "cell-(4, 6)","cell-(4, 7)",1,4,6,4,7
136
+ "cell-(4, 6)","cell-(5, 6)",1,4,6,5,6
137
+ "cell-(3, 5)","cell-(4, 5)",1,3,5,4,5
138
+ "cell-(3, 5)","cell-(3, 6)",1,3,5,3,6
139
+ "cell-(1, 2)","cell-(2, 2)",1,1,2,2,2
140
+ "cell-(1, 2)","cell-(1, 3)",1,1,2,1,3
141
+ "cell-(2, 1)","cell-(1, 1)",1,2,1,1,1
142
+ "cell-(2, 1)","cell-(2, 0)",1,2,1,2,0
143
+ "cell-(3, 2)","cell-(3, 1)",1,3,2,3,1
144
+ "cell-(3, 2)","cell-(2, 2)",1,3,2,2,2
145
+ "cell-(7, 0)","cell-(6, 0)",1,7,0,6,0
146
+ "cell-(7, 0)","cell-(8, 0)",1,7,0,8,0
147
+ "cell-(2, 5)","cell-(2, 6)",1,2,5,2,6
148
+ "cell-(2, 5)","cell-(1, 5)",1,2,5,1,5
149
+ "cell-(7, 1)","cell-(8, 1)",1,7,1,8,1
150
+ "cell-(7, 1)","cell-(7, 2)",1,7,1,7,2
151
+ "cell-(5, 5)","cell-(5, 4)",1,5,5,5,4
152
+ "cell-(5, 5)","cell-(4, 5)",1,5,5,4,5
153
+ "cell-(4, 1)","cell-(4, 2)",1,4,1,4,2
154
+ "cell-(4, 1)","cell-(3, 1)",1,4,1,3,1
155
+ "cell-(2, 4)","cell-(1, 4)",1,2,4,1,4
156
+ "cell-(2, 4)","cell-(2, 3)",1,2,4,2,3
157
+ "cell-(8, 1)","cell-(8, 2)",1,8,1,8,2
158
+ "cell-(8, 1)","cell-(7, 1)",1,8,1,7,1
159
+ "cell-(1, 0)","cell-(2, 0)",1,1,0,2,0
160
+ "cell-(1, 0)","cell-(0, 0)",1,1,0,0,0
161
+ "cell-(5, 9)","cell-(4, 9)",1,5,9,4,9
162
+ "cell-(5, 9)","cell-(6, 9)",1,5,9,6,9
163
+ "cell-(8, 6)","cell-(7, 6)",1,8,6,7,6
164
+ "cell-(8, 6)","cell-(9, 6)",1,8,6,9,6
165
+ "cell-(8, 8)","cell-(9, 8)",1,8,8,9,8
166
+ "cell-(8, 8)","cell-(7, 8)",1,8,8,7,8
167
+ "cell-(6, 1)","cell-(5, 1)",1,6,1,5,1
168
+ "cell-(6, 1)","cell-(6, 0)",1,6,1,6,0
169
+ "cell-(9, 5)","cell-(9, 6)",1,9,5,9,6
170
+ "cell-(9, 5)","cell-(8, 5)",1,9,5,8,5
171
+ "cell-(3, 6)","cell-(3, 5)",1,3,6,3,5
172
+ "cell-(3, 6)","cell-(3, 7)",1,3,6,3,7
173
+ "cell-(5, 2)","cell-(6, 2)",1,5,2,6,2
174
+ "cell-(5, 2)","cell-(5, 1)",1,5,2,5,1
175
+ "cell-(5, 6)","cell-(4, 6)",1,5,6,4,6
176
+ "cell-(5, 6)","cell-(6, 6)",1,5,6,6,6
177
+ "cell-(3, 9)","cell-(4, 9)",1,3,9,4,9
178
+ "cell-(3, 9)","cell-(2, 9)",1,3,9,2,9
179
+ "cell-(3, 8)","cell-(3, 7)",1,3,8,3,7
180
+ "cell-(3, 8)","cell-(4, 8)",1,3,8,4,8
181
+ "cell-(9, 9)","cell-(8, 9)",1,9,9,8,9
182
+ "cell-(9, 9)","cell-(9, 8)",1,9,9,9,8
183
+ "cell-(2, 6)","cell-(1, 6)",1,2,6,1,6
184
+ "cell-(2, 6)","cell-(2, 5)",1,2,6,2,5
185
+ "cell-(0, 1)","cell-(0, 2)",1,0,1,0,2
186
+ "cell-(0, 1)","cell-(1, 1)",1,0,1,1,1
187
+ "cell-(0, 5)","cell-(1, 5)",1,0,5,1,5
188
+ "cell-(0, 5)","cell-(0, 4)",1,0,5,0,4
189
+ "cell-(1, 4)","cell-(0, 4)",1,1,4,0,4
190
+ "cell-(1, 4)","cell-(2, 4)",1,1,4,2,4
191
+ "cell-(1, 7)","cell-(2, 7)",1,1,7,2,7
192
+ "cell-(1, 7)","cell-(0, 7)",1,1,7,0,7
193
+ "cell-(0, 8)","cell-(0, 7)",1,0,8,0,7
194
+ "cell-(0, 8)","cell-(1, 8)",1,0,8,1,8
195
+ "cell-(0, 9)","cell-(1, 9)",1,0,9,1,9
196
+ "cell-(3, 4)","cell-(3, 3)",1,3,4,3,3
197
+ "cell-(3, 4)","cell-(4, 4)",1,3,4,4,4
198
+ "cell-(0, 0)","cell-(1, 0)",1,0,0,1,0
@@ -0,0 +1,59 @@
1
+ # demo.py
2
+ # Copyright (c) 2025 Tobias Karusseit
3
+ # Licensed under the MIT License. See LICENSE file in the project root for full license information
4
+
5
+ from multimodalrouter import RouteGraph
6
+ import os
7
+ import pandas as pd
8
+
9
+ def main():
10
+ try:
11
+ import matplotlib.pyplot as plt
12
+ except ImportError:
13
+ raise ImportError("matplotlib is not installed. Please install matplotlib to use this example.")
14
+
15
+ path = os.path.dirname(os.path.abspath(__file__))
16
+ # init the maze df for the plot
17
+ mazeDf = pd.read_csv(os.path.join(path, "data", "maze.csv"))
18
+ # init the plot
19
+ plt.figure(figsize=(10,10))
20
+ # draw the maze
21
+ for _, row in mazeDf.iterrows():
22
+ plt.plot([row.source_lat, row.destination_lat],
23
+ [row.source_lng, row.destination_lng],
24
+ "k-") # black line for edge
25
+
26
+ # initialize the graph
27
+ graph = RouteGraph(
28
+ maxDistance=50,
29
+ transportModes={"cell": "walk", },
30
+ dataPaths={"cell": os.path.join(path, "data", "maze.csv")},
31
+ compressed=False,
32
+ drivingEnabled=False
33
+ )
34
+ # build the graph
35
+ graph.build()
36
+ # find the shortest route
37
+ route = graph.find_shortest_path(
38
+ start_id="cell-(0, 0)",
39
+ end_id="cell-(0, 9)",
40
+ allowed_modes=["walk"],
41
+ verbose=True,
42
+ max_segments=100
43
+ )
44
+ # print the route
45
+ print(route.flatPath if route else "No route found")
46
+ # make the route blue in the plot
47
+ s_prev = None
48
+ for s, _, _ in route.path:
49
+ if s_prev is not None:
50
+ h1 = graph.getHubById(s_prev)
51
+ h2 = graph.getHubById(s)
52
+ plt.plot([h1.coords[0], h2.coords[0]],
53
+ [h1.coords[1], h2.coords[1]],
54
+ "b-")
55
+ s_prev = s
56
+ # display the plot
57
+ plt.show()
58
+
59
+ if __name__ == "__main__": main()
@@ -0,0 +1,514 @@
1
+ [HOME](../README.md)
2
+
3
+ [graph](#routegraph)
4
+
5
+ - [advanced options](#advanced-options)
6
+ - [custom distance metrics](#swap-distance-method)
7
+ - [higher dimensional graphs](#higher-dimensional-graphs)
8
+
9
+ [dataclasses](#dataclasses)
10
+
11
+ [Hub](#Hub)
12
+
13
+ [EdgeMetadata](#edgemetadata)
14
+
15
+ [Route](#route)
16
+
17
+ # RouteGraph
18
+
19
+ The `RouteGraph` is the central class of the package implemented as a dynamic (cyclic) directed graph. It defines all graph building and routing related functions.
20
+
21
+
22
+ ## Functionality
23
+
24
+ ### initialization
25
+
26
+ This creates a new graph with no `Hubs` or `Edges`.
27
+
28
+ ```python
29
+ def __init__(
30
+ self,
31
+ maxDistance: float,
32
+ transportModes: dict[str, str],
33
+ dataPaths: dict[str, str] = {},
34
+ compressed: bool = False,
35
+ extraMetricsKeys: list[str] = [],
36
+ drivingEnabled: bool = True,
37
+ sourceCoordKeys: list[str] = ["source_lat", "source_lng"],
38
+ destCoordKeys: list[str] = ["destination_lat", "destination_lng"],
39
+ ):
40
+ ```
41
+
42
+ #### args
43
+
44
+ Terminology:
45
+
46
+ > Hub Type: hub types are the user defined names for their hubs. e.g. when having data for flights you have `airports`, thus you may want to define the hubs for the airports as type `airport`. (Hub Types can be anything you want to name them)
47
+
48
+ - ``maxDistance``: float = The maximum distance a driving edge is allowed to span
49
+ - ``transportModes``: dict[str, str] = a dictionary that assigns Hub Types to their mode of travel. E.g.
50
+ ```python
51
+ transportModes = {
52
+ 'airport': 'fly',# here hub type airport is assigned its primary mode of travel as fly
53
+ }
54
+ ```
55
+ - ``dataPaths``: dict[str, str] = a dictionary that stores the paths to datasets realtive to their Hub Types. E.g.:
56
+ ```python
57
+ dataPaths = {
58
+ # hub type: path to dataset
59
+ 'airport': '~/MUltiModalRouter/data/AirportDataset.parquet'
60
+ }
61
+ ```
62
+ - ``compressed``: bool = wheter to save this graph in compressed files or not (NOTE: this is not used at the moment so just skip)
63
+ - ``extraMetricsKeys``: list[str] = a list of metrics the graph will search for in the datasets when building edges (NOTE: default metrics must still be present)
64
+ Example:
65
+ ```python
66
+ # given at least one dataset with the col 'time'
67
+
68
+ extraMetricsKeys = ['time']
69
+ ```
70
+ When the graph finds this key in a dataset it will then add this metric (here `time`) to all edges that come from hubs stored inside this dataset
71
+
72
+ - ``drivingEnabled``: bool = whether the graph should connect all possible hubs that have $distance(a,b) \leq maxDistance$ (default=True)
73
+ - `sourecCoordKeys`: list[str] = a list of keys from your data that contains the column names from your source coordinates. (NOTE: if you have more than one dataset you can just put all source keys into this list as long as the same keys arent for any other metric somewhere else)
74
+ - `destCoordKeys`: list[str] = a list of keys from your data that contains the column names of the destination coordinates. (same conditions as for source apply)
75
+
76
+ > NOTE: the source and dest coord keys are matched to the correct datasets automatically you can just bundle them all together in one list
77
+
78
+ #### example
79
+
80
+ Init a graph with Hubs: `airport`, `trainstation`
81
+
82
+ ```python
83
+ from multimodalrouter import RouteGraph
84
+
85
+ graph = RouteGraph(
86
+ maxDistance = 50,
87
+ transportModes = {
88
+ 'airport': 'plane',
89
+ 'trainstation': 'train'
90
+ },
91
+ dataPaths = {
92
+ 'airport': pathToAirportData,
93
+ 'trainstation': pathToTrainData
94
+ }
95
+ # time and cost must each be present in at least one dataset
96
+ extraMetricsKeys = ['time', 'cost'],
97
+ # default is True so this is not necessary
98
+ drivingEnabled = True,
99
+ )
100
+ ```
101
+
102
+ The resulting graph will be able to build `HUbs` for both `train stations` and `airports`. It will also use the extra metrics in all edges where the data is present
103
+
104
+ ### build
105
+
106
+ After a graph is initialized it doesn't contain any actual nodes or edges yet. To create the nodes and edges the graph has to be build.
107
+
108
+ ```python
109
+ def build(self):
110
+ ```
111
+
112
+ #### example
113
+
114
+ click [here](#example) to see how to init the graph
115
+
116
+ ```python
117
+ # with the graph from the previous example
118
+
119
+ graph.build()
120
+ ```
121
+
122
+ After this finishes the graph is build and ready for routing
123
+
124
+ ### routing / finding the shortest Path form A to B
125
+
126
+ ```python
127
+ def find_shortest_path(
128
+ self,
129
+ start_id: str,
130
+ end_id: str,
131
+ allowed_modes: list[str],
132
+ optimization_metric: OptimizationMetric | str = OptimizationMetric.DISTANCE,
133
+ max_segments: int = 10,
134
+ verbose: bool = False
135
+ ) -> Route | None:
136
+ ```
137
+
138
+ #### args
139
+
140
+ - start_id: str = the Hub.id of the starting hub (e.g. the source field for this hub in your data -> for `airports` likely the iata code) (for coordinate searches see [here](#searching-with-coordinates))
141
+ - end_id: str = the Hub.id of the traget Hub
142
+ - allowed_modes: list[str] = a list of transport modes that are allowed in the path (all edges with different modes are excluded)(The modes are set during the graph [initailization](#args))
143
+ - optimization_metric: str = the metric by which the pathfinder will determine the length of the path (must be numeric and present in all searched edges) (default = `distance`) (metrics where also set during [initialization](#args))
144
+ - max_segments: int = the maximum number of hubs the route is allowed to include (default = 10 to avoid massive searches but should be setvrealtive to the graph size and density)
145
+ - verbose: bool = whether you want to store all edges and their data in the route or just the hub names (default=False)
146
+
147
+ **returns** : [Route](#route) or None if no route was found
148
+
149
+ ### save
150
+
151
+ ```python
152
+ def save(
153
+ self,
154
+ filepath: str = os.path.join(os.getcwd(), "..", "..", "..", "data"),
155
+ compressed: bool = False):
156
+ ```
157
+
158
+ The `save` method will create a save file from the last garph state. Depending on the `arguments` the file will either be stored as `.dill` or `.zlib`.
159
+ A save file contains the complete statedict of the RouteGraph instance except attributes that could break the pickling process (e.g. ``threading.Lock``).
160
+
161
+ #### args
162
+
163
+ - filepath: str = the directory that the savefile will be stored in (defaults to `MultiModalRouter/data`)
164
+ - compressed: bool = whether to compress the output into `.zlib` or store as `.dill`
165
+
166
+ #### example
167
+
168
+ Saving a graph to a custom dir, in a `.dill` file
169
+
170
+ ```python
171
+ ...
172
+ graph.save(filepath=customDir)
173
+ ```
174
+
175
+ ### load
176
+
177
+ ```python
178
+ @staticmethod
179
+ def load(
180
+ filepath: str,
181
+ compressed: bool = False
182
+ ) -> "RouteGraph":
183
+ ```
184
+
185
+ The load method is a static method that allows you to load a graph from its save file into a new graph object.
186
+ The resulting graph object is fully initialized and can be used as is.
187
+
188
+ #### args
189
+
190
+ - filepath: str = the full path to your save file
191
+ - compressed: bool = set this to `True` if your graph was saved to a `.zlib` compressed file (default=`False`)
192
+
193
+ #### example
194
+
195
+ ```python
196
+ from multimodalrouter import RouteGraph
197
+ # load a .dill file from 'pathToMyGraph'
198
+ myGraph = RouteGraph.load(filepath=pathToMyGraph)
199
+ ```
200
+
201
+ The `myGraph` object is now fully loaded and can be used to its full extend.
202
+
203
+ ### searching with coordinates
204
+
205
+ Since searching by hub id is not always possible the graph has a helper that finds a hub closest to a coordinate tuple.
206
+
207
+ ```python
208
+ def findClosestHub(
209
+ self,
210
+ allowedHubTypes: list[str],
211
+ coords: list[float],
212
+ ) -> Hub | None:
213
+ ```
214
+
215
+ #### args
216
+
217
+
218
+ - allowedHubTypes: list[str] = a list that defines which hubs should be searched (e.g. ['airport','trainstation'])
219
+ **NOTE:** if you set this to `None` all hubs will be included in
220
+ the search
221
+ - coords: list[float] = the coordinates of the hub. (not limited to 2 dimensions)
222
+
223
+ > NOTE: the coords must not necessarily be in degrees or any other meaningfull metric aslong as your data provides distances and you turn of enableDrive when building the graph or you do [this](./graph.md#advanced-options)
224
+
225
+ > NOTE: it is entirely possible to setup the graph with custom coordinate systems and distances
226
+
227
+ #### example
228
+
229
+ ```python
230
+ coordinates = 100.0, 100.0
231
+ closestHub = graph.findClosestHub(
232
+ allowedHUbTypes = None, # include all types in search
233
+ *coordinates,
234
+ )
235
+ ```
236
+
237
+ > NOTE: you can now use `closestHub.id` in the [search](#routing--finding-the-shortest-path-form-a-to-b)
238
+
239
+ ### getting hubs by id
240
+
241
+ If you want to inspect a hub and you know its `id` you can get it from the graph as follows
242
+
243
+ ```python
244
+ def getHub(
245
+ self,
246
+ hubType: str,
247
+ id: str
248
+ ) -> Hub | None:
249
+ ```
250
+
251
+ or
252
+
253
+ ```python
254
+ def getHubById(
255
+ self,
256
+ id: str
257
+ ) -> Hub | None:
258
+ ```
259
+
260
+ #### args
261
+
262
+ - hubType: str = the type of the target hub
263
+ - id: str = the id of the target hub
264
+
265
+ **returns:** the Hub or if not found None
266
+
267
+ ### manually adding Hubs
268
+
269
+ If you want to add a new Hub to a graph without building use this:
270
+
271
+ ```python
272
+ def addHub(self, hub: Hub):
273
+ ```
274
+
275
+ This will add your Hub to the garph and if its already present it will fail silently
276
+
277
+ ### args
278
+
279
+ - hub: Hub = the Hub you want to add
280
+
281
+ ---
282
+ ---
283
+
284
+ ### advanced options
285
+
286
+ #### swap distance method
287
+
288
+ When your dataset comes with neither distances nor a coordinate system in degrees you can mount your own distance function. This way you will still be able to build the default driving edges etc.
289
+
290
+ #### example
291
+
292
+ ```python
293
+ from multimodalrouter import RouteGraph
294
+ import types
295
+ # define your own distance metric (NOTE the arguments must be the same as here)
296
+ def myDistancMetric(self, hub1: list[Hub], hub2: list[Hub]):
297
+ ... # here you could for example calculate the euclidean distance
298
+ return distances # np.array or list
299
+
300
+ # create a normal graph object
301
+ specialGraph = RouteGraph(**kwargs)
302
+ # swap the distance method
303
+ specialGraph._hubToHubDistances = types.MethodType(myDistanceMetric, specialGraph)
304
+ # continue as you would normally
305
+ graph.build()
306
+ ```
307
+
308
+ #### NOTES
309
+
310
+ - Naturally you can do the same thing for the preprocessor to calculate the transport mode based distances in the preprocessessing step.
311
+
312
+ #### higher dimensional graphs
313
+
314
+ To build graphs from higher dimensional data a few things have to be done differently. As an example I will use the following datasets
315
+
316
+ | source | destination | sdim1 | sdim2 | sdim3 | ddim1 | ddim2 | ddim3 | distance |
317
+ |--------|-------------|-------|-------|-------|-------|-------|-------|----------|
318
+ | A | B | 0 | 0 | 0 | 1 | 2 | 2 | 3 |
319
+ | C | A | 2 | 4 | 4 | 0 | 0 | 0 | 6 |
320
+ | B | C | 1 | 2 | 2 | 2 | 4 | 4 | 3 |
321
+
322
+ | source | destination | adim1 | adim2 | adim3 | bdim1 | bdim2 | bdim3 | distance |
323
+ |--------|-------------|-------|-------|-------|-------|-------|-------|----------|
324
+ | a | b | 0 | 0 | 0 | 3 | 4 | 0 | 5 |
325
+ | a | c | 0 | 0 | 0 | 0 | 4 | 0 | 4 |
326
+ | c | b | 0 | 4 | 0 | 3 | 4 | 0 | 3 |
327
+
328
+ With these tow 3D datasets you can build a graph as follows:
329
+
330
+ ```python
331
+ sourceKeys = ['sdim1', 'sdim2', 'sdim3', 'adim1', 'adim2', 'adim3']
332
+ destinationKexs = ['ddim2', 'ddim2', 'ddim3', 'bdim1', 'bdim2', 'bdim3']
333
+
334
+ from multimodalrouter import RouteGraph
335
+
336
+ # create a graph
337
+
338
+ nDimGraph = RouteGraph(
339
+ maxDistance = 3,
340
+ transportModes = {
341
+ 'T1': 'mode1',
342
+ 'T2': 'mode2'
343
+ },
344
+ dataPaths = {
345
+ 'T1': path1, # path to the data from 1st table
346
+ 'T2': path2 # path to the data from 2nd table
347
+ },
348
+ drivingEnabled = False, # add your own driving func to enable this
349
+ sourceCoordKeys = sourceKeys, # the keys from the sources
350
+ destCoordKeys = destinationKeys, # the kexs from the destinations
351
+ )
352
+ ```
353
+
354
+ > Now everything else works as normal but with three coordinates
355
+
356
+ #### Notes:
357
+
358
+ > To enable driving add your own distance function like [this](#swap-distance-method)
359
+
360
+ > It is theoretically possible to combine hubs from differnt dimensions as long as a distance metric is given or the distance is pre calculated
361
+
362
+
363
+ ---
364
+ ---
365
+ ---
366
+
367
+ ## Dataclasses
368
+
369
+ ### Hub
370
+
371
+ Hubs are the nodes of the [RouteGraph](#routegraph) and store all outgoing connections alongside the relevant [EdgeMetadata](#edgemetadata)
372
+
373
+ ```python
374
+ def __init__(
375
+ self,
376
+ coords: list[float],
377
+ id: str,
378
+ hubType: str
379
+ ):
380
+ ```
381
+
382
+ #### fields
383
+
384
+ - coords: list[float]: the coordinates of the `Hub`. (NOTE: this can be any ndim coordinate aslong as it fits with the rest)
385
+ - id: str = a string id like iata code UNLOCODE or whatever you want (NOTE: must be unique for the hubType)
386
+ - hubType: str = the type of hub this will be (e.g. `airport`, `trainstation`,...)
387
+
388
+ #### adding edges
389
+
390
+ ```python
391
+ def addOutgoing(
392
+ self,
393
+ mode: str,
394
+ dest_id: str,
395
+ metrics: EdgeMetadata):
396
+ ```
397
+
398
+ #### args
399
+
400
+ - mode: str = the mode of transport along this edge (e.g. `plane`, `car`,...)
401
+ - dest_id: str = the id of the destination Hub
402
+ - metrics: [EdgeMetadata](#edgemetadata) = the edge object that stores the metrics for this connection
403
+
404
+ #### getting the edge metrics
405
+
406
+ Get the edgeMetadata from this Hub to another, with a given transport mode
407
+
408
+ ```python
409
+ def getMetrics(
410
+ self,
411
+ mode: str,
412
+ dest_id: str
413
+ )-> EdgeMetadata:
414
+ ```
415
+
416
+ #### args
417
+
418
+ - mode: str = the mode of transport along the edge
419
+ - dest_id: str = the id of the destination Hub
420
+
421
+ **returns:** the edgeMetadata or None if this edge doesn't exist
422
+
423
+ ---
424
+ ---
425
+ ### EdgeMetadata
426
+
427
+ These objects store data about one edge such as the `transport mode` and metrics like `distance` etc.
428
+
429
+ ```python
430
+ def __init__(
431
+ self,
432
+ transportMode: str = None,
433
+ **metrics):
434
+ ```
435
+
436
+ #### args
437
+
438
+ - transportMode: str = the transpot mode across this edge
439
+ - **metrics: dict = a dictionary of edge metrics like `distance`, `time` etc
440
+
441
+ #### example
442
+
443
+ create data for an edge that is traversed via `plane`, has a `distance` of `100.0` and `cost` of `250.0`
444
+
445
+ ```python
446
+ edgeData = EdgeMetadata(
447
+ transportMode = 'plane',
448
+ **{'distance': 100.0, 'cost': '250.0'}
449
+ )
450
+ ```
451
+
452
+ #### get a specific metric
453
+
454
+ ```python
455
+ def getMetric(
456
+ self,
457
+ metric: OptimizationMetric | str
458
+ ):
459
+ ```
460
+
461
+ #### args
462
+
463
+ - metric: str = the name of the metric you want to retrieve
464
+
465
+ ---
466
+ ---
467
+
468
+ ### Route
469
+
470
+ A dataclass to store all route related data; like Hubs and edges.
471
+
472
+
473
+ #### fields
474
+
475
+ ```python
476
+ path: list[tuple[str, str]]
477
+ totalMetrics: EdgeMetadata
478
+ optimizedMetric: OptimizationMetric
479
+ ```
480
+
481
+
482
+ #### properties
483
+ ---
484
+
485
+ ```
486
+ @property
487
+ def flatPath(
488
+ self,
489
+ toStr=True):
490
+ ```
491
+
492
+ By calling `route.flatPath` you will get the string representation of the route
493
+
494
+ #### example output
495
+
496
+ > NOTE: this is a verbose route from `-1.680000, 29.258334` to `3.490000, 35.840000`, connected through airports with data from [open flights](https://openflights.org/data.php)
497
+
498
+ ```text
499
+ Start: GOM
500
+ Edge: (transportMode=plane, metrics={'distance': 85.9251874180552})
501
+ -> BKY
502
+ Edge: (transportMode=drive, metrics={'distance': np.float32(20.288797)})
503
+ -> KME
504
+ Edge: (transportMode=plane, metrics={'distance': 147.44185301830063})
505
+ -> KGL
506
+ Edge: (transportMode=plane, metrics={'distance': 757.9567739118678})
507
+ -> NBO
508
+ Edge: (transportMode=plane, metrics={'distance': 515.1466233682448})
509
+ -> LOK
510
+ ```
511
+
512
+
513
+
514
+
@@ -0,0 +1,44 @@
1
+ [HOME](../README.md)
2
+
3
+ # Installation Guide
4
+
5
+ ## Step 1
6
+
7
+ First check if your data comes with precomputed distances and if you are going to want to use the default [driving connections](./graph.md) when building your graph.
8
+ Depending on your choices you will need to install the library with torch. To see what your use case requires check the table below and copy the command.
9
+
10
+ | data has distances | use driving edges | installation mode |
11
+ |--------------------|-------------------|-------------------------------------|
12
+ | YES | YES |`pip install .[torch]`|
13
+ | YES | NO |`pip install .[torch]`|
14
+ | NO | YES |`pip install .[torch]`|
15
+ | NO | NO | `pip install .` |
16
+
17
+ ## Step 2
18
+
19
+ > RUN your command from the root of this project
20
+
21
+ ## Step 3
22
+
23
+ The library should now be installed to check you can test with this:
24
+
25
+ ```text
26
+ python -c "import multimodalrouter; print(dir(multimodalrouter))"
27
+ ```
28
+
29
+ The result should look similar to this
30
+
31
+ ```python
32
+ [
33
+ 'EdgeMetadata',
34
+ 'Hub',
35
+ 'OptimizationMetric',
36
+ 'Route',
37
+ 'RouteGraph',
38
+ 'VerboseRoute',
39
+ '...',
40
+ 'preprocessor',
41
+ 'utils'
42
+ ]
43
+ ```
44
+
@@ -0,0 +1 @@
1
+ [HOME](../README.md)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "multimodalrouter"
7
- version = "0.1.0"
7
+ version = "0.1.2"
8
8
  description = "A graph-based routing library for dynamic routing."
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE.md" }
@@ -38,9 +38,15 @@ dependencies = [
38
38
 
39
39
  requires-python = ">=3.11"
40
40
 
41
+ [project.urls]
42
+ Repository = "https://github.com/K-T0BIAS/MultiModalRouter"
43
+
41
44
 
42
45
  [project.optional-dependencies]
43
46
  torch = ["torch>=2.8.0"]
47
+ dev = [
48
+ "pytest>=8.0"
49
+ ]
44
50
 
45
51
  [tool.setuptools]
46
52
  package-dir = {"" = "src"}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: multimodalrouter
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: A graph-based routing library for dynamic routing.
5
5
  Author-email: Tobias Karusseit <karusseittobi@gmail.com>
6
6
  License: MIT License
@@ -14,6 +14,7 @@ License: MIT License
14
14
  THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15
15
 
16
16
 
17
+ Project-URL: Repository, https://github.com/K-T0BIAS/MultiModalRouter
17
18
  Requires-Python: >=3.11
18
19
  Description-Content-Type: text/markdown
19
20
  License-File: LICENSE.md
@@ -41,6 +42,8 @@ Requires-Dist: typing_extensions>=4.15.0
41
42
  Requires-Dist: tzdata>=2025.2
42
43
  Provides-Extra: torch
43
44
  Requires-Dist: torch>=2.8.0; extra == "torch"
45
+ Provides-Extra: dev
46
+ Requires-Dist: pytest>=8.0; extra == "dev"
44
47
  Dynamic: license-file
45
48
 
46
49
  # Multi Modal Router
@@ -2,6 +2,17 @@ LICENSE.md
2
2
  MANIFEST.in
3
3
  README.md
4
4
  pyproject.toml
5
+ docs/cli.md
6
+ docs/graph.md
7
+ docs/installation.md
8
+ docs/solvedMaze1.png
9
+ docs/utils.md
10
+ docs/examples/demoData.csv
11
+ docs/examples/flightRouter/main.py
12
+ docs/examples/flightRouter/data/fullDataset.csv
13
+ docs/examples/mazePathfinder/main.py
14
+ docs/examples/mazePathfinder/data/createMaze.py
15
+ docs/examples/mazePathfinder/data/maze.csv
5
16
  src/multiModalRouter.egg-info/PKG-INFO
6
17
  src/multiModalRouter.egg-info/SOURCES.txt
7
18
  src/multiModalRouter.egg-info/dependency_links.txt
@@ -21,5 +21,8 @@ tqdm>=4.67.1
21
21
  typing_extensions>=4.15.0
22
22
  tzdata>=2025.2
23
23
 
24
+ [dev]
25
+ pytest>=8.0
26
+
24
27
  [torch]
25
28
  torch>=2.8.0