-
Notifications
You must be signed in to change notification settings - Fork 0
/
TLIGCFileConversion.m
138 lines (118 loc) · 4.2 KB
/
TLIGCFileConversion.m
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
//
// TLIGCFileConversion.m
// Tagalog
//
// Created by Nathan Vander Wilt on 10/13/09.
// Copyright 2009 __MyCompanyName__. All rights reserved.
//
#import "TLIGCFileConversion.h"
#import "TLTrack.h"
#import "TLLocation.h"
#import "TLTimestamp.h"
#import "TLWaypoint.h"
@interface NSDate (TLIGCAdditions)
- (NSDate*)tl_nextDay;
@end
@implementation TLIGCFile (TLIGCFileConversion)
- (NSArray*)extractTracks:(NSError**)err {
NSDate* baseDate = [[self header] objectForKey:TLIGCDateKey];
if (!baseDate) {
if (err) {
*err = [NSError errorWithDomain:NSCocoaErrorDomain
code:NSFileReadCorruptFileError
userInfo:nil];
}
return nil;
}
NSMutableArray* tracks = [NSMutableArray array];
NSMutableArray* currentWaypoints = [NSMutableArray array];
int fixIdx = 0;
NSDate* prevDate = nil;
for (NSDictionary* fixInfo in [self fixes]) {
++fixIdx;
TLTimestamp* timestamp = nil;
NSNumber* timeValue = [fixInfo objectForKey:TLIGCFixTimeKey];
if (timeValue) {
NSTimeInterval dayTime = [timeValue doubleValue];
NSDate* date = [baseDate addTimeInterval:dayTime];
if (prevDate && [date isLessThan:prevDate]) {
//printf(" !!! REJIGGERING BASE DATE @ fix %i !!! \n", fixIdx);
baseDate = [baseDate tl_nextDay];
date = [baseDate addTimeInterval:dayTime];
//NSLog(@" \n\nprevDate: %@\n date: %@", prevDate, date);
}
if (!prevDate || [prevDate isLessThan:date]) {
timestamp = [TLTimestamp timestampWithTime:date
accuracy:TLTimestampAccuracyUnknown];
}
else if ([prevDate isEqual:date]) {
/* NOTE: It is common for recorders to repeat the last fix
at the end of the file. Just silently ignore duplicate timestamps. */
//NSLog(@"Identical timestamps found @ fix %i", fixIdx);
}
else if (prevDate) {
NSLog(@"Out-of-order timestamp @ fix %i.", fixIdx);
}
prevDate = date;
}
BOOL validFix = NO;
if ([[fixInfo objectForKey:TLIGCFixValidityKey] isEqual:TLIGCFixValidity3D]) {
/* NOTE: A 2D fix validity can also represent an invalid fix,
and under normal circumstances (theoretically and based on sample files)
an aircraft's GNSS should be able to obtain a 3D fix.
So we only accept 3D fixes.
The only 2D fix example found is 567A0UP2, where they are invalid */
validFix = YES;
}
TLLocation* location = nil;
NSNumber* latValue = [fixInfo objectForKey:TLIGCFixLatitudeKey];
NSNumber* lonValue = [fixInfo objectForKey:TLIGCFixLongitudeKey];
if (validFix && latValue && lonValue) {
TLCoordinate coord = TLCoordinateMake([latValue doubleValue],
[lonValue doubleValue]);
NSNumber* accValue = [fixInfo objectForKey:TLIGCFixAccuracyKey];
TLCoordinateAccuracy acc = (accValue ?
[accValue doubleValue] : TLCoordinateAccuracyUnknown);
NSNumber* altValue = [fixInfo objectForKey:TLIGCFixGeoidAltitudeKey];
TLCoordinateAltitude alt = (altValue ?
[altValue doubleValue] : TLCoordinateAltitudeUnknown);
location = [TLLocation locationWithCoordinate:coord
horizontalAccuracy:acc
altitude:alt
verticalAccuracy:TLCoordinateAccuracyUnknown];
}
if (location && timestamp) {
[currentWaypoints addObject:
[TLWaypoint waypointWithLocation:location
timestamp:timestamp]];
}
else {
// make track from current waypoints in (unlikely) event of a split
if ([currentWaypoints count]) {
TLTrack* track = [[[TLTrack alloc] initWithWaypoints:currentWaypoints] autorelease];
[tracks addObject:track];
currentWaypoints = [NSMutableArray array];
}
}
}
if ([currentWaypoints count]) {
TLTrack* track = [[[TLTrack alloc] initWithWaypoints:currentWaypoints] autorelease];
[tracks addObject:track];
}
//NSLog(@"Read %lu tracks\n", (long unsigned)[tracks count]);
return tracks;
}
- (NSArray*)extractWaypoints:(NSError**)err {
(void)err;
return [NSArray array];
}
@end
@implementation NSDate (TLIGCAdditions)
- (NSDate*)tl_nextDay {
NSCalendar* gregorian = [[[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
NSDateComponents* comps = [[NSDateComponents new] autorelease];
[comps setDay:1];
return [gregorian dateByAddingComponents:comps toDate:self options:0];
}
@end