]> git.mxchange.org Git - simgear.git/blobdiff - simgear/timing/timezone.cxx
Working 'noshadow' animation
[simgear.git] / simgear / timing / timezone.cxx
index cd5db78ff6293b7d5f770dbfde06718d6f769cf6..26174c7538f513d3c27333ee6bb1b0d7215bf3d6 100644 (file)
  * 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 <simgear_config.h>
+#endif
+
+#include <errno.h>
+#include <string.h>
 #include <stdio.h>
-#include "timezone.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)
 {
-  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;
+}
+