|
|
|
|
|
#include "nmDataAttribute.h"
|
|
|
|
|
|
#include <QDebug>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 默认构造函数
|
|
|
|
|
|
nmDataAttribute::nmDataAttribute()
|
|
|
|
|
|
: m_name(""), m_value(), m_unit(""), m_minValue(), m_maxValue(),
|
|
|
|
|
|
m_listValueSelections(), m_listUnitSelections(), m_unitType(UNIT_TYPE_UNKNOWN) {
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 带参数的构造函数
|
|
|
|
|
|
nmDataAttribute::nmDataAttribute(const QString& name, QVariant value, const QString& unit)
|
|
|
|
|
|
: m_name(name), m_value(value), m_unit(unit), m_minValue(), m_maxValue(),
|
|
|
|
|
|
m_listValueSelections(), m_listUnitSelections(), m_unitType(UNIT_TYPE_UNKNOWN) {
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 带可选列表和单位类型的构造函数
|
|
|
|
|
|
nmDataAttribute::nmDataAttribute(const QString& name, QVariant value, const QString& unit, UnitType unitType,
|
|
|
|
|
|
const QStringList& valueSelections, const QStringList& unitSelections)
|
|
|
|
|
|
: m_name(name), m_value(value), m_unit(unit), m_minValue(), m_maxValue(),
|
|
|
|
|
|
m_listValueSelections(valueSelections), m_listUnitSelections(unitSelections), m_unitType(unitType)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nmDataAttribute::~nmDataAttribute()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 析构函数
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 拷贝构造函数
|
|
|
|
|
|
nmDataAttribute::nmDataAttribute(const nmDataAttribute& other) {
|
|
|
|
|
|
*this = other;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 赋值运算符
|
|
|
|
|
|
nmDataAttribute& nmDataAttribute::operator=(const nmDataAttribute& other) {
|
|
|
|
|
|
if (this != &other) {
|
|
|
|
|
|
m_name = other.m_name;
|
|
|
|
|
|
m_value = other.m_value;
|
|
|
|
|
|
m_unit = other.m_unit;
|
|
|
|
|
|
m_unitType = other.m_unitType;
|
|
|
|
|
|
m_minValue = other.m_minValue;
|
|
|
|
|
|
m_maxValue = other.m_maxValue;
|
|
|
|
|
|
m_listValueSelections = other.m_listValueSelections;
|
|
|
|
|
|
m_listUnitSelections = other.m_listUnitSelections;
|
|
|
|
|
|
}
|
|
|
|
|
|
return *this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
rapidjson::Value nmDataAttribute::ToJsonValue(rapidjson::Document::AllocatorType& allocator) const
|
|
|
|
|
|
{
|
|
|
|
|
|
// 创建一个RapidJSON对象
|
|
|
|
|
|
rapidjson::Value attributeValue(rapidjson::kObjectType);
|
|
|
|
|
|
|
|
|
|
|
|
// 添加属性名称,QString转UTF8并移入JSON
|
|
|
|
|
|
attributeValue.AddMember("Name", rapidjson::Value(m_name.toStdString().c_str(), allocator).Move(), allocator);
|
|
|
|
|
|
|
|
|
|
|
|
// 根据QVariant类型添加“值”
|
|
|
|
|
|
if (m_value.type() == QVariant::Double) {
|
|
|
|
|
|
attributeValue.AddMember("Value", m_value.toDouble(), allocator);
|
|
|
|
|
|
} else if (m_value.type() == QVariant::Int) {
|
|
|
|
|
|
attributeValue.AddMember("Value", m_value.toInt(), allocator);
|
|
|
|
|
|
} else { // 字符串及其他类型转UTF8字符串
|
|
|
|
|
|
attributeValue.AddMember("Value", rapidjson::Value(m_value.toString().toStdString().c_str(), allocator).Move(), allocator);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 添加单位,QString转UTF8并移入JSON
|
|
|
|
|
|
attributeValue.AddMember("Unit", rapidjson::Value(m_unit.toStdString().c_str(), allocator).Move(), allocator);
|
|
|
|
|
|
|
|
|
|
|
|
// 如果最小值有效,添加“最小值”
|
|
|
|
|
|
if (m_minValue.isValid()) {
|
|
|
|
|
|
if (m_minValue.type() == QVariant::Double) {
|
|
|
|
|
|
attributeValue.AddMember("MinValue", m_minValue.toDouble(), allocator);
|
|
|
|
|
|
} else if (m_minValue.type() == QVariant::Int) {
|
|
|
|
|
|
attributeValue.AddMember("MinValue", m_minValue.toInt(), allocator);
|
|
|
|
|
|
} else { // 字符串及其他类型转UTF8字符串
|
|
|
|
|
|
attributeValue.AddMember("MinValue", rapidjson::Value(m_minValue.toString().toStdString().c_str(), allocator).Move(), allocator);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果最大值有效,添加“最大值”
|
|
|
|
|
|
if (m_maxValue.isValid()) {
|
|
|
|
|
|
if (m_maxValue.type() == QVariant::Double) {
|
|
|
|
|
|
attributeValue.AddMember("MaxValue", m_maxValue.toDouble(), allocator);
|
|
|
|
|
|
} else if (m_maxValue.type() == QVariant::Int) {
|
|
|
|
|
|
attributeValue.AddMember("MaxValue", m_maxValue.toInt(), allocator);
|
|
|
|
|
|
} else { // 字符串及其他类型转UTF8字符串
|
|
|
|
|
|
attributeValue.AddMember("MaxValue", rapidjson::Value(m_maxValue.toString().toStdString().c_str(), allocator).Move(), allocator);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 序列化可选值列表
|
|
|
|
|
|
if (!m_listValueSelections.isEmpty()) {
|
|
|
|
|
|
rapidjson::Value selectionsArray(rapidjson::kArrayType); // 创建JSON数组
|
|
|
|
|
|
foreach (const QString& selection , m_listValueSelections) { // 遍历列表
|
|
|
|
|
|
selectionsArray.PushBack(rapidjson::Value(selection.toStdString().c_str(), allocator).Move(), allocator);
|
|
|
|
|
|
}
|
|
|
|
|
|
attributeValue.AddMember("ValueSelections", selectionsArray, allocator); // 将数组添加到JSON对象
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 序列化可选单位列表
|
|
|
|
|
|
if (!m_listUnitSelections.isEmpty()) {
|
|
|
|
|
|
rapidjson::Value unitSelectionsArray(rapidjson::kArrayType); // 创建JSON数组
|
|
|
|
|
|
foreach (const QString& unitSelection , m_listUnitSelections) { // 遍历列表
|
|
|
|
|
|
unitSelectionsArray.PushBack(rapidjson::Value(unitSelection.toStdString().c_str(), allocator).Move(), allocator);
|
|
|
|
|
|
}
|
|
|
|
|
|
attributeValue.AddMember("UnitSelections", unitSelectionsArray, allocator); // 将数组添加到JSON对象
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 返回序列化后的RapidJSON值
|
|
|
|
|
|
return attributeValue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 从 RapidJSON Value 反序列化数据到 nmDataAttribute
|
|
|
|
|
|
void nmDataAttribute::FromJsonValue(const rapidjson::Value& jsonValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 检查JSON对象是否有"Name"成员且为字符串,如果有则反序列化到m_name
|
|
|
|
|
|
if (jsonValue.HasMember("Name") && jsonValue["Name"].IsString()) {
|
|
|
|
|
|
m_name = QString::fromUtf8(jsonValue["Name"].GetString());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查JSON对象是否有"Value"成员
|
|
|
|
|
|
if (jsonValue.HasMember("Value")) {
|
|
|
|
|
|
const rapidjson::Value& valueNode = jsonValue["Value"]; // 获取"Value"节点
|
|
|
|
|
|
// 根据节点类型反序列化到m_value
|
|
|
|
|
|
if (valueNode.IsDouble()) {
|
|
|
|
|
|
m_value = valueNode.GetDouble();
|
|
|
|
|
|
} else if (valueNode.IsInt()) {
|
|
|
|
|
|
m_value = valueNode.GetInt();
|
|
|
|
|
|
} else if (valueNode.IsString()) {
|
|
|
|
|
|
m_value = QString::fromUtf8(valueNode.GetString());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查JSON对象是否有"Unit"成员且为字符串,如果有则反序列化到m_unit
|
|
|
|
|
|
if (jsonValue.HasMember("Unit") && jsonValue["Unit"].IsString()) {
|
|
|
|
|
|
m_unit = QString::fromUtf8(jsonValue["Unit"].GetString());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查JSON对象是否有"MinValue"成员,如果有则根据类型反序列化到m_minValue
|
|
|
|
|
|
if (jsonValue.HasMember("MinValue")) {
|
|
|
|
|
|
const rapidjson::Value& minValueNode = jsonValue["MinValue"];
|
|
|
|
|
|
if (minValueNode.IsDouble()) {
|
|
|
|
|
|
m_minValue = minValueNode.GetDouble();
|
|
|
|
|
|
} else if (minValueNode.IsInt()) {
|
|
|
|
|
|
m_minValue = minValueNode.GetInt();
|
|
|
|
|
|
} else if (minValueNode.IsString()) {
|
|
|
|
|
|
m_minValue = QString::fromUtf8(minValueNode.GetString());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查JSON对象是否有"MaxValue"成员,如果有则根据类型反序列化到m_maxValue
|
|
|
|
|
|
if (jsonValue.HasMember("MaxValue")) {
|
|
|
|
|
|
const rapidjson::Value& maxValueNode = jsonValue["MaxValue"];
|
|
|
|
|
|
if (maxValueNode.IsDouble()) {
|
|
|
|
|
|
m_maxValue = maxValueNode.GetDouble();
|
|
|
|
|
|
} else if (maxValueNode.IsInt()) {
|
|
|
|
|
|
m_maxValue = maxValueNode.GetInt();
|
|
|
|
|
|
} else if (maxValueNode.IsString()) {
|
|
|
|
|
|
m_maxValue = QString::fromUtf8(maxValueNode.GetString());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 反序列化可选值列表 "ValueSelections"
|
|
|
|
|
|
// 检查JSON对象是否有"ValueSelections"成员且为数组
|
|
|
|
|
|
if (jsonValue.HasMember("ValueSelections") && jsonValue["ValueSelections"].IsArray()) {
|
|
|
|
|
|
m_listValueSelections.clear(); // 清空当前列表
|
|
|
|
|
|
const rapidjson::Value& selectionsArray = jsonValue["ValueSelections"]; // 获取数组节点
|
|
|
|
|
|
// 遍历数组,将每个字符串元素添加到m_listValueSelections
|
|
|
|
|
|
for (rapidjson::SizeType i = 0; i < selectionsArray.Size(); ++i) {
|
|
|
|
|
|
if (selectionsArray[i].IsString()) {
|
|
|
|
|
|
m_listValueSelections.append(QString::fromUtf8(selectionsArray[i].GetString()));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 反序列化可选单位列表 "UnitSelections"
|
|
|
|
|
|
// 检查JSON对象是否有"UnitSelections"成员且为数组
|
|
|
|
|
|
if (jsonValue.HasMember("UnitSelections") && jsonValue["UnitSelections"].IsArray()) {
|
|
|
|
|
|
m_listUnitSelections.clear(); // 清空当前列表
|
|
|
|
|
|
const rapidjson::Value& unitSelectionsArray = jsonValue["UnitSelections"]; // 获取数组节点
|
|
|
|
|
|
// 遍历数组,将每个字符串元素添加到m_listUnitSelections
|
|
|
|
|
|
for (rapidjson::SizeType i = 0; i < unitSelectionsArray.Size(); ++i) {
|
|
|
|
|
|
if (unitSelectionsArray[i].IsString()) {
|
|
|
|
|
|
m_listUnitSelections.append(QString::fromUtf8(unitSelectionsArray[i].GetString()));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取属性名称
|
|
|
|
|
|
QString nmDataAttribute::getName() const {
|
|
|
|
|
|
return m_name;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 设置属性名称
|
|
|
|
|
|
void nmDataAttribute::setName(const QString& name) {
|
|
|
|
|
|
m_name = name;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取当前显示值(会根据当前单位转换)
|
|
|
|
|
|
QVariant nmDataAttribute::getValue() const {
|
|
|
|
|
|
return m_value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 设置值(考虑当前单位)
|
|
|
|
|
|
void nmDataAttribute::setValue(const QVariant& value) {
|
|
|
|
|
|
m_value = value;
|
|
|
|
|
|
emit sigValueChanged();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取当前显示单位
|
|
|
|
|
|
QString nmDataAttribute::getUnit() const {
|
|
|
|
|
|
return m_unit;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 设置单位(添加值更新逻辑)
|
|
|
|
|
|
void nmDataAttribute::setUnit(const QString& unit) {
|
|
|
|
|
|
m_unit = unit;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 设置值范围
|
|
|
|
|
|
void nmDataAttribute::setValueRange(const QVariant& min, const QVariant& max) {
|
|
|
|
|
|
m_minValue = min;
|
|
|
|
|
|
m_maxValue = max;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查值有效性(考虑当前单位)
|
|
|
|
|
|
bool nmDataAttribute::isValueValid() const {
|
|
|
|
|
|
if (m_minValue.isNull() || m_maxValue.isNull())
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
if (m_value.type() != QVariant::Double && m_value.type() != QVariant::Int)
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
double currentValue = m_value.toDouble();
|
|
|
|
|
|
double min = m_minValue.toDouble();
|
|
|
|
|
|
double max = m_maxValue.toDouble();
|
|
|
|
|
|
|
|
|
|
|
|
return currentValue >= min && currentValue <= max;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取最小值
|
|
|
|
|
|
QVariant nmDataAttribute::getMinValue() const {
|
|
|
|
|
|
return m_minValue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取最大值
|
|
|
|
|
|
QVariant nmDataAttribute::getMaxValue() const {
|
|
|
|
|
|
return m_maxValue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取可选值列表
|
|
|
|
|
|
QStringList nmDataAttribute::getListValueSelections() const {
|
|
|
|
|
|
return m_listValueSelections;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 设置可选值列表
|
|
|
|
|
|
void nmDataAttribute::setListValueSelections(const QStringList &listSelections) {
|
|
|
|
|
|
m_listValueSelections = listSelections;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取可选单位列表
|
|
|
|
|
|
QStringList nmDataAttribute::getListUnitSelections() const {
|
|
|
|
|
|
return m_listUnitSelections;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 设置可选单位列表
|
|
|
|
|
|
void nmDataAttribute::setListUnitSelections(const QStringList &listUnitSelections) {
|
|
|
|
|
|
m_listUnitSelections = listUnitSelections;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取显示文本
|
|
|
|
|
|
QString nmDataAttribute::getDisplayText() const {
|
|
|
|
|
|
if (!m_listValueSelections.isEmpty()) {
|
|
|
|
|
|
return m_value.toString();
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (m_value.type() == QVariant::Bool) {
|
|
|
|
|
|
return m_value.toBool() ? "True" : "False";
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (!m_unit.isEmpty() && (m_value.type() == QVariant::Double || m_value.type() == QVariant::Int)) {
|
|
|
|
|
|
return QString("%1 %2").arg(QString::number(m_value.toDouble(), 'f', 2)).arg(m_unit);
|
|
|
|
|
|
}
|
|
|
|
|
|
return m_value.toString();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UnitType nmDataAttribute::getAttributeUnitType() const {
|
|
|
|
|
|
return m_unitType;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmDataAttribute::setAttributeUnitType(UnitType type) {
|
|
|
|
|
|
m_unitType = type;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double nmDataAttribute::convertValueByUnitType(double value,
|
|
|
|
|
|
const QString& fromUnit,
|
|
|
|
|
|
const QString& toUnit) const
|
|
|
|
|
|
{
|
|
|
|
|
|
// 相同单位,直接返回
|
|
|
|
|
|
if (fromUnit == toUnit) return value;
|
|
|
|
|
|
|
|
|
|
|
|
double orig = value;
|
|
|
|
|
|
double conv = orig;
|
|
|
|
|
|
|
|
|
|
|
|
// 按实例的 m_unitType 分发
|
|
|
|
|
|
switch (m_unitType) {
|
|
|
|
|
|
case UNIT_TYPE_LENGTH:
|
|
|
|
|
|
conv = convertLengthUnit(orig, fromUnit, toUnit);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case UNIT_TYPE_PRESSURE:
|
|
|
|
|
|
conv = convertPressureUnit(orig, fromUnit, toUnit);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case UNIT_TYPE_PERMEABILITY:
|
|
|
|
|
|
conv = convertPermeabilityUnit(orig, fromUnit, toUnit);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case UNIT_TYPE_CONDUCTIVITY:
|
|
|
|
|
|
conv = convertConductivityUnit(orig, fromUnit, toUnit);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case UNIT_TYPE_ANGLE:
|
|
|
|
|
|
conv = convertAngleUnit(orig, fromUnit, toUnit);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case UNIT_TYPE_TIME:
|
|
|
|
|
|
conv = convertTimeUnit(orig, fromUnit, toUnit);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case UNIT_TYPE_COMPRESSIBILITY:
|
|
|
|
|
|
conv = convertCompressibilityUnit(orig, fromUnit, toUnit);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case UNIT_TYPE_FLOW_RATE_RECIPROCAL:
|
|
|
|
|
|
conv = convertFlowRateReciprocalUnit(orig, fromUnit, toUnit);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case UNIT_TYPE_DIMENSIONLESS:
|
|
|
|
|
|
conv = orig;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case UNIT_TYPE_FLOW_RATE:
|
|
|
|
|
|
conv = convertFlowRateUnit(orig, fromUnit, toUnit);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
conv = convertValue(orig, fromUnit, toUnit);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return conv;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double nmDataAttribute::convertValue(double value, const QString& fromUnit, const QString& toUnit) {
|
|
|
|
|
|
// 如果单位相同,无需转换
|
|
|
|
|
|
if (fromUnit == toUnit) {
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 自动检测单位类型
|
|
|
|
|
|
UnitType fromType = detectUnitType(fromUnit);
|
|
|
|
|
|
UnitType toType = detectUnitType(toUnit);
|
|
|
|
|
|
|
|
|
|
|
|
// 检查两个单位是否为同一类型
|
|
|
|
|
|
if (fromType != toType || fromType == UNIT_TYPE_UNKNOWN) {
|
|
|
|
|
|
qDebug() << "Cannot convert between different unit types or unknown units:" << fromUnit << "to" << toUnit;
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 根据单位类型进行转换
|
|
|
|
|
|
switch (fromType) {
|
|
|
|
|
|
case UNIT_TYPE_LENGTH:
|
|
|
|
|
|
return convertLengthUnit(value, fromUnit, toUnit);
|
|
|
|
|
|
|
|
|
|
|
|
case UNIT_TYPE_PRESSURE:
|
|
|
|
|
|
return convertPressureUnit(value, fromUnit, toUnit);
|
|
|
|
|
|
|
|
|
|
|
|
case UNIT_TYPE_PERMEABILITY:
|
|
|
|
|
|
return convertPermeabilityUnit(value, fromUnit, toUnit);
|
|
|
|
|
|
|
|
|
|
|
|
case UNIT_TYPE_CONDUCTIVITY:
|
|
|
|
|
|
return convertConductivityUnit(value, fromUnit, toUnit);
|
|
|
|
|
|
|
|
|
|
|
|
case UNIT_TYPE_ANGLE:
|
|
|
|
|
|
return convertAngleUnit(value, fromUnit, toUnit);
|
|
|
|
|
|
|
|
|
|
|
|
case UNIT_TYPE_TIME:
|
|
|
|
|
|
return convertTimeUnit(value, fromUnit, toUnit);
|
|
|
|
|
|
|
|
|
|
|
|
case UNIT_TYPE_COMPRESSIBILITY:
|
|
|
|
|
|
return convertCompressibilityUnit(value, fromUnit, toUnit);
|
|
|
|
|
|
|
|
|
|
|
|
case UNIT_TYPE_FLOW_RATE_RECIPROCAL:
|
|
|
|
|
|
return convertFlowRateReciprocalUnit(value, fromUnit, toUnit);
|
|
|
|
|
|
|
|
|
|
|
|
case UNIT_TYPE_FLOW_RATE:
|
|
|
|
|
|
return convertFlowRateUnit(value, fromUnit, toUnit);
|
|
|
|
|
|
|
|
|
|
|
|
case UNIT_TYPE_DIMENSIONLESS:
|
|
|
|
|
|
// 无量纲不需要转换
|
|
|
|
|
|
return value;
|
|
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
qDebug() << "Unsupported unit type for conversion:" << fromType;
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UnitType nmDataAttribute::detectUnitType(const QString& unit) {
|
|
|
|
|
|
// 长度单位
|
|
|
|
|
|
if (unit == "m" || unit == "cm" || unit == "mm" || unit == "in" ||
|
|
|
|
|
|
unit == "0.1 in" || unit == "ft" || unit == "mile" || unit == "km") {
|
|
|
|
|
|
return UNIT_TYPE_LENGTH;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 压力单位
|
|
|
|
|
|
if (unit == "MPa" || unit == "psia" || unit == "Pa" || unit == "kPa" ||
|
|
|
|
|
|
unit == "atm" || unit == "bara" || unit == "kg/cm^2" || unit == "psig" ||
|
|
|
|
|
|
unit == "bar" || unit == "kPag") {
|
|
|
|
|
|
return UNIT_TYPE_PRESSURE;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 渗透率单位
|
|
|
|
|
|
if (unit == "md" || unit == "Darcy" || unit == "m^2" || unit == "cm^2" || unit == "um^2") {
|
|
|
|
|
|
return UNIT_TYPE_PERMEABILITY;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 导流能力单位
|
|
|
|
|
|
if (unit == "md.m" || unit == "md.ft" || unit == "m^3") {
|
|
|
|
|
|
return UNIT_TYPE_CONDUCTIVITY;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 角度单位
|
|
|
|
|
|
if (unit == "o" || unit == "radian") {
|
|
|
|
|
|
return UNIT_TYPE_ANGLE;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 时间单位
|
|
|
|
|
|
if (unit == "ms" || unit == "sec" || unit == "min" || unit == "hr" ||
|
|
|
|
|
|
unit == "day" || unit == "Week" || unit == "Month" || unit == "Year") {
|
|
|
|
|
|
return UNIT_TYPE_TIME;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 压缩系数单位
|
|
|
|
|
|
if (unit == "m^3/MPa" || unit == "bbl/psi" || unit == "m^3/bar" ||
|
|
|
|
|
|
unit == "m^3/kPa" || unit == "m^3/Pa" || unit == "m^3.cm^2/kg" || unit == "m^2") {
|
|
|
|
|
|
return UNIT_TYPE_COMPRESSIBILITY;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 流量倒数单位
|
|
|
|
|
|
if (unit == "1/B/D" || unit == "1/MMm^3/D" || unit == "1/Mcf/D" ||
|
|
|
|
|
|
unit == "1/Mm^3/D" || unit == "1/Mm^3/hr" || unit == "1/U.K. gal/hr" ||
|
|
|
|
|
|
unit == "1/U.K. gal/min" || unit == "1/U.S. gal/hr" || unit == "1/U.S. gal/min" ||
|
|
|
|
|
|
unit == "1/cf/D" || unit == "1/cf/s" || unit == "1/cm^3/sec" || unit == "1/l/min" ||
|
|
|
|
|
|
unit == "1/m^3/D" || unit == "1/m^3/hr" || unit == "1/m^3/min" || unit == "1/m^3/sec") {
|
|
|
|
|
|
return UNIT_TYPE_FLOW_RATE_RECIPROCAL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 流量单位
|
|
|
|
|
|
if (unit == "B/D" || unit == "MMm^3/D" || unit == "Mcf/D" ||
|
|
|
|
|
|
unit == "Mm^3/D" || unit == "Mm^3/hr" ||
|
|
|
|
|
|
unit == "U.K. gal/hr" || unit == "U.K. gal/min" ||
|
|
|
|
|
|
unit == "U.S. gal/hr" || unit == "U.S. gal/min" ||
|
|
|
|
|
|
unit == "cf/D" || unit == "cf/s" ||
|
|
|
|
|
|
unit == "cm^3/sec" || unit == "l/min" ||
|
|
|
|
|
|
unit == "m^3/D" || unit == "m^3/hr" ||
|
|
|
|
|
|
unit == "m^3/min" || unit == "m^3/sec") {
|
|
|
|
|
|
return UNIT_TYPE_FLOW_RATE;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 无量纲
|
|
|
|
|
|
if (unit.isEmpty()) {
|
|
|
|
|
|
return UNIT_TYPE_DIMENSIONLESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return UNIT_TYPE_UNKNOWN;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double nmDataAttribute::convertLengthUnit(double value, const QString& fromUnit, const QString& toUnit) {
|
|
|
|
|
|
// 如果单位相同,无需转换
|
|
|
|
|
|
if (fromUnit == toUnit) {
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 统一转换为米,然后再转换为目标单位
|
|
|
|
|
|
double valueInMeters = value;
|
|
|
|
|
|
|
|
|
|
|
|
// 先转换为米
|
|
|
|
|
|
if (fromUnit == "cm") {
|
|
|
|
|
|
valueInMeters = value / 100.0;
|
|
|
|
|
|
} else if (fromUnit == "mm") {
|
|
|
|
|
|
valueInMeters = value / 1000.0;
|
|
|
|
|
|
} else if (fromUnit == "in") {
|
|
|
|
|
|
valueInMeters = value / 39.3701;
|
|
|
|
|
|
} else if (fromUnit == "0.1 in") {
|
|
|
|
|
|
valueInMeters = (value / 10.0) / 39.3701;
|
|
|
|
|
|
} else if (fromUnit == "ft") {
|
|
|
|
|
|
valueInMeters = value / 3.28084;
|
|
|
|
|
|
} else if (fromUnit == "mile") {
|
|
|
|
|
|
valueInMeters = value / 0.000621371;
|
|
|
|
|
|
} else if (fromUnit == "km") {
|
|
|
|
|
|
valueInMeters = value * 1000.0;
|
|
|
|
|
|
} else if (fromUnit != "m") {
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 从米转换为目标单位
|
|
|
|
|
|
if (toUnit == "m") {
|
|
|
|
|
|
return valueInMeters;
|
|
|
|
|
|
} else if (toUnit == "cm") {
|
|
|
|
|
|
return valueInMeters * 100.0;
|
|
|
|
|
|
} else if (toUnit == "mm") {
|
|
|
|
|
|
return valueInMeters * 1000.0;
|
|
|
|
|
|
} else if (toUnit == "in") {
|
|
|
|
|
|
return valueInMeters * 39.3701;
|
|
|
|
|
|
} else if (toUnit == "0.1 in") {
|
|
|
|
|
|
return valueInMeters * 39.3701 * 10.0;
|
|
|
|
|
|
} else if (toUnit == "ft") {
|
|
|
|
|
|
return valueInMeters * 3.28084;
|
|
|
|
|
|
} else if (toUnit == "mile") {
|
|
|
|
|
|
return valueInMeters * 0.000621371;
|
|
|
|
|
|
} else if (toUnit == "km") {
|
|
|
|
|
|
return valueInMeters / 1000.0;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double nmDataAttribute::convertPressureUnit(double value, const QString& fromUnit, const QString& toUnit) {
|
|
|
|
|
|
// 统一转换为Pa(帕斯卡)
|
|
|
|
|
|
double valueInPa = value;
|
|
|
|
|
|
|
|
|
|
|
|
// 转换为Pa
|
|
|
|
|
|
if (fromUnit == "MPa") {
|
|
|
|
|
|
valueInPa = value * 1e6;
|
|
|
|
|
|
} else if (fromUnit == "psia") {
|
|
|
|
|
|
valueInPa = value * 6894.76;
|
|
|
|
|
|
} else if (fromUnit == "kPa") {
|
|
|
|
|
|
valueInPa = value * 1000.0;
|
|
|
|
|
|
} else if (fromUnit == "atm") {
|
|
|
|
|
|
valueInPa = value * 101325;
|
|
|
|
|
|
} else if (fromUnit == "bara") {
|
|
|
|
|
|
valueInPa = value * 100000;
|
|
|
|
|
|
} else if (fromUnit == "kg/cm^2") {
|
|
|
|
|
|
valueInPa = value * 98066.5;
|
|
|
|
|
|
} else if (fromUnit == "psig") {
|
|
|
|
|
|
valueInPa = value * 6894.76; // psig to Pa
|
|
|
|
|
|
} else if (fromUnit == "bar") {
|
|
|
|
|
|
valueInPa = value * 100000;
|
|
|
|
|
|
} else if (fromUnit == "kPag") {
|
|
|
|
|
|
valueInPa = value * 1000.0;
|
|
|
|
|
|
} else if (fromUnit == "Pa") {
|
|
|
|
|
|
valueInPa = value;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
qDebug() << "Unknown pressure unit:" << fromUnit;
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 从Pa转换为目标单位
|
|
|
|
|
|
if (toUnit == "Pa") {
|
|
|
|
|
|
return valueInPa;
|
|
|
|
|
|
} else if (toUnit == "MPa") {
|
|
|
|
|
|
return valueInPa / 1e6;
|
|
|
|
|
|
} else if (toUnit == "psia") {
|
|
|
|
|
|
return valueInPa / 6894.76;
|
|
|
|
|
|
} else if (toUnit == "kPa") {
|
|
|
|
|
|
return valueInPa / 1000.0;
|
|
|
|
|
|
} else if (toUnit == "atm") {
|
|
|
|
|
|
return valueInPa / 101325;
|
|
|
|
|
|
} else if (toUnit == "bara") {
|
|
|
|
|
|
return valueInPa / 100000;
|
|
|
|
|
|
} else if (toUnit == "kg/cm^2") {
|
|
|
|
|
|
return valueInPa / 98066.5;
|
|
|
|
|
|
} else if (toUnit == "psig") {
|
|
|
|
|
|
return valueInPa / 6894.76;
|
|
|
|
|
|
} else if (toUnit == "bar") {
|
|
|
|
|
|
return valueInPa / 100000;
|
|
|
|
|
|
} else if (toUnit == "kPag") {
|
|
|
|
|
|
return valueInPa / 1000.0;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double nmDataAttribute::convertPermeabilityUnit(double value, const QString& fromUnit, const QString& toUnit) {
|
|
|
|
|
|
// 统一转换为Darcy
|
|
|
|
|
|
double valueInDarcy = value;
|
|
|
|
|
|
|
|
|
|
|
|
if (fromUnit == "md") {
|
|
|
|
|
|
valueInDarcy = value / 1000.0; // 1 Darcy = 1000 md
|
|
|
|
|
|
} else if (fromUnit == "Darcy") {
|
|
|
|
|
|
valueInDarcy = value;
|
|
|
|
|
|
} else if (fromUnit == "m^2") {
|
|
|
|
|
|
valueInDarcy = value * 9.869233e-13; // 1 m^2 = 9.869233e-13 Darcy
|
|
|
|
|
|
} else if (fromUnit == "cm^2") {
|
|
|
|
|
|
valueInDarcy = value * 9.869233e-11; // 1 cm^2 = 9.869233e-11 Darcy
|
|
|
|
|
|
} else if (fromUnit == "um^2") {
|
|
|
|
|
|
valueInDarcy = value * 9.869233e-17; // 1 um^2 = 9.869233e-17 Darcy
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 从Darcy转换为目标单位
|
|
|
|
|
|
if (toUnit == "Darcy") {
|
|
|
|
|
|
return valueInDarcy;
|
|
|
|
|
|
} else if (toUnit == "md") {
|
|
|
|
|
|
return valueInDarcy * 1000.0;
|
|
|
|
|
|
} else if (toUnit == "m^2") {
|
|
|
|
|
|
return valueInDarcy / 9.869233e-13;
|
|
|
|
|
|
} else if (toUnit == "cm^2") {
|
|
|
|
|
|
return valueInDarcy / 9.869233e-11;
|
|
|
|
|
|
} else if (toUnit == "um^2") {
|
|
|
|
|
|
return valueInDarcy / 9.869233e-17;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double nmDataAttribute::convertConductivityUnit(double value, const QString& fromUnit, const QString& toUnit) {
|
|
|
|
|
|
double valueInM3 = value;
|
|
|
|
|
|
|
|
|
|
|
|
if (fromUnit == "md.m") {
|
|
|
|
|
|
valueInM3 = value; // 原单位已是标准单位
|
|
|
|
|
|
} else if (fromUnit == "md.ft") {
|
|
|
|
|
|
valueInM3 = value * 0.3048; // 1 ft = 0.3048 m
|
|
|
|
|
|
} else if (fromUnit == "m^3") {
|
|
|
|
|
|
valueInM3 = value;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 转换为目标单位
|
|
|
|
|
|
if (toUnit == "md.m") {
|
|
|
|
|
|
return valueInM3;
|
|
|
|
|
|
} else if (toUnit == "md.ft") {
|
|
|
|
|
|
return valueInM3 / 0.3048;
|
|
|
|
|
|
} else if (toUnit == "m^3") {
|
|
|
|
|
|
return valueInM3;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double nmDataAttribute::convertAngleUnit(double value, const QString& fromUnit, const QString& toUnit) {
|
|
|
|
|
|
double valueInRadians = value;
|
|
|
|
|
|
|
|
|
|
|
|
if (fromUnit == "o" || fromUnit == "degree") {
|
|
|
|
|
|
valueInRadians = value * 3.141592653589793 / 180.0; // 角度转弧度
|
|
|
|
|
|
} else if (fromUnit == "radian") {
|
|
|
|
|
|
valueInRadians = value;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 转换为目标单位
|
|
|
|
|
|
if (toUnit == "radian") {
|
|
|
|
|
|
return valueInRadians;
|
|
|
|
|
|
} else if (toUnit == "degree" || toUnit == "o") {
|
|
|
|
|
|
return valueInRadians * 180.0 / 3.141592653589793; // 弧度转角度
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double nmDataAttribute::convertTimeUnit(double value, const QString& fromUnit, const QString& toUnit) {
|
|
|
|
|
|
double valueInSeconds = value;
|
|
|
|
|
|
// 先把输入值统一转为秒
|
|
|
|
|
|
if (fromUnit == "ms") {
|
|
|
|
|
|
valueInSeconds = value / 1000.0; // 毫秒 -> 秒
|
|
|
|
|
|
} else if (fromUnit == "sec") {
|
|
|
|
|
|
valueInSeconds = value;
|
|
|
|
|
|
} else if (fromUnit == "min") {
|
|
|
|
|
|
valueInSeconds = value * 60.0; // 分钟 -> 秒
|
|
|
|
|
|
} else if (fromUnit == "hr") {
|
|
|
|
|
|
valueInSeconds = value * 3600.0; // 小时 -> 秒
|
|
|
|
|
|
} else if (fromUnit == "day") {
|
|
|
|
|
|
valueInSeconds = value * 86400.0; // 天转换为秒
|
|
|
|
|
|
} else if (fromUnit == "week" || fromUnit == "Week") {
|
|
|
|
|
|
valueInSeconds = value * 604800.0; // 周转换为秒
|
|
|
|
|
|
} else if (fromUnit == "month" || fromUnit == "Month") {
|
|
|
|
|
|
valueInSeconds = value * 2592000.0; // 月转换为秒
|
|
|
|
|
|
} else if (fromUnit == "year" || fromUnit == "Year") {
|
|
|
|
|
|
valueInSeconds = value * 31536000.0; // 年转换为秒
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return value; // 未知单位,原样返回
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 再把秒转换成目标单位
|
|
|
|
|
|
if (toUnit == "ms") {
|
|
|
|
|
|
return valueInSeconds * 1000.0; // 秒 -> 毫秒
|
|
|
|
|
|
} else if (toUnit == "sec") {
|
|
|
|
|
|
return valueInSeconds;
|
|
|
|
|
|
} else if (toUnit == "min") {
|
|
|
|
|
|
return valueInSeconds / 60.0;
|
|
|
|
|
|
} else if (toUnit == "hr") {
|
|
|
|
|
|
return valueInSeconds / 3600.0;
|
|
|
|
|
|
} else if (toUnit == "day") {
|
|
|
|
|
|
return valueInSeconds / 86400.0;
|
|
|
|
|
|
} else if (toUnit == "week" || toUnit == "Week") {
|
|
|
|
|
|
return valueInSeconds / 604800.0;
|
|
|
|
|
|
} else if (toUnit == "month" || toUnit == "Month") {
|
|
|
|
|
|
return valueInSeconds / 2592000.0;
|
|
|
|
|
|
} else if (toUnit == "year" || toUnit == "Year") {
|
|
|
|
|
|
return valueInSeconds / 31536000.0;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double nmDataAttribute::convertCompressibilityUnit(double value, const QString& fromUnit, const QString& toUnit) {
|
|
|
|
|
|
// 统一转换为 m^3/MPa
|
|
|
|
|
|
double valueInM3PerMPa = value;
|
|
|
|
|
|
|
|
|
|
|
|
// 转换为 m^3/MPa
|
|
|
|
|
|
if (fromUnit == "m^3/MPa") {
|
|
|
|
|
|
valueInM3PerMPa = value;
|
|
|
|
|
|
} else if (fromUnit == "bbl/psi") {
|
|
|
|
|
|
valueInM3PerMPa = value * 0.0062945; // 1 bbl/psi = 0.0062945 m^3/MPa
|
|
|
|
|
|
} else if (fromUnit == "m^3/bar") {
|
|
|
|
|
|
valueInM3PerMPa = value * 1.0e6 / 1.01325e5; // 1 m^3/bar = 1e6/1.01325e5 m^3/MPa
|
|
|
|
|
|
} else if (fromUnit == "m^3/kPa") {
|
|
|
|
|
|
valueInM3PerMPa = value * 1000.0; // 1 m^3/kPa = 1000 m^3/MPa
|
|
|
|
|
|
} else if (fromUnit == "m^3/Pa") {
|
|
|
|
|
|
valueInM3PerMPa = value * 1e6; // 1 m^3/Pa = 1e6 m^3/MPa
|
|
|
|
|
|
} else if (fromUnit == "m^3.cm^2/kg") {
|
|
|
|
|
|
valueInM3PerMPa = value * 1e-7; // 1 m^3.cm^2/kg ≈ 1e-7 m^3/MPa
|
|
|
|
|
|
} else if (fromUnit == "m^2") {
|
|
|
|
|
|
valueInM3PerMPa = value * 1.0e-6; // 1 m^2 ≈ 1e-6 m^3/MPa
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 从 m^3/MPa 转换为目标单位
|
|
|
|
|
|
if (toUnit == "m^3/MPa") {
|
|
|
|
|
|
return valueInM3PerMPa;
|
|
|
|
|
|
} else if (toUnit == "bbl/psi") {
|
|
|
|
|
|
return valueInM3PerMPa / 0.0062945;
|
|
|
|
|
|
} else if (toUnit == "m^3/bar") {
|
|
|
|
|
|
return valueInM3PerMPa * 1.01325e5 / 1.0e6;
|
|
|
|
|
|
} else if (toUnit == "m^3/kPa") {
|
|
|
|
|
|
return valueInM3PerMPa / 1000.0;
|
|
|
|
|
|
} else if (toUnit == "m^3/Pa") {
|
|
|
|
|
|
return valueInM3PerMPa / 1e6;
|
|
|
|
|
|
} else if (toUnit == "m^3.cm^2/kg") {
|
|
|
|
|
|
return valueInM3PerMPa / 1e-7;
|
|
|
|
|
|
} else if (toUnit == "m^2") {
|
|
|
|
|
|
return valueInM3PerMPa / 1.0e-6;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double nmDataAttribute::convertFlowRateReciprocalUnit(double value, const QString& fromUnit, const QString& toUnit) {
|
|
|
|
|
|
// 统一转换为 1/B/D
|
|
|
|
|
|
double valueInBPD = value;
|
|
|
|
|
|
|
|
|
|
|
|
// 转换为 1/B/D
|
|
|
|
|
|
if (fromUnit == "1/B/D") {
|
|
|
|
|
|
valueInBPD = value;
|
|
|
|
|
|
} else if (fromUnit == "1/MMm^3/D") {
|
|
|
|
|
|
valueInBPD = value * 1.0e6; // 1/MMm^3/D = 1e6 1/B/D
|
|
|
|
|
|
} else if (fromUnit == "1/Mcf/D") {
|
|
|
|
|
|
valueInBPD = value * 0.0160231; // 1 Mcf/D = 0.0160231 1/B/D
|
|
|
|
|
|
} else if (fromUnit == "1/Mm^3/D") {
|
|
|
|
|
|
valueInBPD = value * 1e9; // 1/Mm^3/D = 1e9 1/B/D
|
|
|
|
|
|
} else if (fromUnit == "1/Mm^3/hr") {
|
|
|
|
|
|
valueInBPD = value * 1e9 / 24.0; // 1/Mm^3/hr = 1e9 1/B/D / 24
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 从 1/B/D 转换为目标单位
|
|
|
|
|
|
if (toUnit == "1/B/D") {
|
|
|
|
|
|
return valueInBPD;
|
|
|
|
|
|
} else if (toUnit == "1/MMm^3/D") {
|
|
|
|
|
|
return valueInBPD / 1.0e6;
|
|
|
|
|
|
} else if (toUnit == "1/Mcf/D") {
|
|
|
|
|
|
return valueInBPD / 0.0160231;
|
|
|
|
|
|
} else if (toUnit == "1/Mm^3/D") {
|
|
|
|
|
|
return valueInBPD / 1e9;
|
|
|
|
|
|
} else if (toUnit == "1/Mm^3/hr") {
|
|
|
|
|
|
return valueInBPD * 24.0 / 1e9;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double nmDataAttribute::convertFlowRateUnit(double value, const QString& fromUnit, const QString& toUnit)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (fromUnit == toUnit) return value;
|
|
|
|
|
|
|
|
|
|
|
|
// 常量:体积换算
|
|
|
|
|
|
const double BBL_TO_M3 = 0.158987294928; // 1 US oil barrel = 0.158987... m^3
|
|
|
|
|
|
const double CF_TO_M3 = 0.028316846592; // 1 cubic foot = 0.028316846592 m^3
|
|
|
|
|
|
const double USGAL_TO_M3 = 0.003785411784; // 1 US gallon = 0.003785411784 m^3
|
|
|
|
|
|
const double UKGAL_TO_M3 = 0.00454609; // 1 UK gallon = 0.00454609 m^3
|
|
|
|
|
|
const double L_TO_M3 = 0.001; // 1 liter = 0.001 m^3
|
|
|
|
|
|
|
|
|
|
|
|
// 常量:时间换算
|
|
|
|
|
|
const double SEC_PER_MIN = 60.0;
|
|
|
|
|
|
const double SEC_PER_HR = 3600.0;
|
|
|
|
|
|
const double SEC_PER_DAY = 86400.0;
|
|
|
|
|
|
|
|
|
|
|
|
// 体积前缀(保持与你“倒数流量”的约定一致)
|
|
|
|
|
|
// 注意:若以后要改为标准 SI:把 MMm^3=1e6, Mm^3=1e6(或 Gm^3=1e9)按需改
|
|
|
|
|
|
const double MMm3_TO_M3 = 1.0e6; // 约定:MMm^3 表示 10^6 m^3
|
|
|
|
|
|
const double Mm3_TO_M3 = 1.0e9; // 约定:Mm^3 表示 10^9 m^3(为与旧代码保持对称)
|
|
|
|
|
|
|
|
|
|
|
|
// 将任意流量先转为 m^3/s
|
|
|
|
|
|
const QString fu = fromUnit;
|
|
|
|
|
|
double m3_per_s = 0.0;
|
|
|
|
|
|
|
|
|
|
|
|
// ---- fromUnit -> m^3/s ----
|
|
|
|
|
|
if (fu == "B/D") {
|
|
|
|
|
|
m3_per_s = value * BBL_TO_M3 / SEC_PER_DAY;
|
|
|
|
|
|
} else if (fu == "MMm^3/D") {
|
|
|
|
|
|
m3_per_s = value * MMm3_TO_M3 / SEC_PER_DAY;
|
|
|
|
|
|
} else if (fu == "Mcf/D") {
|
|
|
|
|
|
m3_per_s = value * (1000.0 * CF_TO_M3) / SEC_PER_DAY;
|
|
|
|
|
|
} else if (fu == "Mm^3/D") {
|
|
|
|
|
|
m3_per_s = value * Mm3_TO_M3 / SEC_PER_DAY;
|
|
|
|
|
|
} else if (fu == "Mm^3/hr") {
|
|
|
|
|
|
m3_per_s = value * Mm3_TO_M3 / SEC_PER_HR;
|
|
|
|
|
|
} else if (fu == "U.K. gal/hr") {
|
|
|
|
|
|
m3_per_s = value * UKGAL_TO_M3 / SEC_PER_HR;
|
|
|
|
|
|
} else if (fu == "U.K. gal/min") {
|
|
|
|
|
|
m3_per_s = value * UKGAL_TO_M3 / SEC_PER_MIN;
|
|
|
|
|
|
} else if (fu == "U.S. gal/hr") {
|
|
|
|
|
|
m3_per_s = value * USGAL_TO_M3 / SEC_PER_HR;
|
|
|
|
|
|
} else if (fu == "U.S. gal/min") {
|
|
|
|
|
|
m3_per_s = value * USGAL_TO_M3 / SEC_PER_MIN;
|
|
|
|
|
|
} else if (fu == "cf/D") {
|
|
|
|
|
|
m3_per_s = value * CF_TO_M3 / SEC_PER_DAY;
|
|
|
|
|
|
} else if (fu == "cf/s") {
|
|
|
|
|
|
m3_per_s = value * CF_TO_M3; // 每秒
|
|
|
|
|
|
} else if (fu == "cm^3/sec") {
|
|
|
|
|
|
m3_per_s = value * 1.0e-6; // 1 cm^3 = 1e-6 m^3
|
|
|
|
|
|
} else if (fu == "l/min") {
|
|
|
|
|
|
m3_per_s = value * L_TO_M3 / SEC_PER_MIN;
|
|
|
|
|
|
} else if (fu == "m^3/D") {
|
|
|
|
|
|
m3_per_s = value / SEC_PER_DAY;
|
|
|
|
|
|
} else if (fu == "m^3/hr") {
|
|
|
|
|
|
m3_per_s = value / SEC_PER_HR;
|
|
|
|
|
|
} else if (fu == "m^3/min") {
|
|
|
|
|
|
m3_per_s = value / SEC_PER_MIN;
|
|
|
|
|
|
} else if (fu == "m^3/sec") {
|
|
|
|
|
|
m3_per_s = value;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 未知单位:原样返回
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---- m^3/s -> toUnit ----
|
|
|
|
|
|
const QString tu = toUnit;
|
|
|
|
|
|
if (tu == "B/D") {
|
|
|
|
|
|
return m3_per_s * SEC_PER_DAY / BBL_TO_M3;
|
|
|
|
|
|
} else if (tu == "MMm^3/D") {
|
|
|
|
|
|
return m3_per_s * SEC_PER_DAY / MMm3_TO_M3;
|
|
|
|
|
|
} else if (tu == "Mcf/D") {
|
|
|
|
|
|
return m3_per_s * SEC_PER_DAY / (1000.0 * CF_TO_M3);
|
|
|
|
|
|
} else if (tu == "Mm^3/D") {
|
|
|
|
|
|
return m3_per_s * SEC_PER_DAY / Mm3_TO_M3;
|
|
|
|
|
|
} else if (tu == "Mm^3/hr") {
|
|
|
|
|
|
return m3_per_s * SEC_PER_HR / Mm3_TO_M3;
|
|
|
|
|
|
} else if (tu == "U.K. gal/hr") {
|
|
|
|
|
|
return m3_per_s * SEC_PER_HR / UKGAL_TO_M3;
|
|
|
|
|
|
} else if (tu == "U.K. gal/min") {
|
|
|
|
|
|
return m3_per_s * SEC_PER_MIN / UKGAL_TO_M3;
|
|
|
|
|
|
} else if (tu == "U.S. gal/hr") {
|
|
|
|
|
|
return m3_per_s * SEC_PER_HR / USGAL_TO_M3;
|
|
|
|
|
|
} else if (tu == "U.S. gal/min") {
|
|
|
|
|
|
return m3_per_s * SEC_PER_MIN / USGAL_TO_M3;
|
|
|
|
|
|
} else if (tu == "cf/D") {
|
|
|
|
|
|
return m3_per_s * SEC_PER_DAY / CF_TO_M3;
|
|
|
|
|
|
} else if (tu == "cf/s") {
|
|
|
|
|
|
return m3_per_s / CF_TO_M3;
|
|
|
|
|
|
} else if (tu == "cm^3/sec") {
|
|
|
|
|
|
return m3_per_s / 1.0e-6;
|
|
|
|
|
|
} else if (tu == "l/min") {
|
|
|
|
|
|
return m3_per_s * SEC_PER_MIN / L_TO_M3;
|
|
|
|
|
|
} else if (tu == "m^3/D") {
|
|
|
|
|
|
return m3_per_s * SEC_PER_DAY;
|
|
|
|
|
|
} else if (tu == "m^3/hr") {
|
|
|
|
|
|
return m3_per_s * SEC_PER_HR;
|
|
|
|
|
|
} else if (tu == "m^3/min") {
|
|
|
|
|
|
return m3_per_s * SEC_PER_MIN;
|
|
|
|
|
|
} else if (tu == "m^3/sec") {
|
|
|
|
|
|
return m3_per_s;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|