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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use error::Error;
use client::Client;
use response::Response;
use std::collections::HashMap;
#[derive(Debug, Deserialize)]
pub struct Point {
pub coordinates: Vec<f64>,
}
#[derive(Debug, Deserialize, Serialize, PartialEq, Clone, Copy)]
pub enum EntityType {
Address,
Neighborhood,
PopulatedPlace,
Postcode1,
AdminDivision1,
AdminDivision2,
CountryRegion,
}
#[derive(Debug, Deserialize)]
pub struct Address {
#[serde(rename = "addressLine")]
pub address_line: Option<String>,
#[serde(rename = "neighborhood")]
pub neighborhood: Option<String>,
#[serde(rename = "locality")]
pub locality: Option<String>,
#[serde(rename = "postalCode")]
pub postal_code: Option<String>,
#[serde(rename = "adminDistrict")]
pub admin_district1: Option<String>,
#[serde(rename = "adminDistrict2")]
pub admin_district2: Option<String>,
#[serde(rename = "countryRegion")]
pub country: Option<String>,
#[serde(rename = "countryRegionIso2")]
pub country_iso: Option<String>,
#[serde(rename = "landmark")]
pub landmark: Option<String>,
#[serde(rename = "formattedAddress")]
pub formatted: Option<String>,
}
#[derive(Debug, Deserialize, PartialEq, Clone, Copy)]
pub enum Confidence {
High,
Medium,
Low,
}
#[derive(Debug, Deserialize, PartialEq, Clone, Copy)]
pub enum MatchCode {
Good,
Ambiguous,
UpHeirarchy,
}
#[derive(Default, Serialize)]
pub struct FindPoint {
pub point: String,
pub include_entity_types: Vec<EntityType>,
pub include_neighborhood: bool,
pub include_ciso2: bool,
}
impl FindPoint {
pub fn from_latlng(lat: f64, lng: f64) -> FindPoint {
let mut params = FindPoint::default();
params.point = format!("{:.5},{:.5}", lat, lng);
params
}
pub fn from_str(latlng: &str) -> FindPoint {
let mut params = FindPoint::default();
params.point = latlng.to_owned();
params
}
}
#[derive(Debug, Deserialize)]
pub struct Location {
pub name: String,
pub point: Point,
pub bbox: Vec<f64>,
#[serde(rename = "entityType")]
pub entity_type: EntityType,
pub address: Address,
pub confidence: Confidence,
#[serde(rename = "matchCodes")]
pub match_codes: Vec<MatchCode>,
}
impl Location {
pub fn find_by_point(client: &Client, find: FindPoint) -> Result<Vec<Location>, Error> {
let path = format!("/Locations/{}", find.point);
let entity_types: String;
let mut params = HashMap::<&str, &str>::new();
if find.include_entity_types.len() > 0 {
let types: Vec<String> = find.include_entity_types.iter().map(|el| format!("{:?}", el)).collect();
entity_types = types.join(",");
params.insert("include_entity_types", &entity_types);
}
if find.include_neighborhood {
params.insert("inclnb", "1");
}
if find.include_ciso2 {
params.insert("incl", "ciso2");
}
let response: Response<Location> = client.get(&path, &mut params)?;
let resource_set = response.resource_sets.into_iter().next();
if let Some(set) = resource_set {
Ok(set.resources)
} else {
Ok(Vec::new())
}
}
pub fn find_by_query(client: &Client, query: &str) -> Result<Vec<Location>, Error> {
let mut params = HashMap::new();
params.insert("q", query);
let response: Response<Location> = client.get("/Locations", &mut params)?;
let resource_set = response.resource_sets.into_iter().next();
if let Some(set) = resource_set {
Ok(set.resources)
} else {
Ok(Vec::new())
}
}
}