X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Ftiming%2Ftimezone.cxx;h=26174c7538f513d3c27333ee6bb1b0d7215bf3d6;hb=5af8bb7c8e259f5bdda67beb87adcc453e0b32e7;hp=cd5db78ff6293b7d5f770dbfde06718d6f769cf6;hpb=1b07b25ad2eb26be45f7df744efa332a230d2baf;p=simgear.git diff --git a/simgear/timing/timezone.cxx b/simgear/timing/timezone.cxx index cd5db78f..26174c75 100644 --- a/simgear/timing/timezone.cxx +++ b/simgear/timing/timezone.cxx @@ -2,146 +2,193 @@ * timezone.cc * Written by Durk Talsma. Started July 1999. * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. + * Library General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * **************************************************************************/ /************************************************************************* * - * Timezone is derived from geocoord, and stores the timezone centerpoint, + * SGTimeZone is derived from geocoord, and stores the timezone centerpoint, * as well as the countrycode and the timezone descriptor. The latter is * used in order to get the local time. * ************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include #include -#include "timezone.h" +#include +#include + +#include "timezone.h" -Timezone::Timezone(float la, float lo, char* cc, char* desc) : - GeoCoord(la, lo) +SGTimeZone::SGTimeZone(const SGGeod& geod, char* cc, char* desc) : + centerpoint(SGVec3d::fromGeod(geod)) { - countryCode = strdup(cc); - descriptor = strdup(desc); + countryCode = cc; + descriptor = desc; } /* Build a timezone object from a textline in zone.tab */ -Timezone::Timezone(const char *infoString) : - GeoCoord() +SGTimeZone::SGTimeZone(const char *infoString) { - int i = 0; - while (infoString[i] != '\t') - i++; - char buffer[128]; - char latlon[128]; - strncpy(buffer, infoString, i); - buffer[i] = 0; - countryCode = strdup(buffer); - i ++; - int start = i; - while (infoString[i] != '\t') - i++; - int size = i - start; - strncpy(latlon, (&infoString[start]), size); - latlon[size] = 0; - char sign; - sign = latlon[0]; - strncpy(buffer, &latlon[1], 2); - lat = atof(buffer); - strncpy(buffer, &latlon[3], 2); - lat += (atof(buffer) / 60); - int nextPos; - if (strlen(latlon) > 12) - { - nextPos = 7; - strncpy(buffer, &latlon[5], 2); - lat += (atof(buffer) / 3600.0); + double lat = 0.0, lon = 0.0; + + int i = 0; + while (infoString[i] != '\t') + i++; + char buffer[128]; + char latlon[128]; + strncpy(buffer, infoString, i); + buffer[i] = 0; + countryCode = buffer; + i ++; + int start = i; + while (infoString[i] != '\t') { + i++; } - else - nextPos = 5; - if (sign == '-') - lat = -lat; - - sign = latlon[nextPos]; - nextPos++; - strncpy(buffer, &latlon[nextPos], 3); - lon = atof(buffer); - nextPos += 3; - strncpy(buffer, &latlon[nextPos], 2); - buffer[2] = 0; + int size = i - start; + strncpy(latlon, (&infoString[start]), size); + latlon[size] = 0; + char sign; + sign = latlon[0]; + strncpy(buffer, &latlon[1], 2); + buffer[2] = 0; + lat = atof(buffer); + strncpy(buffer, &latlon[3], 2); + buffer[2] = 0; + lat += (atof(buffer) / 60); + int nextPos; + if (strlen(latlon) > 12) { + nextPos = 7; + strncpy(buffer, &latlon[5], 2); + buffer[2] = 0; + lat += (atof(buffer) / 3600.0); + } else { + nextPos = 5; + } + if (sign == '-') { + lat = -lat; + } + + sign = latlon[nextPos]; + nextPos++; + strncpy(buffer, &latlon[nextPos], 3); + buffer[3] = 0; + lon = atof(buffer); + nextPos += 3; + strncpy(buffer, &latlon[nextPos], 2); + buffer[2] = 0; - lon += (atof(buffer) / 60); - if (strlen(latlon) > 12) - { - nextPos += 2; - strncpy(buffer, &latlon[nextPos], 2); - lon += (atof (buffer) / 3600.00); + lon += (atof(buffer) / 60); + if (strlen(latlon) > 12) { + nextPos += 2; + strncpy(buffer, &latlon[nextPos], 2); + buffer[2] = 0; + lon += (atof (buffer) / 3600.00); + } + if (sign == '-') { + lon = -lon; } - if (sign == '-') - lon = -lon; - i ++; - start = i; - while (!((infoString[i] == '\t') || (infoString[i] == '\n'))) - i++; - size = i - start; - strncpy(buffer, (&infoString[start]), size); - buffer[size] = 0; - descriptor = strdup(buffer); + i ++; + start = i; + while (!((infoString[i] == '\t') || (infoString[i] == '\n'))) { + i++; + } + size = i - start; + strncpy(buffer, (&infoString[start]), size); + buffer[size] = 0; + descriptor = buffer; + + centerpoint = SGVec3d::fromGeod(SGGeod::fromDeg(lon, lat)); } /* the copy constructor */ -Timezone::Timezone(const Timezone& other) +SGTimeZone::SGTimeZone(const SGTimeZone& other) { - lat = other.getLat(); - lon = other.getLon(); - countryCode = strdup(other.countryCode); - descriptor = strdup(other.descriptor); + centerpoint = other.centerpoint; + countryCode = other.countryCode; + descriptor = other.descriptor; } -/********* Member functions for TimezoneContainer class ********/ +/********* Member functions for SGTimeZoneContainer class ********/ -TimezoneContainer::TimezoneContainer(const char *filename) +SGTimeZoneContainer::SGTimeZoneContainer(const char *filename) { - char buffer[256]; - FILE* infile = fopen(filename, "r"); - if (!(infile)) - { - fprintf(stderr, "Unable to open file %s\n", filename); - exit(1); + char buffer[256]; + FILE* infile = fopen(filename, "rb"); + if (!(infile)) { + string e = "Unable to open time zone file '"; + throw sg_exception(e + filename + '\''); + } + + errno = 0; + + while (1) { + if (0 == fgets(buffer, 256, infile)) + break; + if (feof(infile)) { + break; + } + for (char *p = buffer; *p; p++) { + if (*p == '#') { + *p = 0; + break; + } + } + if (buffer[0]) { + zones.push_back(new SGTimeZone(buffer)); + } } - else - { - - while (1) - { - fgets(buffer, 256, infile); - if (feof(infile)) - break; - for (int i = 0; i < 256; i++) - { - if (buffer[i] == '#') - buffer[i] = 0; - } - if (buffer[0]) - { - data.push_back(new Timezone(buffer)); - } - } + if ( errno ) { + perror( "SGTimeZoneContainer()" ); + errno = 0; } + + fclose(infile); } -TimezoneContainer::~TimezoneContainer() +SGTimeZoneContainer::~SGTimeZoneContainer() { + TZVec::iterator it = zones.begin(); + for (; it != zones.end(); ++it) { + delete *it; + } } + +SGTimeZone* SGTimeZoneContainer::getNearest(const SGGeod& ref) const +{ + SGVec3d refCart(SGVec3d::fromGeod(ref)); + SGTimeZone* match = NULL; + double minDist2 = HUGE_VAL; + + TZVec::const_iterator it = zones.begin(); + for (; it != zones.end(); ++it) { + double d2 = distSqr((*it)->cartCenterpoint(), refCart); + if (d2 < minDist2) { + match = *it; + minDist2 = d2; + } + } + + return match; +} +