Ref T111, coordinate selector

UI component to change and enter coordinates
This commit is contained in:
Klaus Basan
2017-07-26 15:17:18 +02:00
committed by Mathew Sutcliffe
parent ba31171a10
commit d00c0c0519
3 changed files with 545 additions and 0 deletions

View File

@@ -0,0 +1,213 @@
/* Copyright (C) 2017
* swift project Community / Contributors
*
* This file is part of swift Project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
#include "coordinateselector.h"
#include "blackcore/webdataservices.h"
#include "blackcore/db/airportdatareader.h"
#include "blackgui/guiapplication.h"
#include "blackmisc/aviation/airport.h"
#include "ui_coordinateselector.h"
#include <QIntValidator>
using namespace BlackGui;
using namespace BlackMisc::Geo;
using namespace BlackMisc::Aviation;
using namespace BlackMisc::PhysicalQuantities;
namespace BlackGui
{
namespace Components
{
CCoordinateSelector::CCoordinateSelector(QWidget *parent) :
QFrame(parent),
ui(new Ui::CCoordinateSelector)
{
ui->setupUi(this);
ui->lblp_LatCheck->setToolTips("ok", "wrong format");
ui->lblp_LngCheck->setToolTips("ok", "wrong format");
ui->lblp_AltCheck->setToolTips("ok", "wrong format");
ui->le_LatDeg->setValidator(new QIntValidator(-90, 90, ui->le_LatDeg));
ui->le_LatMin->setValidator(new QIntValidator(0, 60, ui->le_LatMin));
ui->le_LatSec->setValidator(new QIntValidator(0, 60, ui->le_LatSec));
ui->le_LatSecFrag->setValidator(new QIntValidator(0, 10E7, ui->le_LatSecFrag));
ui->le_LngDeg->setValidator(new QIntValidator(-180, 180, ui->le_LngDeg));
ui->le_LngMin->setValidator(new QIntValidator(0, 60, ui->le_LngMin));
ui->le_LngSec->setValidator(new QIntValidator(0, 60, ui->le_LngSec));
ui->le_LngSecFrag->setValidator(new QIntValidator(0, 10E7, ui->le_LngSecFrag));
connect(ui->le_Latitude, &QLineEdit::editingFinished, this, &CCoordinateSelector::latEntered);
connect(ui->le_Longitude, &QLineEdit::editingFinished, this, &CCoordinateSelector::lngEntered);
connect(ui->le_Elevation, &QLineEdit::editingFinished, this, &CCoordinateSelector::elvEntered);
connect(ui->le_LatDeg, &QLineEdit::editingFinished, this, &CCoordinateSelector::latCombinedEntered);
connect(ui->le_LatMin, &QLineEdit::editingFinished, this, &CCoordinateSelector::latCombinedEntered);
connect(ui->le_LatSec, &QLineEdit::editingFinished, this, &CCoordinateSelector::latCombinedEntered);
connect(ui->le_LatSecFrag, &QLineEdit::editingFinished, this, &CCoordinateSelector::latCombinedEntered);
connect(ui->le_LngDeg, &QLineEdit::editingFinished, this, &CCoordinateSelector::lngCombinedEntered);
connect(ui->le_LngMin, &QLineEdit::editingFinished, this, &CCoordinateSelector::lngCombinedEntered);
connect(ui->le_LngSec, &QLineEdit::editingFinished, this, &CCoordinateSelector::lngCombinedEntered);
connect(ui->le_LngSecFrag, &QLineEdit::editingFinished, this, &CCoordinateSelector::lngCombinedEntered);
connect(ui->le_Location, &QLineEdit::returnPressed, this, &CCoordinateSelector::locationEntered);
const CCoordinateGeodetic c;
this->setCoordinate(c);
}
CCoordinateSelector::~CCoordinateSelector()
{ }
void CCoordinateSelector::setCoordinate(const ICoordinateGeodetic &coordinate)
{
m_coordinate = coordinate;
const CLatitude lat = coordinate.latitude();
const QString latWgs = lat.toWgs84();
ui->le_Latitude->setText(latWgs);
ui->le_Latitude->setToolTip(QString::number(lat.value(CAngleUnit::deg())));
ui->lblp_LatCheck->setTicked(!lat.isNull());
if (latWgs.contains('S'))
{
ui->rb_S->setChecked(true);
}
else
{
ui->rb_N->setChecked(true);
}
const CLongitude lng = coordinate.longitude();
const QString lngWgs = lng.toWgs84();
ui->le_Longitude->setText(lngWgs);
ui->le_Longitude->setToolTip(QString::number(lng.value(CAngleUnit::deg())));
ui->lblp_LngCheck->setTicked(!lng.isNull());
if (lngWgs.contains('W'))
{
ui->rb_W->setChecked(true);
}
else
{
ui->rb_E->setChecked(true);
}
const CLatitude::DegMinSecFractionalSec latParts = lat.asSexagesimalDegMinSec(true);
ui->le_LatDeg->setText(latParts.degAsString());
ui->le_LatMin->setText(latParts.minAsString());
ui->le_LatSec->setText(latParts.secAsString());
ui->le_LatSecFrag->setText(latParts.fractionalSecAsString());
const CLongitude::DegMinSecFractionalSec lngParts = lng.asSexagesimalDegMinSec(true);
ui->le_LngDeg->setText(lngParts.degAsString());
ui->le_LngMin->setText(lngParts.minAsString());
ui->le_LngSec->setText(lngParts.secAsString());
ui->le_LngSecFrag->setText(lngParts.fractionalSecAsString());
ui->le_Elevation->setText(coordinate.geodeticHeightAsString());
}
void CCoordinateSelector::locationEntered()
{
const QString l = ui->le_Location->text().trimmed().toUpper();
// location based on swift data
if (sApp && sApp->hasWebDataServices())
{
// airport ICAO
if (l.length() == 4 && sApp->getWebDataServices()->getAirportsCount() > 0)
{
const CAirport airport = sApp->getWebDataServices()->getAirportForIcaoDesignator(l);
if (airport.hasValidDbKey())
{
this->setCoordinate(airport);
return;
}
}
}
}
void CCoordinateSelector::latEntered()
{
const QString ls = ui->le_Latitude->text();
const CLatitude l = CLatitude::fromWgs84(ls);
ui->lblp_LatCheck->setTicked(!l.isNull());
CCoordinateGeodetic c = m_coordinate;
c.setLatitude(l);
this->setCoordinate(c);
}
void CCoordinateSelector::latCombinedEntered()
{
bool ok;
int deg = ui->le_LatDeg->text().trimmed().toInt(&ok);
if (!ok) return;
int min = ui->le_LatMin->text().trimmed().toInt(&ok);
if (!ok) return;
const QString secStr = ui->le_LatSec->text().trimmed() + "." + ui->le_LatSecFrag->text().trimmed();
double sec = secStr.toDouble(&ok);
if (!ok) return;
CAngle::unifySign(deg, min, sec);
const CAngle a(deg, min, sec);
CLatitude lat(a);
lat.roundToEpsilon();
CCoordinateGeodetic c = m_coordinate;
c.setLatitude(lat);
this->setCoordinate(c);
}
void CCoordinateSelector::lngEntered()
{
const QString ls = ui->le_Longitude->text();
const CLongitude l = CLongitude::fromWgs84(ls);
ui->lblp_LatCheck->setTicked(!l.isNull());
CCoordinateGeodetic c = m_coordinate;
c.setLongitude(l);
this->setCoordinate(c);
}
void CCoordinateSelector::lngCombinedEntered()
{
bool ok;
int deg = ui->le_LngDeg->text().trimmed().toInt(&ok);
if (!ok) return;
int min = ui->le_LngMin->text().trimmed().toInt(&ok);
if (!ok) return;
const QString secStr = ui->le_LngSec->text().trimmed() + "." + ui->le_LngSecFrag->text().trimmed();
double sec = secStr.toDouble(&ok);
if (!ok) return;
CAngle::unifySign(deg, min, sec);
const CAngle a(deg, min, sec);
CLongitude lng(a);
lng.roundToEpsilon();
CCoordinateGeodetic c = m_coordinate;
c.setLongitude(lng);
this->setCoordinate(c);
}
void CCoordinateSelector::elvEntered()
{
const QString e = ui->le_Elevation->text();
CAltitude a;
a.parseFromString(e);
ui->lblp_AltCheck->setTicked(!e.isNull());
CCoordinateGeodetic c = m_coordinate;
c.setGeodeticHeight(a);
this->setCoordinate(c);
}
} // ns
} // ns

View File

@@ -0,0 +1,58 @@
/* Copyright (C) 2017
* swift project Community / Contributors
*
* This file is part of swift Project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
//! \file
#ifndef BLACKGUI_COMPONENTS_COORDINATESELECTOR_H
#define BLACKGUI_COMPONENTS_COORDINATESELECTOR_H
#include "blackmisc/geo/coordinategeodetic.h"
#include "blackgui/blackguiexport.h"
#include <QFrame>
namespace Ui { class CCoordinateSelector; }
namespace BlackGui
{
namespace Components
{
/**
* Select / enter a geo position
*/
class BLACKGUI_EXPORT CCoordinateSelector : public QFrame
{
Q_OBJECT
public:
//! Ctor
explicit CCoordinateSelector(QWidget *parent = nullptr);
//! Dtor
virtual ~CCoordinateSelector();
//! Get the coordinate
BlackMisc::Geo::CCoordinateGeodetic getCoordinate() const { return m_coordinate; }
//! Set the coordinate
void setCoordinate(const BlackMisc::Geo::ICoordinateGeodetic &coordinate);
private:
QScopedPointer<Ui::CCoordinateSelector> ui;
void locationEntered();
void latEntered();
void latCombinedEntered();
void lngEntered();
void lngCombinedEntered();
void elvEntered();
BlackMisc::Geo::CCoordinateGeodetic m_coordinate;
};
} // ns
} // ns
#endif // guard

