#include #include #include "IxPtyPano.h" #include "ZxBaseUtil.h" #include "ZxSubAxisX.h" #include "ZxSubAxisY.h" #include "nmObjLineFaultTool.h" #include "ZxPlot.h" #include "ZxObjText.h" #include "nmObjLineFault.h" #include "nmDataAnalyzeManager.h" ZX_DEFINE_DYNAMIC(nObjLineFault, nmObjLineFault) nmObjLineFault::nmObjLineFault() { m_sObjTag = "nObjLineFault"; nmObjLineFault::init("", NULL, NULL); } nmObjLineFault::nmObjLineFault(const QString& sName, \ ZxSubAxisX* pAxisX, \ ZxSubAxisY* pAxisY) { m_sObjTag = "nObjLineFault"; nmObjLineFault::init(sName, pAxisX, pAxisY); } nmObjLineFault::~nmObjLineFault() { /* if (m_faultData) { delete m_faultData; m_faultData = nullptr; // 置空指针 } */ } void nmObjLineFault::fillPtyPano(IxPtyPano* sheet) { nmObjBase::fillPtyPano(sheet); IxPtyItem* pProp = ZX_PROP("ObjLineFault.FlowModel", getFaultFlowModel, setFaultFlowModel); if(NULL != pProp) { QStringList listTags; listTags << tr("Leaky") << tr("Composite Limit"); QList listIndexes; listIndexes << 0 << 1; pProp->getPtyPano(); pProp->setOptions(listTags, listIndexes); } ZX_PROP("ObjLineFault.Leakage", getFaultLeakage, setFaultLeakage); // 断层起点位置 ZX_PROP("ObjLineFaultStartPos.StartPointX", getStartX, setStartX); ZX_PROP("ObjLineFaultStartPos.StartPointY", getStartY,setStartY); // 断层终点位置 ZX_PROP("ObjLineFaultEndPos.EndPointX", getEndX, setEndX); ZX_PROP("ObjLineFaultEndPos.EndPointY", getEndY, setEndY); } void nmObjLineFault::init(const QString& sName, \ ZxSubAxisX* pAxisX, \ ZxSubAxisY* pAxisY) { nmObjBase::init(sName, pAxisX, pAxisY); nmObjLineFault::initFlags(); m_oPen = QPen(QBrush(Qt::green), \ 0.3f, Qt::SolidLine); m_faultData = nullptr; loadTempl(); // 连接图元可见性信号和槽 connect(this, SIGNAL(sigObjVisibleChanged(bool)), this, SLOT(onObjVisibleChanged(bool))); } void nmObjLineFault::initTools() { m_pTool = new nmObjLineFaultTool(); nmObjBase::initTools(); } void nmObjLineFault::initFlags() { setLockPos(false); setLockSize(false); setReadOnly(false); } bool nmObjLineFault::hitTest(const QPointF& pt) { return nmObjBase::hitTest(pt); } bool nmObjLineFault::_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 = 1.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; } } // 线 for(int i = 0; i < pts.count(); i++) { int n1 = i; int n2 = (i == pts.count() - 1 ? 0 : i + 1); if(_isNearLine(pt, pts[n1], pts[n2], 1.f * 2)) { // 判断当前线是否已经存在 if(m_oHitOption == OHO_Bound && m_pTool->isLeftDown()) { // 添加新节点 pts.insert(i + 1, pt); m_vecPoints.clear(); m_vecPoints = getValueOf(pts); nOption = (int)OHO_Point; nSubIndex = i + 1; return true; } nOption = (int)OHO_Bound; nSubIndex = i; return true; } } return false; } bool nmObjLineFault::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; nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged(); return moveToPos(vecPts); } else if(m_oHitOption == OHO_Bound && m_nHitIndex >= 0) { for(int i = 0; i < nCount; i++) { vecPts[i] = offsetPoint(vecPts[i], pt1, pt2); } m_dOffsetX = pt2.x() - pt1.x(); m_dOffsetY = pt2.y() - pt1.y(); nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged(); return moveToPos(vecPts); } else { return false; } return true; } void nmObjLineFault::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; } painter->save(); QVector pts = getPosOf(m_vecPoints); // 更新断层几何数据 if (m_faultData != nullptr) { m_faultData->setFaultName(m_sName); m_faultData->setFaultPoints(m_vecPoints); } // 不选中的状态 if(!pts.empty()) { QPen pen = m_oPen; painter->setPen(pen); for(int i = 0; i < pts.count() - 1; i++) { painter->drawLine(pts[i], pts[i + 1]); } //将名称置于中间线段下方 QFont ft = qApp->font(); ft.setPointSize(8); painter->setFont(ft); painter->setPen(Qt::black); int nSegments = pts.count() - 1; int middleIndex = (nSegments - 1) / 2; QPointF startPoint = pts[middleIndex]; QPointF endPoint = pts[middleIndex + 1]; // 计算中点坐标 QPointF middlePoint((startPoint.x() + endPoint.x()) / 2, (startPoint.y() + endPoint.y()) / 2); // 计算线段的方向角度 double dx = endPoint.x() - startPoint.x(); double dy = endPoint.y() - startPoint.y(); double angle = qAtan2(dy, dx) * 180.0 / M_PI; // 偏移距离 double offsetDistance = -3.0; // 线段长度 double length = std::sqrt(dx * dx + dy * dy); // 计算一个垂直于线段方向的单位向量: QPointF offset(0, 0); if (length > 0) { // 选用 (dy, -dx) 作为垂直方向,正负号可根据想要的偏移朝向做调整 offset = QPointF(offsetDistance * (dy / length), offsetDistance * (-dx / length)); } // 最终文字基准点:在原中点的基础上加上垂直方向的偏移 QPointF textPos = middlePoint + offset; painter->save(); painter->translate(textPos); painter->rotate(angle); QRectF textRect(-50, -10, 100, 20); ZxDrawHelper::drawText(painter, textRect, Qt::AlignCenter | Qt::AlignVCenter, m_sName); painter->restore(); } if(isSelected()) { //选中状态下 for(int i = 0; i < pts.count(); i++) { float w = 2.2f; QPointF pt = pts[i]; QRectF rect(pt.x() - w * 0.5f, pt.y() - w * 0.5f, w, w); if(m_nHitIndex == i && m_oHitOption == OHO_Point) { // 填充节点 QBrush br(Qt::red); painter->fillRect(rect, br); } else { painter->setPen(QColor(0, 0, 128)); painter->drawRect(rect); } // 击中线 if(m_nHitIndex == i && m_oHitOption == OHO_Bound) { nmDataLogFile::getInstance()->writeLog("select line " + QString::number(i)); QPen pen(Qt::DashLine); //pen.setWidth(1); // 设置线条宽度 //pen.setColor(Qt::yellow); // 设置线条颜色 painter->setPen(pen); for(int i = 0; i < pts.count() - 1; i++) { painter->drawLine(pts[i], pts[i + 1]); } } } } painter->restore(); } double nmObjLineFault::getFaultLeakage() { return m_faultData->getFaultLeakage().getValue().toDouble(); } void nmObjLineFault::setFaultLeakage(double newFaultLeakage) { // 从Data中取数据 nmDataAttribute tempAttr = m_faultData->getFaultLeakage(); tempAttr.setValue(newFaultLeakage); m_faultData->setFaultLeakage(tempAttr); } int nmObjLineFault::getFaultFlowModel() { if (m_faultData->getFaultFlowModel().getValue() == tr("Leaky")) return 0; else return 1; } void nmObjLineFault::setFaultFlowModel(int newFaultFlowModel) { // 从Data中取数据 nmDataAttribute tempAttr = m_faultData->getFaultFlowModel(); if (newFaultFlowModel == 0) { tempAttr.setValue(tr("Leaky")); } else { tempAttr.setValue(tr("Composite limit")); } m_faultData->setFaultFlowModel(tempAttr); } double nmObjLineFault::getStartX() { return m_faultData->getFaultPoints().first().x(); } void nmObjLineFault::setStartX(double newValue) { m_vecPoints.first().setX(newValue); nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged(); } double nmObjLineFault::getStartY() { return m_faultData->getFaultPoints().first().y(); } void nmObjLineFault::setStartY(double newValue) { m_vecPoints.first().setY(newValue); nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged(); } double nmObjLineFault::getEndX() { return m_faultData->getFaultPoints().last().x(); } void nmObjLineFault::setEndX(double newValue) { m_vecPoints.last().setX(newValue); nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged(); } double nmObjLineFault::getEndY() { return m_faultData->getFaultPoints().last().y(); } void nmObjLineFault::setEndY(double newValue) { m_vecPoints.last().setY(newValue); nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged(); } void nmObjLineFault::onSerialize(ZxSerializer* ser) { nmObjBase::onSerialize(ser); int flowModel; if (m_faultData->getFaultFlowModel().getValue() == tr("Leaky")) flowModel = 0; else flowModel = 1; ser->write("FlowModel", flowModel); ser->write("Leakage", m_faultData->getFaultLeakage().getValue().toDouble()); } void nmObjLineFault::onDeserialize(ZxSerializer* ser) { nmObjBase::onDeserialize(ser); int flowModel; double faultLeakage; ser->read("FlowModel", flowModel); ser->read("Leakage", faultLeakage); // 更新Data this->setFaultFlowModel(flowModel); this->setFaultLeakage(faultLeakage); } void nmObjLineFault::onSaveTempl(ZxSerializer* ser) { nmObjBase::onSaveTempl(ser); int flowModel; if (m_faultData->getFaultFlowModel().getValue() == tr("Leaky")) flowModel = 0; else flowModel = 1; ser->write("FlowModel", flowModel); ser->write("Leakage", m_faultData->getFaultLeakage().getValue().toDouble()); } void nmObjLineFault::onLoadTempl(ZxSerializer* ser) { nmObjBase::onLoadTempl(ser); int flowModel; double faultLeakage; ser->read("FlowModel", flowModel); ser->read("Leakage", faultLeakage); // 更新Data this->setFaultFlowModel(flowModel); this->setFaultLeakage(faultLeakage); } void nmObjLineFault::setFaultData(nmDataFault* newFaultData) { m_faultData = newFaultData; } nmDataFault* nmObjLineFault::getFaultData() const{ return m_faultData; } void nmObjLineFault::afterCreated() { m_faultData = nmDataAnalyzeManager::getCurrentInstance()->createFault(); m_faultData->setFaultName(m_sName); m_faultData->setFaultPoints(m_vecPoints); nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged(); } void nmObjLineFault::removeData() { if (m_faultData) { // 从数据中心移除该数据 nmDataAnalyzeManager::getCurrentInstance()->removeFaultData(m_faultData); m_faultData = nullptr; } } void nmObjLineFault::onObjVisibleChanged(bool bIsVisible) { if (m_faultData != nullptr) { m_faultData->setPlotVisible(bIsVisible); } }