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
use map_model::{Direction, Lane, LaneType, Map, RoadID};

/// Exports a single road to Streetmix's format, returns the filename
pub fn export(r: RoadID, map: &Map) -> String {
    let path = format!("streetmix_export_{}.json", r.0);
    let street = road(r, map);
    abstio::write_json(path.clone(), &street);
    path
}

fn road(id: RoadID, map: &Map) -> serde_json::Map<String, serde_json::value::Value> {
    let r = map.get_r(id);
    let mut street = serde_json::Map::new();
    street.insert("schemaVersion".to_string(), 24.into());
    // TODO Many more fields

    let mut segments = Vec::new();
    for (l, dir, _) in r.lanes_ltr() {
        segments.push(serde_json::value::Value::Object(lane(map.get_l(l), dir)));
    }
    street.insert(
        "segments".to_string(),
        serde_json::value::Value::Array(segments),
    );

    street
}

fn lane(lane: &Lane, dir: Direction) -> serde_json::Map<String, serde_json::value::Value> {
    let mut segment = serde_json::Map::new();
    segment.insert("id".to_string(), lane.id.to_string().into());
    segment.insert("width".to_string(), lane.width.to_feet().into());

    // TODO I'm taking wild stabs at these values for now. Once I can visualize the results, will
    // iterate on these.
    let (segment_type, variant) = match lane.lane_type {
        LaneType::Driving => match dir {
            Direction::Fwd => ("drive-lane", "inbound|car"),
            Direction::Back => ("drive-lane", "outbound|car"),
        },
        LaneType::Parking => match dir {
            Direction::Fwd => ("parking-lane", "inbound|left"),
            Direction::Back => ("parking-lane", "outbound|right"),
        },
        LaneType::Sidewalk => ("sidewalk", "dense"),
        LaneType::Shoulder => ("sidewalk", "dense"),
        LaneType::Biking => match dir {
            Direction::Fwd => ("bike-lane", "inbound|green|road"),
            Direction::Back => ("bike-lane", "outbound|green|road"),
        },
        LaneType::Bus => match dir {
            Direction::Fwd => ("bus-lane", "inbound|shared"),
            Direction::Back => ("bus-lane", "outbound|shared"),
        },
        LaneType::SharedLeftTurn => ("TODO", "TODO"),
        LaneType::Construction => ("TODO", "TODO"),
        LaneType::LightRail => ("TODO", "TODO"),
        LaneType::Buffer(_) => ("TODO", "TODO"),
    };
    segment.insert("type".to_string(), segment_type.into());
    segment.insert("variant".to_string(), variant.into());

    segment
}