* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * 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., 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 <simgear_config.h>
+#endif
+
#include <errno.h>
#include <string.h>
#include <stdio.h>
+#include <cstdlib>
+
+#include <simgear/structure/exception.hxx>
+
#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)
{
+ double lat = 0.0, lon = 0.0;
+
int i = 0;
while (infoString[i] != '\t')
i++;
char latlon[128];
strncpy(buffer, infoString, i);
buffer[i] = 0;
- countryCode = strdup(buffer);
+ countryCode = buffer;
i ++;
int start = i;
while (infoString[i] != '\t') {
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;
sign = latlon[nextPos];
nextPos++;
strncpy(buffer, &latlon[nextPos], 3);
+ buffer[3] = 0;
lon = atof(buffer);
nextPos += 3;
strncpy(buffer, &latlon[nextPos], 2);
if (strlen(latlon) > 12) {
nextPos += 2;
strncpy(buffer, &latlon[nextPos], 2);
+ buffer[2] = 0;
lon += (atof (buffer) / 3600.00);
}
if (sign == '-') {
size = i - start;
strncpy(buffer, (&infoString[start]), size);
buffer[size] = 0;
- descriptor = strdup(buffer);
+ 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, "rb");
if (!(infile)) {
- fprintf(stderr, "Unable to open file %s\n", filename);
- exit(1);
- } else {
- errno = 0;
+ std::string e = "Unable to open time zone file '";
+ throw sg_exception(e + filename + '\'');
+ }
- while (1) {
- fgets(buffer, 256, infile);
- if (feof(infile)) {
+ 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;
- }
- 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( "TimezoneContainer()" );
- errno = 0;
+ if (buffer[0]) {
+ zones.push_back(new SGTimeZone(buffer));
}
}
+ if ( errno ) {
+ perror( "SGTimeZoneContainer()" );
+ errno = 0;
+ }
+
+ fclose(infile);
+}
+
+SGTimeZoneContainer::~SGTimeZoneContainer()
+{
+ TZVec::iterator it = zones.begin();
+ for (; it != zones.end(); ++it) {
+ delete *it;
+ }
}
-TimezoneContainer::~TimezoneContainer()
+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;
}
+