|
|
|
|
|
#include "nmWxPointerPosDlg.h"
|
|
|
|
|
|
#include "nmGUIComponentLineEdit.h"
|
|
|
|
|
|
#include "nmDataAnalyzeManager.h"
|
|
|
|
|
|
#include "nmDataAttribute.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include <QPushButton>
|
|
|
|
|
|
#include <QComboBox>
|
|
|
|
|
|
#include <QLineEdit>
|
|
|
|
|
|
#include <QGroupBox>
|
|
|
|
|
|
#include <QFormLayout>
|
|
|
|
|
|
#include <QHBoxLayout>
|
|
|
|
|
|
#include <QVBoxLayout>
|
|
|
|
|
|
#include <QLabel>
|
|
|
|
|
|
#include <cmath>
|
|
|
|
|
|
|
|
|
|
|
|
nmWxPointerPosDlg::nmWxPointerPosDlg(QWidget* parent)
|
|
|
|
|
|
: iDlgBase(parent)
|
|
|
|
|
|
{
|
|
|
|
|
|
setWindowTitle(tr("Pointer position"));
|
|
|
|
|
|
|
|
|
|
|
|
m_pAttrX = new nmDataAttribute();
|
|
|
|
|
|
m_pAttrX->setName("X");
|
|
|
|
|
|
m_pAttrX->setUnit("m");
|
|
|
|
|
|
m_pAttrX->setListUnitSelections(QStringList() << "m" << "ft" << "cm");
|
|
|
|
|
|
m_pAttrX->setValue(0.0);
|
|
|
|
|
|
|
|
|
|
|
|
m_pAttrY = new nmDataAttribute();
|
|
|
|
|
|
m_pAttrY->setName("Y");
|
|
|
|
|
|
m_pAttrY->setUnit("m");
|
|
|
|
|
|
m_pAttrY->setListUnitSelections(QStringList() << "m" << "ft" << "cm");
|
|
|
|
|
|
m_pAttrY->setValue(0.0);
|
|
|
|
|
|
|
|
|
|
|
|
m_pGeoRefData = nmDataAnalyzeManager::getCurrentInstance()->getGeoRefData();
|
|
|
|
|
|
|
|
|
|
|
|
initUI();
|
|
|
|
|
|
loadGeoRefDataToUI();
|
|
|
|
|
|
this->resize(320, 400);
|
|
|
|
|
|
this->setFixedSize(this->size());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmWxPointerPosDlg::initUI()
|
|
|
|
|
|
{
|
|
|
|
|
|
// Local grid group
|
|
|
|
|
|
QGroupBox* localGroup = new QGroupBox(tr("Local grid"));
|
|
|
|
|
|
|
|
|
|
|
|
QFormLayout* localForm = new QFormLayout;
|
|
|
|
|
|
localForm->setLabelAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
|
|
|
|
|
localForm->setVerticalSpacing(10);
|
|
|
|
|
|
localForm->setHorizontalSpacing(15);
|
|
|
|
|
|
localForm->setContentsMargins(8, 8, 8, 8);
|
|
|
|
|
|
|
|
|
|
|
|
m_pX = new nmGUIComponentLineEdit(m_pAttrX, false);
|
|
|
|
|
|
m_pY = new nmGUIComponentLineEdit(m_pAttrY, false);
|
|
|
|
|
|
QLineEdit* leX = m_pX->findChild<QLineEdit*>();
|
|
|
|
|
|
|
|
|
|
|
|
if(leX) {
|
|
|
|
|
|
leX->setMinimumWidth(100);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QLineEdit* leY = m_pY->findChild<QLineEdit*>();
|
|
|
|
|
|
|
|
|
|
|
|
if(leY) {
|
|
|
|
|
|
leY->setMinimumWidth(100);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QWidget* xWidget = new QWidget;
|
|
|
|
|
|
QHBoxLayout* xLay = new QHBoxLayout(xWidget);
|
|
|
|
|
|
xLay->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
|
xLay->addWidget(m_pX);
|
|
|
|
|
|
|
|
|
|
|
|
QWidget* yWidget = new QWidget;
|
|
|
|
|
|
QHBoxLayout* yLay = new QHBoxLayout(yWidget);
|
|
|
|
|
|
yLay->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
|
yLay->addWidget(m_pY);
|
|
|
|
|
|
|
|
|
|
|
|
localForm->addRow(tr("X:"), xWidget);
|
|
|
|
|
|
localForm->addRow(tr("Y:"), yWidget);
|
|
|
|
|
|
|
|
|
|
|
|
QVBoxLayout* localWrapper = new QVBoxLayout;
|
|
|
|
|
|
localWrapper->addStretch(1);
|
|
|
|
|
|
localWrapper->addLayout(localForm);
|
|
|
|
|
|
localWrapper->addStretch(1);
|
|
|
|
|
|
localWrapper->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
|
localGroup->setLayout(localWrapper);
|
|
|
|
|
|
|
|
|
|
|
|
// Coordinates group
|
|
|
|
|
|
QGroupBox* coordGroup = new QGroupBox(tr("Coordinates"));
|
|
|
|
|
|
coordGroup->setEnabled(true);
|
|
|
|
|
|
|
|
|
|
|
|
QFormLayout* coordForm = new QFormLayout;
|
|
|
|
|
|
coordForm->setLabelAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
|
|
|
|
|
coordForm->setVerticalSpacing(10);
|
|
|
|
|
|
coordForm->setHorizontalSpacing(15);
|
|
|
|
|
|
coordForm->setContentsMargins(8, 8, 8, 8);
|
|
|
|
|
|
|
|
|
|
|
|
m_pLonEdit = new QLineEdit;
|
|
|
|
|
|
m_pLatEdit = new QLineEdit;
|
|
|
|
|
|
m_pUtmZoneCombo = new QComboBox;
|
|
|
|
|
|
m_pEastingEdit = new QLineEdit;
|
|
|
|
|
|
m_pNorthingEdit = new QLineEdit;
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化UTM Zone下拉框选项
|
|
|
|
|
|
QStringList bands;
|
|
|
|
|
|
bands << "C" << "D" << "E" << "F" << "G" << "H" << "J" << "K" << "L" << "M"
|
|
|
|
|
|
<< "N" << "P" << "Q" << "R" << "S" << "T" << "U" << "V" << "W" << "X";
|
|
|
|
|
|
|
|
|
|
|
|
// 外层循环:Band;内层循环:Zone
|
|
|
|
|
|
for(int i = 0; i < bands.size(); ++i) {
|
|
|
|
|
|
QString band = bands.at(i);
|
|
|
|
|
|
for(int zone = 1; zone <= 60; ++zone) {
|
|
|
|
|
|
QString zoneStr = QString("%1%2").arg(zone, 2, 10, QLatin1Char('0')).arg(band);
|
|
|
|
|
|
m_pUtmZoneCombo->addItem(zoneStr);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_pLonEdit->setEnabled(false);
|
|
|
|
|
|
m_pLatEdit->setEnabled(false);
|
|
|
|
|
|
m_pUtmZoneCombo->setEnabled(false); // ComboBox禁用编辑
|
|
|
|
|
|
m_pEastingEdit->setEnabled(false);
|
|
|
|
|
|
m_pNorthingEdit->setEnabled(false);
|
|
|
|
|
|
|
|
|
|
|
|
coordForm->addRow(tr("Longitude:"), m_pLonEdit);
|
|
|
|
|
|
coordForm->addRow(tr("Latitude:"), m_pLatEdit);
|
|
|
|
|
|
coordForm->addItem(new QSpacerItem(0, 20, QSizePolicy::Minimum, QSizePolicy::Fixed));
|
|
|
|
|
|
coordForm->addRow(tr("UTM zone:"), m_pUtmZoneCombo);
|
|
|
|
|
|
coordForm->addRow(tr("Easting:"), m_pEastingEdit);
|
|
|
|
|
|
coordForm->addRow(tr("Northing:"), m_pNorthingEdit);
|
|
|
|
|
|
|
|
|
|
|
|
QVBoxLayout* coordWrapper = new QVBoxLayout;
|
|
|
|
|
|
coordWrapper->addStretch(1);
|
|
|
|
|
|
coordWrapper->addLayout(coordForm);
|
|
|
|
|
|
coordWrapper->addStretch(1);
|
|
|
|
|
|
coordWrapper->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
|
coordGroup->setLayout(coordWrapper);
|
|
|
|
|
|
|
|
|
|
|
|
// Bottom button
|
|
|
|
|
|
m_pCloseButton = new QPushButton(tr("Close"));
|
|
|
|
|
|
connect(m_pCloseButton, SIGNAL(clicked()), this, SLOT(reject()));
|
|
|
|
|
|
QHBoxLayout* btnLay = new QHBoxLayout;
|
|
|
|
|
|
btnLay->addStretch();
|
|
|
|
|
|
btnLay->addWidget(m_pCloseButton);
|
|
|
|
|
|
|
|
|
|
|
|
// 整体布局
|
|
|
|
|
|
QVBoxLayout* mainLay = new QVBoxLayout;
|
|
|
|
|
|
mainLay->setContentsMargins(12, 12, 12, 12);
|
|
|
|
|
|
mainLay->setSpacing(15);
|
|
|
|
|
|
mainLay->addWidget(localGroup);
|
|
|
|
|
|
mainLay->addWidget(coordGroup);
|
|
|
|
|
|
mainLay->addLayout(btnLay);
|
|
|
|
|
|
setLayout(mainLay);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmWxPointerPosDlg::setPointerPos(double x, double y)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 更新X、Y坐标显示
|
|
|
|
|
|
m_pX->setDisplayValue(x);
|
|
|
|
|
|
m_pY->setDisplayValue(y);
|
|
|
|
|
|
|
|
|
|
|
|
// 检查是否有地理参考数据
|
|
|
|
|
|
if (!m_pGeoRefData) {
|
|
|
|
|
|
return; // 提前返回,避免后续无效计算
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 验证地理参考数据有效性
|
|
|
|
|
|
QString utmZone = m_pGeoRefData->getUtmZone().getValue().toString();
|
|
|
|
|
|
if (utmZone.isEmpty()) {
|
|
|
|
|
|
return; // 提前返回,避免后续无效计算
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取基础地理参考坐标
|
|
|
|
|
|
double baseEasting = m_pGeoRefData->getEasting().getValue().toDouble();
|
|
|
|
|
|
double baseNorthing = m_pGeoRefData->getNorthing().getValue().toDouble();
|
|
|
|
|
|
double baseLongitude = m_pGeoRefData->getLongitude().getValue().toDouble();
|
|
|
|
|
|
double baseLatitude = m_pGeoRefData->getLatitude().getValue().toDouble();
|
|
|
|
|
|
|
|
|
|
|
|
// 计算并更新UTM坐标
|
|
|
|
|
|
double newEasting = baseEasting + x;
|
|
|
|
|
|
double newNorthing = baseNorthing + y;
|
|
|
|
|
|
m_pEastingEdit->setText(QString::number(newEasting, 'f', 2));
|
|
|
|
|
|
m_pNorthingEdit->setText(QString::number(newNorthing, 'f', 2));
|
|
|
|
|
|
|
|
|
|
|
|
// 计算并更新经纬度坐标
|
|
|
|
|
|
const double METERS_PER_DEGREE_LAT = 111111.0;
|
|
|
|
|
|
const double PI = 3.14159265358979323846;
|
|
|
|
|
|
|
|
|
|
|
|
double latitudeRadians = baseLatitude * PI / 180.0;
|
|
|
|
|
|
double metersPerDegreeLon = METERS_PER_DEGREE_LAT * cos(latitudeRadians);
|
|
|
|
|
|
|
|
|
|
|
|
double newLatitude = baseLatitude + (y / METERS_PER_DEGREE_LAT);
|
|
|
|
|
|
double newLongitude = baseLongitude + (x / metersPerDegreeLon);
|
|
|
|
|
|
|
|
|
|
|
|
// 转换为度分秒格式并更新UI
|
|
|
|
|
|
QString latStr = formatCoordinate(newLatitude, true);
|
|
|
|
|
|
QString lonStr = formatCoordinate(newLongitude, false);
|
|
|
|
|
|
m_pLatEdit->setText(latStr);
|
|
|
|
|
|
m_pLonEdit->setText(lonStr);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmWxPointerPosDlg::loadGeoRefDataToUI()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!m_pGeoRefData) {
|
|
|
|
|
|
m_pUtmZoneCombo->setCurrentIndex(-1); // 设置为空选项
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查是否有有效的地理参考数据
|
|
|
|
|
|
QString utmZone = m_pGeoRefData->getUtmZone().getValue().toString();
|
|
|
|
|
|
bool hasValidData = !utmZone.isEmpty();
|
|
|
|
|
|
|
|
|
|
|
|
if (hasValidData) {
|
|
|
|
|
|
// 加载经纬度
|
|
|
|
|
|
double longitude = m_pGeoRefData->getLongitude().getValue().toDouble();
|
|
|
|
|
|
double latitude = m_pGeoRefData->getLatitude().getValue().toDouble();
|
|
|
|
|
|
|
|
|
|
|
|
// 分别转换经度和纬度,并设置到UI
|
|
|
|
|
|
QString lonStr = formatCoordinate(longitude, false); // false表示经度
|
|
|
|
|
|
QString latStr = formatCoordinate(latitude, true); // true表示纬度
|
|
|
|
|
|
|
|
|
|
|
|
m_pLonEdit->setText(lonStr); // 显示转换后的经度
|
|
|
|
|
|
m_pLatEdit->setText(latStr); // 显示转换后的纬度
|
|
|
|
|
|
|
|
|
|
|
|
// 加载UTM Zone
|
|
|
|
|
|
int index = m_pUtmZoneCombo->findText(utmZone);
|
|
|
|
|
|
if (index >= 0) {
|
|
|
|
|
|
m_pUtmZoneCombo->setCurrentIndex(index);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 加载UTM坐标
|
|
|
|
|
|
double easting = m_pGeoRefData->getEasting().getValue().toDouble();
|
|
|
|
|
|
double northing = m_pGeoRefData->getNorthing().getValue().toDouble();
|
|
|
|
|
|
|
|
|
|
|
|
m_pEastingEdit->setText(QString::number(easting, 'f', 2));
|
|
|
|
|
|
m_pNorthingEdit->setText(QString::number(northing, 'f', 2));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QString nmWxPointerPosDlg::formatCoordinate(double coordinate, bool isLatitude)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 判断正负,确定方向
|
|
|
|
|
|
bool isPositive = coordinate >= 0;
|
|
|
|
|
|
double absCoordinate = qAbs(coordinate);
|
|
|
|
|
|
|
|
|
|
|
|
// 提取度数
|
|
|
|
|
|
int degrees = static_cast<int>(absCoordinate);
|
|
|
|
|
|
|
|
|
|
|
|
// 计算分数
|
|
|
|
|
|
double minutesFloat = (absCoordinate - degrees) * 60.0;
|
|
|
|
|
|
int minutes = static_cast<int>(minutesFloat);
|
|
|
|
|
|
|
|
|
|
|
|
// 计算秒数
|
|
|
|
|
|
double seconds = (minutesFloat - minutes) * 60.0;
|
|
|
|
|
|
|
|
|
|
|
|
// 防止浮点精度问题导致秒数≥60
|
|
|
|
|
|
if (seconds >= 60.0) {
|
|
|
|
|
|
seconds = 59.999;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 确定方向字符
|
|
|
|
|
|
QString direction;
|
|
|
|
|
|
if (isLatitude) {
|
|
|
|
|
|
direction = isPositive ? "N" : "S"; // 纬度
|
|
|
|
|
|
} else {
|
|
|
|
|
|
direction = isPositive ? "E" : "W"; // 经度
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 分步构建字符串
|
|
|
|
|
|
QString result;
|
|
|
|
|
|
result += QString("%1").arg(degrees, 2, 10, QChar('0')); // 度数
|
|
|
|
|
|
result += QString(tr("deg")); // 度符号
|
|
|
|
|
|
result += QString("%1").arg(minutes, 2, 10, QChar('0')); // 分数
|
|
|
|
|
|
result += QString(tr("min")); // 分符号
|
|
|
|
|
|
result += QString("%1").arg(static_cast<int>(seconds), 2, 10, QChar('0')); // 秒数
|
|
|
|
|
|
result += QString(tr("sec")); // 秒符号
|
|
|
|
|
|
result += direction; // 方向
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|