#ifndef NMWXGEOREFDLG_H #define NMWXGEOREFDLG_H #include "iDlgBase.h" #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(const nmDataGeoRef& oData, QWidget* pParent = 0); // 返回窗口持有的结果副本,仅在 Accepted 后读取;引用有效期不超过窗口生命周期。 const nmDataGeoRef& geoRefData() const; // 判断是否发生坐标编辑;只打开窗口或切换显示单位返回 false,调用方可跳过写回。 bool hasChanges() const; public slots: // 确定按钮和回车共用提交入口;非法/不完整输入保留在界面中,不按零值保存。 virtual void accept(); private slots: // 响应用户修改文本,按信号来源确定经纬度或投影坐标组,检查并更新另一组坐标。 void onCoordinateEdited(const QString& sText); // 响应长度单位选择,仅从米制原值刷新对应字段;无效输入或换算失败时恢复原单位。 void onLengthUnitChanged(int nIndex); // 响应 UTM 带选择,以该带覆盖区域中心初始化四个坐标;程序刷新期间不重复处理。 void onUtmZoneChanged(int nIndex); private: // 坐标字段及数组下标约定:前两项为度制经纬度,后两项为米制投影坐标。 enum CoordinateField { Longitude = 0, Latitude, Easting, Northing, FieldCount }; // 转换输入来源;NoInput 用于刚加载或选带初始化完成、不需要再次反算的状态。 enum InputSource { NoInput = 0, GeographicInput, ProjectedInput }; // 创建两组坐标字段、框架长度单位下拉框及标准按钮栏,不固定窗口和字段宽度。 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; 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; // 只记录坐标编辑;打开窗口和切换单位不算修改。 // 以下控件交给 Qt 父子关系释放;输入框和单位框横向伸展,高度采用主题建议值。 QLineEdit* m_pCoordinateEdits[FieldCount];// 经纬度及投影坐标输入框,顺序对应 CoordinateField。 QComboBox* m_pLengthUnits[FieldCount]; // 仅 Easting/Northing 使用,角度字段对应项为空。 QComboBox* m_pUtmZoneComboBox; // UTM 带选择,沿用数据对象提供的分带选项。 QPushButton* m_pOkButton; // 仅在单位服务和当前坐标均有效时允许提交。 }; #endif // NMWXGEOREFDLG_H