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++

#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);
}
}