Skip to content

Commit 6a57157

Browse files
committed
Add convert mode gml-to-ewkb
1 parent 4c36dda commit 6a57157

File tree

1 file changed

+134
-19
lines changed

1 file changed

+134
-19
lines changed

src/main.rs

Lines changed: 134 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,30 @@ struct Column<'a> {
1313
name: String,
1414
path: String,
1515
value: String,
16+
convert: Option<&'a str>,
1617
search: Option<&'a str>,
1718
replace: Option<&'a str>,
18-
raw: bool
19+
}
20+
21+
struct Geometry {
22+
gtype: u8,
23+
srid: u32,
24+
num: u32,
25+
pos: Vec<f64>
26+
}
27+
28+
fn geom_to_ewkb(geom: Geometry) -> Vec<u8> {
29+
let mut ewkb = Vec::new();
30+
ewkb.push(1);
31+
ewkb.push(geom.gtype);
32+
ewkb.push(0);
33+
ewkb.push(0);
34+
ewkb.push(32);
35+
ewkb.extend_from_slice(&geom.srid.to_le_bytes());
36+
for pos in geom.pos.iter() {
37+
ewkb.extend_from_slice(&pos.to_le_bytes());
38+
}
39+
return ewkb;
1940
}
2041

2142
fn main() {
@@ -44,26 +65,88 @@ fn main() {
4465

4566
for col in colspec {
4667
let name = col["name"].as_str().expect("Column has no 'name' entry in configuration file");
68+
let colpath = col["path"].as_str().expect("Column has no 'path' entry in configuration file");
69+
let convert = col["convert"].as_str();
4770
let search = col["search"].as_str();
4871
let replace = col["replace"].as_str();
49-
let mut raw = false;
50-
if !col["raw"].is_badvalue() { raw = col["raw"].as_bool().unwrap() }
51-
let colpath = col["path"].as_str().unwrap();
52-
// if search != None && replace != None { eprintln!("Column name {} search {} replace {}", name, search.unwrap(), replace.unwrap()); }
5372
let mut path = String::from(rowpath);
5473
path.push_str(colpath);
55-
columns.push(Column { name: name.to_string(), path, value: String::new(), search, replace, raw });
74+
columns.push(Column { name: name.to_string(), path, value: String::new(), convert, search, replace });
5675
}
5776

58-
let mut raw = false;
59-
let mut rawstr = String::new();
77+
let mut xmltotext = false;
78+
let mut text = String::new();
79+
let mut gmltoewkb = false;
80+
let mut gmlsrid: u32 = 4326;
81+
let mut gmlrings: u32 = 0;
82+
let mut gmldims: u8 = 2;
83+
let mut gmlpos = false;
84+
let mut gmlposlist: Vec<f64> = Vec::new();
85+
let mut ewkb: Vec<u8> = vec![1];
6086
loop {
6187
match reader.read_event(&mut buf) {
6288
Ok(Event::Start(ref e)) => {
6389
path.push('/');
6490
path.push_str(reader.decode(e.name()).unwrap());
65-
if raw {
66-
rawstr.push_str(&format!("<{}>", &e.unescape_and_decode(&reader).unwrap()));
91+
if xmltotext {
92+
text.push_str(&format!("<{}>", &e.unescape_and_decode(&reader).unwrap()));
93+
continue;
94+
}
95+
else if gmltoewkb {
96+
for res in e.attributes() {
97+
match res {
98+
Err(_) => (),
99+
Ok(attr) => {
100+
let key = reader.decode(attr.key);
101+
match key {
102+
Ok("srsName") => {
103+
let mut value = String::from(reader.decode(&attr.value).unwrap());
104+
if let Some(i) = value.rfind("::") {
105+
value = value.split_off(i+2);
106+
}
107+
match value.parse::<u32>() {
108+
Ok(int) => gmlsrid = int,
109+
Err(_) => eprintln!("Invalid srsName {} in GML", value)
110+
}
111+
},
112+
Ok("srsDimension") => {
113+
let value = reader.decode(&attr.value).unwrap();
114+
match value.parse::<u8>() {
115+
Ok(int) => gmldims = int,
116+
Err(_) => eprintln!("Invalid srsDimension {} in GML", value)
117+
}
118+
}
119+
_ => ()
120+
}
121+
}
122+
}
123+
}
124+
match reader.decode(e.name()) {
125+
Err(_) => (),
126+
Ok(tag) => match tag {
127+
"gml:Point" => ewkb.push(1),
128+
"gml:LineString" => ewkb.push(2),
129+
"gml:Polygon" => ewkb.push(3),
130+
"gml:exterior" => (),
131+
"gml:LinearRing" => gmlrings += 1,
132+
"gml:posList" => {
133+
gmlpos = true;
134+
ewkb.push(0);
135+
ewkb.push(0);
136+
let code = match gmldims {
137+
2 => 32,
138+
3 => 32 | 128,
139+
_ => {
140+
eprintln!("GML number of dimensions {} not supported", gmldims);
141+
32
142+
}
143+
};
144+
ewkb.push(code);
145+
ewkb.extend_from_slice(&gmlsrid.to_le_bytes());
146+
}
147+
_ => eprintln!("GML type {} not supported", tag)
148+
}
149+
}
67150
continue;
68151
}
69152
else if path == rowpath {
@@ -72,15 +155,29 @@ fn main() {
72155
else if path.len() > rowpath.len() {
73156
for i in 0..columns.len() {
74157
if path == columns[i].path {
75-
if columns[i].raw { raw = true; }
158+
match columns[i].convert {
159+
None => (),
160+
Some("xml-to-text") => xmltotext = true,
161+
Some("gml-to-ewkb") => gmltoewkb = true,
162+
Some(_) => (),
163+
}
76164
break;
77165
}
78166
}
79167
}
80168
},
81169
Ok(Event::Text(ref e)) => {
82-
if raw {
83-
rawstr.push_str(&e.unescape_and_decode(&reader).unwrap());
170+
if xmltotext {
171+
text.push_str(&e.unescape_and_decode(&reader).unwrap());
172+
continue;
173+
}
174+
else if gmltoewkb {
175+
if gmlpos {
176+
let value = String::from(&e.unescape_and_decode(&reader).unwrap());
177+
for pos in value.split(' ') {
178+
gmlposlist.push(pos.parse().unwrap());
179+
}
180+
}
84181
continue;
85182
}
86183
for i in 0..columns.len() {
@@ -106,16 +203,34 @@ fn main() {
106203
}
107204
let i = path.rfind('/').unwrap();
108205
let tag = path.split_off(i);
109-
if raw {
110-
rawstr.push_str(&format!("<{}>", tag));
206+
if xmltotext {
207+
text.push_str(&format!("<{}>", tag));
111208
for i in 0..columns.len() {
112209
if path == columns[i].path {
113-
raw = false;
210+
xmltotext = false;
114211
if let (Some(s), Some(r)) = (columns[i].search, columns[i].replace) {
115-
rawstr = rawstr.replace(s, r);
212+
text = text.replace(s, r);
213+
}
214+
columns[i].value.push_str(&text);
215+
text.clear();
216+
break;
217+
}
218+
}
219+
}
220+
else if gmltoewkb {
221+
for i in 0..columns.len() {
222+
if path == columns[i].path {
223+
gmltoewkb = false;
224+
ewkb.extend_from_slice(&gmlrings.to_le_bytes());
225+
ewkb.extend_from_slice(&((gmlposlist.len() as u32)/gmldims as u32).to_le_bytes());
226+
for pos in gmlposlist.iter() {
227+
ewkb.extend_from_slice(&pos.to_le_bytes());
228+
}
229+
for byte in ewkb.iter() {
230+
columns[i].value.push_str(&format!("{:02X}", byte));
116231
}
117-
columns[i].value.push_str(&rawstr);
118-
rawstr.clear();
232+
ewkb.clear();
233+
gmlposlist.clear();
119234
break;
120235
}
121236
}

0 commit comments

Comments
 (0)