use serde::{Deserialize, Serialize};
use smartstring::alias::String;
use std::iter::FromIterator;
use std::ops::{Deref, DerefMut};
#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct Tags(::flat_map::FlatMap<String, String>);
impl Tags {
pub fn new() -> Tags {
Tags(::flat_map::FlatMap::new())
}
pub fn contains(&self, key: &str, value: &str) -> bool {
self.0.get(key).map_or(false, |v| v.as_str() == value)
}
pub fn into_inner(self) -> ::flat_map::FlatMap<String, String> {
self.0
}
}
impl Deref for Tags {
type Target = ::flat_map::FlatMap<String, String>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for Tags {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl FromIterator<(String, String)> for Tags {
fn from_iter<T: IntoIterator<Item = (String, String)>>(iter: T) -> Self {
Tags(iter.into_iter().collect())
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Copy, Serialize, Deserialize)]
pub struct NodeId(pub i64);
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Copy, Serialize, Deserialize)]
pub struct WayId(pub i64);
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Copy, Serialize, Deserialize)]
pub struct RelationId(pub i64);
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Copy, Serialize, Deserialize)]
pub enum OsmId {
Node(NodeId),
Way(WayId),
Relation(RelationId),
}
impl OsmId {
pub fn is_node(&self) -> bool {
self.node().is_some()
}
pub fn is_way(&self) -> bool {
self.way().is_some()
}
pub fn is_relation(&self) -> bool {
self.relation().is_some()
}
pub fn node(&self) -> Option<NodeId> {
match *self {
OsmId::Node(id) => Some(id),
_ => None,
}
}
pub fn way(&self) -> Option<WayId> {
match *self {
OsmId::Way(id) => Some(id),
_ => None,
}
}
pub fn relation(&self) -> Option<RelationId> {
match *self {
OsmId::Relation(id) => Some(id),
_ => None,
}
}
pub fn inner_id(&self) -> i64 {
match *self {
OsmId::Node(n) => n.0,
OsmId::Way(n) => n.0,
OsmId::Relation(n) => n.0,
}
}
}
#[derive(Debug, PartialEq, PartialOrd, Clone, Serialize, Deserialize)]
pub enum OsmObj {
Node(Node),
Way(Way),
Relation(Relation),
}
impl OsmObj {
pub fn tags(&self) -> &Tags {
match *self {
OsmObj::Node(ref node) => &node.tags,
OsmObj::Way(ref way) => &way.tags,
OsmObj::Relation(ref rel) => &rel.tags,
}
}
pub fn id(&self) -> OsmId {
match *self {
OsmObj::Node(ref node) => OsmId::Node(node.id),
OsmObj::Way(ref way) => OsmId::Way(way.id),
OsmObj::Relation(ref rel) => OsmId::Relation(rel.id),
}
}
pub fn is_node(&self) -> bool {
self.node().is_some()
}
pub fn is_way(&self) -> bool {
self.way().is_some()
}
pub fn is_relation(&self) -> bool {
self.relation().is_some()
}
pub fn node(&self) -> Option<&Node> {
match *self {
OsmObj::Node(ref n) => Some(n),
_ => None,
}
}
pub fn way(&self) -> Option<&Way> {
match *self {
OsmObj::Way(ref w) => Some(w),
_ => None,
}
}
pub fn relation(&self) -> Option<&Relation> {
match *self {
OsmObj::Relation(ref r) => Some(r),
_ => None,
}
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Serialize, Deserialize)]
pub struct Node {
pub id: NodeId,
pub tags: Tags,
pub decimicro_lat: i32,
pub decimicro_lon: i32,
}
impl Node {
pub fn lat(&self) -> f64 {
self.decimicro_lat as f64 * 1e-7
}
pub fn lon(&self) -> f64 {
self.decimicro_lon as f64 * 1e-7
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Serialize, Deserialize)]
pub struct Way {
pub id: WayId,
pub tags: Tags,
pub nodes: Vec<NodeId>,
}
impl Way {
pub fn is_open(&self) -> bool {
!self.is_closed()
}
pub fn is_closed(&self) -> bool {
self.nodes.first() == self.nodes.last()
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Serialize, Deserialize)]
pub struct Ref {
pub member: OsmId,
pub role: String,
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Serialize, Deserialize)]
pub struct Relation {
pub id: RelationId,
pub tags: Tags,
pub refs: Vec<Ref>,
}
impl ::std::convert::From<NodeId> for OsmId {
fn from(n: NodeId) -> Self {
OsmId::Node(n)
}
}
impl ::std::convert::From<WayId> for OsmId {
fn from(w: WayId) -> Self {
OsmId::Way(w)
}
}
impl ::std::convert::From<RelationId> for OsmId {
fn from(r: RelationId) -> Self {
OsmId::Relation(r)
}
}
impl ::std::convert::From<Node> for OsmObj {
fn from(n: Node) -> Self {
OsmObj::Node(n)
}
}
impl ::std::convert::From<Way> for OsmObj {
fn from(w: Way) -> Self {
OsmObj::Way(w)
}
}
impl ::std::convert::From<Relation> for OsmObj {
fn from(r: Relation) -> Self {
OsmObj::Relation(r)
}
}