fix(Nm): 统一模型参考点界面并修复UTM坐标交互

- 统一对话框布局与按钮样式,接入框架长度单位换算
- 修复默认东向坐标、180°经线及特殊分带处理
- 完善坐标联动与输入校验,保留原值精度
- 绑定所属分析,确定后保存,取消不修改数据
- 补充中文注释,清理废弃翻译并同步语言包
feature/Dialog-Unification-20261106
lh 23 hours ago
parent 9ad1e7c6e4
commit d2d0460c20

Binary file not shown.

@ -5822,32 +5822,28 @@ Please choose a smaller length.</source>
<translation>位置</translation>
</message>
<message>
<source>Longitude:</source>
<translation>经度:</translation>
<source>Longitude</source>
<translation>经度</translation>
</message>
<message>
<source>Latitude:</source>
<translation>纬度:</translation>
<source>Latitude</source>
<translation>纬度</translation>
</message>
<message>
<source>Zone</source>
<translation>投影带</translation>
</message>
<message>
<source>UTM zone:</source>
<translation>UTM 带:</translation>
</message>
<message>
<source>Easting:</source>
<translation>东向坐标:</translation>
<source>UTM zone</source>
<translation>UTM 带</translation>
</message>
<message>
<source>Northing:</source>
<translation>北向坐标:</translation>
<source>Easting</source>
<translation>东向坐标</translation>
</message>
<message>
<source>Google</source>
<translation>Google</translation>
<source>Northing</source>
<translation>北向坐标</translation>
</message>
<message>
<source>OK</source>
@ -5857,64 +5853,6 @@ Please choose a smaller length.</source>
<source>Cancel</source>
<translation>取消</translation>
</message>
<message>
<source>Input Error</source>
<translation>输入错误</translation>
</message>
<message>
<source>Please enter valid numbers</source>
<translation>请输入有效的数字</translation>
</message>
<message>
<source>Latitude must be between - 90° and + 90°</source>
<translation>纬度必须在 -90° 到 +90° 之间</translation>
</message>
<message>
<source>Longitude must be between - 180° and + 180°</source>
<translation>经度必须在 -180° 到 +180° 之间</translation>
</message>
<message>
<source>Easting must be between 0 and 1,000,000 meters</source>
<translation>东向坐标必须在 0 到 1,000,000 米之间&quot;</translation>
</message>
<message>
<source>Northing must be between 0 and 10,000,000 meters</source>
<translation>北向坐标必须在 0 到 10,000,000 米之间</translation>
</message>
<message>
<source>Please select a valid UTM Zone</source>
<translation>请选择有效的UTM带</translation>
</message>
<message>
<source>Conversion Error</source>
<translation>转换错误</translation>
</message>
<message>
<source>UTM coordinate conversion result is out of valid range, please check input</source>
<translation>UTM坐标转换结果超出有效范围,请检查输入</translation>
</message>
<message>
<source>Latitude must be between - 90o and + 90o</source>
<translation>纬度必须在-90°至90°之间</translation>
</message>
<message>
<source>Longitude must be between - 180o and + 180o</source>
<translation>经度必须在-180°至180°之间</translation>
</message>
<message>
<source>The UTM coordinates you entered correspond to an extreme polar region where coordinate conversion may be inaccurate.
Please try coordinates closer to the center of the UTM zone.</source>
<translation>您输入的UTM坐标对应极地区域,坐标转换可能不准确。
请尝试使用更接近UTM区域中心的坐标。</translation>
</message>
<message>
<source>UTM coordinate conversion failed.
The coordinates may be outside the valid range for this UTM zone.
Please check your input coordinates.</source>
<translation>UTM坐标转换失败。
输入的坐标可能超出了该UTM区域的有效范围。
请检查您的输入坐标。</translation>
</message>
</context>
<context>
<name>nmWxGeometryLayerDlg</name>

