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
/// Common metadata for an element
///
/// [Openstreetmap wiki](https://wiki.openstreetmap.org/wiki/Elements#Common_attributes)
#[derive(Debug, PartialEq, Clone)]
pub struct ElementMetadata {
  pub id: i64,

  /// The display name of the user who last modified the object; exclusively informative and may be empty.
  /// A user can change their display name at any time (existing elements will reflect the new user name without needing any version change).
  pub user: String,

  /// The user-id of the user who last modified the object.
  pub uid: u64,

  /// The version of the object; newly created objects start at version 1 and the value
  /// is incremented by the server when a client uploads a new version of the object.
  pub version: u32,

  /// The changeset number in which the object was created or last updated.
  pub changeset: u64,

  /// Time of the last modification,
  /// encoded in any [W3C standard date and time format](https://www.w3.org/TR/NOTE-datetime)
  pub timestamp: String,
}

/// A single point in space defined by its latitude, longitude and node id.
///
/// [Openstreetmap wiki](https://wiki.openstreetmap.org/wiki/Node)
#[derive(Debug, PartialEq, Clone)]
pub struct Node {
  pub lat: f64,
  pub lon: f64,
  pub metadata: ElementMetadata,
  pub tags: Vec<Tag>,
}

/// A way is an ordered list of nodes which normally also has at least one tag or is included within a Relation.
/// It can be open or closed, a closed way is one whose last nodes on the way is also the first on that way.
/// A closed way may be interpreted as a closed polyline, a polygon, or both.
///
/// [Openstreetmap wiki](https://wiki.openstreetmap.org/wiki/Way)
///
/// Note that this library does not impose any upper limit for the size of a way, as the 2000-node-limit is considered an API limit
#[derive(Debug, PartialEq, Clone)]
pub struct Way {
  pub nodes: Vec<ReferencedNode>,
  pub metadata: ElementMetadata,
  pub tags: Vec<Tag>,
}

/// A collection of Elements
///
/// [Openstreetmap wiki](https://wiki.openstreetmap.org/wiki/Relation)
#[derive(Debug, PartialEq, Clone)]
pub struct Relation {
  pub members: Vec<RelationMember>,
  pub metadata: ElementMetadata,
  pub tags: Vec<Tag>,
}

/// A reference to a Node, by wrapping it's `id`.
#[derive(Debug, PartialEq, Clone)]
pub struct ReferencedNode {
  pub id: i64,
}

/// A key value pair.
///
/// [Openstreetmap wiki](https://wiki.openstreetmap.org/wiki/Tags)
#[derive(Debug, PartialEq, Clone)]
pub struct Tag {
  pub key: String,
  pub value: String
}

/// A reference to an element, by wrapping it's `id`.
#[derive(Debug, PartialEq, Clone)]
pub enum ReferencedElement {
  Node(i64),
  Way(i64),
  Relation(i64)
}

/// An entry from a Relation which references another element by id and role.
#[derive(Debug, PartialEq, Clone)]
pub struct RelationMember {
  pub role: String,
  pub element: ReferencedElement,
}

#[derive(Debug, PartialEq, Clone)]
pub enum Element {
  Node(Node),
  Way(Way),
  Relation(Relation),
}

impl Element {
  pub fn metadata(&self) -> &ElementMetadata {
    match self {
      Element::Node(me) => &me.metadata,
      Element::Way(me) => &me.metadata,
      Element::Relation(me) => &me.metadata,
    }
  }
}

impl From<Node> for Element {
  fn from(node: Node) -> Element {
    Element::Node(node)
  }
}

impl From<Way> for Element {
  fn from(way: Way) -> Element {
    Element::Way(way)
  }
}

impl From<Relation> for Element {
  fn from(relation: Relation) -> Element {
    Element::Relation(relation)
  }
}