#define _USE_MATH_DEFINES #include "nmWxGeoRefDlg.h" #include #include #include #include #include #include #include "nmDataAnalyzeManager.h" #include "nmDataAxis.h" nmWxGeoRefDlg::nmWxGeoRefDlg(QWidget* parent) : iDlgBase(parent), m_bUpdating(false) { this->setWindowTitle(tr("Geo referencing")); initUI(); this->resize(370, 320); this->setFixedSize(this->size()); m_geoRefData = nmDataAnalyzeManager::getCurrentInstance()->getGeoRefDataCopy(); loadDataToUI(); } void nmWxGeoRefDlg::initUI() { // Location group QGroupBox* locationGroup = new QGroupBox(tr("Location")); // form 布局 QFormLayout* locForm = new QFormLayout; locForm->setLabelAlignment(Qt::AlignRight | Qt::AlignVCenter); locForm->setVerticalSpacing(12); locForm->setHorizontalSpacing(20); locForm->setContentsMargins(8, 8, 8, 8); m_pLongitudeEdit = new QLineEdit; m_pLongitudeEdit->setFixedWidth(180); m_pLatitudeEdit = new QLineEdit; m_pLatitudeEdit ->setFixedWidth(180); locForm->addRow(tr("Longitude:"), m_pLongitudeEdit); locForm->addRow(tr("Latitude:"), m_pLatitudeEdit); // 包一层 vbox,用 stretch 让 form 居中 QVBoxLayout* locWrapper = new QVBoxLayout; locWrapper->addStretch(1); locWrapper->addLayout(locForm); locWrapper->addStretch(1); locWrapper->setContentsMargins(0, 0, 0, 0); // 根据需要调整 groupbox 内边距 locationGroup->setLayout(locWrapper); // Zone group QGroupBox* zoneGroup = new QGroupBox(tr("Zone")); QFormLayout* zoneForm = new QFormLayout; zoneForm->setLabelAlignment(Qt::AlignRight | Qt::AlignVCenter); zoneForm->setVerticalSpacing(12); zoneForm->setHorizontalSpacing(20); zoneForm->setContentsMargins(8, 8, 8, 8); m_pUtmZoneCombo = new QComboBox; m_pUtmZoneCombo->setFixedWidth(180); m_pEastingEdit = new QLineEdit; m_pEastingEdit ->setFixedWidth(180); m_pNorthingEdit = new QLineEdit; m_pNorthingEdit->setFixedWidth(180); zoneForm->addRow(tr("UTM zone:"), m_pUtmZoneCombo); zoneForm->addRow(tr("Easting:"), m_pEastingEdit); zoneForm->addRow(tr("Northing:"), m_pNorthingEdit); // 初始化 UTM Zone 下拉框(格式:01C~60X) 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) { // 格式化为两位数 Zone + 纬度带(例如 "01C", "02C") QString zoneStr = QString("%1%2").arg(zone, 2, 10, QLatin1Char('0')).arg(band); m_pUtmZoneCombo->addItem(zoneStr); } } m_pUtmZoneCombo->setCurrentIndex(-1); QVBoxLayout* zoneWrapper = new QVBoxLayout; zoneWrapper->addStretch(1); zoneWrapper->addLayout(zoneForm); zoneWrapper->addStretch(1); zoneWrapper->setContentsMargins(0, 0, 0, 0); zoneGroup->setLayout(zoneWrapper); // Buttons m_pOkButton = new QPushButton(tr("OK")); m_pCancelButton = new QPushButton(tr("Cancel")); m_pOkButton->setDefault(true); connect(m_pOkButton, SIGNAL(clicked()), this, SLOT(okAccept())); connect(m_pCancelButton, SIGNAL(clicked()), this, SLOT(cancelReject())); QHBoxLayout* btnLay = new QHBoxLayout; btnLay->addStretch(); btnLay->addWidget(m_pOkButton); btnLay->addWidget(m_pCancelButton); // 主布局 QVBoxLayout* mainLay = new QVBoxLayout; mainLay->setContentsMargins(10, 10, 10, 10); mainLay->setSpacing(15); mainLay->addWidget(locationGroup); mainLay->addWidget(zoneGroup); mainLay->addLayout(btnLay); setLayout(mainLay); // 初始都设成不可编辑 m_pLongitudeEdit->setEnabled(false); m_pLatitudeEdit ->setEnabled(false); m_pUtmZoneCombo ->setEnabled(true); m_pEastingEdit ->setEnabled(false); m_pNorthingEdit ->setEnabled(false); connect(m_pUtmZoneCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onUtmZoneChanged(int))); connect(m_pLongitudeEdit, SIGNAL(editingFinished()), this, SLOT(onLongitudeChanged())); connect(m_pLatitudeEdit, SIGNAL(editingFinished()), this, SLOT(onLatitudeChanged())); connect(m_pEastingEdit, SIGNAL(editingFinished()), this, SLOT(onEastingChanged())); connect(m_pNorthingEdit, SIGNAL(editingFinished()), this, SLOT(onNorthingChanged())); } // 根据经纬度和UTM zone计算Northing坐标的辅助函数 double nmWxGeoRefDlg::calculateNorthing(double latitude, double longitude, int zone) { // UTM投影的简化计算公式 // 这里使用基本的UTM投影算法 const double a = 6378137.0; // WGS84长半轴 const double e2 = 0.00669437999014; // WGS84第一偏心率的平方 const double k0 = 0.9996; // UTM比例因子 // 转换为弧度 double lat_rad = latitude * M_PI / 180.0; double lon_rad = longitude * M_PI / 180.0; // 中央经线 double lon0_rad = (-183.0 + zone * 6.0) * M_PI / 180.0; double dlon = lon_rad - lon0_rad; // UTM投影计算 double N = a / sqrt(1 - e2 * sin(lat_rad) * sin(lat_rad)); double T = tan(lat_rad) * tan(lat_rad); double C = e2 * cos(lat_rad) * cos(lat_rad) / (1 - e2); double A = cos(lat_rad) * dlon; double M = a * ((1 - e2 / 4 - 3 * e2 * e2 / 64 - 5 * e2 * e2 * e2 / 256) * lat_rad - (3 * e2 / 8 + 3 * e2 * e2 / 32 + 45 * e2 * e2 * e2 / 1024) * sin(2 * lat_rad) + (15 * e2 * e2 / 256 + 45 * e2 * e2 * e2 / 1024) * sin(4 * lat_rad) - (35 * e2 * e2 * e2 / 3072) * sin(6 * lat_rad)); double northing = k0 * (M + N * tan(lat_rad) * (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A / 24 + (61 - 58 * T + T * T + 600 * C - 330 * e2) * A * A * A * A * A * A / 720)); // 南半球需要加上假北值 if(latitude < 0) { northing += 10000000.0; } return northing; } // 经度编辑完成时的处理 void nmWxGeoRefDlg::onLongitudeChanged() { if(m_bUpdating) return; // 防止递归更新 QString lonText = m_pLongitudeEdit->text(); QString latText = m_pLatitudeEdit->text(); // 检查经度值是否真的发生了变化 if(lonText == m_lastLongitude) { return; // 值没有变化,不进行转换 } if(!lonText.isEmpty() && !latText.isEmpty()) { updateFromLatLon(); } } // 纬度编辑完成时的处理 void nmWxGeoRefDlg::onLatitudeChanged() { if(m_bUpdating) return; // 防止递归更新 QString lonText = m_pLongitudeEdit->text(); QString latText = m_pLatitudeEdit->text(); // 检查纬度值是否真的发生了变化 if(latText == m_lastLatitude) { return; // 值没有变化,不进行转换 } if(!lonText.isEmpty() && !latText.isEmpty()) { updateFromLatLon(); } } // 东向坐标编辑完成时的处理 void nmWxGeoRefDlg::onEastingChanged() { if(m_bUpdating) return; // 防止递归更新 QString eastingText = m_pEastingEdit->text(); QString northingText = m_pNorthingEdit->text(); QString zoneText = m_pUtmZoneCombo->currentText(); // 检查东向坐标值是否真的发生了变化 if(eastingText == m_lastEasting) { return; // 值没有变化,不进行转换 } if(!eastingText.isEmpty() && !northingText.isEmpty() && !zoneText.isEmpty()) { updateFromUTM(); } } // 北向坐标编辑完成时的处理 void nmWxGeoRefDlg::onNorthingChanged() { if(m_bUpdating) return; // 防止递归更新 QString eastingText = m_pEastingEdit->text(); QString northingText = m_pNorthingEdit->text(); QString zoneText = m_pUtmZoneCombo->currentText(); // 检查北向坐标值是否真的发生了变化 if(northingText == m_lastNorthing) { return; // 值没有变化,不进行转换 } if(!eastingText.isEmpty() && !northingText.isEmpty() && !zoneText.isEmpty()) { updateFromUTM(); } } // 更新记录的值 void nmWxGeoRefDlg::updateFromLatLon() { m_bUpdating = true; // 设置更新标志 bool ok1, ok2; double latitude = m_pLatitudeEdit->text().toDouble(&ok1); double longitude = m_pLongitudeEdit->text().toDouble(&ok2); if(!ok1 || !ok2) { QMessageBox::warning(this, tr("Input Error"), tr("Please enter valid numbers")); // 恢复之前的有效值 m_pLongitudeEdit->setText(m_lastLongitude); m_pLatitudeEdit->setText(m_lastLatitude); m_bUpdating = false; return; } // 验证经纬度范围 if(!isValidLatitude(latitude)) { QMessageBox::warning(this, tr("Input Error"), tr("Latitude must be between - 90o and + 90o")); // 恢复之前的有效值 m_pLatitudeEdit->setText(m_lastLatitude); m_bUpdating = false; return; } if(!isValidLongitude(longitude)) { QMessageBox::warning(this, tr("Input Error"), tr("Longitude must be between - 180o and + 180o")); // 恢复之前的有效值 m_pLongitudeEdit->setText(m_lastLongitude); m_bUpdating = false; return; } int zone; char band; double easting, northing; // 执行坐标转换 latLonToUTM(latitude, longitude, zone, band, easting, northing); // 更新UTM Zone下拉框 QString zoneStr = QString("%1%2").arg(zone, 2, 10, QLatin1Char('0')).arg(band); int index = m_pUtmZoneCombo->findText(zoneStr); if(index >= 0) { m_pUtmZoneCombo->setCurrentIndex(index); } // 更新东向和北向坐标 QString eastingStr = QString::number(easting, 'f', 2); QString northingStr = QString::number(northing, 'f', 2); m_pEastingEdit->setText(eastingStr); m_pNorthingEdit->setText(northingStr); // 转换成功后,更新所有记录的值 m_lastLongitude = m_pLongitudeEdit->text(); // 使用当前输入框的值 m_lastLatitude = m_pLatitudeEdit->text(); m_lastEasting = eastingStr; m_lastNorthing = northingStr; m_bUpdating = false; // 清除更新标志 } // 更新记录的值 void nmWxGeoRefDlg::updateFromUTM() { m_bUpdating = true; // 设置更新标志 bool ok1, ok2; double easting = m_pEastingEdit->text().toDouble(&ok1); double northing = m_pNorthingEdit->text().toDouble(&ok2); QString zoneText = m_pUtmZoneCombo->currentText(); if(!ok1 || !ok2) { QMessageBox::warning(this, tr("Input Error"), tr("Please enter valid numbers")); restoreLastValidValues(); return; } // 验证UTM坐标范围 if(!isValidEasting(easting)) { QMessageBox::warning(this, tr("Input Error"), tr("Easting must be between 0 and 1,000,000 meters")); restoreLastValidValues(); return; } if(!isValidNorthing(northing)) { QMessageBox::warning(this, tr("Input Error"), tr("Northing must be between 0 and 10,000,000 meters")); restoreLastValidValues(); return; } if(zoneText.isEmpty()) { QMessageBox::warning(this, tr("Input Error"), tr("Please select a valid UTM Zone")); m_bUpdating = false; return; } // 解析UTM Zone int zone = zoneText.left(2).toInt(); char band = zoneText.right(1).toLocal8Bit().at(0); double latitude, longitude; // 执行坐标转换,检查返回值 bool conversionSuccess = utmToLatLon(zone, band, easting, northing, latitude, longitude); if (!conversionSuccess) { // 根据具体失败原因给出不同的错误信息 if (band == 'C' || band == 'X' || zone <= 2 || zone >= 59) { QMessageBox::warning(this, tr("Conversion Error"), tr("The UTM coordinates you entered correspond to an extreme polar region where coordinate conversion may be inaccurate.\n" "Please try coordinates closer to the center of the UTM zone.")); } else { QMessageBox::warning(this, tr("Conversion Error"), tr("UTM coordinate conversion failed.\n" "The coordinates may be outside the valid range for this UTM zone.\n" "Please check your input coordinates.")); } restoreLastValidValues(); return; } // 验证转换结果 if(!isValidLatitude(latitude) || !isValidLongitude(longitude)) { QMessageBox::warning(this, tr("Conversion Error"), tr("UTM coordinate conversion result is out of valid range, please check input")); restoreLastValidValues(); return; } // 更新经纬度 QString longitudeStr = QString::number(longitude, 'f', 6); QString latitudeStr = QString::number(latitude, 'f', 6); m_pLongitudeEdit->setText(longitudeStr); m_pLatitudeEdit->setText(latitudeStr); // 转换成功后,更新所有记录的值 m_lastLongitude = longitudeStr; m_lastLatitude = latitudeStr; m_lastEasting = m_pEastingEdit->text(); // 使用当前输入框的值 m_lastNorthing = m_pNorthingEdit->text(); m_bUpdating = false; // 清除更新标志 } // 恢复上次有效值 void nmWxGeoRefDlg::restoreLastValidValues() { m_pEastingEdit->setText(m_lastEasting); m_pNorthingEdit->setText(m_lastNorthing); m_bUpdating = false; } // 更新记录的值 void nmWxGeoRefDlg::onUtmZoneChanged(int index) { // 添加这行检查!如果正在更新过程中,直接返回 if(m_bUpdating) return; // 设置更新标志,防止触发其他转换函数 m_bUpdating = true; bool enabled = (index >= 0); // 选择了有效的 UTM Zone 时启用 m_pLongitudeEdit->setEnabled(enabled); m_pLatitudeEdit ->setEnabled(enabled); m_pEastingEdit ->setEnabled(enabled); m_pNorthingEdit ->setEnabled(enabled); if(enabled) { // 获取选中的 UTM Zone QString selectedZone = m_pUtmZoneCombo->itemText(index); // 从选中的 UTM Zone 提取 Zone 和 Band int zone = selectedZone.left(2).toInt(); QString band = selectedZone.right(1); // 计算经度(Longitude) double longitude = -177.0 + (zone - 1) * 6.0; QString longitudeStr = QString::number(longitude, 'f', 6); m_pLongitudeEdit->setText(longitudeStr); // 计算纬度(Latitude) QStringList bands; bands << "C" << "D" << "E" << "F" << "G" << "H" << "J" << "K" << "L" << "M" << "N" << "P" << "Q" << "R" << "S" << "T" << "U" << "V" << "W" << "X"; int bandIndex = bands.indexOf(band); double latitude = -76.0; if(bandIndex >= 0) { if(bandIndex < bands.indexOf("X")) { // X之前的所有band,每个递增8度 latitude += bandIndex * 8.0; } else { // X band:W到X跨度为10度 latitude += (bandIndex - 1) * 8.0 + 10.0; } } QString latitudeStr = QString::number(latitude, 'f', 6); m_pLatitudeEdit->setText(latitudeStr); // 设置东向坐标(Easting) double easting = 50000.00; QString eastingStr = QString::number(easting, 'f', 2); m_pEastingEdit->setText(eastingStr); // 设置北向坐标(Northing) double northing = calculateNorthing(latitude, longitude, zone); QString northingStr = QString::number(northing, 'f', 2); m_pNorthingEdit->setText(northingStr); // 更新记录的所有值 m_lastLongitude = longitudeStr; m_lastLatitude = latitudeStr; m_lastEasting = eastingStr; m_lastNorthing = northingStr; } // 清除更新标志 m_bUpdating = false; } // 经纬度转UTM坐标 void nmWxGeoRefDlg::latLonToUTM(double lat, double lon, int& zone, char& band, double& easting, double& northing) { // 确定UTM Zone zone = getUTMZoneFromLongitude(lon); band = getUTMBandFromLatitude(lat); // WGS84椭球体参数 const double a = 6378137.0; // 长半轴 const double e2 = 0.00669437999014; // 第一偏心率的平方 const double k0 = 0.9996; // 比例因子 // 转换为弧度 double lat_rad = lat * M_PI / 180.0; double lon_rad = lon * M_PI / 180.0; // 中央经线 double lon0 = -183.0 + zone * 6.0; double lon0_rad = lon0 * M_PI / 180.0; double dlon = lon_rad - lon0_rad; // UTM投影计算 double N = a / sqrt(1 - e2 * sin(lat_rad) * sin(lat_rad)); double T = tan(lat_rad) * tan(lat_rad); double C = e2 * cos(lat_rad) * cos(lat_rad) / (1 - e2); double A = cos(lat_rad) * dlon; double M = a * ((1 - e2 / 4 - 3 * e2 * e2 / 64 - 5 * e2 * e2 * e2 / 256) * lat_rad - (3 * e2 / 8 + 3 * e2 * e2 / 32 + 45 * e2 * e2 * e2 / 1024) * sin(2 * lat_rad) + (15 * e2 * e2 / 256 + 45 * e2 * e2 * e2 / 1024) * sin(4 * lat_rad) - (35 * e2 * e2 * e2 / 3072) * sin(6 * lat_rad)); // 计算东向坐标 easting = k0 * N * (A + (1 - T + C) * A * A * A / 6 + (5 - 18 * T + T * T + 72 * C - 58 * e2) * A * A * A * A * A / 120) + 500000.0; // 计算北向坐标 northing = k0 * (M + N * tan(lat_rad) * (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A / 24 + (61 - 58 * T + T * T + 600 * C - 330 * e2) * A * A * A * A * A * A / 720)); // 南半球需要加上假北值 if(lat < 0) { northing += 10000000.0; } } // UTM坐标转经纬度 bool nmWxGeoRefDlg::utmToLatLon(int zone, char band, double easting, double northing, double& lat, double& lon) { // WGS84椭球体参数 const double a = 6378137.0; // 长半轴 (米) const double f = 1.0 / 298.257223563; // 扁率 const double e2 = 2 * f - f * f; // 第一偏心率的平方 const double k0 = 0.9996; // UTM比例因子 const double e1 = (1 - sqrt(1 - e2)) / (1 + sqrt(1 - e2)); // 中央经线经度 double lon0 = -183.0 + zone * 6.0; // 调整北向坐标(南半球处理) double y = northing; if(band < 'N') { // 南半球 y -= 10000000.0; } // 调整东向坐标 double x = easting - 500000.0; // 计算足点纬度 double M = y / k0; double mu = M / (a * (1 - e2 / 4 - 3 * e2 * e2 / 64 - 5 * e2 * e2 * e2 / 256)); // 使用级数展开计算足点纬度 double phi1 = mu + (3 * e1 / 2 - 27 * e1 * e1 * e1 / 32) * sin(2 * mu) + (21 * e1 * e1 / 16 - 55 * e1 * e1 * e1 * e1 / 32) * sin(4 * mu) + (151 * e1 * e1 * e1 / 96) * sin(6 * mu) + (1097 * e1 * e1 * e1 * e1 / 512) * sin(8 * mu); // cos(phi1)是否过小 if (fabs(cos(phi1)) < 1e-6) { // 设置默认值,让调用方知道转换失败 lat = 0.0; lon = 0.0; return false; // 返回false表示转换失败 } // 计算各种参数 double C1 = e2 * cos(phi1) * cos(phi1) / (1 - e2); double T1 = tan(phi1) * tan(phi1); double N1 = a / sqrt(1 - e2 * sin(phi1) * sin(phi1)); double R1 = a * (1 - e2) / pow(1 - e2 * sin(phi1) * sin(phi1), 1.5); double D = x / (N1 * k0); // 计算纬度(弧度) double lat_rad = phi1 - (N1 * tan(phi1) / R1) * (D * D / 2 - (5 + 3 * T1 + 10 * C1 - 4 * C1 * C1 - 9 * e2) * D * D * D * D / 24 + (61 + 90 * T1 + 298 * C1 + 45 * T1 * T1 - 252 * e2 - 3 * C1 * C1) * D * D * D * D * D * D / 720); // 计算经度(弧度) double lon_rad = (D - (1 + 2 * T1 + C1) * D * D * D / 6 + (5 - 2 * C1 + 28 * T1 - 3 * C1 * C1 + 8 * e2 + 24 * T1 * T1) * D * D * D * D * D / 120) / cos(phi1); // 转换为度并加上中央经线 lat = lat_rad * 180.0 / M_PI; lon = lon0 + lon_rad * 180.0 / M_PI; // 第二个检查:确保结果在合理范围内 if (lat != lat || lon != lon || // 检查NaN fabs(lat) > 90.0 || // 纬度必须在-90到90之间 fabs(lon - lon0) > 180.0) { // 经度距离中央经线不应超过180度 // 设置默认值 lat = 0.0; lon = 0.0; return false; // 返回false表示转换失败 } // 确保经度在有效范围内 while(lon > 180.0) lon -= 360.0; while(lon < -180.0) lon += 360.0; return true; // 转换成功 } // 根据经度确定UTM Zone int nmWxGeoRefDlg::getUTMZoneFromLongitude(double longitude) { return (int)floor((longitude + 180.0) / 6.0) + 1; } // 根据纬度确定UTM Band char nmWxGeoRefDlg::getUTMBandFromLatitude(double latitude) { const char bands[] = "CDEFGHJKLMNPQRSTUVWX"; int index = (int)floor((latitude + 80.0) / 8.0); if(index < 0) return 'C'; if(index >= 20) return 'X'; return bands[index]; } bool nmWxGeoRefDlg::isValidLatitude(double lat) { return (lat >= -90.0 && lat <= 90.0); } // 验证经度范围 bool nmWxGeoRefDlg::isValidLongitude(double lon) { return (lon >= -180.0 && lon <= 180.0); } // 验证东向坐标范围 bool nmWxGeoRefDlg::isValidEasting(double easting) { // 基本UTM范围检查 if (easting < 0.0 || easting > 1000000.0) { return false; } // 获取坐标轴数据,考虑画布范围 nmDataAxis* axisData = nmDataAnalyzeManager::getCurrentInstance()->getAxisData(); if (axisData) { double xMin = axisData->getXMin().getValue().toDouble(); double xMax = axisData->getXMax().getValue().toDouble(); // 计算基准坐标的安全范围 double safeEastingMin = 160000.0 - xMin; // UTM东向最小值 - 画布最小X double safeEastingMax = 840000.0 - xMax; // UTM东向最大值 - 画布最大X // 确保范围有效 if (safeEastingMin < 0.0) safeEastingMin = 0.0; if (safeEastingMax > 1000000.0) safeEastingMax = 1000000.0; if (safeEastingMin >= safeEastingMax) { safeEastingMin = 0.0; safeEastingMax = 1000000.0; } return (easting >= safeEastingMin && easting <= safeEastingMax); } return true; // 如果没有坐标轴数据,使用默认验证 } // 验证北向坐标范围 bool nmWxGeoRefDlg::isValidNorthing(double northing) { // 基本UTM范围检查 if (northing < 0.0 || northing > 10000000.0) { return false; } // 获取坐标轴数据,考虑画布范围 nmDataAxis* axisData = nmDataAnalyzeManager::getCurrentInstance()->getAxisData(); if (axisData) { double yMin = axisData->getYMin().getValue().toDouble(); double yMax = axisData->getYMax().getValue().toDouble(); // 计算基准坐标的安全范围 double safeNorthingMin = 0.0 - yMin; // UTM北向最小值 - 画布最小Y double safeNorthingMax = 9000000.0 - yMax; // UTM北向最大值 - 画布最大Y // 确保范围有效 if (safeNorthingMin < 0.0) safeNorthingMin = 0.0; if (safeNorthingMax > 10000000.0) safeNorthingMax = 10000000.0; if (safeNorthingMin >= safeNorthingMax) { safeNorthingMin = 0.0; safeNorthingMax = 10000000.0; } return (northing >= safeNorthingMin && northing <= safeNorthingMax); } return true; // 如果没有坐标轴数据,使用默认验证 } void nmWxGeoRefDlg::loadDataToUI() { m_bUpdating = true; // 检查UTM Zone是否有效 QString utmZone = m_geoRefData.getUtmZone().getValue().toString(); bool hasValidData = !utmZone.isEmpty(); if(hasValidData) { // 有有效数据时,加载所有数据 QString lonStr = QString::number(m_geoRefData.getLongitude().getValue().toDouble(), 'f', 6); m_pLongitudeEdit->setText(lonStr); m_lastLongitude = lonStr; QString latStr = QString::number(m_geoRefData.getLatitude().getValue().toDouble(), 'f', 6); m_pLatitudeEdit->setText(latStr); m_lastLatitude = latStr; int index = m_pUtmZoneCombo->findText(utmZone); if(index >= 0) { m_pUtmZoneCombo->setCurrentIndex(index); } QString eastingStr = QString::number(m_geoRefData.getEasting().getValue().toDouble(), 'f', 2); m_pEastingEdit->setText(eastingStr); m_lastEasting = eastingStr; QString northingStr = QString::number(m_geoRefData.getNorthing().getValue().toDouble(), 'f', 2); m_pNorthingEdit->setText(northingStr); m_lastNorthing = northingStr; // 启用所有控件 m_pLongitudeEdit->setEnabled(true); m_pLatitudeEdit->setEnabled(true); m_pEastingEdit->setEnabled(true); m_pNorthingEdit->setEnabled(true); } else { // 无有效数据时,清空所有文本框,初始化last值 m_pLongitudeEdit->setText(""); m_pLatitudeEdit->setText(""); m_pEastingEdit->setText(""); m_pNorthingEdit->setText(""); m_lastLongitude = ""; m_lastLatitude = ""; m_lastEasting = ""; m_lastNorthing = ""; } m_bUpdating = false; } void nmWxGeoRefDlg::saveDataUI() { // 保存经度 nmDataAttribute longitude = m_geoRefData.getLongitude(); double lonValue = m_pLongitudeEdit->text().toDouble(); longitude.setValue(lonValue); m_geoRefData.setLongitude(longitude); // 保存纬度 nmDataAttribute latitude = m_geoRefData.getLatitude(); double latValue = m_pLatitudeEdit->text().toDouble(); latitude.setValue(latValue); m_geoRefData.setLatitude(latitude); // 保存UTM Zone nmDataAttribute utmZone = m_geoRefData.getUtmZone(); utmZone.setValue(QVariant(m_pUtmZoneCombo->currentText())); m_geoRefData.setUtmZone(utmZone); // 保存东向坐标 nmDataAttribute easting = m_geoRefData.getEasting(); double estValue = m_pEastingEdit->text().toDouble(); easting.setValue(estValue); m_geoRefData.setEasting(easting); // 保存北向坐标 nmDataAttribute northing = m_geoRefData.getNorthing(); double norValue = m_pNorthingEdit->text().toDouble(); northing.setValue(norValue); m_geoRefData.setNorthing(northing); } void nmWxGeoRefDlg::okAccept() { saveDataUI(); // 更新到全局数据管理器 nmDataAnalyzeManager::getCurrentInstance()->updateGeoRefData(m_geoRefData); // 调用基类的accept iDlgBase::accept(); } void nmWxGeoRefDlg::cancelReject() { // 调用基类的reject iDlgBase::reject(); }