#include #include "nmObjRegionMark.h" #include "nmObjRegionMarkTool.h" #include "nmObjRegion.h" #include "ZxSerializer.h" #include "IxPtyPano.h" #include "ZxSubAxisX.h" #include "ZxSubAxisY.h" #include "nmObjRegion.h" #include "nmObjRegionTool.h" #include "ZxBaseUtil.h" #include "ZxPlot.h" #include "nmDataAnalyzeManager.h" ZX_DEFINE_DYNAMIC(nObjRegionMark, nmObjRegionMark) nmObjRegionMark::nmObjRegionMark() : m_bSelectRegion(false) , m_iColorIndex(0) , m_regionMarkData(nullptr) { m_sObjTag = "nObjRegionMark"; nmObjRegionMark::init("", NULL, NULL); } nmObjRegionMark::nmObjRegionMark(const QString& sName, \ ZxSubAxisX* pAxisX, \ ZxSubAxisY* pAxisY, \ int RegionMarkCount) : m_bSelectRegion(false) , m_iColorIndex(RegionMarkCount) , m_regionMarkData(nullptr) { m_sObjTag = "nObjRegionMark"; nmObjRegionMark::init(sName, pAxisX, pAxisY); this->m_iColorIndex = RegionMarkCount; m_clrBackgrd = generateColor(m_iColorIndex); } nmObjRegionMark::~nmObjRegionMark() { if(m_regionMarkData != nullptr) { delete m_regionMarkData; m_regionMarkData = nullptr; } } QColor nmObjRegionMark::generateColor(int index) { int hue = (index % 6) * 60; // 色相,每6个标记循环一次,每次加60度 int saturation = 255; // 饱和度,最大值 int value = 255; // 亮度,最大值 int alpha = 128; // 透明度,半透明,可根据需要调整 return QColor::fromHsv(hue, saturation, value, alpha); // 返回带透明度的颜色 } void nmObjRegionMark::init(const QString& sName, \ ZxSubAxisX* pAxisX, \ ZxSubAxisY* pAxisY) { nmObjBase::init(sName, pAxisX, pAxisY); nmObjRegionMark::initFlags(); m_bSelectRegion = false; m_regionMarkData = nullptr; m_icon = QPixmap(ZxBaseUtil::getDirOf(s_Dir_Res, "Icon") + "Anchor.png"); loadTempl(); // 连接图元可见性信号和槽 connect(this, SIGNAL(sigObjVisibleChanged(bool)), this, SLOT(onObjVisibleChanged(bool))); } void nmObjRegionMark::initTools() { m_pTool = new nmObjRegionMarkTool(); nmObjBase::initTools(); } void nmObjRegionMark::setResevoirType(int newResevoirType) { // 从Data中取数据 nmDataAttribute tempAttr = m_regionMarkData->getReservoirType(); if(newResevoirType == 0) { tempAttr.setValue(tr("Homogeneous")); } else { tempAttr.setValue(tr("Dual porosity pseudo steady state")); } m_regionMarkData->setReservoirType(tempAttr); } int nmObjRegionMark::getResevoirType() { if(m_regionMarkData->getReservoirType().getValue() == tr("Homogeneous")) return 0; else return 1; } void nmObjRegionMark::setComKr(double newComkr) { // 从Data中取数据 nmDataAttribute tempAttr = m_regionMarkData->getComKr(); tempAttr.setValue(newComkr); m_regionMarkData->setComKr(tempAttr); } double nmObjRegionMark::getComKr() { return m_regionMarkData->getComKr().getValue().toDouble(); } void nmObjRegionMark::setComW(double newComW) { // 从Data中取数据 nmDataAttribute tempAttr = m_regionMarkData->getComW(); tempAttr.setValue(newComW); m_regionMarkData->setComW(tempAttr); } double nmObjRegionMark::getComW() { return m_regionMarkData->getComW().getValue().toDouble(); } void nmObjRegionMark::setNetToGross(double newNetToGross) { // 从Data中取数据 nmDataAttribute tempAttr = m_regionMarkData->getNetToGross(); tempAttr.setValue(newNetToGross); m_regionMarkData->setNetToGross(tempAttr); } double nmObjRegionMark::getNetToGross() { return m_regionMarkData->getNetToGross().getValue().toDouble(); } void nmObjRegionMark::onSerialize(ZxSerializer* ser) { nmObjBase::onSerialize(ser); int resevoirType; if(m_regionMarkData->getReservoirType().getValue() == tr("Homogeneous")) resevoirType = 0; else resevoirType = 1; ser->write("ResevoirType", resevoirType); ser->write("dComKr", m_regionMarkData->getComKr().getValue().toDouble()); ser->write("dComW", m_regionMarkData->getComW().getValue().toDouble()); ser->write("NetToGross", m_regionMarkData->getNetToGross().getValue().toDouble()); } void nmObjRegionMark::onDeserialize(ZxSerializer* ser) { nmObjBase::onDeserialize(ser); int resevoirType; double comKr; double comW; double netToGross; ser->read("ResevoirType", resevoirType); ser->read("dComKr", comKr); ser->read("dComW", comW); ser->read("NetToGross", netToGross); this->setResevoirType(resevoirType); this->setComKr(comKr); this->setComW(comW); this->setNetToGross(netToGross); } void nmObjRegionMark::onSaveTempl(ZxSerializer* ser) { nmObjBase::onSaveTempl(ser); int resevoirType; if(m_regionMarkData->getReservoirType().getValue() == tr("Homogeneous")) resevoirType = 0; else resevoirType = 1; ser->write("ResevoirType", resevoirType); ser->write("dComKr", m_regionMarkData->getComKr().getValue().toDouble()); ser->write("dComW", m_regionMarkData->getComW().getValue().toDouble()); ser->write("NetToGross", m_regionMarkData->getNetToGross().getValue().toDouble()); } void nmObjRegionMark::onLoadTempl(ZxSerializer* ser) { nmObjBase::onLoadTempl(ser); int resevoirType; double comKr; double comW; double netToGross; ser->read("ResevoirType", resevoirType); ser->read("dComKr", comKr); ser->read("dComW", comW); ser->read("NetToGross", netToGross); this->setResevoirType(resevoirType); this->setComKr(comKr); this->setComW(comW); this->setNetToGross(netToGross); } void nmObjRegionMark::fillPtyPano(IxPtyPano* sheet) { nmObjBase::fillPtyPano(sheet); IxPtyItem* pProp = ZX_PROP("ObjRegionMark.ResevoirType", getResevoirType, setResevoirType); if(NULL != pProp) { QStringList listTags; listTags << tr("Homogeneous") << tr("Dual porosity pseudo steady state"); QList listIndexes; listIndexes << 0 << 1; pProp->getPtyPano(); pProp->setOptions(listTags, listIndexes); } ZX_PROP("ObjRegionMark.dComKr", getComKr, setComKr); ZX_PROP("ObjRegionMark.dComW", getComW, setComW); ZX_PROP("ObjRegionMark.NetToGross", getNetToGross, setNetToGross); } void nmObjRegionMark::initFlags() { setLockPos(false); setLockSize(false); setReadOnly(false); } bool nmObjRegionMark::hitTest(const QPointF& pt) { return nmObjBase::hitTest(pt); } bool nmObjRegionMark::_runHitTest(const QPointF& pt, int& nOption, int& nSubIndex) { if(!nmObjBase::_runHitTest(pt, nOption, nSubIndex)) { return false; } nOption = -1; nSubIndex = 0; if(NULL == m_pAxisX || NULL == m_pAxisY) { return false; } QVector pts = getPosOf(m_vecPoints); // �� double r = 3.f; for(int i = 0; i < pts.count(); i++) { QPointF ptTopLeft = QPointF(pts[i].x() - r, pts[i].y() - r); QSizeF sz = QSizeF(r * 2.f, r * 2.f); QRectF rt = QRectF(ptTopLeft, sz); bool b = rt.contains(pt); if(b) { nOption = (int)OHO_Point; nSubIndex = i; return true; } } nOption = (int)OHO_None; nSubIndex = -1; return false; } bool nmObjRegionMark::runMove(const QPointF& pt1, const QPointF& pt2) { if(isLockPos()) { return false; } if(NULL == m_pAxisX || NULL == m_pAxisY) { return false; } int nCount = m_vecPoints.count(); QVector vecPts = getPosOf(m_vecPoints); if(m_oHitOption == OHO_Point && m_nHitIndex >= 0) { // 如果是点,不用计算偏移量,直接将该点移动到鼠标抬起的位置即可 vecPts[m_nHitIndex] = pt2; return moveToPos(vecPts); } else { return false; } return true; } void nmObjRegionMark::paintBack(QPainter* painter, const ZxPaintParam& param) { if(NULL == m_pAxisX || NULL == m_pAxisY || \ m_pAxisX->getRangeMin() == m_pAxisX->getRangeMax() || \ m_pAxisY->getRangeMin() == m_pAxisY->getRangeMax()) { return; } QPointF ptPos = getPosOf(m_vecPoints[0]); painter->save(); if(m_regionMarkData != nullptr) { m_regionMarkData->setRegionMarkName(m_sName); m_regionMarkData->setPtPos(m_vecPoints[0]); m_regionMarkData->setBackgroundColor(m_clrBackgrd); m_regionMarkData->setSelectRegion(m_bSelectRegion); } ZxPlot* m_pCurPlot = dynamic_cast(this->getParent()); if (m_pCurPlot == nullptr) { painter->restore(); return; } // 获取当前图表的对象数 int objCount = m_pCurPlot->getObjCount(); for(int i = 0; i < objCount; i++) { ZxObjBase* obj = m_pCurPlot->getObjByIndex(i); if (obj == nullptr) { continue; } QVector pts = obj->getAllPos(); if(_isSame("nObjRegion", obj->getTagName())) { // 获取区域的多边形点 QPolygonF regionPolygon(pts); nmObjRegion* region = static_cast(obj); // 判断 RegionMark 是否在该区域内 if(regionPolygon.containsPoint(ptPos, Qt::OddEvenFill)) { // 判断该区域是否已经被标记 if(region->getRegionMark() == nullptr && m_regionMarkData != nullptr) { region->setRegionMark(this); region->setBackgrdColor(this->m_clrBackgrd); this->setSelectRegion(true); // update Data m_regionMarkData->setSelectRegion(m_bSelectRegion); } else { // 如果区域已被标记 int index = region->getRegionMark()->getColorIndex(); // 判断大小 if(this->m_iColorIndex < index) { region->setRegionMark(this); region->setBackgrdColor(this->m_clrBackgrd); this->setSelectRegion(true); // updata Data m_regionMarkData->setSelectRegion(m_bSelectRegion); } } } } } // 设置字体 //double r = 8.f; //QPointF ptTopLeft = QPointF(ptPos.x() - r, // ptPos.y() - r); //QSizeF sz = QSizeF(r * 2.f, r * 2.f); //QRectF bound = QRectF(ptTopLeft, sz); //QFont ft = qApp->font(); //ft.setPointSize(8); //painter->setFont(ft); //painter->setPen(Qt::black); //ZxDrawHelper::drawText(painter, // bound, // Qt::AlignCenter | Qt::AlignVCenter, // m_sName); ////painter->setPen(QPen(Qt::black, 1.2f)); ////ZxDrawHelper::drawPlus(painter,ptPos,2.2f,false,Qt::black); //painter->restore(); // 设置字体 QFont ft = qApp->font(); ft.setPointSize(8); painter->setFont(ft); painter->setPen(Qt::black); // 定义图标和文本的绘制参数 int iconSize = 6; // 图标大小 int spacing = 0; // 图标和文本之间的间距 int textWidth = 100; // 文本区域的固定宽度 // 计算图标的矩形区域,居中于ptPos QRectF iconRect(ptPos.x() - iconSize / 2, ptPos.y() - iconSize / 2, iconSize, iconSize); painter->drawPixmap(iconRect, m_icon, m_icon.rect()); // 计算文本的矩形区域,位于图标上方 // 文本的y坐标是图标顶部减去间距和文本高度(这里使用iconSize作为文本高度) QRectF textRect( ptPos.x() - textWidth / 2, // 文本水平居中于图标 ptPos.y() - iconSize / 2 - spacing - iconSize, // 在图标上方 textWidth, iconSize // 使用与图标相同的高度 ); ZxDrawHelper::drawText(painter, textRect, Qt::AlignCenter, m_sName); // 使用居中对齐 painter->restore(); } void nmObjRegionMark::setColorIndex(int newIndex) { m_iColorIndex = newIndex; } int nmObjRegionMark::getColorIndex() const { return m_iColorIndex; } void nmObjRegionMark::setSelectRegion(bool select) { m_bSelectRegion = select; } bool nmObjRegionMark::getSelectRegion() const { return m_bSelectRegion; } QColor nmObjRegionMark::getBackgrdColor() const { return m_clrBackgrd; } void nmObjRegionMark::setBackgrdColor(QColor color) { if(m_clrBackgrd != color) { m_clrBackgrd = color; update(); } } void nmObjRegionMark::afterCreated() { m_regionMarkData = nmDataAnalyzeManager::getCurrentInstance()->createRegionMark(); m_regionMarkData->setRegionMarkName(m_sName); m_regionMarkData->setPtPos(m_vecPoints[0]); m_regionMarkData->setSelectRegion(m_bSelectRegion); m_regionMarkData->setBackgroundColor(m_clrBackgrd); } nmDataRegionMark* nmObjRegionMark::getRegionMarkData() const { return m_regionMarkData; } void nmObjRegionMark::removeData() { if(m_regionMarkData) { // 从数据中心移除该数据 nmDataAnalyzeManager::getCurrentInstance()->removeRegionMarkData(m_regionMarkData); m_regionMarkData = nullptr; } } void nmObjRegionMark::onObjVisibleChanged(bool bIsVisible) { if(m_regionMarkData != nullptr) { m_regionMarkData->setPlotVisible(bIsVisible); } }