]> git.mxchange.org Git - simgear.git/blob - simgear/timing/timezone.cxx
Merge branch 'next' of git://gitorious.org/fg/simgear into next
[simgear.git] / simgear / timing / timezone.cxx
1 /* -*- Mode: C++ -*- *****************************************************
2  * timezone.cc
3  * Written by Durk Talsma. Started July 1999.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  *
19  **************************************************************************/
20
21 /*************************************************************************
22  *
23  * SGTimeZone is derived from geocoord, and stores the timezone centerpoint,
24  * as well as the countrycode and the timezone descriptor. The latter is 
25  * used in order to get the local time. 
26  *
27  ************************************************************************/
28
29 #include <errno.h>
30 #include <string.h>
31 #include <stdio.h>
32 #include <cstdlib>
33
34 #include <simgear/structure/exception.hxx>
35
36 #include "timezone.h"
37
38 SGTimeZone::SGTimeZone(const SGGeod& geod, char* cc, char* desc) :
39     centerpoint(SGVec3d::fromGeod(geod))
40
41     countryCode = cc;
42     descriptor = desc;
43 }
44
45 /* Build a timezone object from a textline in zone.tab */
46 SGTimeZone::SGTimeZone(const char *infoString)
47 {
48     double lat = 0.0, lon = 0.0;
49     
50     int i = 0;
51     while (infoString[i] != '\t')
52         i++;
53     char buffer[128];
54     char latlon[128];
55     strncpy(buffer, infoString, i);
56     buffer[i] = 0;
57     countryCode = buffer;
58     i ++;
59     int start = i;
60     while (infoString[i] != '\t') {
61         i++;
62     }
63     int size = i - start;
64     strncpy(latlon, (&infoString[start]), size);
65     latlon[size] = 0;
66     char sign;
67     sign = latlon[0];
68     strncpy(buffer, &latlon[1], 2);
69     buffer[2] = 0;
70     lat = atof(buffer);
71     strncpy(buffer, &latlon[3], 2);
72     buffer[2] = 0;
73     lat += (atof(buffer) / 60);
74     int nextPos;
75     if (strlen(latlon) > 12) {
76         nextPos = 7;
77         strncpy(buffer, &latlon[5], 2);
78         buffer[2] = 0;
79         lat += (atof(buffer) / 3600.0);
80     } else {
81         nextPos = 5;
82     }
83     if (sign == '-') {
84         lat = -lat;
85     }
86
87     sign = latlon[nextPos];
88     nextPos++;
89     strncpy(buffer, &latlon[nextPos], 3);
90     buffer[3] = 0;
91     lon = atof(buffer);
92     nextPos += 3;
93     strncpy(buffer, &latlon[nextPos], 2);
94     buffer[2] = 0;
95  
96     lon  += (atof(buffer) / 60);
97     if (strlen(latlon) > 12) {
98         nextPos += 2;
99         strncpy(buffer, &latlon[nextPos], 2); 
100         buffer[2] = 0;
101         lon +=  (atof (buffer) / 3600.00);
102     }
103     if (sign == '-') {
104         lon = -lon;
105     }
106     i ++;
107     start = i;
108     while (!((infoString[i] == '\t') || (infoString[i] == '\n'))) {
109         i++;
110     }
111     size = i - start;
112     strncpy(buffer, (&infoString[start]), size);
113     buffer[size] = 0;
114     descriptor = buffer;
115     
116     centerpoint = SGVec3d::fromGeod(SGGeod::fromDeg(lon, lat));
117 }
118
119 /* the copy constructor */
120 SGTimeZone::SGTimeZone(const SGTimeZone& other)
121 {
122     centerpoint = other.centerpoint;
123     countryCode = other.countryCode;
124     descriptor = other.descriptor;
125 }
126
127
128 /********* Member functions for SGTimeZoneContainer class ********/
129
130 SGTimeZoneContainer::SGTimeZoneContainer(const char *filename)
131 {
132     char buffer[256];
133     FILE* infile = fopen(filename, "rb");
134     if (!(infile)) {
135         string e = "Unable to open time zone file '";
136         throw sg_exception(e + filename + '\'');
137     }
138     
139     errno = 0;
140
141     while (1) {
142         fgets(buffer, 256, infile);
143         if (feof(infile)) {
144             break;
145         }
146         for (char *p = buffer; *p; p++) {
147             if (*p == '#') {
148                 *p = 0;
149                 break;
150             }    
151         }
152         if (buffer[0]) {
153             zones.push_back(new SGTimeZone(buffer));
154         }
155     }
156     if ( errno ) {
157         perror( "SGTimeZoneContainer()" );
158         errno = 0;
159     }
160     
161     fclose(infile);
162 }
163
164 SGTimeZoneContainer::~SGTimeZoneContainer()
165 {
166   TZVec::iterator it = zones.begin();
167   for (; it != zones.end(); ++it) {
168     delete *it;
169   }
170 }
171
172 SGTimeZone* SGTimeZoneContainer::getNearest(const SGGeod& ref) const
173 {
174   SGVec3d refCart(SGVec3d::fromGeod(ref));
175   SGTimeZone* match = NULL;
176   double minDist2 = HUGE_VAL;
177   
178   TZVec::const_iterator it = zones.begin();
179   for (; it != zones.end(); ++it) {
180     double d2 = distSqr((*it)->cartCenterpoint(), refCart);
181     if (d2 < minDist2) {
182       match = *it;
183       minDist2 = d2;
184     }
185   }
186
187   return match;
188 }
189