#include "nmWxPointerPosDlg.h" #include "nmGUIComponentLineEdit.h" #include "nmDataAnalyzeManager.h" #include "nmDataAttribute.h" #include #include #include #include #include #include #include #include #include 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(); if(leX) { leX->setMinimumWidth(100); } QLineEdit* leY = m_pY->findChild(); 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(absCoordinate); // 计算分数 double minutesFloat = (absCoordinate - degrees) * 60.0; int minutes = static_cast(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(seconds), 2, 10, QChar('0')); // 秒数 result += QString(tr("sec")); // 秒符号 result += direction; // 方向 return result; }