#openstreetmap #osm #map #xml-format #io #data #builder

vadeen_osm

Open Street Map 数据的IO和构建库

9 个版本

0.4.2 2020年12月19日
0.4.1 2020年9月27日
0.3.0 2020年2月19日
0.2.1 2020年2月2日
0.1.3 2020年1月31日

科学 中排名 292

每月下载量 25

MIT 许可证

125KB
3K SLoC

VADEEN OSM

Build Status Crate API

VADEEN OSM 是一个用于读取和写入 Open Street Map 文件的库。目前支持 xml 和 o5m。

目标

有很多与 Open Street Map 文件一起工作的 优秀工具,例如可以将 OSM 地图转换为与 GPS 设备兼容格式的 mkgmap

本项目旨在成为一个易于使用的库,用于从其他地图源组成 OSM 地图。例如,在瑞典,Lantmäteriet(瑞典国家土地测量局)提供高质量的 Creative Common 许可的免费地图数据。

本项目的主要目标不是管理 OSM 数据,而是为第三方地图提供访问 OSM 生态系统的途径。本项目旨在完全符合 OSM,因此应该可以管理纯 OSM 地图。

示例

要运行 examples/ 目录中的示例,请运行 cargo build --examples 并在 target/debug/examples/ 目录中查找二进制文件。

简单的读取和写入

use vadeen_osm::osm_io::{read, write};

// Read from file, format is determined from path.
let osm = read("map.osm")?;

// ...render or modify the map.

// Write to file, format is determined from path.
write("map.o5m", &osm)?;

使用构建器创建地图

OsmBuilder 提供了一种抽象,使得从其他地图数据构建地图变得简单。它使用多边形(用于区域)、折线(用于线)和点等术语。

// Create a builder.
let mut builder = OsmBuilder::default();

// Add a polygon to the map.
builder.add_polygon(
    vec![
        vec![
            // Outer polygon
            (66.29, -3.177),
            (66.29, -0.9422),
            (64.43, -0.9422),
            (64.43, -3.177),
            (66.29, -3.177),
        ],
        vec![
            // One inner polygon
            (66.0, -2.25),
            (65.7, -2.5),
            (65.7, -2.0),
            (66.0, -2.25),
        ],
        // Add more inner polygons here.
    ],
    vec![("natural", "water")],
);

// Add polyline to the map.
builder.add_polyline(vec![(66.29, 1.2), (64.43, 1.2)], vec![("power", "line")]);

// Add point
builder.add_point((66.19, 1.3), vec![("power", "tower")]);

// Build into Osm structure.
let osm = builder.build();

// Write to file in the xml format.
write("example_map.osm", &osm)?;

// Write to file in the o5m format.
write("example_map.o5m", &osm)?;

自定义数据

只要实现了正确的 Into 特性,构建器可以处理所有类型的数据。

例如,如果您有一个自定义标签类型 MyTag 和一个自定义坐标类型 MyCoordinate,只要您实现了适当的 Into<Tag>Into<Coordinate>,您就可以与构建器无缝使用它们。

// Your custom tag.
struct MyTag {
    key: String,
    value: String,
}

// Your custom coordinate type.
struct MyCoordinate {
    lat: f64,
    lon: f64,
}

// All you have to do is to implement the Into traits.
impl Into<Coordinate> for MyCoordinate {
    fn into(self) -> Coordinate {
        Coordinate::new(self.lat, self.lon)
    }
}

impl Into<Tag> for MyTag {
    fn into(self) -> Tag {
        Tag {
            key: self.key,
            value: self.value,
        }
    }
}

// Then you can use them with the builder:
let mut builder = OsmBuilder::default();

// Add a polygon to the map.
builder.add_polygon(
    vec![
        vec![
            // Outer polygon
            MyCoordinate::new(66.29, -3.177),
            MyCoordinate::new(66.29, -0.9422),
            MyCoordinate::new(64.43, -0.9422),
            MyCoordinate::new(64.43, -3.177),
            MyCoordinate::new(66.29, -3.177),
        ],
        // Add inner polygons here.
    ],
    vec![MyTag::new("natural", "water")],
);

// Build into Osm structure.
let osm = builder.build();

// Write to file in the xml format.
write("example_map.osm", &osm)?;

不使用构建器创建地图

当不使用构建器时,您必须自己跟踪所有ID。这仅在您处理实际OSM数据或想违反OsmBuilder的规则时推荐。

let mut osm = Osm::default();

// Add a node
osm.add_node(Node {
    id: 1,
    coordinate: (66.29, -3.177).into(),
    meta: Meta {
        tags: vec![("key", "value").into()],
        version: Some(3),
        author: Some(AuthorInformation {
            created: 12345678,
            change_set: 1,
            uid: 1234,
            user: "Username".to_string(),
        }),
    },
});

// Add a way with no tags or nothing.
osm.add_way(Way {
    id: 2,
    refs: vec![1],
    meta: Default::default(),
});

// Add a relation with no tags or nothing.
osm.add_relation(Relation {
    id: 3,
    members: vec![RelationMember::Way(2, "role".to_owned())],
    meta: Default::default(),
});

// ...etc

依赖项

~2.5MB
~40K SLoC