1#[cfg(feature = "serde")]
13use serde::{Deserialize, Serialize};
14use smartstring::alias::String;
15use std::iter::FromIterator;
16use std::ops::{Deref, DerefMut};
17
18#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
23#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
24pub struct Tags(::flat_map::FlatMap<String, String>);
25
26impl Tags {
27 pub fn new() -> Tags {
29 Tags(::flat_map::FlatMap::new())
30 }
31
32 pub fn contains(&self, key: &str, value: &str) -> bool {
34 self.0.get(key).is_some_and(|v| v.as_str() == value)
35 }
36
37 pub fn into_inner(self) -> ::flat_map::FlatMap<String, String> {
39 self.0
40 }
41}
42
43impl Deref for Tags {
44 type Target = ::flat_map::FlatMap<String, String>;
45
46 fn deref(&self) -> &Self::Target {
47 &self.0
48 }
49}
50
51impl DerefMut for Tags {
52 fn deref_mut(&mut self) -> &mut Self::Target {
53 &mut self.0
54 }
55}
56
57impl FromIterator<(String, String)> for Tags {
58 fn from_iter<T: IntoIterator<Item = (String, String)>>(iter: T) -> Self {
59 Tags(iter.into_iter().collect())
60 }
61}
62
63#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Copy)]
65#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
66pub struct NodeId(pub i64);
67
68#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Copy)]
70#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
71pub struct WayId(pub i64);
72
73#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Copy)]
75#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
76pub struct RelationId(pub i64);
77
78#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Copy)]
80#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
81pub enum OsmId {
82 Node(NodeId),
84 Way(WayId),
86 Relation(RelationId),
88}
89
90impl OsmId {
91 pub fn is_node(&self) -> bool {
93 self.node().is_some()
94 }
95 pub fn is_way(&self) -> bool {
97 self.way().is_some()
98 }
99 pub fn is_relation(&self) -> bool {
101 self.relation().is_some()
102 }
103 pub fn node(&self) -> Option<NodeId> {
105 match *self {
106 OsmId::Node(id) => Some(id),
107 _ => None,
108 }
109 }
110 pub fn way(&self) -> Option<WayId> {
112 match *self {
113 OsmId::Way(id) => Some(id),
114 _ => None,
115 }
116 }
117 pub fn relation(&self) -> Option<RelationId> {
119 match *self {
120 OsmId::Relation(id) => Some(id),
121 _ => None,
122 }
123 }
124 pub fn inner_id(&self) -> i64 {
126 match *self {
127 OsmId::Node(n) => n.0,
128 OsmId::Way(n) => n.0,
129 OsmId::Relation(n) => n.0,
130 }
131 }
132}
133
134#[derive(Debug, PartialEq, PartialOrd, Clone)]
136#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
137pub enum OsmObj {
138 Node(Node),
140 Way(Way),
142 Relation(Relation),
144}
145
146impl OsmObj {
147 pub fn tags(&self) -> &Tags {
149 match *self {
150 OsmObj::Node(ref node) => &node.tags,
151 OsmObj::Way(ref way) => &way.tags,
152 OsmObj::Relation(ref rel) => &rel.tags,
153 }
154 }
155 pub fn id(&self) -> OsmId {
157 match *self {
158 OsmObj::Node(ref node) => OsmId::Node(node.id),
159 OsmObj::Way(ref way) => OsmId::Way(way.id),
160 OsmObj::Relation(ref rel) => OsmId::Relation(rel.id),
161 }
162 }
163 pub fn is_node(&self) -> bool {
165 self.node().is_some()
166 }
167 pub fn is_way(&self) -> bool {
169 self.way().is_some()
170 }
171 pub fn is_relation(&self) -> bool {
173 self.relation().is_some()
174 }
175 pub fn node(&self) -> Option<&Node> {
177 match *self {
178 OsmObj::Node(ref n) => Some(n),
179 _ => None,
180 }
181 }
182 pub fn way(&self) -> Option<&Way> {
184 match *self {
185 OsmObj::Way(ref w) => Some(w),
186 _ => None,
187 }
188 }
189 pub fn relation(&self) -> Option<&Relation> {
191 match *self {
192 OsmObj::Relation(ref r) => Some(r),
193 _ => None,
194 }
195 }
196}
197
198#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
202#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
203pub struct Node {
204 pub id: NodeId,
206 pub tags: Tags,
208 pub decimicro_lat: i32,
210 pub decimicro_lon: i32,
212}
213
214impl Node {
215 pub fn lat(&self) -> f64 {
217 self.decimicro_lat as f64 * 1e-7
218 }
219 pub fn lon(&self) -> f64 {
221 self.decimicro_lon as f64 * 1e-7
222 }
223}
224
225#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
229#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
230pub struct Way {
231 pub id: WayId,
233 pub tags: Tags,
235 pub nodes: Vec<NodeId>,
237}
238
239impl Way {
240 pub fn is_open(&self) -> bool {
243 !self.is_closed()
244 }
245 pub fn is_closed(&self) -> bool {
248 self.nodes.first() == self.nodes.last()
249 }
250}
251
252#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
254#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
255pub struct Ref {
256 pub member: OsmId,
258 pub role: String,
260}
261
262#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
266#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
267pub struct Relation {
268 pub id: RelationId,
270 pub tags: Tags,
272 pub refs: Vec<Ref>,
274}
275
276impl ::std::convert::From<NodeId> for OsmId {
277 fn from(n: NodeId) -> Self {
278 OsmId::Node(n)
279 }
280}
281
282impl ::std::convert::From<WayId> for OsmId {
283 fn from(w: WayId) -> Self {
284 OsmId::Way(w)
285 }
286}
287
288impl ::std::convert::From<RelationId> for OsmId {
289 fn from(r: RelationId) -> Self {
290 OsmId::Relation(r)
291 }
292}
293
294impl ::std::convert::From<Node> for OsmObj {
295 fn from(n: Node) -> Self {
296 OsmObj::Node(n)
297 }
298}
299
300impl ::std::convert::From<Way> for OsmObj {
301 fn from(w: Way) -> Self {
302 OsmObj::Way(w)
303 }
304}
305
306impl ::std::convert::From<Relation> for OsmObj {
307 fn from(r: Relation) -> Self {
308 OsmObj::Relation(r)
309 }
310}