pysochrone/
lib.rs

1#![allow(dead_code)]
2
3mod graph;
4mod isochrone;
5mod overpass;
6mod utils;
7mod cache;
8
9use pyo3::prelude::*;
10
11/// Calculates isochrones from a point
12#[pyfunction]
13fn calc_isochrones(
14    lat: f64,
15    lon: f64,
16    max_dist: f64,
17    time_limits: Vec<f64>,
18    network_type: String,
19    hull_type: String,
20) -> PyResult<Vec<String>> {
21    // Convert network_type string to NetworkType enum
22    let network_type_enum = match network_type.as_str() {
23        "Drive" => overpass::NetworkType::Drive,
24        "DriveService" => overpass::NetworkType::DriveService,
25        "Walk" => overpass::NetworkType::Walk,
26        "Bike" => overpass::NetworkType::Bike,
27        "All" => overpass::NetworkType::All,
28        "AllPrivate" => overpass::NetworkType::AllPrivate,
29        _ => {
30            return Err(pyo3::PyErr::new::<pyo3::exceptions::PyValueError, _>(
31                "Invalid network type",
32            ))
33        }
34    };
35
36    // Convert hull_type string to HullType enum
37    let hull_type_enum = match hull_type.as_str() {
38        "Convex" => isochrone::HullType::Convex,
39        "FastConcave" => isochrone::HullType::FastConcave,
40        "Concave" => isochrone::HullType::Concave,
41        _ => {
42            return Err(pyo3::PyErr::new::<pyo3::exceptions::PyValueError, _>(
43                "Invalid hull type",
44            ))
45        }
46    };
47
48    // Create a new Tokio runtime
49    let rt = tokio::runtime::Runtime::new().unwrap();
50    let isochrones = rt
51        .block_on(isochrone::calculate_isochrones_from_point(
52            lat,
53            lon,
54            max_dist,
55            time_limits,
56            network_type_enum,
57            hull_type_enum,
58        ))
59        .unwrap();
60
61    // Convert from Geo::Polygon to GeoJSON string
62    let mut isochrones_converted = Vec::new();
63    for isochrone in isochrones {
64        let converted = utils::polygon_to_geojson_string(&isochrone);
65        isochrones_converted.push(converted);
66    }
67
68    Ok(isochrones_converted)
69}
70
71/// Calculates a reverse isochrones from a point
72#[pyfunction]
73fn calc_reverse_isochrones(
74    lat: f64,
75    lon: f64,
76    max_dist: f64,
77    time_limits: Vec<f64>,
78    network_type: String,
79    hull_type: String,
80) -> PyResult<Vec<String>> {
81    // Convert network_type string to NetworkType enum
82    let network_type_enum = match network_type.as_str() {
83        "Drive" => overpass::NetworkType::Drive,
84        "DriveService" => overpass::NetworkType::DriveService,
85        "Walk" => overpass::NetworkType::Walk,
86        "Bike" => overpass::NetworkType::Bike,
87        "All" => overpass::NetworkType::All,
88        "AllPrivate" => overpass::NetworkType::AllPrivate,
89        _ => {
90            return Err(pyo3::PyErr::new::<pyo3::exceptions::PyValueError, _>(
91                "Invalid network type",
92            ))
93        }
94    };
95
96    // Convert hull_type string to HullType enum
97    let hull_type_enum = match hull_type.as_str() {
98        "Convex" => isochrone::HullType::Convex,
99        "Concave" => isochrone::HullType::Concave,
100        _ => {
101            return Err(pyo3::PyErr::new::<pyo3::exceptions::PyValueError, _>(
102                "Invalid hull type",
103            ))
104        }
105    };
106
107    // Create a new Tokio runtime
108    let rt = tokio::runtime::Runtime::new().unwrap();
109    let isochrones = rt
110        .block_on(isochrone::calculate_reverse_isochrones_from_point(
111            lat,
112            lon,
113            max_dist,
114            time_limits,
115            network_type_enum,
116            hull_type_enum,
117        ))
118        .unwrap();
119
120    // Convert from Geo::Polygon to GeoJSON string
121    let mut isochrones_converted = Vec::new();
122    for isochrone in isochrones {
123        let converted = utils::polygon_to_geojson_string(&isochrone);
124        isochrones_converted.push(converted);
125    }
126
127    Ok(isochrones_converted)
128}
129
130/// Python module for quickly creating isochrones
131#[pymodule]
132fn pysochrone(_py: Python, m: &PyModule) -> pyo3::PyResult<()> {
133    m.add_function(wrap_pyfunction!(calc_isochrones, m)?)?;
134    m.add_function(wrap_pyfunction!(calc_reverse_isochrones, m)?)?;
135    Ok(())
136}
137