|
|
|
|
@ -12,6 +12,7 @@
|
|
|
|
|
#include <QHBoxLayout>
|
|
|
|
|
#include <QHeaderView>
|
|
|
|
|
#include <QIcon>
|
|
|
|
|
#include <QGridLayout>
|
|
|
|
|
#include <QLabel>
|
|
|
|
|
#include <QLineEdit>
|
|
|
|
|
#include <QMessageBox>
|
|
|
|
|
@ -25,6 +26,7 @@
|
|
|
|
|
#include <QTimer>
|
|
|
|
|
#include <QTransform>
|
|
|
|
|
#include <QVBoxLayout>
|
|
|
|
|
#include <QWidget>
|
|
|
|
|
#include <QtCore/qmath.h>
|
|
|
|
|
|
|
|
|
|
#include "nmCalculationUtils.h"
|
|
|
|
|
@ -32,12 +34,22 @@
|
|
|
|
|
#include "nmGuiPlot.h"
|
|
|
|
|
#include "nmObjPoint.h"
|
|
|
|
|
#include "nmWxPropertyInterpolationPreviewDlg.h"
|
|
|
|
|
#include "iUnitGroup.h"
|
|
|
|
|
#include "iUnitHelper.h"
|
|
|
|
|
#include "tCurvePlotView.h"
|
|
|
|
|
#include "ZxObjText.h"
|
|
|
|
|
#include "ZxPlot.h"
|
|
|
|
|
|
|
|
|
|
namespace
|
|
|
|
|
{
|
|
|
|
|
// 表格第0行保留给单位,实际测点从第1行开始.
|
|
|
|
|
const int POINT_UNIT_ROW = 0;
|
|
|
|
|
const int FIRST_POINT_ROW = 1;
|
|
|
|
|
// 坐标和厚度以m保存,渗透率以D保存但默认使用mD显示.
|
|
|
|
|
const char* LENGTH_BASE_UNIT = "m";
|
|
|
|
|
const char* PERMEABILITY_BASE_UNIT = "D";
|
|
|
|
|
const char* PERMEABILITY_DISPLAY_UNIT = "mD";
|
|
|
|
|
|
|
|
|
|
// 使用独立翻译上下文,便于统一维护对话框文本.
|
|
|
|
|
QString interpolationText(const char* sourceText)
|
|
|
|
|
{
|
|
|
|
|
@ -55,6 +67,133 @@ QDoubleSpinBox* createNumberSpinBox(QWidget* parent, double value)
|
|
|
|
|
return spinBox;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString propertyBaseUnit(const QString& property)
|
|
|
|
|
{
|
|
|
|
|
// 孔隙度为无量纲量,返回空单位后界面会禁用对应单位下拉框.
|
|
|
|
|
if(property == "k") {
|
|
|
|
|
return PERMEABILITY_BASE_UNIT;
|
|
|
|
|
}
|
|
|
|
|
if(property == "h") {
|
|
|
|
|
return LENGTH_BASE_UNIT;
|
|
|
|
|
}
|
|
|
|
|
return QString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString defaultPropertyDisplayUnit(const QString& property)
|
|
|
|
|
{
|
|
|
|
|
// 渗透率采用工程中常用的mD显示,其余属性默认显示基准单位.
|
|
|
|
|
if(property == "k") {
|
|
|
|
|
return PERMEABILITY_DISPLAY_UNIT;
|
|
|
|
|
}
|
|
|
|
|
return propertyBaseUnit(property);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString unitGroupLookupUnit(const QString& unit)
|
|
|
|
|
{
|
|
|
|
|
// D与时间单位d仅大小写不同,使用唯一的mD定位渗透率单位组.
|
|
|
|
|
return unit == PERMEABILITY_BASE_UNIT ?
|
|
|
|
|
QString(PERMEABILITY_DISPLAY_UNIT) : unit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool convertUnitValue(double sourceValue,
|
|
|
|
|
const QString& sourceUnit,
|
|
|
|
|
const QString& destinationUnit,
|
|
|
|
|
double& destinationValue)
|
|
|
|
|
{
|
|
|
|
|
if(sourceUnit == destinationUnit ||
|
|
|
|
|
(sourceUnit.isEmpty() && destinationUnit.isEmpty())) {
|
|
|
|
|
destinationValue = sourceValue;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
if(sourceUnit.isEmpty() || destinationUnit.isEmpty()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 复用框架单位表完成换算,不在插值模块中维护独立换算系数.
|
|
|
|
|
iUnitGroup* unitGroup = iUnitHelper::getUnitGroupByUnit(
|
|
|
|
|
unitGroupLookupUnit(sourceUnit));
|
|
|
|
|
if(unitGroup == NULL || unitGroup->indexOf(destinationUnit) < 0) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int digit = 6;
|
|
|
|
|
return unitGroup->convert(sourceUnit, sourceValue,
|
|
|
|
|
destinationUnit, destinationValue, digit);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double convertedUnitValue(double sourceValue,
|
|
|
|
|
const QString& sourceUnit,
|
|
|
|
|
const QString& destinationUnit)
|
|
|
|
|
{
|
|
|
|
|
double destinationValue = sourceValue;
|
|
|
|
|
convertUnitValue(sourceValue, sourceUnit,
|
|
|
|
|
destinationUnit, destinationValue);
|
|
|
|
|
return destinationValue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString displayValueText(double value)
|
|
|
|
|
{
|
|
|
|
|
// 表格使用较高有效位数,减少多次显示和回写造成的精度损失.
|
|
|
|
|
return QString::number(value, 'g', 15);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void populateUnitCombo(QComboBox* comboBox,
|
|
|
|
|
const QString& baseUnit,
|
|
|
|
|
const QString& selectedUnit)
|
|
|
|
|
{
|
|
|
|
|
if(comboBox == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 单位列表从全局单位表加载,屏蔽信号可避免初始化过程反向修改数据.
|
|
|
|
|
bool oldBlock = comboBox->blockSignals(true);
|
|
|
|
|
comboBox->clear();
|
|
|
|
|
if(baseUnit.isEmpty()) {
|
|
|
|
|
comboBox->addItem(QString());
|
|
|
|
|
comboBox->setCurrentIndex(0);
|
|
|
|
|
comboBox->setEnabled(false);
|
|
|
|
|
comboBox->blockSignals(oldBlock);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const QString lookupUnit = unitGroupLookupUnit(baseUnit);
|
|
|
|
|
QStringList units;
|
|
|
|
|
iUnitGroup* unitGroup = iUnitHelper::getUnitGroupByUnit(lookupUnit);
|
|
|
|
|
if(unitGroup != NULL) {
|
|
|
|
|
units = unitGroup->getAllUnitNames();
|
|
|
|
|
}
|
|
|
|
|
if(units.isEmpty()) {
|
|
|
|
|
units.append(baseUnit);
|
|
|
|
|
}
|
|
|
|
|
comboBox->addItems(units);
|
|
|
|
|
|
|
|
|
|
int selectedIndex = comboBox->findText(selectedUnit);
|
|
|
|
|
if(selectedIndex < 0) {
|
|
|
|
|
selectedIndex = comboBox->findText(lookupUnit);
|
|
|
|
|
}
|
|
|
|
|
if(selectedIndex < 0) {
|
|
|
|
|
selectedIndex = comboBox->findText(baseUnit);
|
|
|
|
|
}
|
|
|
|
|
comboBox->setCurrentIndex(selectedIndex < 0 ? 0 : selectedIndex);
|
|
|
|
|
comboBox->setEnabled(true);
|
|
|
|
|
comboBox->blockSignals(oldBlock);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void setTableUnitComboStyle(QComboBox* comboBox)
|
|
|
|
|
{
|
|
|
|
|
if(comboBox == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 仅借用可编辑模式调整文字对齐,输入区域仍设置为只读.
|
|
|
|
|
comboBox->setEditable(true);
|
|
|
|
|
comboBox->lineEdit()->setAlignment(Qt::AlignCenter);
|
|
|
|
|
comboBox->lineEdit()->setReadOnly(true);
|
|
|
|
|
comboBox->setStyleSheet(
|
|
|
|
|
"QComboBox { border: none; background: transparent; padding-left: 4px; }"
|
|
|
|
|
"QComboBox::drop-down { border: none; }");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 插值测点使用独立的小方块标记,避免与井图元混淆.
|
|
|
|
|
class PropertyInterpolationMarker : public nmObjPoint
|
|
|
|
|
{
|
|
|
|
|
@ -175,8 +314,12 @@ nmWxPropertyInterpolationDlg::nmWxPropertyInterpolationDlg(
|
|
|
|
|
m_pPropertyCombo(NULL),
|
|
|
|
|
m_pNameEdit(NULL),
|
|
|
|
|
m_pNewValueSpin(NULL),
|
|
|
|
|
m_pNewValueUnitCombo(NULL),
|
|
|
|
|
m_pMapPickButton(NULL),
|
|
|
|
|
m_pPointTable(NULL),
|
|
|
|
|
m_pXUnitCombo(NULL),
|
|
|
|
|
m_pYUnitCombo(NULL),
|
|
|
|
|
m_pValueUnitCombo(NULL),
|
|
|
|
|
m_pDeletePointButton(NULL),
|
|
|
|
|
m_pClearPointsButton(NULL),
|
|
|
|
|
m_pShowPointsCheck(NULL),
|
|
|
|
|
@ -184,7 +327,14 @@ nmWxPropertyInterpolationDlg::nmWxPropertyInterpolationDlg(
|
|
|
|
|
m_pNuggetSpin(NULL),
|
|
|
|
|
m_pSillSpin(NULL),
|
|
|
|
|
m_pRangeSpin(NULL),
|
|
|
|
|
m_pRangeUnitCombo(NULL),
|
|
|
|
|
m_pModelCombo(NULL),
|
|
|
|
|
m_pUseKCheck(NULL),
|
|
|
|
|
m_pKCalculationDataSetCombo(NULL),
|
|
|
|
|
m_pUsePhiCheck(NULL),
|
|
|
|
|
m_pPhiCalculationDataSetCombo(NULL),
|
|
|
|
|
m_pUseHCheck(NULL),
|
|
|
|
|
m_pHCalculationDataSetCombo(NULL),
|
|
|
|
|
m_pPreviewButton(NULL),
|
|
|
|
|
m_pApplyButton(NULL),
|
|
|
|
|
m_pPreviewDialog(NULL),
|
|
|
|
|
@ -193,9 +343,10 @@ nmWxPropertyInterpolationDlg::nmWxPropertyInterpolationDlg(
|
|
|
|
|
setWindowTitle(interpolationText("Property Interpolation"));
|
|
|
|
|
setWindowModality(Qt::NonModal);
|
|
|
|
|
setModal(false);
|
|
|
|
|
setMinimumSize(520, 620);
|
|
|
|
|
resize(560, 680);
|
|
|
|
|
setMinimumSize(520, 680);
|
|
|
|
|
resize(560, 740);
|
|
|
|
|
|
|
|
|
|
// 合并连续编辑触发的刷新,避免每次数值变化都立即重新插值.
|
|
|
|
|
m_pPreviewRefreshTimer = new QTimer(this);
|
|
|
|
|
m_pPreviewRefreshTimer->setSingleShot(true);
|
|
|
|
|
m_pPreviewRefreshTimer->setInterval(200);
|
|
|
|
|
@ -270,6 +421,11 @@ void nmWxPropertyInterpolationDlg::initInterpolationUI()
|
|
|
|
|
newPointLayout->addWidget(new QLabel(interpolationText("New value:"), pointGroup));
|
|
|
|
|
m_pNewValueSpin = createNumberSpinBox(pointGroup, 0.0);
|
|
|
|
|
newPointLayout->addWidget(m_pNewValueSpin, 1);
|
|
|
|
|
m_pNewValueUnitCombo = new QComboBox(pointGroup);
|
|
|
|
|
m_pNewValueUnitCombo->setMinimumWidth(80);
|
|
|
|
|
populateUnitCombo(m_pNewValueUnitCombo,
|
|
|
|
|
PERMEABILITY_BASE_UNIT, PERMEABILITY_DISPLAY_UNIT);
|
|
|
|
|
newPointLayout->addWidget(m_pNewValueUnitCombo);
|
|
|
|
|
m_pMapPickButton = new QPushButton(interpolationText("Select on Map"), pointGroup);
|
|
|
|
|
m_pMapPickButton->setCheckable(true);
|
|
|
|
|
m_pMapPickButton->setEnabled(!m_pPlot.isNull() &&
|
|
|
|
|
@ -278,14 +434,31 @@ void nmWxPropertyInterpolationDlg::initInterpolationUI()
|
|
|
|
|
newPointLayout->addWidget(m_pMapPickButton);
|
|
|
|
|
pointLayout->addLayout(newPointLayout);
|
|
|
|
|
|
|
|
|
|
m_pPointTable = new QTableWidget(0, 3, pointGroup);
|
|
|
|
|
m_pPointTable = new QTableWidget(1, 3, pointGroup);
|
|
|
|
|
QStringList headers;
|
|
|
|
|
headers << interpolationText("X") << interpolationText("Y") << interpolationText("Value");
|
|
|
|
|
m_pPointTable->setHorizontalHeaderLabels(headers);
|
|
|
|
|
m_pPointTable->verticalHeader()->setVisible(false);
|
|
|
|
|
m_pPointTable->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
|
|
|
|
|
m_pPointTable->setSelectionBehavior(QAbstractItemView::SelectRows);
|
|
|
|
|
m_pPointTable->setSelectionMode(QAbstractItemView::SingleSelection);
|
|
|
|
|
m_pPointTable->setAlternatingRowColors(true);
|
|
|
|
|
m_pPointTable->setRowHeight(POINT_UNIT_ROW, 24);
|
|
|
|
|
|
|
|
|
|
// 第0行固定显示各列单位,数据行从第1行开始.
|
|
|
|
|
m_pXUnitCombo = new QComboBox(m_pPointTable);
|
|
|
|
|
m_pYUnitCombo = new QComboBox(m_pPointTable);
|
|
|
|
|
m_pValueUnitCombo = new QComboBox(m_pPointTable);
|
|
|
|
|
setTableUnitComboStyle(m_pXUnitCombo);
|
|
|
|
|
setTableUnitComboStyle(m_pYUnitCombo);
|
|
|
|
|
setTableUnitComboStyle(m_pValueUnitCombo);
|
|
|
|
|
populateUnitCombo(m_pXUnitCombo, LENGTH_BASE_UNIT, LENGTH_BASE_UNIT);
|
|
|
|
|
populateUnitCombo(m_pYUnitCombo, LENGTH_BASE_UNIT, LENGTH_BASE_UNIT);
|
|
|
|
|
populateUnitCombo(m_pValueUnitCombo,
|
|
|
|
|
PERMEABILITY_BASE_UNIT, PERMEABILITY_DISPLAY_UNIT);
|
|
|
|
|
m_pPointTable->setCellWidget(POINT_UNIT_ROW, 0, m_pXUnitCombo);
|
|
|
|
|
m_pPointTable->setCellWidget(POINT_UNIT_ROW, 1, m_pYUnitCombo);
|
|
|
|
|
m_pPointTable->setCellWidget(POINT_UNIT_ROW, 2, m_pValueUnitCombo);
|
|
|
|
|
pointLayout->addWidget(m_pPointTable, 1);
|
|
|
|
|
|
|
|
|
|
QHBoxLayout* pointButtonLayout = new QHBoxLayout;
|
|
|
|
|
@ -316,8 +489,17 @@ void nmWxPropertyInterpolationDlg::initInterpolationUI()
|
|
|
|
|
parameterLayout->addRow(interpolationText("Nugget:"), m_pNuggetSpin);
|
|
|
|
|
m_pSillSpin = createNumberSpinBox(parameterGroup, 100.0);
|
|
|
|
|
parameterLayout->addRow(interpolationText("Sill:"), m_pSillSpin);
|
|
|
|
|
QWidget* rangeWidget = new QWidget(parameterGroup);
|
|
|
|
|
QHBoxLayout* rangeLayout = new QHBoxLayout(rangeWidget);
|
|
|
|
|
rangeLayout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
rangeLayout->setSpacing(6);
|
|
|
|
|
m_pRangeSpin = createNumberSpinBox(parameterGroup, 1000.0);
|
|
|
|
|
parameterLayout->addRow(interpolationText("Range:"), m_pRangeSpin);
|
|
|
|
|
rangeLayout->addWidget(m_pRangeSpin, 1);
|
|
|
|
|
m_pRangeUnitCombo = new QComboBox(parameterGroup);
|
|
|
|
|
m_pRangeUnitCombo->setMinimumWidth(80);
|
|
|
|
|
populateUnitCombo(m_pRangeUnitCombo, LENGTH_BASE_UNIT, LENGTH_BASE_UNIT);
|
|
|
|
|
rangeLayout->addWidget(m_pRangeUnitCombo);
|
|
|
|
|
parameterLayout->addRow(interpolationText("Range:"), rangeWidget);
|
|
|
|
|
m_pModelCombo = new QComboBox(parameterGroup);
|
|
|
|
|
m_pModelCombo->addItem(interpolationText("Spherical (0)"), 0);
|
|
|
|
|
m_pModelCombo->addItem(interpolationText("Exponential (1)"), 1);
|
|
|
|
|
@ -325,6 +507,27 @@ void nmWxPropertyInterpolationDlg::initInterpolationUI()
|
|
|
|
|
parameterLayout->addRow(interpolationText("Model:"), m_pModelCombo);
|
|
|
|
|
mainLayout->addWidget(parameterGroup);
|
|
|
|
|
|
|
|
|
|
// 分别指定正式求解时需要使用插值结果的属性和数据组.
|
|
|
|
|
QGroupBox* calculationGroup = new QGroupBox(
|
|
|
|
|
interpolationText("Use Interpolation in Solver"), this);
|
|
|
|
|
QGridLayout* calculationLayout = new QGridLayout(calculationGroup);
|
|
|
|
|
m_pUseKCheck = new QCheckBox(interpolationText("Permeability k"), calculationGroup);
|
|
|
|
|
m_pKCalculationDataSetCombo = new QComboBox(calculationGroup);
|
|
|
|
|
calculationLayout->addWidget(m_pUseKCheck, 0, 0);
|
|
|
|
|
calculationLayout->addWidget(m_pKCalculationDataSetCombo, 0, 1);
|
|
|
|
|
|
|
|
|
|
m_pUsePhiCheck = new QCheckBox(interpolationText("Porosity phi"), calculationGroup);
|
|
|
|
|
m_pPhiCalculationDataSetCombo = new QComboBox(calculationGroup);
|
|
|
|
|
calculationLayout->addWidget(m_pUsePhiCheck, 1, 0);
|
|
|
|
|
calculationLayout->addWidget(m_pPhiCalculationDataSetCombo, 1, 1);
|
|
|
|
|
|
|
|
|
|
m_pUseHCheck = new QCheckBox(interpolationText("Reservoir thickness h"), calculationGroup);
|
|
|
|
|
m_pHCalculationDataSetCombo = new QComboBox(calculationGroup);
|
|
|
|
|
calculationLayout->addWidget(m_pUseHCheck, 2, 0);
|
|
|
|
|
calculationLayout->addWidget(m_pHCalculationDataSetCombo, 2, 1);
|
|
|
|
|
calculationLayout->setColumnStretch(1, 1);
|
|
|
|
|
mainLayout->addWidget(calculationGroup);
|
|
|
|
|
|
|
|
|
|
// 底部操作按钮.
|
|
|
|
|
QHBoxLayout* buttonLayout = new QHBoxLayout;
|
|
|
|
|
m_pPreviewButton = new QPushButton(interpolationText("Preview"), this);
|
|
|
|
|
@ -345,13 +548,23 @@ void nmWxPropertyInterpolationDlg::initInterpolationUI()
|
|
|
|
|
connect(m_pNameEdit, SIGNAL(textChanged(QString)),
|
|
|
|
|
this, SLOT(onDataSetNameChanged(QString)));
|
|
|
|
|
connect(m_pPropertyCombo, SIGNAL(currentIndexChanged(int)),
|
|
|
|
|
this, SLOT(onCurrentDataSetEdited()));
|
|
|
|
|
this, SLOT(onCurrentDataSetPropertyChanged()));
|
|
|
|
|
connect(m_pNuggetSpin, SIGNAL(valueChanged(double)),
|
|
|
|
|
this, SLOT(onCurrentDataSetEdited()));
|
|
|
|
|
connect(m_pSillSpin, SIGNAL(valueChanged(double)),
|
|
|
|
|
this, SLOT(onCurrentDataSetEdited()));
|
|
|
|
|
connect(m_pRangeSpin, SIGNAL(valueChanged(double)),
|
|
|
|
|
this, SLOT(onCurrentDataSetEdited()));
|
|
|
|
|
connect(m_pXUnitCombo, SIGNAL(currentIndexChanged(const QString&)),
|
|
|
|
|
this, SLOT(onXDisplayUnitChanged(const QString&)));
|
|
|
|
|
connect(m_pYUnitCombo, SIGNAL(currentIndexChanged(const QString&)),
|
|
|
|
|
this, SLOT(onYDisplayUnitChanged(const QString&)));
|
|
|
|
|
connect(m_pNewValueUnitCombo, SIGNAL(currentIndexChanged(const QString&)),
|
|
|
|
|
this, SLOT(onValueDisplayUnitChanged(const QString&)));
|
|
|
|
|
connect(m_pValueUnitCombo, SIGNAL(currentIndexChanged(const QString&)),
|
|
|
|
|
this, SLOT(onValueDisplayUnitChanged(const QString&)));
|
|
|
|
|
connect(m_pRangeUnitCombo, SIGNAL(currentIndexChanged(const QString&)),
|
|
|
|
|
this, SLOT(onRangeDisplayUnitChanged(const QString&)));
|
|
|
|
|
connect(m_pModelCombo, SIGNAL(currentIndexChanged(int)),
|
|
|
|
|
this, SLOT(onCurrentDataSetEdited()));
|
|
|
|
|
connect(m_pMapPickButton, SIGNAL(toggled(bool)), this, SLOT(onMapPickToggled(bool)));
|
|
|
|
|
@ -363,6 +576,18 @@ void nmWxPropertyInterpolationDlg::initInterpolationUI()
|
|
|
|
|
connect(m_pClearPointsButton, SIGNAL(clicked()), this, SLOT(onClearPoints()));
|
|
|
|
|
connect(m_pShowPointsCheck, SIGNAL(toggled(bool)), this, SLOT(onShowPointsToggled(bool)));
|
|
|
|
|
connect(m_pShowLabelsCheck, SIGNAL(toggled(bool)), this, SLOT(onShowLabelsToggled(bool)));
|
|
|
|
|
connect(m_pUseKCheck, SIGNAL(toggled(bool)),
|
|
|
|
|
this, SLOT(onCalculationSelectionChanged()));
|
|
|
|
|
connect(m_pKCalculationDataSetCombo, SIGNAL(currentIndexChanged(int)),
|
|
|
|
|
this, SLOT(onCalculationSelectionChanged()));
|
|
|
|
|
connect(m_pUsePhiCheck, SIGNAL(toggled(bool)),
|
|
|
|
|
this, SLOT(onCalculationSelectionChanged()));
|
|
|
|
|
connect(m_pPhiCalculationDataSetCombo, SIGNAL(currentIndexChanged(int)),
|
|
|
|
|
this, SLOT(onCalculationSelectionChanged()));
|
|
|
|
|
connect(m_pUseHCheck, SIGNAL(toggled(bool)),
|
|
|
|
|
this, SLOT(onCalculationSelectionChanged()));
|
|
|
|
|
connect(m_pHCalculationDataSetCombo, SIGNAL(currentIndexChanged(int)),
|
|
|
|
|
this, SLOT(onCalculationSelectionChanged()));
|
|
|
|
|
connect(m_pPreviewButton, SIGNAL(clicked()), this, SLOT(onPreview()));
|
|
|
|
|
connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
|
|
|
|
|
}
|
|
|
|
|
@ -371,6 +596,7 @@ void nmWxPropertyInterpolationDlg::initializeDataSets()
|
|
|
|
|
{
|
|
|
|
|
m_bUpdatingUi = true;
|
|
|
|
|
|
|
|
|
|
// 数据组允许为空,首次进入窗口时不自动创建默认数据组.
|
|
|
|
|
if(!m_pDataManager.isNull()) {
|
|
|
|
|
m_vecDataSets = m_pDataManager->getPropertyInterpolationDataSets();
|
|
|
|
|
}
|
|
|
|
|
@ -400,6 +626,7 @@ void nmWxPropertyInterpolationDlg::initializeDataSets()
|
|
|
|
|
loadDataSet(initialIndex);
|
|
|
|
|
m_bUpdatingUi = false;
|
|
|
|
|
updateDataSetButtons();
|
|
|
|
|
updateCalculationDataSetControls();
|
|
|
|
|
|
|
|
|
|
if(dataChanged) {
|
|
|
|
|
syncDataSetsToManager(false);
|
|
|
|
|
@ -448,26 +675,33 @@ void nmWxPropertyInterpolationDlg::loadDataSet(int index)
|
|
|
|
|
// 切换数据组时批量刷新控件,避免控件信号被误判为用户修改.
|
|
|
|
|
bool wasUpdating = m_bUpdatingUi;
|
|
|
|
|
m_bUpdatingUi = true;
|
|
|
|
|
const nmPropertyInterpolationDataSet& dataSet = m_vecDataSets[index];
|
|
|
|
|
nmPropertyInterpolationDataSet& dataSet = m_vecDataSets[index];
|
|
|
|
|
|
|
|
|
|
m_pNameEdit->setText(dataSet.name);
|
|
|
|
|
int propertyIndex = m_pPropertyCombo->findData(dataSet.property);
|
|
|
|
|
m_pPropertyCombo->setCurrentIndex(propertyIndex < 0 ? 0 : propertyIndex);
|
|
|
|
|
updateUnitControls(dataSet);
|
|
|
|
|
m_pNewValueSpin->setValue(0.0);
|
|
|
|
|
m_pNuggetSpin->setValue(dataSet.nugget);
|
|
|
|
|
m_pSillSpin->setValue(dataSet.sill);
|
|
|
|
|
m_pRangeSpin->setValue(dataSet.range);
|
|
|
|
|
// Range在数据组中保存为m,加载时转换成当前选择的显示单位.
|
|
|
|
|
m_pRangeSpin->setValue(convertedUnitValue(
|
|
|
|
|
dataSet.range, LENGTH_BASE_UNIT,
|
|
|
|
|
m_pRangeUnitCombo->currentText()));
|
|
|
|
|
int modelIndex = m_pModelCombo->findData(dataSet.model);
|
|
|
|
|
m_pModelCombo->setCurrentIndex(modelIndex < 0 ? 0 : modelIndex);
|
|
|
|
|
m_pShowPointsCheck->setChecked(dataSet.showPoints);
|
|
|
|
|
m_pShowLabelsCheck->setChecked(dataSet.showLabels);
|
|
|
|
|
|
|
|
|
|
// 重建测点行时保留第0行单位控件,并阻止itemChanged反向修改数据.
|
|
|
|
|
bool oldTableBlock = m_pPointTable->blockSignals(true);
|
|
|
|
|
m_pPointTable->setRowCount(0);
|
|
|
|
|
clearPointRows();
|
|
|
|
|
const QStringList markerNames = m_vecMarkerNames.value(index);
|
|
|
|
|
for(int i = 0; i < dataSet.points.size(); ++i) {
|
|
|
|
|
appendPointRow(dataSet.points[i], markerNames.value(i));
|
|
|
|
|
}
|
|
|
|
|
m_pPointTable->blockSignals(oldTableBlock);
|
|
|
|
|
updatePointDisplayValues();
|
|
|
|
|
|
|
|
|
|
clearTableSelection();
|
|
|
|
|
updatePointButtons();
|
|
|
|
|
@ -487,7 +721,13 @@ void nmWxPropertyInterpolationDlg::clearCurrentDataSet()
|
|
|
|
|
m_pNameEdit->clear();
|
|
|
|
|
m_pPropertyCombo->setCurrentIndex(-1);
|
|
|
|
|
m_pNewValueSpin->setValue(0.0);
|
|
|
|
|
m_pPointTable->setRowCount(0);
|
|
|
|
|
// 没有当前数据组时保留坐标基准单位,属性值单位置空并禁用.
|
|
|
|
|
populateUnitCombo(m_pXUnitCombo, LENGTH_BASE_UNIT, LENGTH_BASE_UNIT);
|
|
|
|
|
populateUnitCombo(m_pYUnitCombo, LENGTH_BASE_UNIT, LENGTH_BASE_UNIT);
|
|
|
|
|
populateUnitCombo(m_pNewValueUnitCombo, QString(), QString());
|
|
|
|
|
populateUnitCombo(m_pValueUnitCombo, QString(), QString());
|
|
|
|
|
populateUnitCombo(m_pRangeUnitCombo, LENGTH_BASE_UNIT, LENGTH_BASE_UNIT);
|
|
|
|
|
clearPointRows();
|
|
|
|
|
m_pShowPointsCheck->setChecked(false);
|
|
|
|
|
m_pShowLabelsCheck->setChecked(false);
|
|
|
|
|
m_pNuggetSpin->setValue(0.01);
|
|
|
|
|
@ -510,15 +750,106 @@ void nmWxPropertyInterpolationDlg::saveCurrentDataSet()
|
|
|
|
|
nmPropertyInterpolationDataSet& dataSet = m_vecDataSets[m_nCurrentDataSetIndex];
|
|
|
|
|
dataSet.name = m_pNameEdit->text();
|
|
|
|
|
dataSet.property = m_pPropertyCombo->itemData(m_pPropertyCombo->currentIndex()).toString();
|
|
|
|
|
// 显示单位作为界面偏好保存,Range写回数据组前统一转换为米.
|
|
|
|
|
dataSet.xDisplayUnit = m_pXUnitCombo->currentText();
|
|
|
|
|
dataSet.yDisplayUnit = m_pYUnitCombo->currentText();
|
|
|
|
|
dataSet.valueDisplayUnit = propertyBaseUnit(dataSet.property).isEmpty() ?
|
|
|
|
|
QString() : m_pValueUnitCombo->currentText();
|
|
|
|
|
dataSet.rangeDisplayUnit = m_pRangeUnitCombo->currentText();
|
|
|
|
|
dataSet.nugget = m_pNuggetSpin->value();
|
|
|
|
|
dataSet.sill = m_pSillSpin->value();
|
|
|
|
|
dataSet.range = m_pRangeSpin->value();
|
|
|
|
|
dataSet.range = convertedUnitValue(
|
|
|
|
|
m_pRangeSpin->value(), dataSet.rangeDisplayUnit,
|
|
|
|
|
LENGTH_BASE_UNIT);
|
|
|
|
|
dataSet.model = m_pModelCombo->itemData(m_pModelCombo->currentIndex()).toInt();
|
|
|
|
|
dataSet.showPoints = m_pShowPointsCheck->isChecked();
|
|
|
|
|
dataSet.showLabels = m_pShowLabelsCheck->isChecked();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmWxPropertyInterpolationDlg::updateUnitControls(
|
|
|
|
|
nmPropertyInterpolationDataSet& dataSet)
|
|
|
|
|
{
|
|
|
|
|
populateUnitCombo(m_pXUnitCombo, LENGTH_BASE_UNIT,
|
|
|
|
|
dataSet.xDisplayUnit);
|
|
|
|
|
populateUnitCombo(m_pYUnitCombo, LENGTH_BASE_UNIT,
|
|
|
|
|
dataSet.yDisplayUnit);
|
|
|
|
|
|
|
|
|
|
const QString valueBaseUnit = propertyBaseUnit(dataSet.property);
|
|
|
|
|
// 未保存显示单位时按属性默认值初始化,孔隙度使用空单位.
|
|
|
|
|
const QString valueDisplayUnit = dataSet.valueDisplayUnit.isEmpty() ?
|
|
|
|
|
defaultPropertyDisplayUnit(dataSet.property) :
|
|
|
|
|
dataSet.valueDisplayUnit;
|
|
|
|
|
populateUnitCombo(m_pNewValueUnitCombo,
|
|
|
|
|
valueBaseUnit, valueDisplayUnit);
|
|
|
|
|
populateUnitCombo(m_pValueUnitCombo,
|
|
|
|
|
valueBaseUnit, valueDisplayUnit);
|
|
|
|
|
populateUnitCombo(m_pRangeUnitCombo, LENGTH_BASE_UNIT,
|
|
|
|
|
dataSet.rangeDisplayUnit);
|
|
|
|
|
dataSet.xDisplayUnit = m_pXUnitCombo->currentText();
|
|
|
|
|
dataSet.yDisplayUnit = m_pYUnitCombo->currentText();
|
|
|
|
|
dataSet.valueDisplayUnit = valueBaseUnit.isEmpty() ?
|
|
|
|
|
QString() : m_pValueUnitCombo->currentText();
|
|
|
|
|
dataSet.rangeDisplayUnit = m_pRangeUnitCombo->currentText();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmWxPropertyInterpolationDlg::updatePointDisplayValues()
|
|
|
|
|
{
|
|
|
|
|
if(m_nCurrentDataSetIndex < 0 ||
|
|
|
|
|
m_nCurrentDataSetIndex >= m_vecDataSets.size()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const nmPropertyInterpolationDataSet& dataSet =
|
|
|
|
|
m_vecDataSets[m_nCurrentDataSetIndex];
|
|
|
|
|
const QString valueBaseUnit = propertyBaseUnit(dataSet.property);
|
|
|
|
|
// 测点保留基准值,仅换算表格和地图标签;屏蔽信号避免刷新时反向写回.
|
|
|
|
|
bool oldTableBlock = m_pPointTable->blockSignals(true);
|
|
|
|
|
for(int pointIndex = 0; pointIndex < dataSet.points.size(); ++pointIndex) {
|
|
|
|
|
const int tableRow = pointIndex + FIRST_POINT_ROW;
|
|
|
|
|
if(tableRow >= m_pPointTable->rowCount()) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const nmPropertyInterpolationPointData& point = dataSet.points[pointIndex];
|
|
|
|
|
QTableWidgetItem* xItem = m_pPointTable->item(tableRow, 0);
|
|
|
|
|
QTableWidgetItem* yItem = m_pPointTable->item(tableRow, 1);
|
|
|
|
|
QTableWidgetItem* valueItem = m_pPointTable->item(tableRow, 2);
|
|
|
|
|
if(xItem != NULL) {
|
|
|
|
|
xItem->setText(displayValueText(convertedUnitValue(
|
|
|
|
|
point.x, LENGTH_BASE_UNIT,
|
|
|
|
|
dataSet.xDisplayUnit)));
|
|
|
|
|
}
|
|
|
|
|
if(yItem != NULL) {
|
|
|
|
|
yItem->setText(displayValueText(convertedUnitValue(
|
|
|
|
|
point.y, LENGTH_BASE_UNIT,
|
|
|
|
|
dataSet.yDisplayUnit)));
|
|
|
|
|
}
|
|
|
|
|
const double displayValue = convertedUnitValue(
|
|
|
|
|
point.value, valueBaseUnit,
|
|
|
|
|
dataSet.valueDisplayUnit);
|
|
|
|
|
const QString valueText = displayValueText(displayValue);
|
|
|
|
|
if(valueItem != NULL) {
|
|
|
|
|
valueItem->setText(valueText);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nmObjPoint* marker = markerAt(tableRow);
|
|
|
|
|
if(marker != NULL) {
|
|
|
|
|
setMarkerLabel(marker, valueText);
|
|
|
|
|
marker->update();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
m_pPointTable->blockSignals(oldTableBlock);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmWxPropertyInterpolationDlg::clearPointRows()
|
|
|
|
|
{
|
|
|
|
|
// 只删除测点数据行,第0行的单位下拉框始终保留.
|
|
|
|
|
if(m_pPointTable != NULL && m_pPointTable->rowCount() > FIRST_POINT_ROW) {
|
|
|
|
|
m_pPointTable->setRowCount(FIRST_POINT_ROW);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmWxPropertyInterpolationDlg::syncDataSetsToManager(bool markModified)
|
|
|
|
|
{
|
|
|
|
|
if(!m_pDataManager.isNull()) {
|
|
|
|
|
@ -536,23 +867,99 @@ void nmWxPropertyInterpolationDlg::updateDataSetButtons()
|
|
|
|
|
m_nCurrentDataSetIndex < m_vecDataSets.size();
|
|
|
|
|
const bool canPickOnMap = hasCurrent && !m_pPlot.isNull() &&
|
|
|
|
|
m_pPlot->m_pPlotView != NULL && m_pPlot->m_pPlot != NULL;
|
|
|
|
|
const bool hasValueUnit = hasCurrent &&
|
|
|
|
|
!propertyBaseUnit(m_vecDataSets[m_nCurrentDataSetIndex].property).isEmpty();
|
|
|
|
|
|
|
|
|
|
m_pDataSetCombo->setEnabled(hasCurrent);
|
|
|
|
|
m_pDeleteDataSetButton->setEnabled(hasCurrent);
|
|
|
|
|
m_pNameEdit->setEnabled(hasCurrent);
|
|
|
|
|
m_pPropertyCombo->setEnabled(hasCurrent);
|
|
|
|
|
m_pNewValueSpin->setEnabled(hasCurrent);
|
|
|
|
|
m_pNewValueUnitCombo->setEnabled(hasValueUnit);
|
|
|
|
|
m_pMapPickButton->setEnabled(canPickOnMap);
|
|
|
|
|
m_pPointTable->setEnabled(hasCurrent);
|
|
|
|
|
m_pXUnitCombo->setEnabled(hasCurrent);
|
|
|
|
|
m_pYUnitCombo->setEnabled(hasCurrent);
|
|
|
|
|
m_pValueUnitCombo->setEnabled(hasValueUnit);
|
|
|
|
|
m_pShowPointsCheck->setEnabled(hasCurrent);
|
|
|
|
|
m_pShowLabelsCheck->setEnabled(hasCurrent);
|
|
|
|
|
m_pNuggetSpin->setEnabled(hasCurrent);
|
|
|
|
|
m_pSillSpin->setEnabled(hasCurrent);
|
|
|
|
|
m_pRangeSpin->setEnabled(hasCurrent);
|
|
|
|
|
m_pRangeUnitCombo->setEnabled(hasCurrent);
|
|
|
|
|
m_pModelCombo->setEnabled(hasCurrent);
|
|
|
|
|
updatePointButtons();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmWxPropertyInterpolationDlg::updateCalculationDataSetControls()
|
|
|
|
|
{
|
|
|
|
|
// 批量重建三个下拉框时阻止选择变化信号写回未完成的界面状态.
|
|
|
|
|
bool wasUpdating = m_bUpdatingUi;
|
|
|
|
|
m_bUpdatingUi = true;
|
|
|
|
|
updateCalculationDataSetControl("k", m_pUseKCheck,
|
|
|
|
|
m_pKCalculationDataSetCombo);
|
|
|
|
|
updateCalculationDataSetControl("phi", m_pUsePhiCheck,
|
|
|
|
|
m_pPhiCalculationDataSetCombo);
|
|
|
|
|
updateCalculationDataSetControl("h", m_pUseHCheck,
|
|
|
|
|
m_pHCalculationDataSetCombo);
|
|
|
|
|
m_bUpdatingUi = wasUpdating;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmWxPropertyInterpolationDlg::updateCalculationDataSetControl(
|
|
|
|
|
const QString& property,
|
|
|
|
|
QCheckBox* checkBox,
|
|
|
|
|
QComboBox* comboBox)
|
|
|
|
|
{
|
|
|
|
|
if(checkBox == NULL || comboBox == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 下拉项保存原数据组下标,并根据useForCalculation恢复当前选择.
|
|
|
|
|
comboBox->clear();
|
|
|
|
|
int selectedComboIndex = -1;
|
|
|
|
|
for(int dataSetIndex = 0; dataSetIndex < m_vecDataSets.size(); ++dataSetIndex) {
|
|
|
|
|
const nmPropertyInterpolationDataSet& dataSet = m_vecDataSets[dataSetIndex];
|
|
|
|
|
if(dataSet.property != property) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
comboBox->addItem(dataSet.name, dataSetIndex);
|
|
|
|
|
if(selectedComboIndex < 0 && dataSet.useForCalculation) {
|
|
|
|
|
selectedComboIndex = comboBox->count() - 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
comboBox->setCurrentIndex(selectedComboIndex >= 0 ? selectedComboIndex :
|
|
|
|
|
(comboBox->count() > 0 ? 0 : -1));
|
|
|
|
|
checkBox->setChecked(selectedComboIndex >= 0);
|
|
|
|
|
checkBox->setEnabled(comboBox->count() > 0);
|
|
|
|
|
comboBox->setEnabled(checkBox->isChecked() && comboBox->count() > 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmWxPropertyInterpolationDlg::saveCalculationSelection(
|
|
|
|
|
const QString& property,
|
|
|
|
|
QCheckBox* checkBox,
|
|
|
|
|
QComboBox* comboBox)
|
|
|
|
|
{
|
|
|
|
|
// 先清除同属性的旧标记,保证每个属性最多启用一个插值数据组.
|
|
|
|
|
for(int dataSetIndex = 0; dataSetIndex < m_vecDataSets.size(); ++dataSetIndex) {
|
|
|
|
|
if(m_vecDataSets[dataSetIndex].property == property) {
|
|
|
|
|
m_vecDataSets[dataSetIndex].useForCalculation = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(checkBox == NULL || comboBox == NULL || !checkBox->isChecked()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const int selectedDataSetIndex = comboBox->itemData(
|
|
|
|
|
comboBox->currentIndex()).toInt();
|
|
|
|
|
if(selectedDataSetIndex >= 0 && selectedDataSetIndex < m_vecDataSets.size() &&
|
|
|
|
|
m_vecDataSets[selectedDataSetIndex].property == property) {
|
|
|
|
|
m_vecDataSets[selectedDataSetIndex].useForCalculation = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmWxPropertyInterpolationDlg::onDataSetChanged(int index)
|
|
|
|
|
{
|
|
|
|
|
if(m_bUpdatingUi || index < 0 || index >= m_vecDataSets.size() ||
|
|
|
|
|
@ -582,6 +989,7 @@ void nmWxPropertyInterpolationDlg::onAddDataSet()
|
|
|
|
|
m_nCurrentDataSetIndex = newIndex;
|
|
|
|
|
loadDataSet(newIndex);
|
|
|
|
|
updateDataSetButtons();
|
|
|
|
|
updateCalculationDataSetControls();
|
|
|
|
|
syncDataSetsToManager(true);
|
|
|
|
|
schedulePreviewRefresh();
|
|
|
|
|
}
|
|
|
|
|
@ -608,6 +1016,7 @@ void nmWxPropertyInterpolationDlg::onDeleteDataSet()
|
|
|
|
|
m_nCurrentDataSetIndex = newIndex;
|
|
|
|
|
loadDataSet(newIndex);
|
|
|
|
|
updateDataSetButtons();
|
|
|
|
|
updateCalculationDataSetControls();
|
|
|
|
|
syncDataSetsToManager(true);
|
|
|
|
|
schedulePreviewRefresh();
|
|
|
|
|
}
|
|
|
|
|
@ -621,6 +1030,30 @@ void nmWxPropertyInterpolationDlg::onDataSetNameChanged(const QString& name)
|
|
|
|
|
|
|
|
|
|
m_vecDataSets[m_nCurrentDataSetIndex].name = name;
|
|
|
|
|
m_pDataSetCombo->setItemText(m_nCurrentDataSetIndex, name);
|
|
|
|
|
updateCalculationDataSetControls();
|
|
|
|
|
syncDataSetsToManager(true);
|
|
|
|
|
schedulePreviewRefresh();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmWxPropertyInterpolationDlg::onCurrentDataSetPropertyChanged()
|
|
|
|
|
{
|
|
|
|
|
if(m_bUpdatingUi || m_nCurrentDataSetIndex < 0 ||
|
|
|
|
|
m_nCurrentDataSetIndex >= m_vecDataSets.size()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 数据组切换属性后取消原有求解选择,并切换到对应的基准显示单位.
|
|
|
|
|
nmPropertyInterpolationDataSet& dataSet =
|
|
|
|
|
m_vecDataSets[m_nCurrentDataSetIndex];
|
|
|
|
|
dataSet.useForCalculation = false;
|
|
|
|
|
dataSet.property = m_pPropertyCombo->itemData(
|
|
|
|
|
m_pPropertyCombo->currentIndex()).toString();
|
|
|
|
|
dataSet.valueDisplayUnit = defaultPropertyDisplayUnit(dataSet.property);
|
|
|
|
|
updateUnitControls(dataSet);
|
|
|
|
|
m_pNewValueSpin->setValue(0.0);
|
|
|
|
|
updatePointDisplayValues();
|
|
|
|
|
saveCurrentDataSet();
|
|
|
|
|
updateCalculationDataSetControls();
|
|
|
|
|
syncDataSetsToManager(true);
|
|
|
|
|
schedulePreviewRefresh();
|
|
|
|
|
}
|
|
|
|
|
@ -636,6 +1069,114 @@ void nmWxPropertyInterpolationDlg::onCurrentDataSetEdited()
|
|
|
|
|
schedulePreviewRefresh();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmWxPropertyInterpolationDlg::onXDisplayUnitChanged(const QString& unit)
|
|
|
|
|
{
|
|
|
|
|
if(m_bUpdatingUi || m_nCurrentDataSetIndex < 0 ||
|
|
|
|
|
m_nCurrentDataSetIndex >= m_vecDataSets.size()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 坐标基准值保持为m,仅刷新X列的显示文本.
|
|
|
|
|
m_vecDataSets[m_nCurrentDataSetIndex].xDisplayUnit = unit;
|
|
|
|
|
updatePointDisplayValues();
|
|
|
|
|
syncDataSetsToManager(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmWxPropertyInterpolationDlg::onYDisplayUnitChanged(const QString& unit)
|
|
|
|
|
{
|
|
|
|
|
if(m_bUpdatingUi || m_nCurrentDataSetIndex < 0 ||
|
|
|
|
|
m_nCurrentDataSetIndex >= m_vecDataSets.size()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 坐标基准值保持为m,仅刷新Y列的显示文本.
|
|
|
|
|
m_vecDataSets[m_nCurrentDataSetIndex].yDisplayUnit = unit;
|
|
|
|
|
updatePointDisplayValues();
|
|
|
|
|
syncDataSetsToManager(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmWxPropertyInterpolationDlg::onValueDisplayUnitChanged(const QString& unit)
|
|
|
|
|
{
|
|
|
|
|
if(m_bUpdatingUi || m_nCurrentDataSetIndex < 0 ||
|
|
|
|
|
m_nCurrentDataSetIndex >= m_vecDataSets.size()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nmPropertyInterpolationDataSet& dataSet =
|
|
|
|
|
m_vecDataSets[m_nCurrentDataSetIndex];
|
|
|
|
|
const QString baseUnit = propertyBaseUnit(dataSet.property);
|
|
|
|
|
if(baseUnit.isEmpty() || unit.isEmpty() ||
|
|
|
|
|
unit == dataSet.valueDisplayUnit) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 经基准单位中转,切换单位时不会改变待添加值表示的物理量.
|
|
|
|
|
const double baseNewValue = convertedUnitValue(
|
|
|
|
|
m_pNewValueSpin->value(),
|
|
|
|
|
dataSet.valueDisplayUnit, baseUnit);
|
|
|
|
|
dataSet.valueDisplayUnit = unit;
|
|
|
|
|
|
|
|
|
|
// 新值和表头共用显示单位,联动时屏蔽信号以避免递归触发.
|
|
|
|
|
bool oldBlock = m_pNewValueUnitCombo->blockSignals(true);
|
|
|
|
|
m_pNewValueUnitCombo->setCurrentIndex(
|
|
|
|
|
m_pNewValueUnitCombo->findText(unit));
|
|
|
|
|
m_pNewValueUnitCombo->blockSignals(oldBlock);
|
|
|
|
|
oldBlock = m_pValueUnitCombo->blockSignals(true);
|
|
|
|
|
m_pValueUnitCombo->setCurrentIndex(m_pValueUnitCombo->findText(unit));
|
|
|
|
|
m_pValueUnitCombo->blockSignals(oldBlock);
|
|
|
|
|
oldBlock = m_pNewValueSpin->blockSignals(true);
|
|
|
|
|
m_pNewValueSpin->setValue(convertedUnitValue(
|
|
|
|
|
baseNewValue, baseUnit, unit));
|
|
|
|
|
m_pNewValueSpin->blockSignals(oldBlock);
|
|
|
|
|
|
|
|
|
|
updatePointDisplayValues();
|
|
|
|
|
syncDataSetsToManager(true);
|
|
|
|
|
schedulePreviewRefresh();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmWxPropertyInterpolationDlg::onRangeDisplayUnitChanged(const QString& unit)
|
|
|
|
|
{
|
|
|
|
|
if(m_bUpdatingUi || unit.isEmpty() || m_nCurrentDataSetIndex < 0 ||
|
|
|
|
|
m_nCurrentDataSetIndex >= m_vecDataSets.size()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nmPropertyInterpolationDataSet& dataSet =
|
|
|
|
|
m_vecDataSets[m_nCurrentDataSetIndex];
|
|
|
|
|
// 先按旧显示单位还原米制基准值,再使用新单位回显.
|
|
|
|
|
dataSet.range = convertedUnitValue(
|
|
|
|
|
m_pRangeSpin->value(), dataSet.rangeDisplayUnit,
|
|
|
|
|
LENGTH_BASE_UNIT);
|
|
|
|
|
dataSet.rangeDisplayUnit = unit;
|
|
|
|
|
|
|
|
|
|
bool oldBlock = m_pRangeSpin->blockSignals(true);
|
|
|
|
|
m_pRangeSpin->setValue(convertedUnitValue(
|
|
|
|
|
dataSet.range, LENGTH_BASE_UNIT, unit));
|
|
|
|
|
m_pRangeSpin->blockSignals(oldBlock);
|
|
|
|
|
syncDataSetsToManager(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmWxPropertyInterpolationDlg::onCalculationSelectionChanged()
|
|
|
|
|
{
|
|
|
|
|
if(m_bUpdatingUi) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 先保存当前编辑内容,再统一更新三个属性的唯一求解数据组.
|
|
|
|
|
saveCurrentDataSet();
|
|
|
|
|
saveCalculationSelection("k", m_pUseKCheck,
|
|
|
|
|
m_pKCalculationDataSetCombo);
|
|
|
|
|
saveCalculationSelection("phi", m_pUsePhiCheck,
|
|
|
|
|
m_pPhiCalculationDataSetCombo);
|
|
|
|
|
saveCalculationSelection("h", m_pUseHCheck,
|
|
|
|
|
m_pHCalculationDataSetCombo);
|
|
|
|
|
|
|
|
|
|
m_pKCalculationDataSetCombo->setEnabled(m_pUseKCheck->isChecked());
|
|
|
|
|
m_pPhiCalculationDataSetCombo->setEnabled(m_pUsePhiCheck->isChecked());
|
|
|
|
|
m_pHCalculationDataSetCombo->setEnabled(m_pUseHCheck->isChecked());
|
|
|
|
|
syncDataSetsToManager(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool nmWxPropertyInterpolationDlg::eventFilter(QObject* watched, QEvent* event)
|
|
|
|
|
{
|
|
|
|
|
// 点击表格空白处或其他控件时取消测点行的选中状态.
|
|
|
|
|
@ -706,10 +1247,15 @@ void nmWxPropertyInterpolationDlg::appendPoint(const QPointF& valuePoint)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nmPropertyInterpolationDataSet& dataSet = m_vecDataSets[m_nCurrentDataSetIndex];
|
|
|
|
|
double pointValue = m_pNewValueSpin->value();
|
|
|
|
|
const QString valueBaseUnit = propertyBaseUnit(dataSet.property);
|
|
|
|
|
const double displayPointValue = m_pNewValueSpin->value();
|
|
|
|
|
// 属性值按求解器基准单位保存,地图标签继续使用当前显示值.
|
|
|
|
|
const double pointValue = convertedUnitValue(
|
|
|
|
|
displayPointValue, dataSet.valueDisplayUnit,
|
|
|
|
|
valueBaseUnit);
|
|
|
|
|
nmPropertyInterpolationPointData point(valuePoint.x(), valuePoint.y(), pointValue);
|
|
|
|
|
QString markerName = createMarker(valuePoint, pointValue,
|
|
|
|
|
dataSet.showPoints, dataSet.showLabels);
|
|
|
|
|
QString markerName = createMarker(valuePoint, displayPointValue,
|
|
|
|
|
dataSet.showPoints, dataSet.showLabels);
|
|
|
|
|
|
|
|
|
|
// 测点数据、地图标记和表格行按相同顺序同步追加.
|
|
|
|
|
dataSet.points.append(point);
|
|
|
|
|
@ -728,20 +1274,38 @@ void nmWxPropertyInterpolationDlg::appendPointRow(
|
|
|
|
|
const nmPropertyInterpolationPointData& point,
|
|
|
|
|
const QString& markerName)
|
|
|
|
|
{
|
|
|
|
|
// rowCount已包含单位行,新插入行天然与points下标保持FIRST_POINT_ROW偏移.
|
|
|
|
|
int row = m_pPointTable->rowCount();
|
|
|
|
|
m_pPointTable->insertRow(row);
|
|
|
|
|
|
|
|
|
|
QTableWidgetItem* xItem = new QTableWidgetItem(QString::number(point.x, 'g', 15));
|
|
|
|
|
QString xUnit = LENGTH_BASE_UNIT;
|
|
|
|
|
QString yUnit = LENGTH_BASE_UNIT;
|
|
|
|
|
QString valueUnit;
|
|
|
|
|
QString valueBaseUnit;
|
|
|
|
|
if(m_nCurrentDataSetIndex >= 0 &&
|
|
|
|
|
m_nCurrentDataSetIndex < m_vecDataSets.size()) {
|
|
|
|
|
const nmPropertyInterpolationDataSet& dataSet =
|
|
|
|
|
m_vecDataSets[m_nCurrentDataSetIndex];
|
|
|
|
|
xUnit = dataSet.xDisplayUnit;
|
|
|
|
|
yUnit = dataSet.yDisplayUnit;
|
|
|
|
|
valueUnit = dataSet.valueDisplayUnit;
|
|
|
|
|
valueBaseUnit = propertyBaseUnit(dataSet.property);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QTableWidgetItem* xItem = new QTableWidgetItem(displayValueText(
|
|
|
|
|
convertedUnitValue(point.x, LENGTH_BASE_UNIT, xUnit)));
|
|
|
|
|
xItem->setFlags(xItem->flags() & ~Qt::ItemIsEditable);
|
|
|
|
|
// 将地图标记名称绑定在X列,后续可由表格行直接定位对应标记.
|
|
|
|
|
xItem->setData(Qt::UserRole, markerName);
|
|
|
|
|
m_pPointTable->setItem(row, 0, xItem);
|
|
|
|
|
|
|
|
|
|
QTableWidgetItem* yItem = new QTableWidgetItem(QString::number(point.y, 'g', 15));
|
|
|
|
|
QTableWidgetItem* yItem = new QTableWidgetItem(displayValueText(
|
|
|
|
|
convertedUnitValue(point.y, LENGTH_BASE_UNIT, yUnit)));
|
|
|
|
|
yItem->setFlags(yItem->flags() & ~Qt::ItemIsEditable);
|
|
|
|
|
m_pPointTable->setItem(row, 1, yItem);
|
|
|
|
|
|
|
|
|
|
m_pPointTable->setItem(row, 2,
|
|
|
|
|
new QTableWidgetItem(QString::number(point.value, 'f', 6)));
|
|
|
|
|
m_pPointTable->setItem(row, 2, new QTableWidgetItem(displayValueText(
|
|
|
|
|
convertedUnitValue(point.value, valueBaseUnit, valueUnit))));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString nmWxPropertyInterpolationDlg::createMarker(const QPointF& valuePosition,
|
|
|
|
|
@ -793,6 +1357,7 @@ void nmWxPropertyInterpolationDlg::createMarkersForAllDataSets()
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 地图标签使用显示单位,数据组中的测点基准值保持不变.
|
|
|
|
|
for(int dataSetIndex = 0; dataSetIndex < m_vecDataSets.size(); ++dataSetIndex) {
|
|
|
|
|
const nmPropertyInterpolationDataSet& dataSet = m_vecDataSets[dataSetIndex];
|
|
|
|
|
QStringList markerNames;
|
|
|
|
|
@ -800,8 +1365,11 @@ void nmWxPropertyInterpolationDlg::createMarkersForAllDataSets()
|
|
|
|
|
for(int pointIndex = 0; pointIndex < dataSet.points.size(); ++pointIndex) {
|
|
|
|
|
const nmPropertyInterpolationPointData& point = dataSet.points[pointIndex];
|
|
|
|
|
QPointF valuePosition(point.x, point.y);
|
|
|
|
|
markerNames.append(createMarker(valuePosition, point.value,
|
|
|
|
|
dataSet.showPoints, dataSet.showLabels));
|
|
|
|
|
const double displayValue = convertedUnitValue(
|
|
|
|
|
point.value, propertyBaseUnit(dataSet.property),
|
|
|
|
|
dataSet.valueDisplayUnit);
|
|
|
|
|
markerNames.append(createMarker(valuePosition, displayValue,
|
|
|
|
|
dataSet.showPoints, dataSet.showLabels));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_vecMarkerNames[dataSetIndex] = markerNames;
|
|
|
|
|
@ -831,7 +1399,8 @@ void nmWxPropertyInterpolationDlg::removeAllMarkers()
|
|
|
|
|
|
|
|
|
|
QString nmWxPropertyInterpolationDlg::markerNameAt(int row) const
|
|
|
|
|
{
|
|
|
|
|
if(m_pPointTable == NULL || row < 0 || row >= m_pPointTable->rowCount()) {
|
|
|
|
|
if(m_pPointTable == NULL || row < FIRST_POINT_ROW ||
|
|
|
|
|
row >= m_pPointTable->rowCount()) {
|
|
|
|
|
return QString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -867,20 +1436,33 @@ void nmWxPropertyInterpolationDlg::removeMarkerByName(const QString& markerName)
|
|
|
|
|
|
|
|
|
|
void nmWxPropertyInterpolationDlg::onPointSelectionChanged()
|
|
|
|
|
{
|
|
|
|
|
// 单位行只用于切换显示单位,不作为可删除的测点行.
|
|
|
|
|
if(m_pPointTable->currentRow() == POINT_UNIT_ROW) {
|
|
|
|
|
clearTableSelection();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
updatePointButtons();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmWxPropertyInterpolationDlg::onPointItemChanged(QTableWidgetItem* item)
|
|
|
|
|
{
|
|
|
|
|
// 表格行减去单位行偏移后,才是数据组中的测点下标.
|
|
|
|
|
const int pointIndex = item == NULL ? -1 :
|
|
|
|
|
item->row() - FIRST_POINT_ROW;
|
|
|
|
|
if(m_bUpdatingUi || item == NULL || item->column() != 2 ||
|
|
|
|
|
pointIndex < 0 ||
|
|
|
|
|
m_nCurrentDataSetIndex < 0 ||
|
|
|
|
|
m_nCurrentDataSetIndex >= m_vecDataSets.size() ||
|
|
|
|
|
item->row() >= m_vecDataSets[m_nCurrentDataSetIndex].points.size()) {
|
|
|
|
|
pointIndex >= m_vecDataSets[m_nCurrentDataSetIndex].points.size()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 数值修改后同步更新数据组和地图标签,坐标列保持只读.
|
|
|
|
|
m_vecDataSets[m_nCurrentDataSetIndex].points[item->row()].value = item->text().toDouble();
|
|
|
|
|
nmPropertyInterpolationDataSet& dataSet =
|
|
|
|
|
m_vecDataSets[m_nCurrentDataSetIndex];
|
|
|
|
|
dataSet.points[pointIndex].value = convertedUnitValue(
|
|
|
|
|
item->text().toDouble(), dataSet.valueDisplayUnit,
|
|
|
|
|
propertyBaseUnit(dataSet.property));
|
|
|
|
|
nmObjPoint* marker = markerAt(item->row());
|
|
|
|
|
if(marker != NULL) {
|
|
|
|
|
setMarkerLabel(marker, item->text());
|
|
|
|
|
@ -893,17 +1475,19 @@ void nmWxPropertyInterpolationDlg::onPointItemChanged(QTableWidgetItem* item)
|
|
|
|
|
void nmWxPropertyInterpolationDlg::onDeleteSelectedPoint()
|
|
|
|
|
{
|
|
|
|
|
int row = m_pPointTable->currentRow();
|
|
|
|
|
if(row < 0 || m_nCurrentDataSetIndex < 0 ||
|
|
|
|
|
// 同时删除相同下标的数据、地图标记和表格行,保持三者一一对应.
|
|
|
|
|
const int pointIndex = row - FIRST_POINT_ROW;
|
|
|
|
|
if(pointIndex < 0 || m_nCurrentDataSetIndex < 0 ||
|
|
|
|
|
m_nCurrentDataSetIndex >= m_vecDataSets.size()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
removeMarkerByName(markerNameAt(row));
|
|
|
|
|
if(row < m_vecDataSets[m_nCurrentDataSetIndex].points.size()) {
|
|
|
|
|
m_vecDataSets[m_nCurrentDataSetIndex].points.remove(row);
|
|
|
|
|
if(pointIndex < m_vecDataSets[m_nCurrentDataSetIndex].points.size()) {
|
|
|
|
|
m_vecDataSets[m_nCurrentDataSetIndex].points.remove(pointIndex);
|
|
|
|
|
}
|
|
|
|
|
if(row < m_vecMarkerNames[m_nCurrentDataSetIndex].size()) {
|
|
|
|
|
m_vecMarkerNames[m_nCurrentDataSetIndex].removeAt(row);
|
|
|
|
|
if(pointIndex < m_vecMarkerNames[m_nCurrentDataSetIndex].size()) {
|
|
|
|
|
m_vecMarkerNames[m_nCurrentDataSetIndex].removeAt(pointIndex);
|
|
|
|
|
}
|
|
|
|
|
m_pPointTable->removeRow(row);
|
|
|
|
|
clearTableSelection();
|
|
|
|
|
@ -921,7 +1505,7 @@ void nmWxPropertyInterpolationDlg::onClearPoints()
|
|
|
|
|
|
|
|
|
|
removeDataSetMarkers(m_nCurrentDataSetIndex);
|
|
|
|
|
m_vecDataSets[m_nCurrentDataSetIndex].points.clear();
|
|
|
|
|
m_pPointTable->setRowCount(0);
|
|
|
|
|
clearPointRows();
|
|
|
|
|
clearTableSelection();
|
|
|
|
|
updatePointButtons();
|
|
|
|
|
syncDataSetsToManager(true);
|
|
|
|
|
@ -964,8 +1548,11 @@ void nmWxPropertyInterpolationDlg::updatePointButtons()
|
|
|
|
|
{
|
|
|
|
|
const bool hasCurrent = m_nCurrentDataSetIndex >= 0 &&
|
|
|
|
|
m_nCurrentDataSetIndex < m_vecDataSets.size();
|
|
|
|
|
m_pDeletePointButton->setEnabled(hasCurrent && m_pPointTable->currentRow() >= 0);
|
|
|
|
|
m_pClearPointsButton->setEnabled(hasCurrent && m_pPointTable->rowCount() > 0);
|
|
|
|
|
m_pDeletePointButton->setEnabled(
|
|
|
|
|
hasCurrent && m_pPointTable->currentRow() >= FIRST_POINT_ROW);
|
|
|
|
|
m_pClearPointsButton->setEnabled(
|
|
|
|
|
hasCurrent && m_pPointTable->rowCount() > FIRST_POINT_ROW);
|
|
|
|
|
// Kriging预览至少需要两个已知测点.
|
|
|
|
|
m_pPreviewButton->setEnabled(hasCurrent &&
|
|
|
|
|
m_vecDataSets[m_nCurrentDataSetIndex].points.size() >= 2);
|
|
|
|
|
}
|
|
|
|
|
@ -1095,17 +1682,40 @@ void nmWxPropertyInterpolationDlg::updatePreviewWindow(bool activateWindow)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Kriging使用内部基准值;渲染前统一转换表面和测点的显示单位.
|
|
|
|
|
const QString valueBaseUnit = propertyBaseUnit(dataSet.property);
|
|
|
|
|
QVector<double> displayInterpolationValues;
|
|
|
|
|
displayInterpolationValues.reserve(interpolationValues.size());
|
|
|
|
|
for(int i = 0; i < interpolationValues.size(); ++i) {
|
|
|
|
|
displayInterpolationValues.append(convertedUnitValue(
|
|
|
|
|
interpolationValues[i],
|
|
|
|
|
valueBaseUnit,
|
|
|
|
|
dataSet.valueDisplayUnit));
|
|
|
|
|
}
|
|
|
|
|
QVector<double> displayMeasurementValues;
|
|
|
|
|
displayMeasurementValues.reserve(measurementValues.size());
|
|
|
|
|
for(int i = 0; i < measurementValues.size(); ++i) {
|
|
|
|
|
displayMeasurementValues.append(convertedUnitValue(
|
|
|
|
|
measurementValues[i],
|
|
|
|
|
valueBaseUnit,
|
|
|
|
|
dataSet.valueDisplayUnit));
|
|
|
|
|
}
|
|
|
|
|
QString scalarTitle = m_pPropertyCombo->currentText();
|
|
|
|
|
if(!dataSet.valueDisplayUnit.isEmpty()) {
|
|
|
|
|
scalarTitle += QString(" (%1)").arg(dataSet.valueDisplayUnit);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 预览窗口只负责裁剪和渲染,不修改数据组及正式求解参数.
|
|
|
|
|
if(m_pPreviewDialog.isNull()) {
|
|
|
|
|
m_pPreviewDialog = new nmWxPropertyInterpolationPreviewDlg(
|
|
|
|
|
dataSet.name,
|
|
|
|
|
m_pPropertyCombo->currentText(),
|
|
|
|
|
scalarTitle,
|
|
|
|
|
previewBounds,
|
|
|
|
|
columnCount,
|
|
|
|
|
rowCount,
|
|
|
|
|
interpolationValues,
|
|
|
|
|
displayInterpolationValues,
|
|
|
|
|
measurementPoints,
|
|
|
|
|
measurementValues,
|
|
|
|
|
displayMeasurementValues,
|
|
|
|
|
outlinePoints,
|
|
|
|
|
dataSet.showPoints,
|
|
|
|
|
dataSet.showLabels,
|
|
|
|
|
@ -1115,13 +1725,13 @@ void nmWxPropertyInterpolationDlg::updatePreviewWindow(bool activateWindow)
|
|
|
|
|
else {
|
|
|
|
|
m_pPreviewDialog->updatePreview(
|
|
|
|
|
dataSet.name,
|
|
|
|
|
m_pPropertyCombo->currentText(),
|
|
|
|
|
scalarTitle,
|
|
|
|
|
previewBounds,
|
|
|
|
|
columnCount,
|
|
|
|
|
rowCount,
|
|
|
|
|
interpolationValues,
|
|
|
|
|
displayInterpolationValues,
|
|
|
|
|
measurementPoints,
|
|
|
|
|
measurementValues,
|
|
|
|
|
displayMeasurementValues,
|
|
|
|
|
outlinePoints,
|
|
|
|
|
dataSet.showPoints,
|
|
|
|
|
dataSet.showLabels);
|
|
|
|
|
|