|
|
|
|
@ -33,10 +33,12 @@
|
|
|
|
|
#include "nmDataOutline.h"
|
|
|
|
|
#include "nmGuiPlot.h"
|
|
|
|
|
#include "nmObjPoint.h"
|
|
|
|
|
#include "nmObjPointWell.h"
|
|
|
|
|
#include "nmWxPropertyInterpolationPreviewDlg.h"
|
|
|
|
|
#include "iUnitGroup.h"
|
|
|
|
|
#include "iUnitHelper.h"
|
|
|
|
|
#include "tCurvePlotView.h"
|
|
|
|
|
#include "ZxDataWell.h"
|
|
|
|
|
#include "ZxObjText.h"
|
|
|
|
|
#include "ZxPlot.h"
|
|
|
|
|
|
|
|
|
|
@ -336,15 +338,14 @@ nmWxPropertyInterpolationDlg::nmWxPropertyInterpolationDlg(
|
|
|
|
|
m_pUseHCheck(NULL),
|
|
|
|
|
m_pHCalculationDataSetCombo(NULL),
|
|
|
|
|
m_pPreviewButton(NULL),
|
|
|
|
|
m_pApplyButton(NULL),
|
|
|
|
|
m_pPreviewDialog(NULL),
|
|
|
|
|
m_pPreviewRefreshTimer(NULL)
|
|
|
|
|
{
|
|
|
|
|
setWindowTitle(interpolationText("Property Interpolation"));
|
|
|
|
|
setWindowModality(Qt::NonModal);
|
|
|
|
|
setModal(false);
|
|
|
|
|
setMinimumSize(520, 680);
|
|
|
|
|
resize(560, 740);
|
|
|
|
|
setMinimumSize(600, 620);
|
|
|
|
|
resize(640, 680);
|
|
|
|
|
|
|
|
|
|
// 合并连续编辑触发的刷新,避免每次数值变化都立即重新插值.
|
|
|
|
|
m_pPreviewRefreshTimer = new QTimer(this);
|
|
|
|
|
@ -375,38 +376,52 @@ nmWxPropertyInterpolationDlg::~nmWxPropertyInterpolationDlg()
|
|
|
|
|
|
|
|
|
|
void nmWxPropertyInterpolationDlg::initInterpolationUI()
|
|
|
|
|
{
|
|
|
|
|
const int topControlWidth = 350;
|
|
|
|
|
const int compactComboWidth = 200;
|
|
|
|
|
|
|
|
|
|
QVBoxLayout* mainLayout = new QVBoxLayout(this);
|
|
|
|
|
mainLayout->setContentsMargins(12, 10, 12, 10);
|
|
|
|
|
mainLayout->setSpacing(8);
|
|
|
|
|
|
|
|
|
|
// 数据组创建、切换及删除.
|
|
|
|
|
QHBoxLayout* dataSetSelectLayout = new QHBoxLayout;
|
|
|
|
|
dataSetSelectLayout->addWidget(new QLabel(interpolationText("Dataset:"), this));
|
|
|
|
|
m_pDataSetCombo = new QComboBox(this);
|
|
|
|
|
// 数据组、名称和属性共用一个表单,保证三行标签及输入控件对齐.
|
|
|
|
|
QFormLayout* dataSetLayout = new QFormLayout;
|
|
|
|
|
dataSetLayout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
dataSetLayout->setHorizontalSpacing(8);
|
|
|
|
|
dataSetLayout->setVerticalSpacing(6);
|
|
|
|
|
dataSetLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
|
|
|
|
|
|
|
|
|
|
QWidget* dataSetSelectWidget = new QWidget(this);
|
|
|
|
|
dataSetSelectWidget->setMaximumWidth(topControlWidth);
|
|
|
|
|
QHBoxLayout* dataSetSelectLayout = new QHBoxLayout(dataSetSelectWidget);
|
|
|
|
|
dataSetSelectLayout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
dataSetSelectLayout->setSpacing(6);
|
|
|
|
|
m_pDataSetCombo = new QComboBox(dataSetSelectWidget);
|
|
|
|
|
dataSetSelectLayout->addWidget(m_pDataSetCombo, 1);
|
|
|
|
|
|
|
|
|
|
QString iconDir = QCoreApplication::applicationDirPath();
|
|
|
|
|
iconDir = iconDir.section('/', 0, -2) + "/Res/Icon/";
|
|
|
|
|
|
|
|
|
|
m_pAddDataSetButton = new QPushButton(this);
|
|
|
|
|
m_pAddDataSetButton = new QPushButton(dataSetSelectWidget);
|
|
|
|
|
m_pAddDataSetButton->setIcon(QIcon(iconDir + "Add.png"));
|
|
|
|
|
m_pAddDataSetButton->setIconSize(QSize(18, 18));
|
|
|
|
|
m_pAddDataSetButton->setFixedSize(28, 28);
|
|
|
|
|
m_pAddDataSetButton->setToolTip(interpolationText("Add dataset"));
|
|
|
|
|
dataSetSelectLayout->addWidget(m_pAddDataSetButton);
|
|
|
|
|
|
|
|
|
|
m_pDeleteDataSetButton = new QPushButton(this);
|
|
|
|
|
m_pDeleteDataSetButton = new QPushButton(dataSetSelectWidget);
|
|
|
|
|
m_pDeleteDataSetButton->setIcon(QIcon(iconDir + "NmDelete.png"));
|
|
|
|
|
m_pDeleteDataSetButton->setIconSize(QSize(18, 18));
|
|
|
|
|
m_pDeleteDataSetButton->setFixedSize(28, 28);
|
|
|
|
|
m_pDeleteDataSetButton->setToolTip(interpolationText("Delete dataset"));
|
|
|
|
|
dataSetSelectLayout->addWidget(m_pDeleteDataSetButton);
|
|
|
|
|
mainLayout->addLayout(dataSetSelectLayout);
|
|
|
|
|
dataSetLayout->addRow(interpolationText("Dataset:"), dataSetSelectWidget);
|
|
|
|
|
|
|
|
|
|
// 当前数据组的名称和属性.
|
|
|
|
|
QFormLayout* dataSetLayout = new QFormLayout;
|
|
|
|
|
m_pNameEdit = new QLineEdit(this);
|
|
|
|
|
m_pNameEdit->setMaximumWidth(topControlWidth);
|
|
|
|
|
dataSetLayout->addRow(interpolationText("Name:"), m_pNameEdit);
|
|
|
|
|
|
|
|
|
|
m_pPropertyCombo = new QComboBox(this);
|
|
|
|
|
m_pPropertyCombo->setMaximumWidth(topControlWidth);
|
|
|
|
|
m_pPropertyCombo->addItem(interpolationText("Permeability k"), QString("k"));
|
|
|
|
|
m_pPropertyCombo->addItem(interpolationText("Porosity phi"), QString("phi"));
|
|
|
|
|
m_pPropertyCombo->addItem(interpolationText("Reservoir thickness h"), QString("h"));
|
|
|
|
|
@ -416,17 +431,23 @@ void nmWxPropertyInterpolationDlg::initInterpolationUI()
|
|
|
|
|
// 测点数据录入区域.
|
|
|
|
|
QGroupBox* pointGroup = new QGroupBox(interpolationText("Measurement Points"), this);
|
|
|
|
|
QVBoxLayout* pointLayout = new QVBoxLayout(pointGroup);
|
|
|
|
|
pointLayout->setContentsMargins(10, 8, 10, 10);
|
|
|
|
|
pointLayout->setSpacing(6);
|
|
|
|
|
|
|
|
|
|
QHBoxLayout* newPointLayout = new QHBoxLayout;
|
|
|
|
|
newPointLayout->setSpacing(6);
|
|
|
|
|
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);
|
|
|
|
|
m_pNewValueUnitCombo->setFixedWidth(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->setIcon(QIcon(iconDir + "AddPoint.png"));
|
|
|
|
|
m_pMapPickButton->setIconSize(QSize(16, 16));
|
|
|
|
|
m_pMapPickButton->setMinimumWidth(100);
|
|
|
|
|
m_pMapPickButton->setCheckable(true);
|
|
|
|
|
m_pMapPickButton->setEnabled(!m_pPlot.isNull() &&
|
|
|
|
|
m_pPlot->m_pPlotView != NULL &&
|
|
|
|
|
@ -438,11 +459,17 @@ void nmWxPropertyInterpolationDlg::initInterpolationUI()
|
|
|
|
|
QStringList headers;
|
|
|
|
|
headers << interpolationText("X") << interpolationText("Y") << interpolationText("Value");
|
|
|
|
|
m_pPointTable->setHorizontalHeaderLabels(headers);
|
|
|
|
|
m_pPointTable->verticalHeader()->setVisible(false);
|
|
|
|
|
m_pPointTable->verticalHeader()->setVisible(true);
|
|
|
|
|
m_pPointTable->verticalHeader()->setFixedWidth(36);
|
|
|
|
|
m_pPointTable->verticalHeader()->setDefaultAlignment(Qt::AlignCenter);
|
|
|
|
|
// 第0行为单位选择,不占用测点序号.
|
|
|
|
|
m_pPointTable->setVerticalHeaderItem(
|
|
|
|
|
POINT_UNIT_ROW, new QTableWidgetItem(QString()));
|
|
|
|
|
m_pPointTable->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
|
|
|
|
|
m_pPointTable->setSelectionBehavior(QAbstractItemView::SelectRows);
|
|
|
|
|
m_pPointTable->setSelectionMode(QAbstractItemView::SingleSelection);
|
|
|
|
|
m_pPointTable->setAlternatingRowColors(true);
|
|
|
|
|
m_pPointTable->setMinimumHeight(170);
|
|
|
|
|
m_pPointTable->setRowHeight(POINT_UNIT_ROW, 24);
|
|
|
|
|
|
|
|
|
|
// 第0行固定显示各列单位,数据行从第1行开始.
|
|
|
|
|
@ -461,83 +488,99 @@ void nmWxPropertyInterpolationDlg::initInterpolationUI()
|
|
|
|
|
m_pPointTable->setCellWidget(POINT_UNIT_ROW, 2, m_pValueUnitCombo);
|
|
|
|
|
pointLayout->addWidget(m_pPointTable, 1);
|
|
|
|
|
|
|
|
|
|
// 显示选项放在左侧,当前测点操作放在右侧,减少分散的按钮行.
|
|
|
|
|
QHBoxLayout* pointButtonLayout = new QHBoxLayout;
|
|
|
|
|
pointButtonLayout->setSpacing(8);
|
|
|
|
|
m_pShowPointsCheck = new QCheckBox(interpolationText("Show measurement points"), pointGroup);
|
|
|
|
|
m_pShowPointsCheck->setChecked(true);
|
|
|
|
|
pointButtonLayout->addWidget(m_pShowPointsCheck);
|
|
|
|
|
m_pShowLabelsCheck = new QCheckBox(interpolationText("Show labels"), pointGroup);
|
|
|
|
|
m_pShowLabelsCheck->setChecked(true);
|
|
|
|
|
pointButtonLayout->addWidget(m_pShowLabelsCheck);
|
|
|
|
|
pointButtonLayout->addStretch();
|
|
|
|
|
m_pDeletePointButton = new QPushButton(interpolationText("Delete Selected"), pointGroup);
|
|
|
|
|
m_pDeletePointButton->setMinimumWidth(84);
|
|
|
|
|
m_pDeletePointButton->setEnabled(false);
|
|
|
|
|
pointButtonLayout->addWidget(m_pDeletePointButton);
|
|
|
|
|
m_pClearPointsButton = new QPushButton(interpolationText("Clear"), pointGroup);
|
|
|
|
|
m_pClearPointsButton->setMinimumWidth(72);
|
|
|
|
|
m_pClearPointsButton->setEnabled(false);
|
|
|
|
|
pointButtonLayout->addWidget(m_pClearPointsButton);
|
|
|
|
|
pointLayout->addLayout(pointButtonLayout);
|
|
|
|
|
|
|
|
|
|
QHBoxLayout* displayLayout = new QHBoxLayout;
|
|
|
|
|
m_pShowPointsCheck = new QCheckBox(interpolationText("Show measurement points"), pointGroup);
|
|
|
|
|
m_pShowPointsCheck->setChecked(true);
|
|
|
|
|
displayLayout->addWidget(m_pShowPointsCheck);
|
|
|
|
|
m_pShowLabelsCheck = new QCheckBox(interpolationText("Show labels"), pointGroup);
|
|
|
|
|
m_pShowLabelsCheck->setChecked(true);
|
|
|
|
|
displayLayout->addWidget(m_pShowLabelsCheck);
|
|
|
|
|
displayLayout->addStretch();
|
|
|
|
|
pointLayout->addLayout(displayLayout);
|
|
|
|
|
mainLayout->addWidget(pointGroup, 1);
|
|
|
|
|
|
|
|
|
|
// Kriging插值参数设置.
|
|
|
|
|
// Kriging参数采用两行双列布局,保持信息完整并压缩纵向空间.
|
|
|
|
|
QGroupBox* parameterGroup = new QGroupBox(interpolationText("Kriging Parameters"), this);
|
|
|
|
|
QFormLayout* parameterLayout = new QFormLayout(parameterGroup);
|
|
|
|
|
QGridLayout* parameterLayout = new QGridLayout(parameterGroup);
|
|
|
|
|
parameterLayout->setContentsMargins(10, 8, 10, 10);
|
|
|
|
|
parameterLayout->setHorizontalSpacing(8);
|
|
|
|
|
parameterLayout->setVerticalSpacing(6);
|
|
|
|
|
m_pNuggetSpin = createNumberSpinBox(parameterGroup, 0.01);
|
|
|
|
|
parameterLayout->addRow(interpolationText("Nugget:"), m_pNuggetSpin);
|
|
|
|
|
parameterLayout->addWidget(new QLabel(interpolationText("Nugget:"), parameterGroup), 0, 0);
|
|
|
|
|
parameterLayout->addWidget(m_pNuggetSpin, 0, 1);
|
|
|
|
|
m_pSillSpin = createNumberSpinBox(parameterGroup, 100.0);
|
|
|
|
|
parameterLayout->addRow(interpolationText("Sill:"), m_pSillSpin);
|
|
|
|
|
parameterLayout->addWidget(new QLabel(interpolationText("Sill:"), parameterGroup), 0, 2);
|
|
|
|
|
parameterLayout->addWidget(m_pSillSpin, 0, 3);
|
|
|
|
|
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);
|
|
|
|
|
m_pRangeSpin = createNumberSpinBox(rangeWidget, 1000.0);
|
|
|
|
|
rangeLayout->addWidget(m_pRangeSpin, 1);
|
|
|
|
|
m_pRangeUnitCombo = new QComboBox(parameterGroup);
|
|
|
|
|
m_pRangeUnitCombo->setMinimumWidth(80);
|
|
|
|
|
m_pRangeUnitCombo = new QComboBox(rangeWidget);
|
|
|
|
|
m_pRangeUnitCombo->setFixedWidth(72);
|
|
|
|
|
populateUnitCombo(m_pRangeUnitCombo, LENGTH_BASE_UNIT, LENGTH_BASE_UNIT);
|
|
|
|
|
rangeLayout->addWidget(m_pRangeUnitCombo);
|
|
|
|
|
parameterLayout->addRow(interpolationText("Range:"), rangeWidget);
|
|
|
|
|
parameterLayout->addWidget(new QLabel(interpolationText("Range:"), parameterGroup), 1, 0);
|
|
|
|
|
parameterLayout->addWidget(rangeWidget, 1, 1);
|
|
|
|
|
m_pModelCombo = new QComboBox(parameterGroup);
|
|
|
|
|
m_pModelCombo->setFixedWidth(compactComboWidth);
|
|
|
|
|
m_pModelCombo->addItem(interpolationText("Spherical (0)"), 0);
|
|
|
|
|
m_pModelCombo->addItem(interpolationText("Exponential (1)"), 1);
|
|
|
|
|
m_pModelCombo->addItem(interpolationText("Gaussian (2)"), 2);
|
|
|
|
|
parameterLayout->addRow(interpolationText("Model:"), m_pModelCombo);
|
|
|
|
|
parameterLayout->addWidget(new QLabel(interpolationText("Model:"), parameterGroup), 1, 2);
|
|
|
|
|
parameterLayout->addWidget(m_pModelCombo, 1, 3);
|
|
|
|
|
parameterLayout->setColumnStretch(1, 1);
|
|
|
|
|
parameterLayout->setColumnStretch(3, 1);
|
|
|
|
|
mainLayout->addWidget(parameterGroup);
|
|
|
|
|
|
|
|
|
|
// 分别指定正式求解时需要使用插值结果的属性和数据组.
|
|
|
|
|
QGroupBox* calculationGroup = new QGroupBox(
|
|
|
|
|
interpolationText("Use Interpolation in Solver"), this);
|
|
|
|
|
QGridLayout* calculationLayout = new QGridLayout(calculationGroup);
|
|
|
|
|
calculationLayout->setContentsMargins(10, 8, 10, 10);
|
|
|
|
|
calculationLayout->setHorizontalSpacing(8);
|
|
|
|
|
calculationLayout->setVerticalSpacing(6);
|
|
|
|
|
m_pUseKCheck = new QCheckBox(interpolationText("Permeability k"), calculationGroup);
|
|
|
|
|
m_pKCalculationDataSetCombo = new QComboBox(calculationGroup);
|
|
|
|
|
m_pKCalculationDataSetCombo->setFixedWidth(compactComboWidth);
|
|
|
|
|
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);
|
|
|
|
|
m_pPhiCalculationDataSetCombo->setFixedWidth(compactComboWidth);
|
|
|
|
|
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);
|
|
|
|
|
m_pHCalculationDataSetCombo->setFixedWidth(compactComboWidth);
|
|
|
|
|
calculationLayout->addWidget(m_pUseHCheck, 2, 0);
|
|
|
|
|
calculationLayout->addWidget(m_pHCalculationDataSetCombo, 2, 1);
|
|
|
|
|
calculationLayout->setColumnStretch(1, 1);
|
|
|
|
|
calculationLayout->setColumnMinimumWidth(1, compactComboWidth);
|
|
|
|
|
calculationLayout->setColumnStretch(2, 1);
|
|
|
|
|
mainLayout->addWidget(calculationGroup);
|
|
|
|
|
|
|
|
|
|
// 底部操作按钮.
|
|
|
|
|
QHBoxLayout* buttonLayout = new QHBoxLayout;
|
|
|
|
|
m_pPreviewButton = new QPushButton(interpolationText("Preview"), this);
|
|
|
|
|
m_pPreviewButton->setMinimumWidth(84);
|
|
|
|
|
m_pPreviewButton->setEnabled(false);
|
|
|
|
|
buttonLayout->addWidget(m_pPreviewButton);
|
|
|
|
|
buttonLayout->addStretch();
|
|
|
|
|
m_pApplyButton = new QPushButton(interpolationText("Apply"), this);
|
|
|
|
|
m_pApplyButton->setEnabled(false);
|
|
|
|
|
buttonLayout->addWidget(m_pApplyButton);
|
|
|
|
|
QPushButton* closeButton = new QPushButton(interpolationText("Close"), this);
|
|
|
|
|
closeButton->setMinimumWidth(84);
|
|
|
|
|
buttonLayout->addWidget(closeButton);
|
|
|
|
|
mainLayout->addLayout(buttonLayout);
|
|
|
|
|
|
|
|
|
|
@ -848,6 +891,28 @@ void nmWxPropertyInterpolationDlg::clearPointRows()
|
|
|
|
|
if(m_pPointTable != NULL && m_pPointTable->rowCount() > FIRST_POINT_ROW) {
|
|
|
|
|
m_pPointTable->setRowCount(FIRST_POINT_ROW);
|
|
|
|
|
}
|
|
|
|
|
updatePointRowNumbers();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmWxPropertyInterpolationDlg::updatePointRowNumbers()
|
|
|
|
|
{
|
|
|
|
|
if(m_pPointTable == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 单位行留空,测点数据行始终从1开始连续编号.
|
|
|
|
|
for(int row = POINT_UNIT_ROW; row < m_pPointTable->rowCount(); ++row) {
|
|
|
|
|
const QString number = row < FIRST_POINT_ROW ?
|
|
|
|
|
QString() : QString::number(row - FIRST_POINT_ROW + 1);
|
|
|
|
|
QTableWidgetItem* headerItem = m_pPointTable->verticalHeaderItem(row);
|
|
|
|
|
if(headerItem == NULL) {
|
|
|
|
|
m_pPointTable->setVerticalHeaderItem(row,
|
|
|
|
|
new QTableWidgetItem(number));
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
headerItem->setText(number);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmWxPropertyInterpolationDlg::syncDataSetsToManager(bool markModified)
|
|
|
|
|
@ -1277,6 +1342,9 @@ void nmWxPropertyInterpolationDlg::appendPointRow(
|
|
|
|
|
// rowCount已包含单位行,新插入行天然与points下标保持FIRST_POINT_ROW偏移.
|
|
|
|
|
int row = m_pPointTable->rowCount();
|
|
|
|
|
m_pPointTable->insertRow(row);
|
|
|
|
|
m_pPointTable->setVerticalHeaderItem(
|
|
|
|
|
row, new QTableWidgetItem(QString::number(
|
|
|
|
|
row - FIRST_POINT_ROW + 1)));
|
|
|
|
|
|
|
|
|
|
QString xUnit = LENGTH_BASE_UNIT;
|
|
|
|
|
QString yUnit = LENGTH_BASE_UNIT;
|
|
|
|
|
@ -1294,14 +1362,12 @@ void nmWxPropertyInterpolationDlg::appendPointRow(
|
|
|
|
|
|
|
|
|
|
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(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(displayValueText(
|
|
|
|
|
@ -1449,7 +1515,8 @@ void nmWxPropertyInterpolationDlg::onPointItemChanged(QTableWidgetItem* item)
|
|
|
|
|
// 表格行减去单位行偏移后,才是数据组中的测点下标.
|
|
|
|
|
const int pointIndex = item == NULL ? -1 :
|
|
|
|
|
item->row() - FIRST_POINT_ROW;
|
|
|
|
|
if(m_bUpdatingUi || item == NULL || item->column() != 2 ||
|
|
|
|
|
if(m_bUpdatingUi || item == NULL || item->column() < 0 ||
|
|
|
|
|
item->column() > 2 ||
|
|
|
|
|
pointIndex < 0 ||
|
|
|
|
|
m_nCurrentDataSetIndex < 0 ||
|
|
|
|
|
m_nCurrentDataSetIndex >= m_vecDataSets.size() ||
|
|
|
|
|
@ -1457,15 +1524,72 @@ void nmWxPropertyInterpolationDlg::onPointItemChanged(QTableWidgetItem* item)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 数值修改后同步更新数据组和地图标签,坐标列保持只读.
|
|
|
|
|
nmPropertyInterpolationDataSet& dataSet =
|
|
|
|
|
m_vecDataSets[m_nCurrentDataSetIndex];
|
|
|
|
|
dataSet.points[pointIndex].value = convertedUnitValue(
|
|
|
|
|
item->text().toDouble(), dataSet.valueDisplayUnit,
|
|
|
|
|
propertyBaseUnit(dataSet.property));
|
|
|
|
|
nmPropertyInterpolationPointData& point = dataSet.points[pointIndex];
|
|
|
|
|
|
|
|
|
|
// X、Y及属性值分别按当前显示单位换算回数据中心使用的基准单位.
|
|
|
|
|
QString baseUnit;
|
|
|
|
|
QString displayUnit;
|
|
|
|
|
double oldBaseValue = 0.0;
|
|
|
|
|
if(item->column() == 0) {
|
|
|
|
|
baseUnit = LENGTH_BASE_UNIT;
|
|
|
|
|
displayUnit = dataSet.xDisplayUnit;
|
|
|
|
|
oldBaseValue = point.x;
|
|
|
|
|
}
|
|
|
|
|
else if(item->column() == 1) {
|
|
|
|
|
baseUnit = LENGTH_BASE_UNIT;
|
|
|
|
|
displayUnit = dataSet.yDisplayUnit;
|
|
|
|
|
oldBaseValue = point.y;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
baseUnit = propertyBaseUnit(dataSet.property);
|
|
|
|
|
displayUnit = dataSet.valueDisplayUnit;
|
|
|
|
|
oldBaseValue = point.value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool valueOk = false;
|
|
|
|
|
const double displayValue = item->text().toDouble(&valueOk);
|
|
|
|
|
if(!valueOk || (item->column() == 2 && displayValue < 0.0)) {
|
|
|
|
|
// 坐标允许为负数;属性值仍要求非负,非法输入恢复为修改前的值.
|
|
|
|
|
const double oldDisplayValue = convertedUnitValue(
|
|
|
|
|
oldBaseValue, baseUnit, displayUnit);
|
|
|
|
|
const bool oldBlock = m_pPointTable->blockSignals(true);
|
|
|
|
|
item->setText(displayValueText(oldDisplayValue));
|
|
|
|
|
m_pPointTable->blockSignals(oldBlock);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const double baseValue = convertedUnitValue(
|
|
|
|
|
displayValue, displayUnit, baseUnit);
|
|
|
|
|
if(item->column() == 0) {
|
|
|
|
|
point.x = baseValue;
|
|
|
|
|
}
|
|
|
|
|
else if(item->column() == 1) {
|
|
|
|
|
point.y = baseValue;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
point.value = baseValue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const QString displayText = displayValueText(displayValue);
|
|
|
|
|
if(item->text() != displayText) {
|
|
|
|
|
const bool oldBlock = m_pPointTable->blockSignals(true);
|
|
|
|
|
item->setText(displayText);
|
|
|
|
|
m_pPointTable->blockSignals(oldBlock);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 坐标修改后移动Map标记,属性值修改后刷新标记标签.
|
|
|
|
|
nmObjPoint* marker = markerAt(item->row());
|
|
|
|
|
if(marker != NULL) {
|
|
|
|
|
setMarkerLabel(marker, item->text());
|
|
|
|
|
if(item->column() < 2) {
|
|
|
|
|
QVector<QPointF> positions;
|
|
|
|
|
positions.append(QPointF(point.x, point.y));
|
|
|
|
|
marker->setAllValues(positions);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
setMarkerLabel(marker, displayText);
|
|
|
|
|
}
|
|
|
|
|
marker->update();
|
|
|
|
|
}
|
|
|
|
|
syncDataSetsToManager(true);
|
|
|
|
|
@ -1490,6 +1614,7 @@ void nmWxPropertyInterpolationDlg::onDeleteSelectedPoint()
|
|
|
|
|
m_vecMarkerNames[m_nCurrentDataSetIndex].removeAt(pointIndex);
|
|
|
|
|
}
|
|
|
|
|
m_pPointTable->removeRow(row);
|
|
|
|
|
updatePointRowNumbers();
|
|
|
|
|
clearTableSelection();
|
|
|
|
|
updatePointButtons();
|
|
|
|
|
syncDataSetsToManager(true);
|
|
|
|
|
@ -1548,6 +1673,14 @@ void nmWxPropertyInterpolationDlg::updatePointButtons()
|
|
|
|
|
{
|
|
|
|
|
const bool hasCurrent = m_nCurrentDataSetIndex >= 0 &&
|
|
|
|
|
m_nCurrentDataSetIndex < m_vecDataSets.size();
|
|
|
|
|
const bool hasPoints = hasCurrent &&
|
|
|
|
|
!m_vecDataSets[m_nCurrentDataSetIndex].points.isEmpty();
|
|
|
|
|
|
|
|
|
|
// 已有测点的数值含义已经确定,需清空测点后才能切换数据组属性.
|
|
|
|
|
m_pPropertyCombo->setEnabled(hasCurrent && !hasPoints);
|
|
|
|
|
m_pPropertyCombo->setToolTip(hasPoints ?
|
|
|
|
|
interpolationText("Clear measurement points before changing the property.") :
|
|
|
|
|
QString());
|
|
|
|
|
m_pDeletePointButton->setEnabled(
|
|
|
|
|
hasCurrent && m_pPointTable->currentRow() >= FIRST_POINT_ROW);
|
|
|
|
|
m_pClearPointsButton->setEnabled(
|
|
|
|
|
@ -1646,8 +1779,8 @@ void nmWxPropertyInterpolationDlg::updatePreviewWindow(bool activateWindow)
|
|
|
|
|
|
|
|
|
|
// 按行生成规则待插值点,输出下标与预览网格下标保持一致;
|
|
|
|
|
// 较疏采样可使分级色带边界更清晰.
|
|
|
|
|
const int columnCount = 31;
|
|
|
|
|
const int rowCount = 31;
|
|
|
|
|
const int columnCount = 19;
|
|
|
|
|
const int rowCount = 19;
|
|
|
|
|
QVector<QPointF> targetPoints;
|
|
|
|
|
targetPoints.reserve(columnCount * rowCount);
|
|
|
|
|
for(int row = 0; row < rowCount; ++row) {
|
|
|
|
|
@ -1705,6 +1838,31 @@ void nmWxPropertyInterpolationDlg::updatePreviewWindow(bool activateWindow)
|
|
|
|
|
scalarTitle += QString(" (%1)").arg(dataSet.valueDisplayUnit);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 直接读取Map中实际显示的井,避免“参与计算井”尚未设置时预览中没有井位.
|
|
|
|
|
QVector<QPointF> wellPoints;
|
|
|
|
|
QStringList wellNames;
|
|
|
|
|
const QVector<nmObjPointWell*> wellPlots = m_pPlot.isNull() ?
|
|
|
|
|
QVector<nmObjPointWell*>() : m_pPlot->getWellPlots();
|
|
|
|
|
for(int i = 0; i < wellPlots.size(); ++i) {
|
|
|
|
|
nmObjPointWell* wellPlot = wellPlots[i];
|
|
|
|
|
if(wellPlot == NULL || wellPlot->getWellData() == NULL) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const QVector<double> wellInformation = wellPlot->getWellInformation();
|
|
|
|
|
const QString wellName = wellPlot->getWellData()->getName();
|
|
|
|
|
if(wellInformation.size() < 2 || wellName.isEmpty() ||
|
|
|
|
|
wellNames.contains(wellName)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const QPointF wellPoint(wellInformation[0], wellInformation[1]);
|
|
|
|
|
if(previewBounds.contains(wellPoint)) {
|
|
|
|
|
wellPoints.append(wellPoint);
|
|
|
|
|
wellNames.append(wellName);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 预览窗口只负责裁剪和渲染,不修改数据组及正式求解参数.
|
|
|
|
|
if(m_pPreviewDialog.isNull()) {
|
|
|
|
|
m_pPreviewDialog = new nmWxPropertyInterpolationPreviewDlg(
|
|
|
|
|
@ -1717,6 +1875,8 @@ void nmWxPropertyInterpolationDlg::updatePreviewWindow(bool activateWindow)
|
|
|
|
|
measurementPoints,
|
|
|
|
|
displayMeasurementValues,
|
|
|
|
|
outlinePoints,
|
|
|
|
|
wellPoints,
|
|
|
|
|
wellNames,
|
|
|
|
|
dataSet.showPoints,
|
|
|
|
|
dataSet.showLabels,
|
|
|
|
|
this);
|
|
|
|
|
@ -1733,6 +1893,8 @@ void nmWxPropertyInterpolationDlg::updatePreviewWindow(bool activateWindow)
|
|
|
|
|
measurementPoints,
|
|
|
|
|
displayMeasurementValues,
|
|
|
|
|
outlinePoints,
|
|
|
|
|
wellPoints,
|
|
|
|
|
wellNames,
|
|
|
|
|
dataSet.showPoints,
|
|
|
|
|
dataSet.showLabels);
|
|
|
|
|
}
|
|
|
|
|
|