cli/
one_step_import.rs

1use anyhow::Result;
2
3use abstio::CityName;
4use geom::LonLat;
5
6pub async fn run(
7    geojson_path: String,
8    name: String,
9    use_geofabrik: bool,
10    use_osmium: bool,
11    options: convert_osm::Options,
12    create_uk_travel_demand_model: bool,
13    opts: map_model::RawToMapOptions,
14) -> Result<()> {
15    if name.contains(' ') || name.is_empty() {
16        panic!(
17            "--map_name must be non-empty and contain no spaces: {}",
18            name
19        );
20    }
21
22    let city = CityName::new("zz", "oneshot");
23    let osm;
24    if !use_geofabrik {
25        println!("Downloading OSM data from Overpass...");
26        osm = city.input_path(format!("osm/{}.osm", name));
27
28        let geojson = abstio::slurp_file(geojson_path.clone())?;
29        let mut polygons = LonLat::parse_geojson_polygons(String::from_utf8(geojson)?)?;
30        let mut filter = "poly:\"".to_string();
31        for pt in polygons.pop().unwrap().0 {
32            filter.push_str(&format!("{} {} ", pt.y(), pt.x()));
33        }
34        filter.pop();
35        filter.push('"');
36        // See https://wiki.openstreetmap.org/wiki/Overpass_API/Overpass_QL
37        let query = format!(
38            "(\n   nwr({});\n     node(w)->.x;\n   <;\n);\nout meta;\n",
39            filter
40        );
41        abstio::download_to_file("https://overpass-api.de/api/interpreter", Some(query), &osm)
42            .await?;
43    } else {
44        println!("Figuring out what Geofabrik file contains your boundary");
45        let (url, pbf) = importer::pick_geofabrik(geojson_path.clone()).await?;
46        osm = city.input_path(format!("osm/{}.osm.pbf", name));
47        fs_err::create_dir_all(std::path::Path::new(&pbf).parent().unwrap())
48            .expect("Creating parent dir failed");
49        fs_err::create_dir_all(std::path::Path::new(&osm).parent().unwrap())
50            .expect("Creating parent dir failed");
51
52        // Download it!
53        // TODO This is timing out. Also, really could use progress bars.
54        if !abstio::file_exists(&pbf) {
55            println!("Downloading {}", url);
56            abstio::download_to_file(url, None, &pbf).await?;
57        }
58
59        // Clip it
60        println!("Clipping {pbf} to your boundary");
61        if use_osmium {
62            importer::osmium(
63                pbf,
64                geojson_path.clone(),
65                osm.clone(),
66                &importer::ImporterConfiguration::load(),
67            );
68        } else {
69            crate::clip_osm::run(pbf, geojson_path.clone(), osm.clone())?;
70        }
71    }
72
73    // Import!
74    println!("Running importer");
75    importer::oneshot(
76        osm,
77        Some(geojson_path),
78        options,
79        create_uk_travel_demand_model,
80        opts,
81    )
82    .await;
83
84    Ok(())
85}