View File

@@ -0,0 +1,274 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CCoordinateSelector</class>
<widget class="QFrame" name="CCoordinateSelector">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>740</width>
<height>116</height>
</rect>
</property>
<property name="windowTitle">
<string>Frame</string>
</property>
<layout class="QGridLayout" name="gl_CoordinateSelector">
<item row="3" column="2">
<widget class="BlackGui::CTickLabel" name="lblp_AltCheck">
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="5">
<widget class="QLineEdit" name="le_LngDeg">
<property name="placeholderText">
<string>deg.</string>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="QLineEdit" name="le_LatMin">
<property name="placeholderText">
<string>min</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QRadioButton" name="rb_E">
<property name="text">
<string>E</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">bg_EW</string>
</attribute>
</widget>
</item>
<item row="1" column="3">
<widget class="QRadioButton" name="rb_N">
<property name="text">
<string>N</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">bg_NS</string>
</attribute>
</widget>
</item>
<item row="1" column="8">
<widget class="QLineEdit" name="le_LatSecFrag">
<property name="placeholderText">
<string>fract.sec</string>
</property>
</widget>
</item>
<item row="3" column="5" colspan="4">
<widget class="QLineEdit" name="le_Location"/>
</item>
<item row="2" column="8">
<widget class="QLineEdit" name="le_LngSecFrag">
<property name="placeholderText">
<string>fract.sec</string>
</property>
</widget>
</item>
<item row="2" column="7">
<widget class="QLineEdit" name="le_LngSec">
<property name="placeholderText">
<string>sec</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lbl_Latitude">
<property name="text">
<string>Latitude (0°-90°):</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="lbl_Longitude">
<property name="text">
<string>Longitude (0°-180°):</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="BlackGui::CTickLabel" name="lblp_LngCheck">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="le_Longitude">
<property name="minimumSize">
<size>
<width>120</width>
<height>0</height>
</size>
</property>
<property name="placeholderText">
<string>WGS 0° 0' 0.000&quot; E/W</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="le_Latitude">
<property name="minimumSize">
<size>
<width>120</width>
<height>0</height>
</size>
</property>
<property name="placeholderText">
<string>WGS 0° 0' 0.000&quot; N/S</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="BlackGui::CTickLabel" name="lblp_LatCheck">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="le_Elevation">
<property name="minimumSize">
<size>
<width>120</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="lbl_Altitude">
<property name="text">
<string>Elevation:</string>
</property>
</widget>
</item>
<item row="1" column="7">
<widget class="QLineEdit" name="le_LatSec">
<property name="placeholderText">
<string>sec</string>
</property>
</widget>
</item>
<item row="2" column="6">
<widget class="QLineEdit" name="le_LngMin">
<property name="placeholderText">
<string>min</string>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QRadioButton" name="rb_W">
<property name="text">
<string>W</string>
</property>
<attribute name="buttonGroup">
<string notr="true">bg_EW</string>
</attribute>
</widget>
</item>
<item row="1" column="5">
<widget class="QLineEdit" name="le_LatDeg">
<property name="placeholderText">
<string>deg.</string>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QRadioButton" name="rb_S">
<property name="text">
<string>S</string>
</property>
<attribute name="buttonGroup">
<string notr="true">bg_NS</string>
</attribute>
</widget>
</item>
<item row="3" column="3" colspan="2">
<widget class="QLabel" name="lbl_Location">
<property name="text">
<string>Location:</string>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QLabel" name="lbl_Deg">
<property name="text">
<string>deg</string>
</property>
</widget>
</item>
<item row="0" column="6">
<widget class="QLabel" name="lbl_Min">
<property name="text">
<string>min</string>
</property>
</widget>
</item>
<item row="0" column="7">
<widget class="QLabel" name="lbl_Sec">
<property name="text">
<string>sec</string>
</property>
</widget>
</item>
<item row="0" column="8">
<widget class="QLabel" name="lbl_FracSec">
<property name="text">
<string>fract.sec</string>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>BlackGui::CTickLabel</class>
<extends>QLabel</extends>
<header>blackgui/ticklabel.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>le_Latitude</tabstop>
<tabstop>rb_N</tabstop>
<tabstop>rb_S</tabstop>
<tabstop>le_LatDeg</tabstop>
<tabstop>le_LatMin</tabstop>
<tabstop>le_LatSec</tabstop>
<tabstop>le_LatSecFrag</tabstop>
<tabstop>le_Longitude</tabstop>
<tabstop>rb_E</tabstop>
<tabstop>rb_W</tabstop>
<tabstop>le_LngDeg</tabstop>
<tabstop>le_LngMin</tabstop>
<tabstop>le_LngSec</tabstop>
<tabstop>le_LngSecFrag</tabstop>
<tabstop>le_Elevation</tabstop>
<tabstop>le_Location</tabstop>
</tabstops>
<resources/>
<connections/>
<buttongroups>
<buttongroup name="bg_EW"/>
<buttongroup name="bg_NS"/>
</buttongroups>
</ui>