@ -2,70 +2,86 @@
#define NMWXGEOREFDLG_H
#include "iDlgBase.h"
#include <QLineEdit>
#include <QComboBox>
#include <QPushButton>
#include <QMessageBox>
#include "nmSubWxs_global.h"
#include "nmDataGeoRef.h"
class QComboBox;
class QGridLayout;
class QLineEdit;
class QPushButton;
class iUnitGroup;
// 模型参考点编辑器:编辑本地原点对应的 WGS84 经纬度和 UTM 坐标。
// 只持有数据副本,不读取全局当前分析;调用方在确定后负责写回所属分析,取消不改工程。
class NM_SUB_WXS_EXPORT nmWxGeoRefDlg : public iDlgBase
{
Q_OBJECT
public:
explicit nmWxGeoRefDlg(QWidget* parent = 0);
void loadDataToUI(); // 从数据加载到界面
void saveDataUI(); // 从界面保存到数据
// 坐标转换辅助函数
void updateFromLatLon(); // 根据经纬度更新UTM坐标
void updateFromUTM(); // 根据UTM坐标更新经纬度
void latLonToUTM(double lat, double lon, int& zone, char& band, double& easting, double& northing);
bool utmToLatLon(int zone, char band, double easting, double northing, double& lat, double& lon);
int getUTMZoneFromLongitude(double longitude);
char getUTMBandFromLatitude(double latitude);
double calculateNorthing(double latitude, double longitude, int zone);
void restoreLastValidValues();
// 复制传入的参考点并初始化界面;构造和加载均不修改调用方数据,不自动重算旧坐标。
explicit nmWxGeoRefDlg(const nmDataGeoRef& oData, QWidget* pParent = 0);
// 返回窗口持有的结果副本,仅在 Accepted 后读取;引用有效期不超过窗口生命周期。
const nmDataGeoRef& geoRefData() const;
// 判断是否发生坐标编辑;只打开窗口或切换显示单位返回 false,调用方可跳过写回。
bool hasChanges() const;
// 输入验证函数
bool isValidLatitude(double lat);
bool isValidLongitude(double lon);
bool isValidEasting(double easting);
bool isValidNorthing(double northing);
public slots:
// 确定按钮和回车共用提交入口;非法/不完整输入保留在界面中,不按零值保存。
virtual void accept();
private slots:
void onUtmZoneChanged(int index);
void onLongitudeChanged(); // 经度改变槽函数
void onLatitudeChanged(); // 纬度改变槽函数
void onEastingChanged(); // 东向坐标改变槽函数
void onNorthingChanged(); // 北向坐标改变槽函数
void okAccept();
void cancelReject();
// 响应用户修改文本,按信号来源确定经纬度或投影坐标组,检查并更新另一组坐标。
void onCoordinateEdited(const QString& sText);
// 响应长度单位选择,仅从米制原值刷新对应字段;无效输入或换算失败时恢复原单位。
void onLengthUnitChanged(int nIndex);
// 响应 UTM 带选择,以该带覆盖区域中心初始化四个坐标;程序刷新期间不重复处理。
void onUtmZoneChanged(int nIndex);
private:
void initUI();
QLineEdit* m_pLongitudeEdit;
QLineEdit* m_pLatitudeEdit;
// 坐标字段及数组下标约定:前两项为度制经纬度,后两项为米制投影坐标。
enum CoordinateField { Longitude = 0, Latitude, Easting, Northing, FieldCount };
// 转换输入来源;NoInput 用于刚加载或选带初始化完成、不需要再次反算的状态。
enum InputSource { NoInput = 0, GeographicInput, ProjectedInput };
QComboBox* m_pUtmZoneCombo;
QLineEdit* m_pEastingEdit;
QLineEdit* m_pNorthingEdit;
QPushButton* m_pOkButton;
QPushButton* m_pCancelButton;
QString m_lastLongitude;
QString m_lastLatitude;
QString m_lastEasting;
QString m_lastNorthing;
// 创建两组坐标字段、框架长度单位下拉框及标准按钮栏,不固定窗口和字段宽度。
void initUI();
// 回显副本中的原始坐标并记录完整精度;空值保持为空,不因打开窗口触发投影或写回。
void loadDataToUI();
// 在指定网格行创建字段;经纬度跨两列,东向/北向字段附带框架长度单位选择。
void createCoordinateField(QGridLayout* pGrid, int nRow, CoordinateField eField,
const QString& sLabel, const QString& sObjectName);
// 读取时优先保留未编辑字段的完整原值;长度文本通过框架单位组换算为米。
bool readField(CoordinateField eField, double& dValue) const;
// 将度/米制原值格式化为显示文本;长度采用框架目标单位精度,换算失败返回空串。
QString displayValue(CoordinateField eField, double dValue, const QString& sUnit) const;
// 经纬度/投影坐标成对转换,全部成功后才替换副本;失败保留输入,禁用确定。
bool updateCoordinates(InputSource eSource);
// 一次性接收成功转换的完整坐标(度、米),保留输入组原文并刷新派生组和 UTM 带。
void applyCoordinates(double dLongitude, double dLatitude, double dEasting,
double dNorthing, const QString& sZone, InputSource eSource);
// 按单位服务和输入有效性更新操作状态;无效输入阻止确定,并暂时锁住另一坐标组。
void updateActions();
// 检查框架长度单位组及米制入口是否可用;不可用时禁止坐标编辑和保存。
bool unitsAvailable() const;
// 防止递归更新的标志
bool m_bUpdating;
private:
nmDataGeoRef m_oGeoRefData; // 工程参考点的编辑副本,保留原属性及持久化格式。
iUnitGroup* m_pLengthUnitGroup; // 借用框架长度单位组;单位选项和换算规则均由框架维护。
double m_dBaseValues[FieldCount]; // 最近一组完整坐标:经纬度为度,东向/北向为米。
QString m_sShownTexts[FieldCount]; // 对应原值的显示文本,用于避免舍入显示反写完整精度。
QString m_sDisplayUnits[FieldCount]; // 当前显示单位;经纬度固定为度,长度允许分别切换。
QString m_sUtmZone; // 最近一组完整坐标的分带标识,如 50S;字母表示纬度带。
InputSource m_eLastInput; // 最近编辑的坐标组,确定时按该组再次检查转换结果。
bool m_bHasCoordinates; // 是否已有一组完整坐标,可用于保留未编辑字段的原值。
bool m_bInputValid; // 当前输入能否转换;无效时保留原文并阻止确定。
bool m_bRefreshing; // 程序刷新控件期间抑制联动,避免递归转换。
bool m_bChanged; // 只记录坐标编辑;打开窗口和切换单位不算修改。
nmDataGeoRef m_geoRefData;
// 以下控件交给 Qt 父子关系释放;输入框和单位框横向伸展,高度采用主题建议值。
QLineEdit* m_pCoordinateEdits[FieldCount];// 经纬度及投影坐标输入框,顺序对应 CoordinateField。
QComboBox* m_pLengthUnits[FieldCount]; // 仅 Easting/Northing 使用,角度字段对应项为空。
QComboBox* m_pUtmZoneComboBox; // UTM 带选择,沿用数据对象提供的分带选项。
QPushButton* m_pOkButton; // 仅在单位服务和当前坐标均有效时允许提交。
};
#endif // NMWXGEOREFDLG_H

@ -1646,8 +1646,14 @@ void nmSubWndMain::drawMeasure()
void nmSubWndMain::drawGeoRef()
{
nmWxGeoRefDlg dlg(nullptr);
dlg.exec();
// 参考点属于当前地图绑定的分析;编辑器只收发副本,不访问全局当前分析。
nmGuiPlot* pPlot = dynamic_cast<nmGuiPlot*>(m_pWxPlot);
QPointer<nmDataAnalyzeManager> pManager = pPlot ? pPlot->boundDataManager() : nullptr;
if (!pManager) return;
nmWxGeoRefDlg dialog(pManager->getGeoRefDataCopy(), this);
if (dialog.exec() == QDialog::Accepted && pManager && dialog.hasChanges()) {
pManager->updateGeoRefData(dialog.geoRefData());
}
}
void nmSubWndMain::drawPointerPos()

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save