@@ -13,9 +13,30 @@ struct Column<'a> {
13
13
name : String ,
14
14
path : String ,
15
15
value : String ,
16
+ convert : Option < & ' a str > ,
16
17
search : Option < & ' a str > ,
17
18
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;
19
40
}
20
41
21
42
fn main ( ) {
@@ -44,26 +65,88 @@ fn main() {
44
65
45
66
for col in colspec {
46
67
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 ( ) ;
47
70
let search = col[ "search" ] . as_str ( ) ;
48
71
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()); }
53
72
let mut path = String :: from ( rowpath) ;
54
73
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 } ) ;
56
75
}
57
76
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 ] ;
60
86
loop {
61
87
match reader. read_event ( & mut buf) {
62
88
Ok ( Event :: Start ( ref e) ) => {
63
89
path. push ( '/' ) ;
64
90
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
+ }
67
150
continue ;
68
151
}
69
152
else if path == rowpath {
@@ -72,15 +155,29 @@ fn main() {
72
155
else if path. len ( ) > rowpath. len ( ) {
73
156
for i in 0 ..columns. len ( ) {
74
157
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
+ }
76
164
break ;
77
165
}
78
166
}
79
167
}
80
168
} ,
81
169
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
+ }
84
181
continue ;
85
182
}
86
183
for i in 0 ..columns. len ( ) {
@@ -106,16 +203,34 @@ fn main() {
106
203
}
107
204
let i = path. rfind ( '/' ) . unwrap ( ) ;
108
205
let tag = path. split_off ( i) ;
109
- if raw {
110
- rawstr . push_str ( & format ! ( "<{}>" , tag) ) ;
206
+ if xmltotext {
207
+ text . push_str ( & format ! ( "<{}>" , tag) ) ;
111
208
for i in 0 ..columns. len ( ) {
112
209
if path == columns[ i] . path {
113
- raw = false ;
210
+ xmltotext = false ;
114
211
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) ) ;
116
231
}
117
- columns [ i ] . value . push_str ( & rawstr ) ;
118
- rawstr . clear ( ) ;
232
+ ewkb . clear ( ) ;
233
+ gmlposlist . clear ( ) ;
119
234
break ;
120
235
}
121
236
}
0 commit comments