1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
//! Export module for the OpenRailwayMap Exporter.
//!
//! This module provides functions to generate a DOT or SVG string representation of a RailwayGraph.
//! The generated strings can be used to visualize the railway infrastructure data.
pub use crate::exporter::svg::generate_svg_string;
use crate::prelude::RailwayGraph;
use petgraph::dot::{Config, Dot};
use std::error::Error;
/// Generates a DOT string representation of a given RailwayGraph.
///
/// The DOT string can be used to visualize the graph using tools like Graphviz.
///
/// # Arguments
///
/// * `graph` - A reference to a RailwayGraph.
///
/// # Returns
///
/// A `Result` containing a DOT-formatted `String` on success, or a `Box<dyn Error>` on failure.
///
/// # Example
///
/// ```
/// use openrailwaymap_exporter::importer::overpass_importer::RailwayElement;
/// use openrailwaymap_exporter::prelude::generate_dot_string;
/// use openrailwaymap_exporter::importer::overpass_importer::from_railway_elements;
///
/// let elements = vec![
/// RailwayElement::new_with_id(1),
/// RailwayElement::new_with_id(2),
/// ];
///
/// let railway_graph = from_railway_elements(&elements);
/// let dot_string = generate_dot_string(&railway_graph).unwrap();
///
/// println!("{}", dot_string);
/// ```
pub fn generate_dot_string(graph: &RailwayGraph) -> Result<String, Box<dyn Error>> {
let dot = Dot::with_config(&graph.physical_graph.graph, &[Config::EdgeNoLabel]);
Ok(format!("{:?}", dot))
}
#[cfg(test)]
mod tests {
use std::collections::HashMap;
use crate::importer::overpass_importer::{
from_railway_elements, Coordinate, ElementType, RailwayElement,
};
use super::*;
#[test]
fn test_generate_dot_string() {
let elements = vec![
RailwayElement {
id: 1,
element_type: ElementType::Way,
lat: None,
lon: None,
tags: None,
nodes: Some(vec![2, 3]),
geometry: Some(vec![
Coordinate {
lat: 50.0,
lon: 8.0,
},
Coordinate {
lat: 51.0,
lon: 9.0,
},
]),
},
RailwayElement {
id: 2,
element_type: ElementType::Node,
lat: Some(50.0),
lon: Some(8.0),
tags: None,
nodes: None,
geometry: None,
},
RailwayElement {
id: 3,
element_type: ElementType::Node,
lat: Some(51.0),
lon: Some(9.0),
tags: None,
nodes: None,
geometry: None,
},
];
let railway_graph = from_railway_elements(&elements);
let dot_string = generate_dot_string(&railway_graph).unwrap();
println!("{}", &dot_string);
assert!(dot_string.contains("graph {"));
assert!(dot_string.contains(
"0 [ label = \"TransitNode { id: 2, location: Coord { x: 8.0, y: 50.0 } }\" ]"
));
assert!(dot_string.contains(
"1 [ label = \"TransitNode { id: 3, location: Coord { x: 9.0, y: 51.0 } }\" ]"
));
assert!(dot_string.contains("0 -- 1 [ ]"));
assert!(dot_string.contains('}'));
}
#[test]
fn test_generate_svg_string() {
let elements = vec![
RailwayElement {
id: 1,
element_type: ElementType::Node,
lat: Some(50.1109),
lon: Some(8.6821),
tags: Some(HashMap::new()),
nodes: None,
geometry: None,
},
RailwayElement {
id: 2,
element_type: ElementType::Node,
lat: Some(50.1122),
lon: Some(8.6833),
tags: Some(HashMap::new()),
nodes: None,
geometry: None,
},
RailwayElement {
id: 3,
element_type: ElementType::Way,
lat: None,
lon: None,
tags: Some(HashMap::new()),
nodes: Some(vec![1, 2]),
geometry: Some(vec![
Coordinate {
lat: 50.1109,
lon: 8.6821,
},
Coordinate {
lat: 50.1122,
lon: 8.6833,
},
]),
},
];
let railway_graph = from_railway_elements(&elements);
let svg_string = generate_svg_string(&railway_graph).unwrap();
assert!(svg_string.contains("<svg"));
assert!(svg_string.contains("</svg>"));
assert!(svg_string.contains("<circle"));
assert!(svg_string.contains("<path"));
}
}