-
Notifications
You must be signed in to change notification settings - Fork 0
/
TLGPXWaypoint.m
154 lines (137 loc) · 4.79 KB
/
TLGPXWaypoint.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//
// TLGPXWaypoint.m
// Mercatalog
//
// Created by Nathan Vander Wilt on 3/17/08.
// Copyright 2008 Calf Trail Software, LLC. All rights reserved.
//
#import "TLGPXWaypoint.h"
NSDate* TLNSDateFromStandardString(NSString* str);
@implementation TLGPXWaypoint
- (id)initWithParent:(TLGPXNode*)theParent
forElement:(NSString*)elementName
namespaceURI:(NSString*)namespaceURI
qualifiedName:(NSString*)qualifiedName
attributes:(NSDictionary*)attributes
{
self = [super initWithParent:theParent
forElement:elementName
namespaceURI:namespaceURI
qualifiedName:qualifiedName
attributes:attributes];
if (self) {
coordinate.lat = [[attributes valueForKey:@"lat"] doubleValue];
coordinate.lon = [[attributes valueForKey:@"lon"] doubleValue];
elevation = TLCoordinateAltitudeUnknown;
}
return self;
}
- (void)dealloc {
[time release];
[name release];
[super dealloc];
}
#pragma mark Parsing out of XML
- (void)parser:(NSXMLParser*)parser didStartElement:(NSString*)elementName
namespaceURI:(NSString*)namespaceURI
qualifiedName:(NSString*)qualifiedName
attributes:(NSDictionary*)attributeDict
{
(void)parser;
(void)namespaceURI;
(void)qualifiedName;
(void)attributeDict;
if ([elementName isEqualToString:@"time"] ||
[elementName isEqualToString:@"name"] ||
[elementName isEqualToString:@"ele"] ||
[elementName isEqualToString:@"hdop"] ||
[elementName isEqualToString:@"vdop"] ||
[elementName isEqualToString:@"pdop"])
{
[self setGatheringCharacters:YES];
}
}
NSDate* TLNSDateFromStandardString(NSString* str) {
NSCParameterAssert(str != nil);
/* Parse xsd:dateTime http://www.w3.org/TR/xmlschema-2/#dateTime in an accepting manner.
'-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? ((('+' | '-') hh ':' mm) | 'Z')?
Note that yyyy may be negative, or more than 4 digits.
When a timezone is added to a UTC dateTime, the result is the date and time "in that timezone". */
int year = 0;
unsigned int month = 0, day = 0, hours = 0, minutes = 0;
double seconds = 0.0;
char timeZoneBuffer[7] = "";
int numFieldsParsed = sscanf([str UTF8String], "%d-%u-%u T %u:%u:%lf %6s",
&year, &month, &day, &hours, &minutes, &seconds, timeZoneBuffer);
if (numFieldsParsed < 6) {
return nil;
}
int timeZoneSeconds = 0;
if (timeZoneBuffer[0] && timeZoneBuffer[0] != 'Z') {
int tzHours = 0;
unsigned int tzMinutes = 0;
int numTimezoneFieldsParsed = sscanf(timeZoneBuffer, "%d:%ud", &tzHours, &tzMinutes);
if (numTimezoneFieldsParsed < 2) {
return nil;
}
timeZoneSeconds = 60 * (tzMinutes + (60 * abs(tzHours)));
if (tzHours < 0) {
timeZoneSeconds = -timeZoneSeconds;
}
}
NSDateComponents* parsedComponents = [[NSDateComponents new] autorelease];
[parsedComponents setYear:year];
[parsedComponents setMonth:month];
[parsedComponents setDay:day];
[parsedComponents setHour:hours];
[parsedComponents setMinute:minutes];
// NOTE: I don't know how exactly this calendar deals with negative years, or the transition from Julian
NSCalendar* gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
[gregorian setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:timeZoneSeconds]];
NSDate* dateWithoutSeconds = [gregorian dateFromComponents:parsedComponents];
NSDate* date = [dateWithoutSeconds addTimeInterval:seconds];
//printf("'%s' yielded %s\n", [str UTF8String], [[date description] UTF8String]);
return date;
}
- (void)parser:(NSXMLParser*)parser didEndElement:(NSString*)elementName
namespaceURI:(NSString*)namespaceURI
qualifiedName:(NSString*)qualifiedName
{
if ([elementName isEqualToString:@"time"]) {
time = [TLNSDateFromStandardString([self gatheredCharacters]) copy];
if (!time) NSLog(@"Could not convert string '%@' to a date!", [self gatheredCharacters]);
[self setGatheringCharacters:NO];
}
else if ([elementName isEqualToString:@"ele"]) {
elevation = [[self gatheredCharacters] doubleValue];
[self setGatheringCharacters:NO];
}
else if ([elementName isEqualToString:@"name"]) {
name = [[self gatheredCharacters] copy];
[self setGatheringCharacters:NO];
}
else if ([elementName isEqualToString:@"hdop"]) {
horizontalDOP = [[self gatheredCharacters] doubleValue];
[self setGatheringCharacters:NO];
}
else if ([elementName isEqualToString:@"vdop"]) {
verticalDOP = [[self gatheredCharacters] doubleValue];
[self setGatheringCharacters:NO];
}
else if ([elementName isEqualToString:@"pdop"]) {
positionDOP = [[self gatheredCharacters] doubleValue];
[self setGatheringCharacters:NO];
}
else {
[super parser:parser didEndElement:elementName namespaceURI:namespaceURI qualifiedName:qualifiedName];
}
}
#pragma mark Accessors
@synthesize name;
@synthesize time;
@synthesize coordinate;
@synthesize elevation;
@synthesize horizontalDOP;
@synthesize verticalDOP;
@synthesize positionDOP;
@end