23 #include <QStringList> 
   24 #include <QCoreApplication> 
   39     enum DirPosition { PrefixDir, PostfixDir };
 
   41     static QString createDecimalPointExp();
 
   42     static QString regExp( 
const QString& 
string );
 
   43     static void getLocaleList( QStringList& localeList, 
const QString& localeListString,
 
   44                                const QLatin1String& placeholder, 
const QString& separator );
 
   45     static bool isDirection( 
const QString& input, 
const QString& 
direction);
 
   46     static bool isDirection( 
const QString& input, 
const QStringList& directions);
 
   47     static bool isOneOfDirections( 
const QString& input,
 
   48                                    const QString& firstDirection,
 
   49                                    const QString& secondDirection,
 
   50                                    bool& isFirstDirection);
 
   51     static bool isOneOfDirections( 
const QString& input,
 
   52                                    const QStringList& firstDirections,
 
   53                                    const QStringList& secondDirections,
 
   54                                    bool& isFirstDirection);
 
   65     static qreal degreeValueFromDMS( 
const QRegExp& regex, 
int c, 
bool isPosHemisphere );
 
   66     static qreal degreeValueFromDM( 
const QRegExp& regex, 
int c, 
bool isPosHemisphere );
 
   67     static qreal degreeValueFromD( 
const QRegExp& regex, 
int c, 
bool isPosHemisphere );
 
   76     bool parse( 
const QString& input );
 
   80     qreal lon()
 const { 
return m_lon; }
 
   84     qreal lat()
 const { 
return m_lat; }
 
   93     bool tryMatchFromDms( 
const QString& input, DirPosition dirPosition );
 
   94     bool tryMatchFromDm( 
const QString& input, DirPosition dirPosition );
 
   95     bool tryMatchFromD( 
const QString& input, DirPosition dirPosition );
 
  113     bool isCorrectDirections( 
const QString& dir1, 
const QString& dir2,
 
  115                               bool& isLonDirPosHemisphere, 
bool& isLatDirPosHemisphere ) 
const;
 
  116     bool isLocaleLonDirection( 
const QString& input,
 
  117                                bool& isDirPosHemisphere ) 
const;
 
  118     bool isLocaleLatDirection( 
const QString& input,
 
  119                                bool& isDirPosHemisphere ) 
const;
 
  120     bool isLonDirection( 
const QString& input,
 
  121                          bool& isDirPosHemisphere ) 
const;
 
  122     bool isLatDirection( 
const QString& input,
 
  123                          bool& isDirPosHemisphere ) 
