128 lines
5.3 KiB
C
128 lines
5.3 KiB
C
#ifndef SURVEYGEOMETRY_H
|
||
#define SURVEYGEOMETRY_H
|
||
|
||
#include <QJsonArray>
|
||
#include <QJsonObject>
|
||
#include <QVector>
|
||
|
||
struct SurveyGeometry {
|
||
double rtkOffsetX = 0.0; // RTK相对天线中心的设备x轴偏移(m),头文件无对应字段,保留给用户输入
|
||
double rtkOffsetY = 0.0; // RTK相对天线中心的设备y轴偏移(m),来自CH_Y_OFFSETS
|
||
double ch1XRel = 0.0; // 第1通道相对天线中心的x坐标(m),由CH_X_OFFSETS首尾值推导
|
||
QVector<double> channelXRel; // 各通道相对天线中心的x坐标(m),来自CH_X_OFFSETS归一到天线中心
|
||
int channelCount = 1; // 通道总数,来自NUMBER_OF_CH
|
||
int cgcsZone = 0; // CGCS2000 3度带带号,0表示自动检测
|
||
double centralMeridianDeg = 0.0; // 中央经线(度),自动推导
|
||
|
||
bool operator==(const SurveyGeometry &other) const {
|
||
return rtkOffsetX == other.rtkOffsetX &&
|
||
rtkOffsetY == other.rtkOffsetY &&
|
||
ch1XRel == other.ch1XRel &&
|
||
channelXRel == other.channelXRel &&
|
||
channelCount == other.channelCount &&
|
||
cgcsZone == other.cgcsZone &&
|
||
centralMeridianDeg == other.centralMeridianDeg;
|
||
}
|
||
|
||
void applyHeaderOffsets(int numberOfChannels,
|
||
const QVector<float> &chXOffsets,
|
||
const QVector<float> &chYOffsets)
|
||
{
|
||
const int offsetChannelCount = qMax(chXOffsets.size(), chYOffsets.size());
|
||
channelCount = qMax(1, numberOfChannels > 0 ? numberOfChannels : offsetChannelCount);
|
||
rtkOffsetY = chYOffsets.isEmpty() ? 0.0 : static_cast<double>(chYOffsets.first());
|
||
|
||
channelXRel.clear();
|
||
channelXRel.reserve(channelCount);
|
||
|
||
if (chXOffsets.size() >= 2) {
|
||
const double centerX = (static_cast<double>(chXOffsets.first()) + chXOffsets.last()) / 2.0;
|
||
for (int i = 0; i < chXOffsets.size() && i < channelCount; ++i) {
|
||
channelXRel.append(static_cast<double>(chXOffsets[i]) - centerX);
|
||
}
|
||
ch1XRel = channelXRel.isEmpty() ? 0.0 : channelXRel.first();
|
||
} else {
|
||
ch1XRel = 0.0;
|
||
}
|
||
|
||
if (channelXRel.size() < channelCount) {
|
||
const int existing = channelXRel.size();
|
||
channelXRel.resize(channelCount);
|
||
if (existing == 0) {
|
||
for (int c = 0; c < channelCount; ++c) {
|
||
channelXRel[c] = 0.0;
|
||
}
|
||
} else if (channelCount > 1) {
|
||
const double lastXRel = -ch1XRel;
|
||
for (int c = existing; c < channelCount; ++c) {
|
||
channelXRel[c] = ch1XRel + (lastXRel - ch1XRel) * c / (channelCount - 1.0);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
static SurveyGeometry fromHeaderOffsets(int numberOfChannels,
|
||
const QVector<float> &chXOffsets,
|
||
const QVector<float> &chYOffsets)
|
||
{
|
||
SurveyGeometry g;
|
||
g.applyHeaderOffsets(numberOfChannels, chXOffsets, chYOffsets);
|
||
return g;
|
||
}
|
||
|
||
QJsonObject toJson() const {
|
||
QJsonObject obj;
|
||
obj["rtkOffsetX"] = rtkOffsetX;
|
||
obj["rtkOffsetY"] = rtkOffsetY;
|
||
obj["ch1XRel"] = ch1XRel;
|
||
QJsonArray channelXRelArray;
|
||
for (double x : channelXRel) {
|
||
channelXRelArray.append(x);
|
||
}
|
||
obj["channelXRel"] = channelXRelArray;
|
||
obj["channelCount"] = channelCount;
|
||
obj["cgcsZone"] = cgcsZone;
|
||
obj["centralMeridianDeg"] = centralMeridianDeg;
|
||
return obj;
|
||
}
|
||
|
||
static SurveyGeometry fromJson(const QJsonObject &obj) {
|
||
SurveyGeometry g;
|
||
g.rtkOffsetX = obj.value("rtkOffsetX").toDouble(0.0);
|
||
g.rtkOffsetY = obj.value("rtkOffsetY").toDouble(0.0);
|
||
g.ch1XRel = obj.value("ch1XRel").toDouble(0.0);
|
||
g.channelCount = qMax(1, obj.value("channelCount").toInt(1));
|
||
g.cgcsZone = obj.value("cgcsZone").toInt(0);
|
||
g.centralMeridianDeg = obj.value("centralMeridianDeg").toDouble(0.0);
|
||
|
||
const QJsonArray channelXRelArray = obj.value("channelXRel").toArray();
|
||
for (const QJsonValue &value : channelXRelArray) {
|
||
g.channelXRel.append(value.toDouble(0.0));
|
||
}
|
||
|
||
if (g.channelXRel.isEmpty() && obj.contains("ch16XRel")) {
|
||
const double legacyLastXRel = obj.value("ch16XRel").toDouble(-g.ch1XRel);
|
||
g.channelXRel.resize(g.channelCount);
|
||
for (int c = 0; c < g.channelCount; ++c) {
|
||
g.channelXRel[c] = (g.channelCount > 1)
|
||
? g.ch1XRel + (legacyLastXRel - g.ch1XRel) * c / (g.channelCount - 1.0)
|
||
: g.ch1XRel;
|
||
}
|
||
} else if (g.channelXRel.isEmpty()) {
|
||
g.channelXRel.resize(g.channelCount);
|
||
const double lastXRel = -g.ch1XRel;
|
||
for (int c = 0; c < g.channelCount; ++c) {
|
||
g.channelXRel[c] = (g.channelCount > 1)
|
||
? g.ch1XRel + (lastXRel - g.ch1XRel) * c / (g.channelCount - 1.0)
|
||
: g.ch1XRel;
|
||
}
|
||
} else if (g.channelXRel.size() != g.channelCount) {
|
||
g.channelCount = qMax(1, g.channelXRel.size());
|
||
}
|
||
|
||
return g;
|
||
}
|
||
};
|
||
|
||
#endif // SURVEYGEOMETRY_H
|