#include "nmDataVerticalWell.h" nmDataVerticalWell::nmDataVerticalWell() : nmDataWellBase() { m_perforationLength = nmDataAttribute("Perforation Length", 30.0, "m", UNIT_TYPE_LENGTH, QStringList(),QStringList() << "m" << "cm" << "mm" << "in" << "0.1 in" << "ft" << "mile" << "km"); // 直井 m_eWellType = NM_WELL_MODEL::Vertical_Well; this->connectAttributeSignals(); } // 拷贝构造函数 nmDataVerticalWell::nmDataVerticalWell(const nmDataVerticalWell& other) : nmDataWellBase() { *this = other; // 使用赋值运算符实现 this->connectAttributeSignals(); } // 赋值运算符 nmDataVerticalWell& nmDataVerticalWell::operator=(const nmDataVerticalWell& other) { if (this != &other) { nmDataWellBase::operator=(other); m_perforationLength = other.m_perforationLength; } return *this; } nmDataWellBase* nmDataVerticalWell::clone() const { return new nmDataVerticalWell(*this); } // 序列化 nmDataVerticalWell 为 RapidJSON Value rapidjson::Value nmDataVerticalWell::ToJsonValue(rapidjson::Document::AllocatorType& allocator) const { // 序列化井基础参数 rapidjson::Value verticalWellObject = nmDataWellBase::ToJsonValue(allocator); // 序列化 nmDataAttribute 类型的成员 // 调用 nmDataAttribute 自身的 ToJsonValue 方法进行递归序列化 verticalWellObject.AddMember("PerforationLength", m_perforationLength.ToJsonValue(allocator), allocator); return verticalWellObject; // 返回序列化后的 RapidJSON Value } // 从 RapidJSON Value 反序列化数据到 nmDataVerticalWell void nmDataVerticalWell::FromJsonValue(const rapidjson::Value& jsonValue) { // 反序列化井基础参数 nmDataWellBase::FromJsonValue(jsonValue); // 反序列化 nmDataAttribute 类型的成员 // 调用 nmDataAttribute 自身的 FromJsonValue 方法进行递归反序列化 if (jsonValue.HasMember("PerforationLength") && jsonValue["PerforationLength"].IsObject()) { m_perforationLength.FromJsonValue(jsonValue["PerforationLength"]); } } void nmDataVerticalWell::connectAttributeSignals() { // 直井属性 connect(&m_perforationLength, SIGNAL(sigValueChanged()), this, SIGNAL(sigWellDataChanged())); } void nmDataVerticalWell::getPerforationAllowedMdRange(nmDataPerforation* pPerfToValidate, double& dUpperAllowedMd, double& dLowerAllowedMd) { // 1. 获取井筒的整体MD范围作为默认边界 double dWellboreTopMd = getBottomholeMD().getValue().toDouble(); double dWellboreBottomMd = dWellboreTopMd + getWellLength().getValue().toDouble(); // 初始化允许范围为整个井筒的MD范围 dUpperAllowedMd = dWellboreTopMd; dLowerAllowedMd = dWellboreBottomMd; // 2. 获取当前正在操作的射孔段的当前MD值 // 使用传入的指针,而不是从模型中再次查找,以避免在拖动过程中数据不一致 double dCurrentPerfMdStart = pPerfToValidate->getMdStart().getValue().toDouble(); double dCurrentPerfMdEnd = pPerfToValidate->getMdEnd().getValue().toDouble(); // 3. 遍历所有射孔段,找到与当前射孔段相邻的上下边界 foreach(nmDataPerforation* pOtherPerf, m_vecPerforations) { if(pOtherPerf == pPerfToValidate) { continue; // 跳过当前正在操作的射孔段本身 } double dOtherStart = pOtherPerf->getMdStart().getValue().toDouble(); double dOtherEnd = pOtherPerf->getMdEnd().getValue().toDouble(); // 检查在当前射孔段上方的其他射孔段 // 如果 pOtherPerf 的结束MD 小于或等于当前射孔段的起始MD (考虑容差) if(dOtherEnd <= dCurrentPerfMdStart + DBL_EPSILON) { dUpperAllowedMd = std::max(dUpperAllowedMd, dOtherEnd); } // 检查在当前射孔段下方的其他射孔段 // 如果 pOtherPerf 的起始MD 大于或等于当前射孔段的结束MD (考虑容差) else if(dOtherStart >= dCurrentPerfMdEnd - DBL_EPSILON) { dLowerAllowedMd = std::min(dLowerAllowedMd, dOtherStart); } } // 4. 最后,确保计算出的范围不超出井筒的物理范围 dUpperAllowedMd = std::max(dUpperAllowedMd, dWellboreTopMd); dLowerAllowedMd = std::min(dLowerAllowedMd, dWellboreBottomMd); } void nmDataVerticalWell::setPerforationLength(const nmDataAttribute& attr) { m_perforationLength = attr; } nmDataAttribute& nmDataVerticalWell::getPerforationLength() { return m_perforationLength; }