const;
 
  130     const QString m_north;
 
  131     const QString m_east;
 
  132     const QString m_south;
 
  133     const QString m_west;
 
  135     const QString m_decimalPointExp;
 
  138     QStringList m_northLocale;
 
  139     QStringList m_eastLocale;
 
  140     QStringList m_southLocale;
 
  141     QStringList m_westLocale;
 
  143     QStringList m_degreeLocale;
 
  144     QStringList m_minutesLocale;
 
  145     QStringList m_secondsLocale;
 
  149     QString m_minutesExp;
 
  150     QString m_secondsExp;
 
  153 LonLatParser::LonLatParser()
 
  156     , m_north( QLatin1String(
"n") )
 
  157     , m_east(  QLatin1String(
"e") )
 
  158     , m_south( QLatin1String(
"s") )
 
  159     , m_west(  QLatin1String(
"w") )
 
  160     , m_decimalPointExp( createDecimalPointExp() )
 
  165 void LonLatParser::initAll()
 
  168     if (! m_dirCapExp.isEmpty() )
 
  171     const QLatin1String placeholder = QLatin1String(
"*");
 
  172     const QString separator = QLatin1String(
"|");
 
  174     getLocaleList( m_northLocale, GeoDataCoordinates::tr( 
"*", 
"North direction terms, see http://techbase.kde.org/Projects/Marble/GeoDataCoordinatesTranslation" ),
 
  175                    placeholder, separator );
 
  176     getLocaleList( m_eastLocale, GeoDataCoordinates::tr( 
"*", 
"East direction terms, see http://techbase.kde.org/Projects/Marble/GeoDataCoordinatesTranslation" ),
 
  177                    placeholder, separator );
 
  178     getLocaleList( m_southLocale, GeoDataCoordinates::tr( 
"*", 
"South direction terms, see http://techbase.kde.org/Projects/Marble/GeoDataCoordinatesTranslation" ),
 
  179                    placeholder, separator );
 
  180     getLocaleList( m_westLocale, GeoDataCoordinates::tr( 
"*", 
"West direction terms, see http://techbase.kde.org/Projects/Marble/GeoDataCoordinatesTranslation" ),
 
  181                    placeholder, separator );
 
  184     QSet<QString> dirs = QSet<QString>()
 
  185         << m_north << m_east << m_south << m_west;
 
  186     dirs += m_northLocale.toSet();
 
  187     dirs += m_eastLocale.toSet();
 
  188     dirs += m_southLocale.toSet();
 
  189     dirs += m_westLocale.toSet();
 
  191     QString fullNamesExp;
 
  192     QString simpleLetters;
 
  194     foreach( 
const QString& dir, dirs ) {
 
  196         if ((dir.length() == 1) && (QLatin1Char(
'a')<=dir.at(0)) && (dir.at(0)<=QLatin1Char(
'z'))) {
 
  197             simpleLetters += dir;
 
  202         fullNamesExp += regExp(dir) + QLatin1Char(
'|');
 
  207         QLatin1Char(
'(') + fullNamesExp + QLatin1Char(
'[') + simpleLetters + QLatin1String(
"])");
 
  210     getLocaleList( m_degreeLocale, GeoDataCoordinates::tr( 
"*", 
"Degree symbol terms, see http://techbase.kde.org/Projects/Marble/GeoDataCoordinatesTranslation" ),
 
  211                    placeholder, separator );
 
  212     getLocaleList( m_minutesLocale, GeoDataCoordinates::tr( 
"*", 
"Minutes symbol terms, see http://techbase.kde.org/Projects/Marble/GeoDataCoordinatesTranslation" ),
 
  213                    placeholder, separator );
 
  214     getLocaleList( m_secondsLocale, GeoDataCoordinates::tr( 
"*", 
"Seconds symbol terms, see http://techbase.kde.org/Projects/Marble/GeoDataCoordinatesTranslation" ),
 
  215                    placeholder, separator );
 
  227     m_degreeExp = QLatin1String(
"\\x00B0|\\x00BA");
 
  228     foreach(
const QString& symbol, m_degreeLocale) {
 
  229         m_degreeExp += QLatin1Char(
'|') + regExp(symbol);
 
  231     m_minutesExp = QLatin1String(
"'|\\x2032|\\x00B4|\\x20C2|\\x2019");
 
  232     foreach(
const QString& symbol, m_minutesLocale) {
 
  233         m_minutesExp += QLatin1Char(
'|') + regExp(symbol);
 
  235     m_secondsExp = QLatin1String(
"\"|\\x2033|\\x201D|''|\\x2032\\x2032|\\x00B4\\x00B4|\\x20C2\\x20C2|\\x2019\\x2019");
 
  236     foreach(
const QString& symbol, m_secondsLocale) {
 
  237         m_secondsExp += QLatin1Char(
'|') + regExp(symbol);
 
  241 bool LonLatParser::parse( 
const QString& 
string )
 
  243     QString input = 
string.toLower().trimmed();
 
  247         const QString numberCapExp = QString::fromLatin1(
 
  248             "([-+]?\\d{1,3}%1?\\d*(?:[eE][+-]?\\d+)?)(?:,|;|\\s)\\s*" 
  249             "([-+]?\\d{1,3}%1?\\d*(?:[eE][+-]?\\d+)?)" 
  250             ).arg(m_decimalPointExp);
 
  252         const QRegExp regex = QRegExp( numberCapExp );
 
  253         if( regex.exactMatch(input) ) {
 
  254             m_lon = regex.cap(2).toDouble();
 
  255             m_lat = regex.cap(1).toDouble();
 
  263     if ( tryMatchFromD( input, PostfixDir ) ) {
 
  267     if ( tryMatchFromD( input, PrefixDir ) ) {
 
  271     if ( tryMatchFromDms( input, PostfixDir ) ) {
 
  275     if ( tryMatchFromDms( input, PrefixDir ) ) {
 
  279     if ( tryMatchFromDm( input, PostfixDir ) ) {
 
  283     if ( tryMatchFromDm( input, PrefixDir ) ) {
 
  291 bool LonLatParser::tryMatchFromDms( 
const QString& input, DirPosition dirPosition )
 
  294     const char *postfixCapExp =
 
  295         "([-+]?)(\\d{1,3})(?:%3|\\s)\\s*(\\d{1,2})(?:%4|\\s)\\s*" 
  296         "(\\d{1,2}%1?\\d*)(?:%5)?\\s*%2[,;]?\\s*" 
  297         "([-+]?)(\\d{1,3})(?:%3|\\s)\\s*(\\d{1,2})(?:%4|\\s)\\s*" 
  298         "(\\d{1,2}%1?\\d*)(?:%5)?\\s*%2";
 
  301     const char *prefixCapExp =
 
  302         "%2\\s*([-+]?)(\\d{1,3})(?:%3|\\s)\\s*(\\d{1,2})(?:%4|\\s)\\s*" 
  303         "(\\d{1,2}%1?\\d*)(?:%5)?\\s*(?:,|;|\\s)\\s*" 
  304         "%2\\s*([-+]?)(\\d{1,3})(?:%3|\\s)\\s*(\\d{1,2})(?:%4|\\s)\\s*" 
  305         "(\\d{1,2}%1?\\d*)(?:%5)?";
 
  307     const char *expTemplate = ( dirPosition == PostfixDir ) ? postfixCapExp
 
  310     const QString numberCapExp =
 
  311         QString::fromLatin1( expTemplate ).arg( m_decimalPointExp, m_dirCapExp,
 
  312                                                 m_degreeExp, m_minutesExp, m_secondsExp);
 
  314     const QRegExp regex = QRegExp( numberCapExp );
 
  315     if( !regex.exactMatch( input ) ) {
 
  320     bool isLonDirPosHemisphere;
 
  321     bool isLatDirPosHemisphere;
 
  322     const QString dir1 = regex.cap( dirPosition == PostfixDir ? 5 : 1 );
 
  323     const QString dir2 = regex.cap( dirPosition == PostfixDir ? 10 : 6 );
 
  324     if ( !isCorrectDirections( dir1, dir2, isDir1LonDir,
 
  325                                isLonDirPosHemisphere, isLatDirPosHemisphere ) ) {
 
  329     const int valueStartIndex1 = (dirPosition == PostfixDir ? 1 : 2);
 
  330     const int valueStartIndex2 = (dirPosition == PostfixDir ? 6 : 7);
 
  331     m_lon = degreeValueFromDMS( regex, isDir1LonDir ? valueStartIndex1 : valueStartIndex2,
 
  332                                 isLonDirPosHemisphere );
 
  333     m_lat = degreeValueFromDMS( regex, isDir1LonDir ? valueStartIndex2 : valueStartIndex1,
 
  334                                 isLatDirPosHemisphere );
 
  340 bool LonLatParser::tryMatchFromDm( 
const QString& input, DirPosition dirPosition )
 
  343     const char *postfixCapExp =
 
  344         "([-+]?)(\\d{1,3})(?:%3|\\s)\\s*(\\d{1,2}%1?\\d*)(?:%4)?\\s*%2[,;]?\\s*" 
  345         "([-+]?)(\\d{1,3})(?:%3|\\s)\\s*(\\d{1,2}%1?\\d*)(?:%4)?\\s*%2";
 
  348     const char *prefixCapExp =
 
  349         "%2\\s*([-+]?)(\\d{1,3})(?:%3|\\s)\\s*(\\d{1,2}%1?\\d*)(?:%4)?\\s*(?:,|;|\\s)\\s*" 
  350         "%2\\s*([-+]?)(\\d{1,3})(?:%3|\\s)\\s*(\\d{1,2}%1?\\d*)(?:%4)?";
 
  352     const char *expTemplate = ( dirPosition == PostfixDir ) ? postfixCapExp
 
  355     const QString numberCapExp =
 
  356         QString::fromLatin1( expTemplate ).arg( m_decimalPointExp, m_dirCapExp,
 
  357                                                 m_degreeExp, m_minutesExp );
 
  358     const QRegExp regex = QRegExp( numberCapExp );
 
  359     if( !regex.exactMatch(input) ) {
 
  364     bool isLonDirPosHemisphere;
 
  365     bool isLatDirPosHemisphere;
 
  366     const QString dir1 = regex.cap( dirPosition == PostfixDir ? 4 : 1 );
 
  367     const QString dir2 = regex.cap( dirPosition == PostfixDir ? 8 : 5 );
 
  368     if ( !isCorrectDirections( dir1, dir2, isDir1LonDir,
 
  369                                isLonDirPosHemisphere, isLatDirPosHemisphere ) ) {
 
  373     const int valueStartIndex1 = ( dirPosition == PostfixDir ? 1 : 2 );
 
  374     const int valueStartIndex2 = ( dirPosition == PostfixDir ? 5 : 6 );
 
  375     m_lon = degreeValueFromDM( regex, isDir1LonDir ? valueStartIndex1 : valueStartIndex2,
 
  376                                isLonDirPosHemisphere );
 
  377     m_lat = degreeValueFromDM( regex, isDir1LonDir ? valueStartIndex2 : valueStartIndex1,
 
  378                                isLatDirPosHemisphere );
 
  384 bool LonLatParser::tryMatchFromD( 
const QString& input, DirPosition dirPosition )
 
  387     const char *postfixCapExp =
 
  388         "([-+]?\\d{1,3}%1?\\d*)(?:%3)?(?:\\s*)%2(?:,|;|\\s)\\s*" 
  389         "([-+]?\\d{1,3}%1?\\d*)(?:%3)?(?:\\s*)%2";
 
  392     const char *prefixCapExp =
 
  393         "%2\\s*([-+]?\\d{1,3}%1?\\d*)(?:%3)?\\s*(?:,|;|\\s)\\s*" 
  394         "%2\\s*([-+]?\\d{1,3}%1?\\d*)(?:%3)?";
 
  396     const char *expTemplate = ( dirPosition == PostfixDir ) ? postfixCapExp
 
  399     const QString numberCapExp =
 
  400         QString::fromLatin1( expTemplate ).arg( m_decimalPointExp, m_dirCapExp, m_degreeExp );
 
  401     const QRegExp regex = QRegExp( numberCapExp );
 
  402     if( !regex.exactMatch( input ) ) {
 
  407     bool isLonDirPosHemisphere;
 
  408     bool isLatDirPosHemisphere;
 
  409     const QString dir1 = regex.cap( dirPosition == PostfixDir ? 2 : 1 );
 
  410     const QString dir2 = regex.cap( dirPosition == PostfixDir ? 4 : 3 );
 
  411     if ( !isCorrectDirections( dir1, dir2, isDir1LonDir,
 
  412                                isLonDirPosHemisphere, isLatDirPosHemisphere ) ) {
 
  416     const int valueStartIndex1 = ( dirPosition == PostfixDir ? 1 : 2 );
 
  417     const int valueStartIndex2 = ( dirPosition == PostfixDir ? 3 : 4 );
 
  418     m_lon = degreeValueFromD( regex, isDir1LonDir ? valueStartIndex1 : valueStartIndex2,
 
  419                               isLonDirPosHemisphere );
 
  420     m_lat = degreeValueFromD( regex, isDir1LonDir ? valueStartIndex2 : valueStartIndex1,
 
  421                               isLatDirPosHemisphere );
 
  426 QString LonLatParser::createDecimalPointExp()
 
  428     const QChar decimalPoint = QLocale::system().decimalPoint();
 
  430     return (decimalPoint == QLatin1Char(
'.')) ? QString::fromLatin1(
"\\.") :
 
  431         QLatin1String(
"[.") + decimalPoint + QLatin1Char(
']');
 
  434 QString LonLatParser::regExp(
const QString& 
string)
 
  437     for (
int i = 0; i < 
string.length(); ++i) {
 
  438         const QChar c = 
string.at(i);
 
  439         if ((QLatin1Char(
'a') <= c) && (c <= QLatin1Char(
'z'))) {
 
  441         } 
else if (c.isSpace()) {
 
  442             result += QLatin1String(
"\\s");
 
  443         } 
else if (c == QLatin1Char(
'.')) {
 
  444             result += QLatin1String(
"\\.");
 
  446             result += QString::fromLatin1(
"\\x%1").arg(c.unicode(), 4, 16, QLatin1Char(
'0'));
 
  452 void LonLatParser::getLocaleList( QStringList& localeList, 
const QString& localeListString,
 
  453                                   const QLatin1String& placeholder, 
const QString& separator )
 
  455     const QString lowerLocaleListString = localeListString.toLower();
 
  456     if (lowerLocaleListString != placeholder) {
 
  457         localeList = lowerLocaleListString.split(separator, QString::SkipEmptyParts);
 
  461 bool LonLatParser::isDirection( 
const QString& input, 
const QStringList& directions )
 
  463     return ( directions.contains(input) );
 
  466 bool LonLatParser::isDirection( 
const QString& input, 
const QString& 
direction )
 
  468     return ( input == direction );
 
  471 bool LonLatParser::isOneOfDirections( 
const QString& input,
 
  472                                       const QString& firstDirection,
 
  473                                       const QString& secondDirection,
 
  474                                       bool& isFirstDirection )
 
  476     isFirstDirection = isDirection(input, firstDirection);
 
  477     return isFirstDirection || isDirection(input, secondDirection);
 
  480 bool LonLatParser::isOneOfDirections( 
const QString& input,
 
  481                                       const QStringList& firstDirections,
 
  482                                       const QStringList& secondDirections,
 
  483                                       bool& isFirstDirection )
 
  485     isFirstDirection = isDirection(input, firstDirections);
 
  486     return isFirstDirection || isDirection(input, secondDirections);
 
  490 bool LonLatParser::isLocaleLonDirection( 
const QString& input,
 
  491                                          bool& isDirPosHemisphere )
 const 
  493     return isOneOfDirections(input, m_eastLocale, m_westLocale, isDirPosHemisphere);
 
  496 bool LonLatParser::isLocaleLatDirection( 
const QString& input,
 
  497                                          bool& isDirPosHemisphere )
 const 
  499     return isOneOfDirections(input, m_northLocale, m_southLocale, isDirPosHemisphere);
 
  502 bool LonLatParser::isLonDirection( 
const QString& input,
 
  503                                    bool& isDirPosHemisphere )
 const 
  505     return isOneOfDirections(input, m_east, m_west, isDirPosHemisphere);
 
  508 bool LonLatParser::isLatDirection( 
const QString& input,
 
  509                                    bool& isDirPosHemisphere )
 const 
  511     return isOneOfDirections(input, m_north, m_south, isDirPosHemisphere);
 
  515 qreal LonLatParser::degreeValueFromDMS( 
const QRegExp& regex, 
int c, 
bool isPosHemisphere )
 
  517     const bool isNegativeValue = (regex.cap( c++ ) == QLatin1String(
"-"));
 
  518     const uint degree = regex.cap( c++ ).toUInt();
 
  519     const uint minutes = regex.cap( c++ ).toUInt();
 
  520     const qreal seconds = regex.cap( c ).toDouble();
 
  526     if (! isPosHemisphere)
 
  532 qreal LonLatParser::degreeValueFromDM( 
const QRegExp& regex, 
int c, 
bool isPosHemisphere )
 
  534     const bool isNegativeValue = (regex.cap( c++ ) == QLatin1String(
"-"));
 
  535     const uint degree = regex.cap( c++ ).toUInt();
 
  536     const qreal minutes = regex.cap( c ).toDouble();
 
  538     qreal result = degree + (minutes*
MIN2HOUR);
 
  542     if (! isPosHemisphere)
 
  548 qreal LonLatParser::degreeValueFromD( 
const QRegExp& regex, 
int c, 
bool isPosHemisphere )
 
  550     qreal result = regex.cap( c ).toDouble();
 
  552     if (! isPosHemisphere)
 
  558 bool LonLatParser::isCorrectDirections(
const QString& dir1, 
const QString& dir2,
 
  560                                        bool& isLonDirPosHemisphere,
 
  561                                        bool& isLatDirPosHemisphere)
 const 
  564     isDir1LonDir = isLocaleLonDirection(dir1, isLonDirPosHemisphere);
 
  565     const bool resultLocale = isDir1LonDir ?
 
  566         isLocaleLatDirection(dir2, isLatDirPosHemisphere) :
 
  567         (isLocaleLatDirection(dir1, isLatDirPosHemisphere) &&
 
  568          isLocaleLonDirection(dir2, isLonDirPosHemisphere));
 
  574     isDir1LonDir = isLonDirection(dir1, isLonDirPosHemisphere);
 
  575     return isDir1LonDir ?
 
  576         isLatDirection(dir2, isLatDirPosHemisphere) :
 
  577         (isLatDirection(dir1, isLatDirPosHemisphere) &&
 
  578          isLonDirection(dir2, isLonDirPosHemisphere));
 
  585 const GeoDataCoordinates GeoDataCoordinates::null = GeoDataCoordinates( 0, 0, 0 ); 
 
  638 #if QT_VERSION < 0x050000 
  641     if(
d->
ref.load() == 1)
 
  772     s_notation = notation;
 
  786     if ( lon > halfCircle ) {
 
  787         int cycles = (int)( ( lon + halfCircle ) / ( 2 * halfCircle ) );
 
  788         return lon - ( cycles * 2 * halfCircle );
 
  790     if ( lon < -halfCircle ) {
 
  791         int cycles = (int)( ( lon - halfCircle ) / ( 2 * halfCircle ) );
 
  792         return lon - ( cycles * 2 * halfCircle );
 
  809     if ( lat > ( halfCircle / 2.0 ) ) {
 
  810         int cycles = (int)( ( lat + halfCircle ) / ( 2 * halfCircle ) );
 
  813             temp = halfCircle - lat;
 
  815             temp = lat - ( cycles * 2 * halfCircle );
 
  817         if ( temp > ( halfCircle / 2.0 ) ) {
 
  818             return ( halfCircle - temp );
 
  820         if ( temp < ( -halfCircle / 2.0 ) ) {
 
  821             return ( -halfCircle - temp );
 
  825     if ( lat < ( -halfCircle / 2.0 ) ) {
 
  826         int cycles = (int)( ( lat - halfCircle ) / ( 2 * halfCircle ) );
 
  829             temp = -halfCircle - lat;
 
  831             temp = lat - ( cycles * 2 * halfCircle );
 
  833         if ( temp > ( +halfCircle / 2.0 ) ) {
 
  834             return ( +halfCircle - temp );
 
  836         if ( temp < ( -halfCircle / 2.0 ) ) {
 
  837             return ( -halfCircle - temp );
 
  855     if ( lon > +halfCircle ) {
 
  856         int cycles = (int)( ( lon + halfCircle ) / ( 2 * halfCircle ) );
 
  857         lon = lon - ( cycles * 2 * halfCircle );
 
  859     if ( lon < -halfCircle ) {
 
  860         int cycles = (int)( ( lon - halfCircle ) / ( 2 * halfCircle ) );
 
  861         lon = lon - ( cycles * 2 * halfCircle );
 
  864     if ( lat > ( +halfCircle / 2.0 ) ) {
 
  865         int cycles = (int)( ( lat + halfCircle ) / ( 2 * halfCircle ) );
 
  868             temp = halfCircle - lat;
 
  870             temp = lat - ( cycles * 2 * halfCircle );
 
  872         if ( temp > ( +halfCircle / 2.0 ) ) {
 
  873             lat =  +halfCircle - temp;
 
  875         if ( temp < ( -halfCircle / 2.0 ) ) {
 
  876             lat =  -halfCircle - temp;
 
  880             lon = -halfCircle + lon;
 
  882             lon = halfCircle + lon;
 
  885     if ( lat < ( -halfCircle / 2.0 ) ) {
 
  886         int cycles = (int)( ( lat - halfCircle ) / ( 2 * halfCircle ) );
 
  889             temp = -halfCircle - lat;
 
  891             temp = lat - ( cycles * 2 * halfCircle );
 
  893         if ( temp > ( +halfCircle / 2.0 ) ) {
 
  894             lat =  +halfCircle - temp;
 
  896         if ( temp < ( -halfCircle / 2.0 ) ) {
 
  897             lat =  -halfCircle - temp;
 
  901             lon = -halfCircle + lon;
 
  903             lon = halfCircle + lon;
 
  912     successful = parser.parse(
string);
 
  938     if ( notation == 
UTM ) {
 
  939         int zoneNumber = 
static_cast<int>( lon / 6.0 ) + 30;
 
  940         return QString::number( zoneNumber );
 
  943     QString weString = ( lon < 0 ) ? tr(
"W") : tr(
"E");
 
  947     qreal lonDegF = ( unit == 
Degree ) ? fabs( lon ) : fabs( (qreal)(lon) * 
RAD2DEG );
 
  950     precision = ( precision < 0 ) ? 5 : precision;
 
  952     if ( notation == 
DMS || notation == 
DM ) {
 
  953         int lonDeg = (int) lonDegF;
 
  954         qreal lonMinF = 60 * (lonDegF - lonDeg);
 
  955         int lonMin = (int) lonMinF;
 
  956         qreal lonSecF = 60 * (lonMinF - lonMin);
 
  957         int lonSec = (int) lonSecF;
 
  960         if ( precision == 0 ) {
 
  961             lonDeg = qRound( lonDegF );
 
  962         } 
else if ( precision <= 2 ) {
 
  963             lonMin = qRound( lonMinF );
 
  964         } 
else if ( precision <= 4 && notation == 
DMS ) {
 
  965             lonSec = qRound( lonSecF );
 
  967             if ( notation == 
DMS ) {
 
  968                 lonSec = lonSecF = qRound( lonSecF * qPow( 10, precision - 4 ) ) / qPow( 10, precision - 4 );
 
  971                 lonMin = lonMinF = qRound( lonMinF * qPow( 10, precision - 2 ) ) / qPow( 10, precision - 2 );
 
  975         if (lonSec > 59 && notation == 
DMS ) {
 
  976             lonSec = lonSecF = 0;
 
  977             lonMin = lonMinF = lonMinF + 1;
 
  980             lonMin = lonMinF = 0;
 
  981             lonDeg = lonDegF = lonDegF + 1;
 
  985         lonString = QString::fromUtf8(
"%1\xc2\xb0").arg(lonDeg, 3, 10, QChar(
' ') );
 
  987         if ( precision == 0 ) {
 
  988             return lonString + weString;
 
  991         if ( notation == 
DMS || precision < 3 ) {
 
  992             lonString += QString(
" %2\'").arg(lonMin, 2, 10, QChar(
'0') );
 
  995         if ( precision < 3 ) {
 
  996             return lonString + weString;
 
  999         if ( notation == 
DMS ) {
 
 1001             if ( precision < 5 ) {
 
 1002                 lonString += QString(
" %3\"").arg(lonSec, 2, 
'f', 0, QChar(
'0') );
 
 1003                 return lonString + weString;
 
 1006             lonString += QString(
" %L3\"").arg(lonSecF, precision - 1, 
'f', precision - 4, QChar(
'0') );
 
 1009             lonString += QString(
" %L3'").arg(lonMinF, precision + 1, 
'f', precision - 2, QChar(
'0') );
 
 1014         lonString = QString::fromUtf8(
"%L1\xc2\xb0").arg(lonDegF, 4 + precision, format, precision, QChar(
' ') );
 
 1022         qreal lonHourF = ( unit == 
Degree ) ? fabs( lon/15.0  ) : fabs( (qreal)(lon/15.0) * RAD2DEG );
 
 1023         int lonHour = (int) lonHourF;
 
 1024         qreal lonMinF = 60 * (lonHourF - lonHour);
 
 1025         int lonMin = (int) lonMinF;
 
 1026         qreal lonSecF = 60 * (lonMinF - lonMin);
 
 1027         int lonSec = (int) lonSecF;
 
 1030         if ( precision == 0 ) {
 
 1031             lonHour = qRound( lonHourF );
 
 1032         } 
else if ( precision <= 2 ) {
 
 1033             lonMin = qRound( lonMinF );
 
 1034         } 
else if ( precision <= 4 ) {
 
 1035             lonSec = qRound( lonSecF );
 
 1037             lonSec = lonSecF = qRound( lonSecF * qPow( 10, precision - 4 ) ) / qPow( 10, precision - 4 );
 
 1041             lonSec = lonSecF = 0;
 
 1042             lonMin = lonMinF = lonMinF + 1;
 
 1045             lonMin = lonMinF = 0;
 
 1046             lonHour = lonHourF = lonHourF + 1;
 
 1050         lonString = QString::fromUtf8(
"%1h").arg(lonHour, 3, 10, QChar(
' ') );
 
 1052         if ( precision == 0 ) {
 
 1056         lonString += QString(
" %2\'").arg(lonMin, 2, 10, QChar(
'0') );
 
 1058         if ( precision < 3 ) {
 
 1063         if ( precision < 5 ) {
 
 1064             lonString += QString(
" %3\"").arg(lonSec, 2, 
'f', 0, QChar(
'0') );
 
 1068         lonString += QString(
" %L3\"").arg(lonSecF, precision - 1, 
'f', precision - 4, QChar(
'0') );
 
 1072     return lonString + weString;
 
 1085     if ( notation == 
UTM ) {
 
 1086         int bandLetterIndex = 
static_cast<int>( lat / 8.0 ) + 10;
 
 1087         return QString( 
"CDEFGHJKLMNPQRSTUVWX???" ).at( bandLetterIndex );
 
 1094         pmString = ( lat > 0 ) ? 
"+" : 
"-";
 
 1097         nsString = ( lat > 0 ) ? tr(
"N") : tr(
"S");
 
 1102     qreal latDegF = ( unit == 
Degree ) ? fabs( lat ) : fabs( (qreal)(lat) * 
RAD2DEG );
 
 1105     precision = ( precision < 0 ) ? 5 : precision;
 
 1107     if ( notation == 
DMS || notation == 
DM || notation == 
Astro) {
 
 1108         int latDeg = (int) latDegF;
 
 1109         qreal latMinF = 60 * (latDegF - latDeg);
 
 1110         int latMin = (int) latMinF;
 
 1111         qreal latSecF = 60 * (latMinF - latMin);
 
 1112         int latSec = (int) latSecF;
 
 1115         if ( precision == 0 ) {
 
 1116             latDeg = qRound( latDegF );
 
 1117         } 
else if ( precision <= 2 ) {
 
 1118             latMin = qRound( latMinF );
 
 1119         } 
else if ( precision <= 4 && notation == 
DMS ) {
 
 1120             latSec = qRound( latSecF );
 
 1122             if ( notation == 
DMS || notation == 
Astro ) {
 
 1123                 latSec = latSecF = qRound( latSecF * qPow( 10, precision - 4 ) ) / qPow( 10, precision - 4 );
 
 1126                 latMin = latMinF = qRound( latMinF * qPow( 10, precision - 2 ) ) / qPow( 10, precision - 2 );
 
 1130         if (latSec > 59 && ( notation == 
DMS || notation == 
Astro )) {
 
 1133             latMin = latMin + 1;
 
 1138             latDeg = latDeg + 1;
 
 1142         latString = QString::fromUtf8(
"%1\xc2\xb0").arg(latDeg, 3, 10, QChar(
' ') );
 
 1144         if ( precision == 0 ) {
 
 1145             return pmString + latString + nsString;
 
 1148         if ( notation == 
DMS || notation == 
Astro || precision < 3 ) {
 
 1149             latString += QString(
" %2\'").arg(latMin, 2, 10, QChar(
'0') );
 
 1152         if ( precision < 3 ) {
 
 1153             return pmString + latString + nsString;
 
 1156         if ( notation == 
DMS || notation == 
Astro ) {
 
 1158             if ( precision < 5 ) {
 
 1159                 latString += QString(
" %3\"").arg(latSec, 2, 
'f', 0, QChar(
'0') );
 
 1160                 return latString + nsString;
 
 1163             latString += QString(
" %L3\"").arg(latSecF, precision - 1, 
'f', precision - 4, QChar(
'0') );
 
 1166             latString += QString(
" %L3'").arg(latMinF, precision + 1, 
'f', precision - 2, QChar(
'0') );
 
 1171         latString = QString::fromUtf8(
"%L1\xc2\xb0").arg(latDegF, 4 + precision, format, precision, QChar(
' ') );
 
 1173     return pmString + latString + nsString;
 
 1183     return *
d == *rhs.
d;
 
 1188     return *
d != *rhs.
d;
 
 1216         double const offset = unit == 
Degree ? 180.0 : 
M_PI;
 
 1221     double const bearing = atan2( sin ( delta ) * cos ( other.
d->
m_lat ),
 
 1236     if ( fabs( (qreal) 2.0 * 
d->
m_lat ) < 
M_PI ) {
 
 1240         if ( fabs( (qreal) 2.0 * 
d->
m_lat ) == 
M_PI ) {
 
 1260             mDebug() << 
"GeoDataCoordinates not normalized!";
 
 1289     qAtomicAssign(
d, other.
d);
 
Unit
enum used constructor to specify the units used 
 
virtual bool operator==(const GeoDataCoordinates &) const 
 
virtual void unpack(QDataStream &stream)
Unserialize the contents of the feature from stream. 
 
A 3d point representation. 
 
int detail() const 
return the detail flag detail range: 0 for most important points, 5 for least important ...
 
GeoDataCoordinatesPrivate * d
 
void setAltitude(const qreal altitude)
set the altitude of the Point in meters 
 
static qreal normalizeLon(qreal lon, GeoDataCoordinates::Unit=GeoDataCoordinates::Radian)
normalize the longitude to always be -M_PI <= lon <= +M_PI (Radian). 
 
virtual ~GeoDataCoordinates()
 
GeoDataCoordinates()
constructs an invalid instance 
 
"Decimal" notation (base-10) 
 
qreal latitude(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const 
retrieves the latitude of the GeoDataCoordinates object use the unit parameter to switch between Radi...
 
void setDetail(const int det)
set the detail flag 
 
BearingType
The BearingType enum specifies where to measure the bearing along great circle arcs. 
 
qreal altitude() const 
return the altitude of the Point in meters 
 
void geoCoordinates(qreal &lon, qreal &lat, GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const 
use this function to get the longitude and latitude with one call - use the unit parameter to switch ...
 
qreal bearing(const GeoDataCoordinates &other, Unit unit=Radian, BearingType type=InitialBearing) const 
Returns the bearing (true bearing, the angle between the line defined by this point and the other and...
 
static qreal normalizeLat(qreal lat, GeoDataCoordinates::Unit=GeoDataCoordinates::Radian)
normalize latitude to always be in -M_PI / 2. 
 
static void normalizeLonLat(qreal &lon, qreal &lat, GeoDataCoordinates::Unit=GeoDataCoordinates::Radian)
normalize both longitude and latitude at the same time This method normalizes both latitude and longi...
 
void set(qreal lon, qreal lat, qreal alt=0, GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian)
(re)set the coordinates in a GeoDataCoordinates object 
 
QString latToString() const 
return a string representation of latitude of the coordinate convenience function that uses the defau...
 
virtual bool operator!=(const GeoDataCoordinates &) const 
 
QString lonToString() const 
return a string representation of longitude of the coordinate convenience function that uses the defa...
 
qreal longitude(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const 
retrieves the longitude of the GeoDataCoordinates object use the unit parameter to switch between Rad...
 
void setLatitude(qreal lat, GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian)
set the longitude in a GeoDataCoordinates object 
 
void setLongitude(qreal lon, GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian)
set the longitude in a GeoDataCoordinates object 
 
Notation
enum used to specify the notation / numerical system 
 
bool isPole(Pole=AnyPole) const 
return whether our coordinates represent a pole This method can be used to check whether the coordina...
 
QString toString() const 
return a string representation of the coordinate this is a convenience function which uses the defaul...
 
static void setDefaultNotation(GeoDataCoordinates::Notation notation)
set the Notation of the string representation 
 
static GeoDataCoordinates fromString(const QString &string, bool &successful)
try to parse the string into a coordinate pair 
 
bool isValid() const 
Returns. 
 
"Sexagesimal DMS" notation (base-60) 
 
static GeoDataCoordinates::Notation defaultNotation()
return Notation of string representation 
 
"Sexagesimal DM" notation (base-60) 
 
QDebug mDebug()
a function to replace qDebug() in Marble library code 
 
< "RA and DEC" notation (used for astronomical sky coordinates) 
 
static Quaternion fromSpherical(qreal lon, qreal lat)
used to generate Quaternion from longitude and latitude 
 
const Quaternion & quaternion() const 
return a Quaternion with the used coordinates 
 
virtual void pack(QDataStream &stream) const 
Serialize the contents of the feature to stream. 
 
GeoDataCoordinates & operator=(const GeoDataCoordinates &other)