scgraph 3.2.4__tar.gz → 3.4.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.
- {scgraph-3.2.4 → scgraph-3.4.0}/PKG-INFO +26 -11
- {scgraph-3.2.4 → scgraph-3.4.0}/README.md +13 -8
- {scgraph-3.2.4 → scgraph-3.4.0}/pyproject.toml +23 -3
- {scgraph-3.2.4 → scgraph-3.4.0}/scgraph/__init__.py +15 -7
- {scgraph-3.2.4 → scgraph-3.4.0}/scgraph/geograph.py +105 -4
- {scgraph-3.2.4 → scgraph-3.4.0}/scgraph/utils.py +7 -0
- scgraph-3.2.4/build/cp314-cp314-linux_x86_64/CMakeFiles/CheckCXX/CMakeLists.txt +0 -6
- {scgraph-3.2.4 → scgraph-3.4.0}/CMakeLists.txt +0 -0
- {scgraph-3.2.4 → scgraph-3.4.0}/LICENSE +0 -0
- {scgraph-3.2.4 → scgraph-3.4.0}/scgraph/contraction_hierarchies.py +0 -0
- {scgraph-3.2.4 → scgraph-3.4.0}/scgraph/cpp/bindings/graph_bindings.cpp +0 -0
- {scgraph-3.2.4 → scgraph-3.4.0}/scgraph/cpp/src/bmssp.hpp +0 -0
- {scgraph-3.2.4 → scgraph-3.4.0}/scgraph/cpp/src/contraction_hierarchies.cpp +0 -0
- {scgraph-3.2.4 → scgraph-3.4.0}/scgraph/cpp/src/contraction_hierarchies.hpp +0 -0
- {scgraph-3.2.4 → scgraph-3.4.0}/scgraph/cpp/src/graph.cpp +0 -0
- {scgraph-3.2.4 → scgraph-3.4.0}/scgraph/cpp/src/graph.hpp +0 -0
- {scgraph-3.2.4 → scgraph-3.4.0}/scgraph/cpp/src/graph_utils.cpp +0 -0
- {scgraph-3.2.4 → scgraph-3.4.0}/scgraph/cpp/src/graph_utils.hpp +0 -0
- {scgraph-3.2.4 → scgraph-3.4.0}/scgraph/cpp/src/transit_node_routing.cpp +0 -0
- {scgraph-3.2.4 → scgraph-3.4.0}/scgraph/cpp/src/transit_node_routing.hpp +0 -0
- {scgraph-3.2.4 → scgraph-3.4.0}/scgraph/graph.py +0 -0
- {scgraph-3.2.4 → scgraph-3.4.0}/scgraph/graph_utils.py +0 -0
- {scgraph-3.2.4 → scgraph-3.4.0}/scgraph/grid.py +0 -0
- {scgraph-3.2.4 → scgraph-3.4.0}/scgraph/helpers/__init__.py +0 -0
- {scgraph-3.2.4 → scgraph-3.4.0}/scgraph/helpers/geojson.py +0 -0
- {scgraph-3.2.4 → scgraph-3.4.0}/scgraph/helpers/visvalingam.py +0 -0
- {scgraph-3.2.4 → scgraph-3.4.0}/scgraph/transit_node_routing.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: scgraph
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.4.0
|
|
4
4
|
Summary: Determine an approximate distance and route between two points on earth.
|
|
5
5
|
Author-Email: Connor Makowski <conmak@mit.edu>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -10,10 +10,20 @@ Classifier: Operating System :: OS Independent
|
|
|
10
10
|
Project-URL: Homepage, https://github.com/connor-makowski/scgraph
|
|
11
11
|
Project-URL: Bug Tracker, https://github.com/connor-makowski/scgraph/issues
|
|
12
12
|
Project-URL: Documentation, https://connor-makowski.github.io/scgraph/scgraph.html
|
|
13
|
-
Requires-Python: >=3.
|
|
13
|
+
Requires-Python: >=3.11
|
|
14
14
|
Requires-Dist: geokdtree==1.2.3
|
|
15
|
-
Requires-Dist: bmsspy<3.0.0,>=2.2.
|
|
15
|
+
Requires-Dist: bmsspy<3.0.0,>=2.2.1
|
|
16
16
|
Requires-Dist: requests<3.0.0,>=2.32.0
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: pytest>=9.0.3; extra == "dev"
|
|
19
|
+
Requires-Dist: pamda>=2.10.0; extra == "dev"
|
|
20
|
+
Requires-Dist: autoflake>=2.3.1; extra == "dev"
|
|
21
|
+
Requires-Dist: black>=25.1.0; extra == "dev"
|
|
22
|
+
Requires-Dist: build>=1.2.2; extra == "dev"
|
|
23
|
+
Requires-Dist: nox>=2026.4.10; extra == "dev"
|
|
24
|
+
Requires-Dist: nox-uv>=0.8.0; extra == "dev"
|
|
25
|
+
Requires-Dist: pdoc>=15.0.1; extra == "dev"
|
|
26
|
+
Requires-Dist: twine>=6.1.0; extra == "dev"
|
|
17
27
|
Description-Content-Type: text/markdown
|
|
18
28
|
|
|
19
29
|
# SCGraph
|
|
@@ -733,17 +743,22 @@ dist_mi = distance_converter(dist_km, input_units='km', output_units='mi')
|
|
|
733
743
|
|
|
734
744
|
# Development
|
|
735
745
|
|
|
736
|
-
|
|
746
|
+
Dev dependencies are declared in `[project.optional-dependencies] dev` in `pyproject.toml`. Install them with:
|
|
747
|
+
|
|
748
|
+
```bash
|
|
749
|
+
uv sync --extra dev
|
|
750
|
+
```
|
|
737
751
|
|
|
738
752
|
| Command | Description |
|
|
739
753
|
|---|---|
|
|
740
|
-
|
|
|
741
|
-
|
|
|
742
|
-
|
|
|
743
|
-
|
|
|
744
|
-
|
|
|
745
|
-
|
|
746
|
-
|
|
754
|
+
| `uv run pytest` | Run all tests |
|
|
755
|
+
| `uv run pytest test/NN_*.py` | Run a specific test file |
|
|
756
|
+
| `uv run nox` | Run tests (C++ then no-C++) across Python 3.11–3.14 |
|
|
757
|
+
| `uv run nox -s tests-3.14` | Run both build variants on a single Python version |
|
|
758
|
+
| `uv run utils/benchmark.py` | Run all benchmarks, output `benchmark_results.json` |
|
|
759
|
+
| `uv run utils/prettify.py` | Format with autoflake + black |
|
|
760
|
+
|
|
761
|
+
For full developer documentation see [DEVELOPMENT.md](DEVELOPMENT.md).
|
|
747
762
|
|
|
748
763
|
---
|
|
749
764
|
|
|
@@ -715,17 +715,22 @@ dist_mi = distance_converter(dist_km, input_units='km', output_units='mi')
|
|
|
715
715
|
|
|
716
716
|
# Development
|
|
717
717
|
|
|
718
|
-
|
|
718
|
+
Dev dependencies are declared in `[project.optional-dependencies] dev` in `pyproject.toml`. Install them with:
|
|
719
|
+
|
|
720
|
+
```bash
|
|
721
|
+
uv sync --extra dev
|
|
722
|
+
```
|
|
719
723
|
|
|
720
724
|
| Command | Description |
|
|
721
725
|
|---|---|
|
|
722
|
-
|
|
|
723
|
-
|
|
|
724
|
-
|
|
|
725
|
-
|
|
|
726
|
-
|
|
|
727
|
-
|
|
728
|
-
|
|
726
|
+
| `uv run pytest` | Run all tests |
|
|
727
|
+
| `uv run pytest test/NN_*.py` | Run a specific test file |
|
|
728
|
+
| `uv run nox` | Run tests (C++ then no-C++) across Python 3.11–3.14 |
|
|
729
|
+
| `uv run nox -s tests-3.14` | Run both build variants on a single Python version |
|
|
730
|
+
| `uv run utils/benchmark.py` | Run all benchmarks, output `benchmark_results.json` |
|
|
731
|
+
| `uv run utils/prettify.py` | Format with autoflake + black |
|
|
732
|
+
|
|
733
|
+
For full developer documentation see [DEVELOPMENT.md](DEVELOPMENT.md).
|
|
729
734
|
|
|
730
735
|
---
|
|
731
736
|
|
|
@@ -26,20 +26,40 @@ include = [
|
|
|
26
26
|
|
|
27
27
|
[project]
|
|
28
28
|
name = "scgraph"
|
|
29
|
-
version = "3.
|
|
29
|
+
version = "3.4.0"
|
|
30
30
|
description = "Determine an approximate distance and route between two points on earth."
|
|
31
31
|
authors = [
|
|
32
32
|
{name="Connor Makowski", email="conmak@mit.edu"}
|
|
33
33
|
]
|
|
34
34
|
readme = "README.md"
|
|
35
|
-
requires-python = ">=3.
|
|
35
|
+
requires-python = ">=3.11"
|
|
36
36
|
license="MIT"
|
|
37
37
|
classifiers = [
|
|
38
38
|
"Programming Language :: Python :: 3",
|
|
39
39
|
"Programming Language :: C++",
|
|
40
40
|
"Operating System :: OS Independent",
|
|
41
41
|
]
|
|
42
|
-
dependencies = ["geokdtree==1.2.3","bmsspy>=2.2.
|
|
42
|
+
dependencies = ["geokdtree==1.2.3","bmsspy>=2.2.1,<3.0.0","requests>=2.32.0,<3.0.0"]
|
|
43
|
+
|
|
44
|
+
[project.optional-dependencies]
|
|
45
|
+
dev = [
|
|
46
|
+
"pytest>=9.0.3",
|
|
47
|
+
"pamda>=2.10.0",
|
|
48
|
+
"autoflake>=2.3.1",
|
|
49
|
+
"black>=25.1.0",
|
|
50
|
+
"build>=1.2.2",
|
|
51
|
+
"nox>=2026.4.10",
|
|
52
|
+
"nox-uv>=0.8.0",
|
|
53
|
+
"pdoc>=15.0.1",
|
|
54
|
+
"twine>=6.1.0",
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
[tool.pytest.ini_options]
|
|
58
|
+
testpaths = ["test"]
|
|
59
|
+
pythonpath = ["test"]
|
|
60
|
+
|
|
61
|
+
[tool.uv]
|
|
62
|
+
no-build-isolation-package = []
|
|
43
63
|
|
|
44
64
|
[project.urls]
|
|
45
65
|
"Homepage" = "https://github.com/connor-makowski/scgraph"
|
|
@@ -716,23 +716,29 @@ dist_mi = distance_converter(dist_km, input_units='km', output_units='mi')
|
|
|
716
716
|
|
|
717
717
|
# Development
|
|
718
718
|
|
|
719
|
-
|
|
719
|
+
Dev dependencies are declared in `[project.optional-dependencies] dev` in `pyproject.toml`. Install them with:
|
|
720
|
+
|
|
721
|
+
```bash
|
|
722
|
+
uv sync --extra dev
|
|
723
|
+
```
|
|
720
724
|
|
|
721
725
|
| Command | Description |
|
|
722
726
|
|---|---|
|
|
723
|
-
|
|
|
724
|
-
|
|
|
725
|
-
|
|
|
726
|
-
|
|
|
727
|
-
|
|
|
727
|
+
| `uv run pytest` | Run all tests |
|
|
728
|
+
| `uv run pytest test/NN_*.py` | Run a specific test file |
|
|
729
|
+
| `uv run nox` | Run tests (C++ then no-C++) across Python 3.11–3.14 |
|
|
730
|
+
| `uv run nox -s tests-3.14` | Run both build variants on a single Python version |
|
|
731
|
+
| `uv run utils/benchmark.py` | Run all benchmarks, output `benchmark_results.json` |
|
|
732
|
+
| `uv run utils/prettify.py` | Format with autoflake + black |
|
|
728
733
|
|
|
729
|
-
|
|
734
|
+
For full developer documentation see [DEVELOPMENT.md](DEVELOPMENT.md).
|
|
730
735
|
|
|
731
736
|
---
|
|
732
737
|
|
|
733
738
|
## Attributions and Thanks
|
|
734
739
|
|
|
735
740
|
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 with this package.
|
|
741
|
+
|
|
736
742
|
"""
|
|
737
743
|
|
|
738
744
|
try:
|
|
@@ -740,5 +746,7 @@ try:
|
|
|
740
746
|
except ImportError:
|
|
741
747
|
from scgraph.graph import Graph
|
|
742
748
|
from scgraph.contraction_hierarchies import CHGraph
|
|
749
|
+
|
|
743
750
|
from scgraph.geograph import GeoGraph
|
|
744
751
|
from scgraph.grid import GridGraph
|
|
752
|
+
|
|
@@ -737,6 +737,107 @@ class GeoGraphModifiers:
|
|
|
737
737
|
symmetric=symmetric,
|
|
738
738
|
)
|
|
739
739
|
|
|
740
|
+
def add_coord_edge(
|
|
741
|
+
self,
|
|
742
|
+
origin_coord_dict: dict[str, float | int],
|
|
743
|
+
destination_coord_dict: dict[str, float | int],
|
|
744
|
+
symmetric: bool = True,
|
|
745
|
+
distance: float | int | None = None,
|
|
746
|
+
circuity: float | int = 1,
|
|
747
|
+
) -> None:
|
|
748
|
+
"""
|
|
749
|
+
Function:
|
|
750
|
+
|
|
751
|
+
- Add an edge to the graph between two nodes specified by their coordinates
|
|
752
|
+
- Finds the closest nodes in the graph to the provided coordinates and adds an edge between them
|
|
753
|
+
|
|
754
|
+
Required Arguments:
|
|
755
|
+
|
|
756
|
+
- `origin_coord_dict`
|
|
757
|
+
- Type: dict
|
|
758
|
+
- What: A dictionary with the keys 'latitude' and 'longitude' for the origin node
|
|
759
|
+
- Note: The function will find the closest node in the graph to these coordinates and use that as the origin node for the edge
|
|
760
|
+
- `destination_coord_dict`
|
|
761
|
+
- Type: dict
|
|
762
|
+
- What: A dictionary with the keys 'latitude' and 'longitude' for the destination node
|
|
763
|
+
- Note: The function will find the closest node in the graph to these coordinates and use that as the destination node for the edge
|
|
764
|
+
|
|
765
|
+
Optional Arguments:
|
|
766
|
+
|
|
767
|
+
- `symmetric`
|
|
768
|
+
- Type: bool
|
|
769
|
+
- What: Whether to add the edge in both directions
|
|
770
|
+
- Default: True
|
|
771
|
+
- `distance`
|
|
772
|
+
- Type: int | float | None
|
|
773
|
+
- What: The distance to use for the edge. If None, the haversine distance between the origin and destination nodes (the closest nodes to the provided ones) will be used (with circuity applied)
|
|
774
|
+
- Default: None
|
|
775
|
+
- `circuity`
|
|
776
|
+
- Type: int | float
|
|
777
|
+
- What: The circuity to apply to the distance calculation if distance is None
|
|
778
|
+
- Default: 1
|
|
779
|
+
"""
|
|
780
|
+
assert isinstance(
|
|
781
|
+
origin_coord_dict, dict
|
|
782
|
+
), "Origin node must be a dictionary"
|
|
783
|
+
assert isinstance(
|
|
784
|
+
destination_coord_dict, dict
|
|
785
|
+
), "Destination node must be a dictionary"
|
|
786
|
+
assert (
|
|
787
|
+
"latitude" in origin_coord_dict.keys()
|
|
788
|
+
), "Origin node must have a latitude"
|
|
789
|
+
assert (
|
|
790
|
+
"longitude" in origin_coord_dict.keys()
|
|
791
|
+
), "Origin node must have a longitude"
|
|
792
|
+
assert (
|
|
793
|
+
"latitude" in destination_coord_dict.keys()
|
|
794
|
+
), "Destination node must have a latitude"
|
|
795
|
+
assert (
|
|
796
|
+
"longitude" in destination_coord_dict.keys()
|
|
797
|
+
), "Destination node must have a longitude"
|
|
798
|
+
assert (
|
|
799
|
+
origin_coord_dict["latitude"] >= -90
|
|
800
|
+
and origin_coord_dict["latitude"] <= 90
|
|
801
|
+
), "Origin latitude must be between -90 and 90"
|
|
802
|
+
assert (
|
|
803
|
+
origin_coord_dict["longitude"] >= -180
|
|
804
|
+
and origin_coord_dict["longitude"] <= 180
|
|
805
|
+
), "Origin longitude must be between -180 and 180"
|
|
806
|
+
assert (
|
|
807
|
+
destination_coord_dict["latitude"] >= -90
|
|
808
|
+
and destination_coord_dict["latitude"] <= 90
|
|
809
|
+
), "Destination latitude must be between -90 and 90"
|
|
810
|
+
assert (
|
|
811
|
+
destination_coord_dict["longitude"] >= -180
|
|
812
|
+
and destination_coord_dict["longitude"] <= 180
|
|
813
|
+
), "Destination longitude must be between -180 and 180"
|
|
814
|
+
origin_node = [
|
|
815
|
+
origin_coord_dict["latitude"],
|
|
816
|
+
origin_coord_dict["longitude"],
|
|
817
|
+
]
|
|
818
|
+
destination_node = [
|
|
819
|
+
destination_coord_dict["latitude"],
|
|
820
|
+
destination_coord_dict["longitude"],
|
|
821
|
+
]
|
|
822
|
+
closest_origin_idx = self.geokdtree.closest_idx(point=origin_node)
|
|
823
|
+
closest_destination_idx = self.geokdtree.closest_idx(
|
|
824
|
+
point=destination_node
|
|
825
|
+
)
|
|
826
|
+
if distance is None:
|
|
827
|
+
distance = (
|
|
828
|
+
haversine(
|
|
829
|
+
self.nodes[closest_origin_idx],
|
|
830
|
+
self.nodes[closest_destination_idx],
|
|
831
|
+
)
|
|
832
|
+
* circuity
|
|
833
|
+
)
|
|
834
|
+
self.add_edge(
|
|
835
|
+
origin_id=closest_origin_idx,
|
|
836
|
+
destination_id=closest_destination_idx,
|
|
837
|
+
distance=distance,
|
|
838
|
+
symmetric=symmetric,
|
|
839
|
+
)
|
|
840
|
+
|
|
740
841
|
def add_coord_node(
|
|
741
842
|
self,
|
|
742
843
|
coord_dict: dict[str, float | int],
|
|
@@ -819,7 +920,7 @@ class GeoGraphModifiers:
|
|
|
819
920
|
), "Longitude must be between -180 and 180"
|
|
820
921
|
node = [coord_dict["latitude"], coord_dict["longitude"]]
|
|
821
922
|
if auto_edge:
|
|
822
|
-
assert circuity
|
|
923
|
+
assert circuity >= 1, "Circuity must be greater than or equal to 1"
|
|
823
924
|
assert node_addition_type in [
|
|
824
925
|
"quadrant",
|
|
825
926
|
"all",
|
|
@@ -901,8 +1002,8 @@ class GeoGraphModifiers:
|
|
|
901
1002
|
self.graph_object.graph
|
|
902
1003
|
), "Destination node does not exist"
|
|
903
1004
|
self.add_edge(
|
|
904
|
-
|
|
905
|
-
|
|
1005
|
+
origin_id=origin_idx,
|
|
1006
|
+
destination_id=destination_idx,
|
|
906
1007
|
distance=haversine(
|
|
907
1008
|
self.nodes[origin_idx], self.nodes[destination_idx]
|
|
908
1009
|
),
|
|
@@ -1950,7 +2051,7 @@ class GeoGraph(
|
|
|
1950
2051
|
"You can ensure a solution by setting destination_node_addition_type='all' and setting your lat_lon_bound=180.\n"
|
|
1951
2052
|
"This will, however, result in a much longer runtime per shortest path query.\n"
|
|
1952
2053
|
"If not in an exception block, see the stacktrace below for more details:\n"
|
|
1953
|
-
|
|
2054
|
+
),
|
|
1954
2055
|
silent=silent,
|
|
1955
2056
|
)
|
|
1956
2057
|
raise e
|
|
@@ -344,6 +344,13 @@ def time_test(name, function, args=None, kwargs=None):
|
|
|
344
344
|
print(f"{name}: {round((time.time()-start)*1000, 4)}ms")
|
|
345
345
|
|
|
346
346
|
|
|
347
|
+
def has_cpp():
|
|
348
|
+
try:
|
|
349
|
+
return True
|
|
350
|
+
except ImportError:
|
|
351
|
+
return False
|
|
352
|
+
|
|
353
|
+
|
|
347
354
|
def cpp_check():
|
|
348
355
|
try:
|
|
349
356
|
print("Using C++ & Python implementation of SCGraph.")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|