You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWTAI-Platform/Src/nmNum/nmPlot/nmObjPointWell.cpp

518 lines
14 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <QPainter>
//#include <QDialog.h>
#include <ZxSerializer.h>
#include "IxPtyPano.h"
#include "ZxSubAxisX.h"
#include "ZxSubAxisY.h"
#include "zxLogInstance.h"
#include "ZxPlot.h"
#include "ZxObjText.h"
#include "ZxDataWell.h"
#include "nmObjPointWellTool.h"
#include "nmObjPointWell.h"
#include "nmDataLogFile.h"
#include "iWxWellNew.h"
#include "ZxDataProject.h"
#include "TreeWxMain.h"
#include "Defines.h"
#include "zxSysUtils.h"
#include "iDataTypes.h"
#include "nmSingalCenter.h"
#include "nmPlotGraphicBinder.h"
ZX_DEFINE_DYNAMIC(nObjPointWell, nmObjPointWell)
nmObjPointWell::nmObjPointWell()
: nmObjPoint()
, m_pNameLabel(nullptr)
, m_bSelectWell(false)
, m_pGraphicBinder(nullptr)
, m_enumWellType(NM_WELL_MODEL::Vertical_Well)
{
nmObjPointWell::init("", NULL, NULL);
}
nmObjPointWell::nmObjPointWell(const QString& sName, \
ZxSubAxisX* pAxisX, \
ZxSubAxisY* pAxisY)
: nmObjPoint(sName, pAxisX, pAxisY)
, m_pNameLabel(nullptr)
, m_bSelectWell(false)
, m_pGraphicBinder(nullptr)
, m_enumWellType(NM_WELL_MODEL::Vertical_Well)
{
nmObjPointWell::init(sName, pAxisX, pAxisY);
}
nmObjPointWell::~nmObjPointWell()
{
// 井数据由 DataManager 和工程树统一管理,图元不持有数据指针。
}
void nmObjPointWell::init(const QString& sName, \
ZxSubAxisX* pAxisX, \
ZxSubAxisY* pAxisY)
{
m_sObjTag = "nObjPointWell";
nmObjBase::init(sName, pAxisX, pAxisY);
nmObjPointWell::initFlags();
m_oDot = ZxDot(DTS_DownTriangle, QColor(255, 0, 0, 125), 1.f, true);
m_sDesc = "";
m_bShowSubObjs = true;
m_oDot = ZxDot(DTS_Circle, QColor(0, 255, 0), 1.5f, true);
m_clrFillUnvalid = QColor(0, 255, 255);
m_clrOuter = QColor(255, 0, 0);
m_vecPoints << QPointF(0.f, 0.f);
loadTempl();
m_pGraphicBinder = nullptr;
// 连接图元可见性信号和槽
connect(this, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onObjVisibleChanged(bool)));
}
void nmObjPointWell::initTools()
{
m_pTool = new nmObjPointWellTool();
nmObjBase::initTools();
}
bool nmObjPointWell::runMove(const QPointF &pt1, const QPointF &pt2)
{
nmObjPoint::runMove(pt1, pt2);
// 更新井的位置信息
if(m_pGraphicBinder) {
QPointF newLocation = this->getValueOf(pt2);
m_pGraphicBinder->syncWellMoveFromGraphic(this, m_enumWellType, newLocation);
}
if (m_pGraphicBinder) {
m_pGraphicBinder->notifyDataChanged();
}
return true;
}
void nmObjPointWell::initFlags()
{
// TODO如果是选择的井则位置和大小都不能动设置为true
setLockPos(false);
setLockSize(false);
setReadOnly(false);
}
void nmObjPointWell::initSubObjs()
{
}
void nmObjPointWell::setPointTag(QString s)
{
nmObjPoint::setPointTag(s);
}
void nmObjPointWell::update()
{
nmObjBase::update();
}
void nmObjPointWell::onSerialize(ZxSerializer* ser)
{
nmObjBase::onSerialize(ser);
ser->write("NMWellID", m_sWellID);
}
void nmObjPointWell::onDeserialize(ZxSerializer* ser)
{
nmObjBase::onDeserialize(ser);
ser->read("NMWellID", m_sWellID);
// 根据wellID获取井的信息
ZxDataWell* pWellData = getWellData();
if(pWellData) {
// 设置图元的位置信息将井的坐标设置为plot对象的坐标
m_vecPoints.clear();
m_vecPoints << QPointF(pWellData->getLocationX(), pWellData->getLocationY());
return;
}
// TODO如果井数据不存在则其实就是新建井了
}
void nmObjPointWell::onSaveTempl(ZxSerializer* ser)
{
nmObjBase::onSaveTempl(ser);
ser->write("NMWellID", m_sWellID);
}
void nmObjPointWell::onLoadTempl(ZxSerializer* ser)
{
nmObjBase::onLoadTempl(ser);
ser->read("NMWellID", m_sWellID);
// 根据wellID获取井的信息
ZxDataWell* pWellData = getWellData();
if(pWellData) {
// 设置图元的位置信息将井的坐标设置为plot对象的坐标
m_vecPoints.clear();
m_vecPoints << QPointF(pWellData->getLocationX(), pWellData->getLocationY());
return;
}
// TODO如果井数据不存在则其实就是新建井了
}
void nmObjPointWell::afterCreated()
{
ZxDataWell* pWellData = getWellData();
if(pWellData) {
ZxPlot* pPlot = dynamic_cast<ZxPlot*>(this->getParent());
if(NULL != pPlot) {
QString sName = pWellData->getName();
this->setName(sName);
ZxObjBase* p = pPlot->addOneObj(POT_Text, sName, false, \
m_pAxisX, m_pAxisY);
appendSubObjs(p);
m_pNameLabel = dynamic_cast<ZxObjText*>(p);
Q_ASSERT(NULL != m_pNameLabel);
if (m_pNameLabel != NULL) {
m_pNameLabel->setFrameVisible(false);
QColor clr = QColor(255, 255, 255, 64);
m_pNameLabel->setBackgroundColor(clr);
m_pNameLabel->setReadOnly(true);
int n = Qt::AlignHCenter | Qt::AlignVCenter;
m_pNameLabel->setAlignFlag(n);
m_pNameLabel->setFont(QFont("Times", 8));
m_pNameLabel->deselect(true);
m_pNameLabel->deselectOthers();
// 设置字体颜色为黑色
QColor textColor = QColor(0, 0, 0); // 黑色
m_pNameLabel->setTextColor(textColor);
m_pNameLabel->setText(sName);
}
}
}
// 如果是选择的井则不弹出创建的dialog
if(m_bSelectWell) {
// 选择已有井时通过Binder初始化对应的井数据
if (pWellData == nullptr) {
return;
}
if (m_pGraphicBinder == nullptr ||
!m_pGraphicBinder->ensureSelectedWellData(this, m_enumWellType)) {
return;
}
return;
}
if(pWellData == nullptr) {
this->createWell();
}
}
void nmObjPointWell::setWellData(ZxDataWell *wellObj)
{
if(wellObj) {
m_bSelectWell = true;
m_sWellID = wellObj->getCode();
}
}
void nmObjPointWell::createWell()
{
if (m_vecPoints.isEmpty() || zxCurProject == nullptr) {
return;
}
// 弹出井属性的设置dialog
iWxWellNew* pWellDialog = new iWxWellNew();
ZxDataWell* pWellData = new ZxDataWell();
// 设置图元的坐标
pWellData->setLocationX(m_vecPoints[0].x());
pWellData->setLocationY(m_vecPoints[0].y());
// 生成code
QString sCode = pWellData->getDefaultCode(zxCurProject);
pWellData->setCode(sCode);
// 添加到整体结构树上
zxCurProject->appendChild(pWellData);
Q_ASSERT(NULL != pWellDialog);
// dialog框展示井数据并支持编辑
pWellDialog->setDataWell(dynamic_cast<ZxDataWell*>(pWellData));
pWellDialog->setActionMode(DAM_Edit);
// 初始化UI
pWellDialog->initUI();
// 图元保存井ID
m_sWellID = pWellData->getCode();
// 模态展示
if(pWellDialog->exec() == QDialog::Rejected) {
// TODO如果是选择的井则直接删除画布上的图元
// TODO如果是新建的井删除图元 + 井数据!
nmSingalCenter::getInstance()->emitSigDeleteWell(sCode);
} else {
// 将数据做转换,然后移动到指定的位置
QVector<QPointF> vecPoss;
vecPoss << QPointF(pWellData->getLocationX(), pWellData->getLocationY());
nmDataLogFile::getInstance()->writeLog(" =========== " + QString::number(vecPoss[0].x()) + " " + QString::number(
vecPoss[0].y()));
// 将数据做转换,然后移动到指定的位置
this->setAllPos(vecPoss);
moveToPos(this->getPosOf(this->getAllPos()));
m_bSelectWell = true;
this->afterCreated();
}
delete pWellDialog;
}
void nmObjPointWell::editWell()
{
if (m_pGraphicBinder == nullptr) {
return;
}
if(m_pGraphicBinder->editWellForGraphic(this, m_enumWellType, m_pNameLabel)) {
ZxDataWell* pWellData = getWellData();
if (pWellData != nullptr) {
// 根据新坐标进行移动
QVector<QPointF> vecPoss;
vecPoss << QPointF(pWellData->getLocationX(), pWellData->getLocationY());
// 将数据做转换,然后移动到指定的位置
this->setAllPos(vecPoss);
moveToPos(this->getPosOf(this->getAllPos()));
}
}
m_pGraphicBinder->notifyDataChanged();
this->update();
}
QVector<double> nmObjPointWell::getWellInformation()
{
QVector<double> wellInformation;
ZxDataWell* pWellData = getWellData();
if(pWellData) {
wellInformation.append(pWellData->getLocationX());
wellInformation.append(pWellData->getLocationY());
wellInformation.append(pWellData->getWellRadius());
}
return wellInformation;
}
ZxDataWell* nmObjPointWell::getWellData() const
{
if (zxCurProject == nullptr) {
return nullptr;
}
return dynamic_cast<ZxDataWell*>(zxCurProject->getChild(iDataModelType::sTypeWell, m_sWellID));
}
const QString& nmObjPointWell::getWellID() const
{
return m_sWellID;
}
void nmObjPointWell::paintBack(QPainter* painter, const ZxPaintParam& param)
{
if (m_pGraphicBinder) {
m_pGraphicBinder->syncWellData(this);
}
// 同步名称标签(用户在属性面板改名后更新画布显示)
if (m_pNameLabel != nullptr) {
QString sName = this->getName();
if (m_pNameLabel->getText() != sName) {
m_pNameLabel->setText(sName);
}
}
if (m_pGraphicBinder == nullptr) {
return;
}
nmPlotGraphicBinder::WellRenderData renderData = m_pGraphicBinder->getWellRenderData(this);
if (!renderData.valid) {
return;
}
m_enumWellType = renderData.wellType;
if(renderData.wellType == NM_WELL_MODEL::Vertical_Fractured_Well) { // 编辑完井之后
Q_ASSERT(NULL != m_pAxisX);
Q_ASSERT(NULL != m_pAxisY);
if(m_pAxisX->getRangeMin() == m_pAxisX->getRangeMax() || \
m_pAxisY->getRangeMin() == m_pAxisY->getRangeMax()) {
return;
}
painter->save();
QPointF point(renderData.x, renderData.y);
m_vecPoints[0] = point;
QPointF ptPos = getPosOf(point);
moveToPos(this->getPosOf(m_vecPoints));
// 绘制填充
double r = m_oDot.radius();
QColor clrInner = m_oDot.color();
ZxDrawHelper::drawPoint(painter, ptPos, (int)m_oDot.style(),
r, m_oDot.isFilling(), clrInner);
//if (bCenter)
{
ZxDrawHelper::drawPoint(painter,
ptPos,
(int)m_oDot.style(),
m_oDot.radius() * 0.5f,
m_oDot.isFilling(),
QColor(255, 0, 0));
}
painter->setPen(m_clrOuter);
painter->drawEllipse(ptPos, r, r);
// 设置裂缝的画笔
QPen fracturePen(QColor(255, 0, 0));
fracturePen.setWidth(0.3f);
painter->setPen(fracturePen);
// 绘制裂缝
if (renderData.verticalFracs.size() == 2) {
QPointF startPos = getPosOf(renderData.verticalFracs[0]);
QPointF endPos_frac = getPosOf(renderData.verticalFracs[1]);
painter->drawLine(startPos, endPos_frac);
}
painter->restore();
} else if(renderData.wellType == NM_WELL_MODEL::Horizontal_Fractured_Well) {
Q_ASSERT(NULL != m_pAxisX);
Q_ASSERT(NULL != m_pAxisY);
if(m_pAxisX->getRangeMin() == m_pAxisX->getRangeMax() || \
m_pAxisY->getRangeMin() == m_pAxisY->getRangeMax()) {
return;
}
painter->save();
QPointF point(renderData.x, renderData.y);
m_vecPoints[0] = point;
QPointF ptPos = getPosOf(point);
moveToPos(this->getPosOf(m_vecPoints));
// 获取井长
double wellLength = renderData.wellLength;
// 获取井的角度
double drainAngle = renderData.drainAngle;
// 将角度从度转换为弧度
double angleRad = drainAngle * M_PI / 180.0; // M_PI 是π的值,表示 180 度
// 获取裂缝角度(单位:度)
//double fractureAngle = m_HFracturedWell->getFractureAngle().getValue().toDouble();
//double fractureAngleRad = fractureAngle * M_PI / 180.0; // 转换为弧度
// 计算井的终点坐标
double endX = renderData.x + wellLength * cos(angleRad);
double endY = renderData.y + wellLength * sin(angleRad);
QPointF endPoint(endX, endY);
QPointF endPos = getPosOf(endPoint);
// 绘制填充
double r = m_oDot.radius();
QColor clrInner = m_oDot.color();
ZxDrawHelper::drawPoint(painter, ptPos, (int)m_oDot.style(),
r, m_oDot.isFilling(), clrInner);
//if (bCenter)
{
ZxDrawHelper::drawPoint(painter,
ptPos,
(int)m_oDot.style(),
m_oDot.radius() * 0.5f,
m_oDot.isFilling(),
QColor(255, 0, 0));
}
painter->setPen(m_clrOuter);
painter->drawEllipse(ptPos, r, r);
QPen linePen(QColor(0, 255, 255));
linePen.setWidth(0.8f);
painter->setPen(linePen);
// 井筒
painter->drawLine(ptPos, endPos);
// 设置裂缝的画笔
QPen fracturePen(QColor(255, 0, 0));
fracturePen.setWidth(0.3f);
painter->setPen(fracturePen);
// 遍历并绘制所有裂缝
for(int i = 0; i < renderData.horizontalFracs.size(); ++i) {
const QPair<QPointF, QPointF>& frac = renderData.horizontalFracs.at(i);
// 将世界坐标转换为绘图坐标
QPointF startPos = getPosOf(frac.first);
QPointF endPos_frac = getPosOf(frac.second);
// 绘制裂缝线段
painter->drawLine(startPos, endPos_frac);
}
painter->restore();
} else { //其他
m_vecPoints[0] = QPointF(renderData.x, renderData.y);
moveToPos(this->getPosOf(m_vecPoints));
nmObjPoint::paintBack(painter, param);
}
}
void nmObjPointWell::removeData()
{
if (m_pGraphicBinder) {
m_pGraphicBinder->removeWellBinding(this);
}
}
void nmObjPointWell::markWellDataBound(NM_WELL_MODEL wellType)
{
m_bSelectWell = false;
m_enumWellType = wellType;
}
void nmObjPointWell::onObjVisibleChanged(bool bIsVisible)
{
if (m_pGraphicBinder) {
m_pGraphicBinder->setWellVisible(this, bIsVisible);
}
}