Skip to content

Commit a70b1ad

Browse files
committed
31: Graph Export Feature to GraphML
1 parent 597666d commit a70b1ad

File tree

2 files changed

+28
-16
lines changed

2 files changed

+28
-16
lines changed

graphfaker/cli.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from graphfaker.fetchers.osm import OSMGraphFetcher
1010
from graphfaker.fetchers.flights import FlightGraphFetcher
1111
from graphfaker.utils import parse_date_range
12+
import os
1213

1314
app = typer.Typer()
1415

@@ -111,8 +112,11 @@ def gen(
111112
f"Generated flight graph with {g.number_of_nodes()} nodes and {g.number_of_edges()} edges."
112113
)
113114

114-
gf.export_graph(g, export)
115-
logger.info(f"exported graph to {export}, with {g.number_of_nodes()} nodes and {g.number_of_edges()} edges.")
115+
abs_export_path = os.path.abspath(export)
116+
os.makedirs(os.path.dirname(abs_export_path) or ".", exist_ok=True)
117+
118+
gf.export_graph(g, source=fetcher, path=abs_export_path)
119+
logger.info(f"exported graph to {abs_export_path}, with {g.number_of_nodes()} nodes and {g.number_of_edges()} edges.")
116120

117121

118122
if __name__ == "__main__":

graphfaker/core.py

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -319,35 +319,43 @@ def generate_graph(
319319
)
320320
else:
321321
raise ValueError(f"Unknown source '{source}'. Use 'random' or 'osm'.")
322-
323-
def export_graph(self, G: nx.Graph = None, path: str = "graph.graphml"):
322+
323+
def export_graph(self, G: nx.Graph = None, source: str = None, path: str = "graph.graphml"):
324324
"""
325-
Export the graph to a GraphML format.
325+
Export the graph to GraphML format.
326326
327-
args:
328-
G: Optional Networkx graph. If None, uses self.G.
327+
Args:
328+
G: Optional NetworkX graph. If None, uses self.G.
329+
source: Optional string, if "osm" uses osmnx for export.
329330
path: Destination file path for .graphml output.
330-
331+
331332
Notes:
332-
GraphML is useful for visualization in tools like G.V(), Gephi or Cytoscape.
333-
It supports node and edge attributes but may not handle complex types like tuples.
333+
GraphML is useful for visualization in tools like Gephi or Cytoscape.
334+
Node/edge attributes should be simple types (str, int, float).
334335
"""
335336
import os
336337

338+
abs_path = os.path.abspath(path)
339+
os.makedirs(os.path.dirname(abs_path) or ".", exist_ok=True)
340+
337341
if G is None:
338342
G = self.G
339343
if G is None:
340344
raise ValueError("No graph available to export.")
341-
345+
342346
# Sanitize attributes that are not GraphML-friendly
343347
for _, data in G.nodes(data=True):
344348
if 'coordinates' in data and isinstance(data['coordinates'], tuple):
345349
lat, lon = data['coordinates']
346350
data['coordinates'] = f"{lat},{lon}"
347351

348-
# Ensure directory exists
349-
abs_path = os.path.abspath(path)
350-
os.makedirs(os.path.dirname(abs_path) or ".", exist_ok=True)
352+
if source == "osm":
353+
try:
354+
import osmnx as ox
355+
ox.io.save_graphml(G, filepath=abs_path)
356+
except ImportError:
357+
raise ImportError("osmnx is required to export OSM graphs.")
358+
else:
359+
nx.write_graphml(G, abs_path)
351360

352-
nx.write_graphml(G, path)
353-
print(f"✅ Graph exported to: {path}")
361+
print(f"✅ Graph exported to: {abs_path}")

0 commit comments

Comments
 (0)