@@ -4,30 +4,42 @@ import ZIPFoundation
44
55/// CSV Coded Departure Route Parser for parsing CDR.csv
66///
7- /// CDR is a comma-delimited file with 6 fields:
8- /// Route Code, Origin, Destination, Departure Fix, Route String, ARTCC
7+ /// CDR is a comma-delimited file with 12 fields:
8+ /// RCode, Orig, Dest, DepFix, Route String, DCNTR, ACNTR, TCNTRs, CoordReq, Play, NavEqp, Length
99class CSVCodedDepartureRouteParser : CSVParser {
1010 var csvDirectory = URL ( fileURLWithPath: " / " )
1111 var routes = [ String: CodedDepartureRoute] ( )
1212
1313 // CSV field mapping (0-based indices)
14- // Fields: Route Code, Origin, Destination, Departure Fix, Route String, ARTCC
14+ // Fields: RCode, Orig, Dest, DepFix, Route String, DCNTR, ACNTR, TCNTRs, CoordReq, Play, NavEqp, Length
1515 private let csvFieldMapping : [ Int ] = [
16- 0 , // 0: Route Code
17- 1 , // 1: Origin
18- 2 , // 2: Destination
19- 3 , // 3: Departure Fix
16+ 0 , // 0: RCode ( Route Code)
17+ 1 , // 1: Orig ( Origin)
18+ 2 , // 2: Dest ( Destination)
19+ 3 , // 3: DepFix ( Departure Fix)
2020 4 , // 4: Route String
21- 5 // 5: ARTCC
21+ 5 , // 5: DCNTR (Departure Center)
22+ 6 , // 6: ACNTR (Arrival Center)
23+ 7 , // 7: TCNTRs (Transition Centers)
24+ 8 , // 8: CoordReq (Coordination Required)
25+ 9 , // 9: Play (Play Info)
26+ 10 , // 10: NavEqp (Navigation Equipment)
27+ 11 // 11: Length
2228 ]
2329
2430 private let transformer = CSVTransformer ( [
25- . string( ) , // 0: Route Code
26- . string( ) , // 1: Origin
27- . string( ) , // 2: Destination
28- . string( ) , // 3: Departure Fix
31+ . string( ) , // 0: RCode
32+ . string( ) , // 1: Orig
33+ . string( ) , // 2: Dest
34+ . string( ) , // 3: DepFix
2935 . string( ) , // 4: Route String
30- . string( ) // 5: ARTCC
36+ . string( ) , // 5: DCNTR
37+ . string( nullable: . blank) , // 6: ACNTR
38+ . string( nullable: . blank) , // 7: TCNTRs
39+ . string( nullable: . blank) , // 8: CoordReq (Y/N)
40+ . string( nullable: . blank) , // 9: Play
41+ . string( nullable: . blank) , // 10: NavEqp
42+ . unsignedInteger( nullable: . blank) // 11: Length
3143 ] )
3244
3345 func prepare( distribution: Distribution ) throws {
@@ -44,35 +56,50 @@ class CSVCodedDepartureRouteParser: CSVParser {
4456 }
4557
4658 func parse( data _: Data ) async throws {
47- try await parseCSVFile ( filename: " CDR.csv " , expectedFieldCount: 6 ) { fields in
48- guard fields. count >= 3 else {
59+ try await parseCSVFile ( filename: " CDR.csv " , expectedFieldCount: 12 ) { fields in
60+ guard fields. count >= 6 else {
4961 throw ParserError . truncatedRecord (
5062 recordType: " CDR " ,
51- expectedMinLength: 3 ,
63+ expectedMinLength: 6 ,
5264 actualLength: fields. count
5365 )
5466 }
5567
56- var mappedFields = [ String] ( repeating: " " , count: 6 )
68+ var mappedFields = [ String] ( repeating: " " , count: 12 )
5769 for (transformerIndex, csvIndex) in self . csvFieldMapping. enumerated ( )
5870 where csvIndex < fields. count {
5971 mappedFields [ transformerIndex] = fields [ csvIndex]
6072 }
6173
6274 let transformedValues = try self . transformer. applyTo (
6375 mappedFields,
64- indices: Array ( 0 ..< 6 )
76+ indices: Array ( 0 ..< 12 )
6577 )
6678
6779 let routeCode = transformedValues [ 0 ] as! String
6880
81+ // Parse CoordReq (Y/N) to Bool
82+ let coordReqString = transformedValues [ 8 ] as? String
83+ let coordinationRequired : Bool ?
84+ switch coordReqString? . uppercased ( ) {
85+ case " Y " : coordinationRequired = true
86+ case " N " : coordinationRequired = false
87+ default : coordinationRequired = nil
88+ }
89+
6990 let route = CodedDepartureRoute (
7091 routeCode: routeCode,
7192 origin: transformedValues [ 1 ] as! String ,
7293 destination: transformedValues [ 2 ] as! String ,
7394 departureFix: transformedValues [ 3 ] as! String ,
7495 routeString: transformedValues [ 4 ] as! String ,
75- ARTCCIdentifier: transformedValues [ 5 ] as! String
96+ departureCenterIdentifier: transformedValues [ 5 ] as! String ,
97+ arrivalCenterIdentifier: transformedValues [ 6 ] as? String ,
98+ transitionCenterIdentifiers: transformedValues [ 7 ] as? String ,
99+ coordinationRequired: coordinationRequired,
100+ playInfo: transformedValues [ 9 ] as? String ,
101+ navigationEquipment: transformedValues [ 10 ] as? String ,
102+ lengthNM: transformedValues [ 11 ] as? UInt
76103 )
77104
78105 self . routes [ routeCode] = route
0 commit comments