326 lines
7.2 KiB
C++
Executable File
326 lines
7.2 KiB
C++
Executable File
|
|
|
|
|
|
#include "lts_coord_widget_p.h"
|
|
|
|
|
|
namespace LtsCoordWidget
|
|
{
|
|
|
|
|
|
|
|
void LtsCoordInputWidgetHandler::onCoordinateDataChanged()
|
|
{
|
|
const QPointF coord(coordinate());
|
|
if (coord.isNull())
|
|
{
|
|
emit invalidCoordinate();
|
|
return;
|
|
}
|
|
emit coordinateChanged(coord);
|
|
}
|
|
|
|
|
|
|
|
|
|
MgrsEdit::MgrsEdit(int precision, QWidget *widget)
|
|
: LtsCoordInputWidgetHandler(widget)
|
|
, m_precision(precision)
|
|
, m_ui(new Ui::Mgrs)
|
|
{
|
|
m_ui->setupUi(widget);
|
|
|
|
if (m_precision < 0)
|
|
m_precision = 0;
|
|
if (m_precision > 11)
|
|
m_precision = 11;
|
|
const int upperLimit = pow(10, m_precision) - 1;
|
|
m_ui->leEast->setValidator(new QIntValidator(0, upperLimit, m_ui->leEast));
|
|
m_ui->leNorth->setValidator(new QIntValidator(0, upperLimit, m_ui->leNorth));
|
|
setDefaultMgrsSquares();
|
|
|
|
connect(m_ui->cbxZone, QOverload<const QString &>::of(&QComboBox::currentIndexChanged),
|
|
this, &MgrsEdit::onCoordinateDataChanged);
|
|
connect(m_ui->leEast, &QLineEdit::editingFinished,
|
|
this, &MgrsEdit::onCoordinateDataChanged);
|
|
connect(m_ui->leNorth, &QLineEdit::editingFinished,
|
|
this, &MgrsEdit::onCoordinateDataChanged);
|
|
}
|
|
|
|
MgrsEdit::~MgrsEdit()
|
|
{
|
|
delete m_ui;
|
|
}
|
|
|
|
bool MgrsEdit::isValid()
|
|
{
|
|
|
|
const QString &east = m_ui->leEast->text();
|
|
if (east.size() != m_precision)
|
|
return false;
|
|
|
|
const QString &north = m_ui->leNorth->text();
|
|
if (north.size() != m_precision)
|
|
return false;
|
|
|
|
if (m_ui->cbxZone->currentIndex() < 0)
|
|
return false;
|
|
|
|
if (m_ui->cbxZone->currentText().isEmpty())
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void MgrsEdit::setCoordinate(const QPointF &geoCoord)
|
|
{
|
|
const QString mgrsString = LtsCoordTrans::mgrsFromGeographic(geoCoord.x(), geoCoord.y(), m_precision, false);
|
|
if (mgrsString.isEmpty())
|
|
{
|
|
m_ui->leEast->clear();
|
|
m_ui->leNorth->clear();
|
|
return;
|
|
}
|
|
|
|
m_ui->leEast->setText(QString());
|
|
m_ui->leNorth->setText(QString());
|
|
|
|
|
|
const QString mgrsSquare = mgrsString.left(3) + QLatin1Char(' ') + mgrsString.mid(3, 2);
|
|
QString east = mgrsString.mid(5, m_precision);
|
|
QString north = mgrsString.mid(5 + m_precision, m_precision);
|
|
int idx = m_ui->cbxZone->findText(mgrsSquare);
|
|
if (idx < 0)
|
|
{
|
|
addMgrsSquare(mgrsSquare);
|
|
idx = m_ui->cbxZone->findText(mgrsSquare);
|
|
}
|
|
m_ui->cbxZone->setCurrentIndex(idx);
|
|
m_ui->leEast->setText(east);
|
|
m_ui->leNorth->setText(north);
|
|
}
|
|
|
|
static inline QString getMgrsCoord(QLineEdit *le, int prec)
|
|
{
|
|
QString ret = le->text();
|
|
if (ret.isEmpty())
|
|
return ret;
|
|
while (ret.size() < prec)
|
|
ret += QLatin1Char('0');
|
|
le->setText(ret);
|
|
return ret;
|
|
}
|
|
|
|
QPointF MgrsEdit::coordinate() const
|
|
{
|
|
const QString east = getMgrsCoord(m_ui->leEast, m_precision);
|
|
const QString north = getMgrsCoord(m_ui->leNorth, m_precision);
|
|
if (east.isEmpty() || north.isEmpty() || m_ui->cbxZone->currentIndex() < 0)
|
|
return QPointF();
|
|
|
|
const QString mgrsString(m_ui->cbxZone->currentText() + east + north);
|
|
return LtsCoordTrans::geographicFromMgrs(mgrsString);
|
|
}
|
|
|
|
QToolButton *MgrsEdit::resetButton()
|
|
{
|
|
return m_ui->tbReset;
|
|
}
|
|
|
|
void MgrsEdit::cleanup()
|
|
{
|
|
|
|
|
|
delete m_ui->horizontalLayout;
|
|
delete m_ui->cbxZone;
|
|
delete m_ui->leEast;
|
|
delete m_ui->leNorth;
|
|
delete m_ui->tbReset;
|
|
}
|
|
|
|
void MgrsEdit::clear()
|
|
{
|
|
m_ui->cbxZone->clear();
|
|
m_ui->leEast->clear();
|
|
m_ui->leNorth->clear();
|
|
setDefaultMgrsSquares();
|
|
}
|
|
|
|
void MgrsEdit::setSquaresEditable(bool bEditable)
|
|
{
|
|
m_ui->cbxZone->setEditable(bEditable);
|
|
}
|
|
|
|
void MgrsEdit::setWithSurroundingSquare(bool bEnabled)
|
|
{
|
|
m_withMgrsSquareOffset = bEnabled;
|
|
}
|
|
|
|
static QStringList defaultMgrsSquares()
|
|
{
|
|
const QVector<LtsCoordTrans::UtmCoordinate> squares(LtsCoordTrans::defaultMgrsSquares());
|
|
QStringList sl;
|
|
sl.reserve(squares.size());
|
|
for (const LtsCoordTrans::UtmCoordinate &c : squares)
|
|
sl += c.mgrs(0);
|
|
std::sort(sl.begin(), sl.end());
|
|
return sl;
|
|
}
|
|
|
|
static QString preferedMgrsSquare()
|
|
{
|
|
const LtsCoordTrans::UtmCoordinate c(LtsCoordTrans::preferedMgrsSquare());
|
|
return c.mgrs(0);
|
|
}
|
|
|
|
|
|
void MgrsEdit::setDefaultMgrsSquares()
|
|
{
|
|
m_ui->cbxZone->addItems(defaultMgrsSquares());
|
|
m_ui->cbxZone->setCurrentIndex(m_ui->cbxZone->findText(preferedMgrsSquare()));
|
|
}
|
|
|
|
void MgrsEdit::addMgrsSquare(const QString &newMgrsSquare)
|
|
{
|
|
QStringList sl = defaultMgrsSquares();
|
|
sl += newMgrsSquare;
|
|
if (m_withMgrsSquareOffset)
|
|
{
|
|
QStringList squares = utmCoordsToList(LtsCoordTrans::defaultMgrsSquareWithOffsets());
|
|
|
|
for (const auto &sq : qAsConst(squares))
|
|
if (!sl.contains(sq))
|
|
sl.append(sq);
|
|
}
|
|
std::sort(sl.begin(), sl.end());
|
|
m_ui->cbxZone->clear();
|
|
m_ui->cbxZone->addItems(sl);
|
|
}
|
|
|
|
QStringList MgrsEdit::utmCoordsToList(const QVector<LtsCoordTrans::UtmCoordinate> &coords)
|
|
{
|
|
QStringList list;
|
|
list.reserve(coords.count());
|
|
for (const auto &utm : coords)
|
|
list.append(utm.mgrs(0));
|
|
|
|
return list;
|
|
}
|
|
|
|
void MgrsEdit::setMgrsSquares(const QVector<LtsCoordTrans::UtmCoordinate> &geoCoords)
|
|
{
|
|
QStringList sl = utmCoordsToList(geoCoords);
|
|
if (sl.isEmpty())
|
|
return;
|
|
|
|
std::sort(sl.begin(), sl.end());
|
|
m_ui->cbxZone->clear();
|
|
m_ui->cbxZone->addItems(sl);
|
|
}
|
|
|
|
|
|
|
|
|
|
Wgs84Edit::Wgs84Edit(QWidget *widget)
|
|
: LtsCoordInputWidgetHandler(widget)
|
|
, m_ui(new Ui::Wgs84)
|
|
{
|
|
m_ui->setupUi(widget);
|
|
|
|
DoubleValidator *v = new DoubleValidator(-180, 180, 9, m_ui->leLon);
|
|
v->setNotation(QDoubleValidator::StandardNotation);
|
|
m_ui->leLon->setValidator(v);
|
|
|
|
v = new DoubleValidator(-180, 180, 9, m_ui->leLat);
|
|
v->setNotation(QDoubleValidator::StandardNotation);
|
|
m_ui->leLat->setValidator(v);
|
|
|
|
connect(m_ui->leLon, &QLineEdit::editingFinished,
|
|
this, &Wgs84Edit::onCoordinateDataChanged);
|
|
connect(m_ui->leLat, &QLineEdit::editingFinished,
|
|
this, &Wgs84Edit::onCoordinateDataChanged);
|
|
}
|
|
|
|
Wgs84Edit::~Wgs84Edit()
|
|
{
|
|
delete m_ui;
|
|
}
|
|
|
|
bool Wgs84Edit::isValid()
|
|
{
|
|
|
|
return (!m_ui->leLon->text().isEmpty()) && (!m_ui->leLat->text().isEmpty());
|
|
}
|
|
|
|
void Wgs84Edit::setCoordinate(const QPointF &geoCoord)
|
|
{
|
|
const QPointF coord(geoCoord * LtsCoordTrans::rad2deg());
|
|
const QLocale l;
|
|
m_ui->leLon->setText(l.toString(coord.x(), 'f', 9));
|
|
m_ui->leLat->setText(l.toString(coord.y(), 'f', 9));
|
|
}
|
|
|
|
QPointF Wgs84Edit::coordinate() const
|
|
{
|
|
QPointF ret;
|
|
const QLocale l;
|
|
|
|
|
|
const QString lonStr = m_ui->leLon->text().remove(l.groupSeparator());
|
|
const QString latStr = m_ui->leLat->text().remove(l.groupSeparator());
|
|
if (lonStr.isEmpty() || latStr.isEmpty())
|
|
return ret;
|
|
|
|
ret.rx() = l.toDouble(lonStr);
|
|
ret.ry() = l.toDouble(latStr);
|
|
|
|
return ret * LtsCoordTrans::deg2rad();
|
|
}
|
|
|
|
QToolButton *Wgs84Edit::resetButton()
|
|
{
|
|
return m_ui->tbReset;
|
|
}
|
|
|
|
void Wgs84Edit::cleanup()
|
|
{
|
|
|
|
|
|
delete m_ui->horizontalLayout;
|
|
delete m_ui->leLon;
|
|
delete m_ui->leLat;
|
|
delete m_ui->tbReset;
|
|
delete m_ui->lblLon;
|
|
delete m_ui->lblLat;
|
|
}
|
|
|
|
void Wgs84Edit::clear()
|
|
{
|
|
m_ui->leLon->clear();
|
|
m_ui->leLat->clear();
|
|
}
|
|
|
|
|
|
|
|
|
|
DoubleValidator::DoubleValidator(double bottom, double top, int decimals, QObject *parent)
|
|
: QDoubleValidator(bottom, top, decimals, parent)
|
|
{}
|
|
|
|
QValidator::State DoubleValidator::validate(QString &input, int &pos) const
|
|
{
|
|
const QValidator::State ret = QDoubleValidator::validate(input, pos);
|
|
if (ret != QValidator::Acceptable)
|
|
return ret;
|
|
QLocale l;
|
|
const QChar gs(l.groupSeparator());
|
|
if (gs.isNull())
|
|
return ret;
|
|
if (input.contains(gs))
|
|
return QValidator::Invalid;
|
|
return ret;
|
|
}
|
|
|
|
}
|
|
|