sameer-graph-lib 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1,28 @@
1
+ """Public API for sameer_graph_lib."""
2
+
3
+ from .affinity_graph import AffinityGraph
4
+ from .corridor_extractor import CorridorExtractor
5
+ from .geometry import getLatLng, get_latlng, h3_convex_hull, h3_convex_hull_geojson, makingHull, making_hull
6
+ from .hex_graph import HexGraph
7
+ from .plotting import cells_to_geodataframe, plot_h3_cells, plot_h3_cells_map
8
+ from .spatial_ingestor import SpatialIngestor
9
+ from .topology_analyzer import TopologyAnalyzer
10
+
11
+ __all__ = [
12
+ "AffinityGraph",
13
+ "CorridorExtractor",
14
+ "HexGraph",
15
+ "cells_to_geodataframe",
16
+ "getLatLng",
17
+ "get_latlng",
18
+ "h3_convex_hull",
19
+ "h3_convex_hull_geojson",
20
+ "makingHull",
21
+ "making_hull",
22
+ "plot_h3_cells",
23
+ "plot_h3_cells_map",
24
+ "SpatialIngestor",
25
+ "TopologyAnalyzer",
26
+ ]
27
+
28
+ __version__ = "0.1.0"
@@ -0,0 +1,123 @@
1
+ """Small compatibility layer for h3-py 3.x and 4.x APIs."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import math
6
+ from typing import List, Tuple
7
+
8
+ import h3
9
+
10
+ LatLng = Tuple[float, float]
11
+
12
+ EARTH_RADIUS_KM = 6371.0088
13
+
14
+
15
+ def is_valid_cell(cell: str) -> bool:
16
+ fn = getattr(h3, "is_valid_cell", None) or getattr(h3, "h3_is_valid", None)
17
+ return bool(fn(cell)) if fn else False
18
+
19
+
20
+ def latlng_to_cell(lat: float, lng: float, resolution: int) -> str:
21
+ fn = getattr(h3, "latlng_to_cell", None)
22
+ if fn:
23
+ return fn(lat, lng, resolution)
24
+ return h3.geo_to_h3(lat, lng, resolution)
25
+
26
+
27
+ def cell_to_latlng(cell: str) -> LatLng:
28
+ fn = getattr(h3, "cell_to_latlng", None)
29
+ if fn:
30
+ lat, lng = fn(cell)
31
+ else:
32
+ lat, lng = h3.h3_to_geo(cell)
33
+ return float(lat), float(lng)
34
+
35
+
36
+ def cell_to_boundary(cell: str) -> List[LatLng]:
37
+ fn = getattr(h3, "cell_to_boundary", None)
38
+ if fn:
39
+ return [(float(lat), float(lng)) for lat, lng in fn(cell)]
40
+
41
+ legacy_fn = getattr(h3, "h3_to_geo_boundary", None)
42
+ if legacy_fn:
43
+ return [(float(lat), float(lng)) for lat, lng in legacy_fn(cell, geo_json=False)]
44
+
45
+ raise RuntimeError("Installed h3 package does not expose cell boundary helpers.")
46
+
47
+
48
+ def get_resolution(cell: str) -> int:
49
+ fn = getattr(h3, "get_resolution", None) or getattr(h3, "h3_get_resolution", None)
50
+ return int(fn(cell))
51
+
52
+
53
+ def grid_path_cells(start: str, end: str) -> List[str]:
54
+ fn = getattr(h3, "grid_path_cells", None) or getattr(h3, "h3_line", None)
55
+ if not fn:
56
+ raise RuntimeError("Installed h3 package does not expose grid path helpers.")
57
+ return list(fn(start, end))
58
+
59
+
60
+ def average_hexagon_edge_length(resolution: int, unit: str = "km") -> float:
61
+ fn = getattr(h3, "average_hexagon_edge_length", None)
62
+ if fn:
63
+ return float(fn(resolution, unit=unit))
64
+
65
+ fn = getattr(h3, "edge_length", None)
66
+ if fn:
67
+ try:
68
+ return float(fn(resolution, unit=unit))
69
+ except TypeError:
70
+ return float(fn(res=resolution, unit=unit))
71
+
72
+ raise RuntimeError("Installed h3 package does not expose edge length helpers.")
73
+
74
+
75
+ def cell_area(cell: str, unit: str = "km^2") -> float:
76
+ fn = getattr(h3, "cell_area", None)
77
+ if not fn:
78
+ raise RuntimeError("Installed h3 package does not expose cell_area.")
79
+ return float(fn(cell, unit=unit))
80
+
81
+
82
+ def haversine_km(a: LatLng, b: LatLng) -> float:
83
+ lat1, lng1 = map(math.radians, a)
84
+ lat2, lng2 = map(math.radians, b)
85
+ dlat = lat2 - lat1
86
+ dlng = lng2 - lng1
87
+ sin_dlat = math.sin(dlat / 2.0)
88
+ sin_dlng = math.sin(dlng / 2.0)
89
+ h = sin_dlat**2 + math.cos(lat1) * math.cos(lat2) * sin_dlng**2
90
+ return 2.0 * EARTH_RADIUS_KM * math.asin(min(1.0, math.sqrt(h)))
91
+
92
+
93
+ def approximate_grid_distance(start: str, end: str) -> int:
94
+ if start == end:
95
+ return 0
96
+
97
+ resolution = get_resolution(start)
98
+ edge_km = average_hexagon_edge_length(resolution, unit="km")
99
+ center_spacing_km = max(edge_km * math.sqrt(3), 1e-9)
100
+ distance_km = haversine_km(cell_to_latlng(start), cell_to_latlng(end))
101
+ return max(1, int(round(distance_km / center_spacing_km)))
102
+
103
+
104
+ def grid_distance(start: str, end: str) -> int:
105
+ """Return native H3 grid distance between two cells."""
106
+ if start == end:
107
+ return 0
108
+
109
+ fn = getattr(h3, "grid_distance", None)
110
+ if fn:
111
+ try:
112
+ return int(fn(start, end))
113
+ except Exception:
114
+ pass
115
+
116
+ legacy_fn = getattr(h3, "h3_distance", None)
117
+ if legacy_fn:
118
+ try:
119
+ return int(legacy_fn(start, end))
120
+ except Exception:
121
+ pass
122
+
123
+ return approximate_grid_distance(start, end)