@@ -71,36 +71,39 @@ struct Geometry {
71
71
rings : Vec < Vec < f64 > >
72
72
}
73
73
impl Geometry {
74
- fn new ( ) -> Geometry {
75
- Geometry { gtype : 0 , dims : 2 , srid : 4326 , rings : Vec :: new ( ) }
76
- }
77
- fn reset ( & mut self ) {
78
- self . gtype = 0 ;
79
- self . dims = 2 ;
80
- self . srid = 4326 ;
81
- self . rings . clear ( ) ;
74
+ fn new ( gtype : u8 ) -> Geometry {
75
+ Geometry { gtype, dims : 2 , srid : 4326 , rings : Vec :: new ( ) }
82
76
}
83
77
}
84
78
85
- fn gml_to_ewkb ( cell : & RefCell < String > , geom : & Geometry ) {
86
- let mut ewkb = vec ! [ 1 , geom. gtype, 0 , 0 ] ;
87
- let code = match geom. dims {
88
- 2 => 32 ,
89
- 3 => 32 | 128 ,
90
- _ => {
91
- eprintln ! ( "GML number of dimensions {} not supported" , geom. dims) ;
92
- 32
93
- }
94
- } ;
95
- ewkb. push ( code) ;
96
- ewkb. extend_from_slice ( & geom. srid . to_le_bytes ( ) ) ;
97
- ewkb. extend_from_slice ( & ( geom. rings . len ( ) as u32 ) . to_le_bytes ( ) ) ;
98
- for ring in geom. rings . iter ( ) {
99
- ewkb. extend_from_slice ( & ( ( ring. len ( ) as u32 ) /geom. dims as u32 ) . to_le_bytes ( ) ) ;
100
- for pos in ring. iter ( ) {
101
- ewkb. extend_from_slice ( & pos. to_le_bytes ( ) ) ;
79
+ fn gml_to_ewkb ( cell : & RefCell < String > , coll : & Vec < Geometry > ) {
80
+ let mut ewkb: Vec < u8 > = vec ! [ ] ;
81
+
82
+ // if coll.len() > 1 {
83
+ ewkb. extend_from_slice ( & [ 1 , 6 , 0 , 0 , 0 ] ) ;
84
+ ewkb. extend_from_slice ( & ( coll. len ( ) as u32 ) . to_le_bytes ( ) ) ;
85
+ // }
86
+
87
+ for geom in coll {
88
+ let code = match geom. dims {
89
+ 2 => 32 , // Indicate EWKB where the srid follows this byte
90
+ 3 => 32 | 128 , // Add bit to indicate the presense of Z values
91
+ _ => {
92
+ eprintln ! ( "GML number of dimensions {} not supported" , geom. dims) ;
93
+ 32
94
+ }
95
+ } ;
96
+ ewkb. extend_from_slice ( & [ 1 , geom. gtype , 0 , 0 , code] ) ;
97
+ ewkb. extend_from_slice ( & geom. srid . to_le_bytes ( ) ) ;
98
+ ewkb. extend_from_slice ( & ( geom. rings . len ( ) as u32 ) . to_le_bytes ( ) ) ;
99
+ for ring in geom. rings . iter ( ) {
100
+ ewkb. extend_from_slice ( & ( ( ring. len ( ) as u32 ) /geom. dims as u32 ) . to_le_bytes ( ) ) ;
101
+ for pos in ring. iter ( ) {
102
+ ewkb. extend_from_slice ( & pos. to_le_bytes ( ) ) ;
103
+ }
102
104
}
103
105
}
106
+
104
107
let mut value = cell. borrow_mut ( ) ;
105
108
for byte in ewkb. iter ( ) {
106
109
value. push_str ( & format ! ( "{:02X}" , byte) ) ;
@@ -191,8 +194,7 @@ fn main() -> std::io::Result<()> {
191
194
let mut text = String :: new ( ) ;
192
195
let mut gmltoewkb = false ;
193
196
let mut gmlpos = false ;
194
- let mut gmlint = false ;
195
- let mut gmlgeom = Geometry :: new ( ) ;
197
+ let mut gmlcoll: Vec < Geometry > = vec ! [ ] ;
196
198
let start = Instant :: now ( ) ;
197
199
loop {
198
200
match reader. read_event ( & mut buf) {
@@ -217,14 +219,18 @@ fn main() -> std::io::Result<()> {
217
219
value = value. split_off ( i+2 ) ;
218
220
}
219
221
match value. parse :: < u32 > ( ) {
220
- Ok ( int) => gmlgeom. srid = int,
222
+ Ok ( int) => {
223
+ if let Some ( geom) = gmlcoll. last_mut ( ) { geom. srid = int } ;
224
+ } ,
221
225
Err ( _) => eprintln ! ( "Invalid srsName {} in GML" , value)
222
226
}
223
227
} ,
224
228
Ok ( "srsDimension" ) => {
225
229
let value = reader. decode ( & attr. value ) . unwrap ( ) ;
226
230
match value. parse :: < u8 > ( ) {
227
- Ok ( int) => gmlgeom. dims = int,
231
+ Ok ( int) => {
232
+ if let Some ( geom) = gmlcoll. last_mut ( ) { geom. dims = int } ;
233
+ } ,
228
234
Err ( _) => eprintln ! ( "Invalid srsDimension {} in GML" , value)
229
235
}
230
236
}
@@ -236,17 +242,14 @@ fn main() -> std::io::Result<()> {
236
242
match reader. decode ( e. name ( ) ) {
237
243
Err ( _) => ( ) ,
238
244
Ok ( tag) => match tag {
239
- "gml:Point" => gmlgeom . gtype = 1 ,
240
- "gml:LineString" => gmlgeom . gtype = 2 ,
241
- "gml:Polygon" => gmlgeom . gtype = 3 ,
245
+ "gml:Point" => gmlcoll . push ( Geometry :: new ( 1 ) ) ,
246
+ "gml:LineString" => gmlcoll . push ( Geometry :: new ( 2 ) ) ,
247
+ "gml:Polygon" => gmlcoll . push ( Geometry :: new ( 3 ) ) ,
242
248
"gml:MultiPolygon" => ( ) ,
243
249
"gml:polygonMember" => ( ) ,
244
250
"gml:exterior" => ( ) ,
245
- "gml:interior" => {
246
- eprintln ! ( "GML polygon interior ring not yet supported; ignored" ) ;
247
- gmlint = true ;
248
- } ,
249
- "gml:LinearRing" => gmlgeom. rings . push ( Vec :: new ( ) ) ,
251
+ "gml:interior" => ( ) ,
252
+ "gml:LinearRing" => gmlcoll. last_mut ( ) . unwrap ( ) . rings . push ( Vec :: new ( ) ) ,
250
253
"gml:posList" => gmlpos = true ,
251
254
_ => eprintln ! ( "GML type {} not supported" , tag)
252
255
}
@@ -314,10 +317,10 @@ fn main() -> std::io::Result<()> {
314
317
continue ;
315
318
}
316
319
else if gmltoewkb {
317
- if gmlpos && !gmlint {
320
+ if gmlpos {
318
321
let value = String :: from ( & e. unescape_and_decode ( & reader) . unwrap ( ) ) ;
319
322
for pos in value. split ( ' ' ) {
320
- gmlgeom . rings . last_mut ( ) . unwrap ( ) . push ( pos. parse ( ) . unwrap ( ) ) ;
323
+ gmlcoll . last_mut ( ) . unwrap ( ) . rings . last_mut ( ) . unwrap ( ) . push ( pos. parse ( ) . unwrap ( ) ) ;
321
324
}
322
325
}
323
326
continue ;
@@ -352,15 +355,14 @@ fn main() -> std::io::Result<()> {
352
355
}
353
356
} ,
354
357
Ok ( Event :: End ( _) ) => {
355
- if path == table. path {
358
+ if path == table. path { // This is an end tag of the row path
356
359
if filtered {
357
360
filtered = false ;
358
361
filtercount += 1 ;
359
362
}
360
363
else {
361
364
362
- // End tag of a subtable; write the first column value of the parent table as the first column of the subtable
363
- if !tables. is_empty ( ) {
365
+ if !tables. is_empty ( ) { // This is a subtable; write the first column value of the parent table as the first column of the subtable (for use as a foreign key)
364
366
table. write ( & tables. last ( ) . unwrap ( ) . columns [ 0 ] . value . borrow ( ) ) ;
365
367
table. write ( "\t " ) ;
366
368
}
@@ -401,12 +403,11 @@ fn main() -> std::io::Result<()> {
401
403
}
402
404
else if gmltoewkb {
403
405
if gmlpos && ( tag == "/gml:posList" ) { gmlpos = false ; }
404
- if gmlint && ( tag == "/gml:interior" ) { gmlint = false ; }
405
406
for i in 0 ..table. columns . len ( ) {
406
407
if path == table. columns [ i] . path {
407
408
gmltoewkb = false ;
408
- gml_to_ewkb ( & table. columns [ i] . value , & gmlgeom ) ;
409
- gmlgeom . reset ( ) ;
409
+ gml_to_ewkb ( & table. columns [ i] . value , & gmlcoll ) ;
410
+ gmlcoll . clear ( ) ;
410
411
break ;
411
412
}
412
413
}
0 commit comments