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/nmObjRegionMark.cpp

498 lines
13 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 "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<QVariant> 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<QPointF> pts = getPosOf(m_vecPoints);
// <20><>
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<QPointF> 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<ZxPlot*>(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<QPointF> pts = obj->getAllPos();
if(_isSame("nObjRegion", obj->getTagName())) {
// 获取区域的多边形点
QPolygonF regionPolygon(pts);
nmObjRegion* region = static_cast<nmObjRegion*>(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);
}
}