From e99c3d4705e8bfecd648007bceca24075befdfdd Mon Sep 17 00:00:00 2001 From: James Turner Date: Thu, 29 Jul 2010 10:12:00 +0100 Subject: [PATCH] Collapse SGGeoCoord into SGTimeZone, and switch timezone search to cartesian math. --- projects/VC90/SimGear.vcproj | 8 ---- simgear/timing/Makefile.am | 2 - simgear/timing/geocoord.cxx | 69 --------------------------- simgear/timing/geocoord.h | 90 ------------------------------------ simgear/timing/sg_time.cxx | 10 ++-- simgear/timing/timezone.cxx | 75 ++++++++++++++++++++---------- simgear/timing/timezone.h | 51 ++++++++++---------- 7 files changed, 78 insertions(+), 227 deletions(-) delete mode 100644 simgear/timing/geocoord.cxx delete mode 100644 simgear/timing/geocoord.h diff --git a/projects/VC90/SimGear.vcproj b/projects/VC90/SimGear.vcproj index 7ef14fc9..e80a935c 100644 --- a/projects/VC90/SimGear.vcproj +++ b/projects/VC90/SimGear.vcproj @@ -883,14 +883,6 @@ - - - - diff --git a/simgear/timing/Makefile.am b/simgear/timing/Makefile.am index 234bea5a..6a45c628 100644 --- a/simgear/timing/Makefile.am +++ b/simgear/timing/Makefile.am @@ -3,14 +3,12 @@ includedir = @includedir@/timing lib_LIBRARIES = libsgtiming.a include_HEADERS = \ - geocoord.h \ lowleveltime.h \ sg_time.hxx \ timestamp.hxx \ timezone.h libsgtiming_a_SOURCES = \ - geocoord.cxx \ lowleveltime.cxx \ sg_time.cxx \ timestamp.cxx \ diff --git a/simgear/timing/geocoord.cxx b/simgear/timing/geocoord.cxx deleted file mode 100644 index d3f52260..00000000 --- a/simgear/timing/geocoord.cxx +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- Mode: C++ -*- ***************************************************** - * geocoord.h - * Written by Durk Talsma. Started March 1998. - * - * 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 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 - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - **************************************************************************/ - -/************************************************************************* - * - * This file defines a small and simple class to store geocentric - * coordinates. Basically, class SGGeoCoord is intended as a base class for - * any kind of of object, that can be categorized according to its - * location on earth, be it navaids, or aircraft. This class for originally - * written for FlightGear, in order to store Timezone control points. - * - ************************************************************************/ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include "geocoord.h" - -SGGeoCoord::SGGeoCoord(const SGGeoCoord& other) -{ - lat = other.lat; - lon = other.lon; -} - -SGGeoCoord* SGGeoCoordContainer::getNearest(const SGGeoCoord& ref) const -{ - if (data.empty()) - return 0; - - float maxCosAng = -2; - SGVec3f refVec(ref.getX(), ref.getY(), ref.getZ()); - SGGeoCoordVectorConstIterator i, nearest; - for (i = data.begin(); i != data.end(); ++i) - { - float cosAng = dot(refVec, SGVec3f((*i)->getX(), (*i)->getY(), (*i)->getZ())); - if (maxCosAng < cosAng) - { - maxCosAng = cosAng; - nearest = i; - } - } - return *nearest; -} - - -SGGeoCoordContainer::~SGGeoCoordContainer() -{ - SGGeoCoordVectorIterator i = data.begin(); - while (i != data.end()) - delete *i++; -} diff --git a/simgear/timing/geocoord.h b/simgear/timing/geocoord.h deleted file mode 100644 index 536cf0f9..00000000 --- a/simgear/timing/geocoord.h +++ /dev/null @@ -1,90 +0,0 @@ -/* -*- Mode: C++ -*- ***************************************************** - * geocoord.h - * Written by Durk Talsma. Started July 1999. - * - * 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 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 - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - **************************************************************************/ - -/************************************************************************* - * - * This file defines a small and simple class to store geocentric - * coordinates. Basically, class GeoCoord is intended as a base class for - * any kind of of object, that can be categorized according to its - * location on earth, be it navaids, or aircraft. This class for originally - * written for FlightGear, in order to store Timezone control points. - * - ************************************************************************/ - - -#ifndef _GEOCOORD_H_ -#define _GEOCOORD_H_ - -#include - - -#include -#include - -#include - -class SGGeoCoord -{ -protected: - float lat; - float lon; - -public: - SGGeoCoord() { lat = 0.0; lon = 0.0;}; - SGGeoCoord(float la, float lo) { lat = la; lon = lo;}; - SGGeoCoord(const SGGeoCoord& other); - virtual ~SGGeoCoord() {}; - - void set(float la, float lo) { lat = la; lon = lo; }; - float getLat() const { return lat; }; - float getLon() const { return lon; }; - float getX() const { return cos(SGD_DEGREES_TO_RADIANS*lat) * cos(SGD_DEGREES_TO_RADIANS*lon); }; - float getY() const { return cos(SGD_DEGREES_TO_RADIANS*lat) * sin(SGD_DEGREES_TO_RADIANS*lon); }; - float getZ() const { return sin(SGD_DEGREES_TO_RADIANS*lat); }; - - - virtual const char * getDescription() {return 0;}; -}; - -typedef std::vector SGGeoCoordVector; -typedef std::vector::iterator SGGeoCoordVectorIterator; -typedef std::vector::const_iterator SGGeoCoordVectorConstIterator; - -/************************************************************************ - * SGGeoCoordContainer is a simple container class, that stores objects - * derived from SGGeoCoord. Basically, it is a wrapper around an STL vector, - * with some added functionality - ***********************************************************************/ - -class SGGeoCoordContainer -{ -protected: - SGGeoCoordVector data; - -public: - SGGeoCoordContainer() {}; - virtual ~SGGeoCoordContainer(); - - const SGGeoCoordVector& getData() const { return data; }; - SGGeoCoord* getNearest(const SGGeoCoord& ref) const; -}; - - -#endif // _GEO_COORD_H_ diff --git a/simgear/timing/sg_time.cxx b/simgear/timing/sg_time.cxx index 45fd41c1..9bc52c18 100644 --- a/simgear/timing/sg_time.cxx +++ b/simgear/timing/sg_time.cxx @@ -88,9 +88,8 @@ void SGTime::init( double lon_rad, double lat_rad, SG_LOG( SG_EVENT, SG_INFO, "Reading timezone info from: " << zone.str() ); tzContainer = new SGTimeZoneContainer( zone.c_str() ); - - SGGeoCoord location( SGD_RADIANS_TO_DEGREES * lat_rad, SGD_RADIANS_TO_DEGREES * lon_rad ); - SGGeoCoord* nearestTz = tzContainer->getNearest(location); + SGGeod location(SGGeod::fromRad(lon_rad, lat_rad)); + SGTimeZone* nearestTz = tzContainer->getNearest(location); SGPath name( root ); name.append( nearestTz->getDescription() ); @@ -283,9 +282,8 @@ void SGTime::updateLocal( double lon_rad, double lat_rad, const string& root ) { } time_t currGMT; time_t aircraftLocalTime; - SGGeoCoord location( SGD_RADIANS_TO_DEGREES * lat_rad, - SGD_RADIANS_TO_DEGREES * lon_rad ); - SGGeoCoord* nearestTz = tzContainer->getNearest(location); + SGGeod location(SGGeod::fromRad(lon_rad, lat_rad)); + SGTimeZone* nearestTz = tzContainer->getNearest(location); SGPath zone( root ); zone.append ( nearestTz->getDescription() ); zonename = zone.str(); diff --git a/simgear/timing/timezone.cxx b/simgear/timing/timezone.cxx index 0b2e74c6..52811586 100644 --- a/simgear/timing/timezone.cxx +++ b/simgear/timing/timezone.cxx @@ -34,17 +34,18 @@ #include "timezone.h" -SGTimeZone::SGTimeZone(float la, float lo, char* cc, char* desc) : - SGGeoCoord(la, lo) +SGTimeZone::SGTimeZone(const SGGeod& geod, char* cc, char* desc) : + centerpoint(SGVec3d::fromGeod(geod)) { countryCode = cc; descriptor = desc; } /* Build a timezone object from a textline in zone.tab */ -SGTimeZone::SGTimeZone(const char *infoString) : - SGGeoCoord() +SGTimeZone::SGTimeZone(const char *infoString) { + double lat = 0.0, lon = 0.0; + int i = 0; while (infoString[i] != '\t') i++; @@ -110,13 +111,14 @@ SGTimeZone::SGTimeZone(const char *infoString) : strncpy(buffer, (&infoString[start]), size); buffer[size] = 0; descriptor = buffer; + + centerpoint = SGVec3d::fromGeod(SGGeod::fromDeg(lon, lat)); } /* the copy constructor */ SGTimeZone::SGTimeZone(const SGTimeZone& other) { - lat = other.getLat(); - lon = other.getLon(); + centerpoint = other.centerpoint; countryCode = other.countryCode; descriptor = other.descriptor; } @@ -131,33 +133,56 @@ SGTimeZoneContainer::SGTimeZoneContainer(const char *filename) if (!(infile)) { string e = "Unable to open time zone file '"; throw sg_exception(e + filename + '\''); - - } else { - errno = 0; + } - while (1) { - fgets(buffer, 256, infile); - if (feof(infile)) { + errno = 0; + + while (1) { + fgets(buffer, 256, infile); + if (feof(infile)) { + break; + } + for (char *p = buffer; *p; p++) { + if (*p == '#') { + *p = 0; break; - } - for (char *p = buffer; *p; p++) { - if (*p == '#') { - *p = 0; - break; - } - } - if (buffer[0]) { - data.push_back(new SGTimeZone(buffer)); - } + } } - if ( errno ) { - perror( "SGTimeZoneContainer()" ); - 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; + } +} + +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; } + diff --git a/simgear/timing/timezone.h b/simgear/timing/timezone.h index f5779fd3..76c62a32 100644 --- a/simgear/timing/timezone.h +++ b/simgear/timing/timezone.h @@ -27,46 +27,38 @@ #ifndef _TIMEZONE_H_ #define _TIMEZONE_H_ -#include #include +#include -#include +#include +#include /** - * SGTimeZone is derived from geocoord, and stores the timezone centerpoint, + * SGTimeZone stores the timezone centerpoint, * as well as the countrycode and the timezone descriptor. The latter is * used in order to get the local time. * */ -class SGTimeZone : public SGGeoCoord +class SGTimeZone { private: + SGVec3d centerpoint; // centre of timezone, in cartesian coordinates std::string countryCode; std::string descriptor; public: - /** - * Default constructor. - */ - SGTimeZone() : SGGeoCoord() - { - countryCode.erase(); - descriptor.erase(); - }; - /** * Build a timezone object with a specifed latitude, longitude, country * code, and descriptor - * @param la latitude - * @param lo longitude + * @param pt centerpoint * @param cc country code * @param desc descriptor */ - SGTimeZone(float la, float lo, char* cc, char* desc); + SGTimeZone(const SGGeod& pt, char* cc, char* desc); /** * Build a timezone object from a textline in zone.tab @@ -79,29 +71,34 @@ public: * @param other the source object */ SGTimeZone(const SGTimeZone &other); - - /** - * Virutal destructor - */ - virtual ~SGTimeZone() { }; /** * Return the descriptor string * @return descriptor string (char array) */ - virtual const char * getDescription() { return descriptor.c_str(); }; + const char * getDescription() { return descriptor.c_str(); }; + + const SGVec3d& cartCenterpoint() const + { + return centerpoint; + } }; /** - * SGTimeZoneContainer is derived from SGGeoCoordContainer, and has some - * added functionality. + * SGTimeZoneContainer */ -class SGTimeZoneContainer : public SGGeoCoordContainer +class SGTimeZoneContainer { - public: +public: SGTimeZoneContainer(const char *filename); - virtual ~SGTimeZoneContainer(); + ~SGTimeZoneContainer(); + + SGTimeZone* getNearest(const SGGeod& ref) const; + +private: + typedef std::vector TZVec; + TZVec zones; }; -- 2.39.5