/** * Class for reading oc data * $Id: handler_oc_situation_data.h 57655 2022-07-20 11:38:28Z karwat $ * $HeadURL: svn://192.168.133.21/TDS/branches/product/features/3dws_devel/Lts/Services/OcSituationClient/handler_oc_situation_data.h $ * $Author: karwat $ * Created by Hannes Fritsche, SLTE, 30-08-2023 */ #include "central_aes_byte_reader.h" #include #include "main_handler.h" #include "settings.h" namespace OcSituationClient { CentralAesByteReader::CentralAesByteReader(const QByteArray &data) : m_data(data) , m_logger(getLogger("CentralAesByteReader")) {} bool CentralAesByteReader::getRemoveMessage(size_t &pos, CentralAesByteReader::RemoveMessage &removeMessage) const { bool result = getAesItemId(pos, removeMessage.aesItemId); result &= getAesType(pos, removeMessage.aesType); DEBUG_LOG(m_logger) << "Got remove message:" << "\naesItemId = " << removeMessage.aesItemId << "\naesType = " << removeMessage.aesType; return result; } bool CentralAesByteReader::getNContamination(size_t &pos, AreaEffectSimulation::NContaminationModifyRequest &nContamination) const { bool result = getAesItemId(pos, nContamination.id()); result &= getName(pos, nContamination.name()); result &= getOptionalNumber(pos, nContamination.effectStart(), &CentralAesByteReader::getEffectStart); result &= getEffectDuration(pos, nContamination.effectDuration()); result &= getChargeTypeId(pos, nContamination.chargeTypeId()); result &= getImpactPosition(pos, nContamination.impactPosition()); result &= getBorderLengthInner(pos, nContamination.borderLengthInner()); result &= getBorderLengthOuter(pos, nContamination.borderLengthOuter()); result &= getImpactRadius(pos, nContamination.impactRadius()); result &= getSpanAngle(pos, nContamination.spanAngle()); result &= getRotationAngle(pos, nContamination.rotationAngle()); result &= getDetonationValue(pos, nContamination.detonationValue()); result &= getOptionalNumber(pos, nContamination.partyId(), &CentralAesByteReader::getPartyId); nContamination.weatherSource(AreaEffectSimulation::AesWeatherSource::AwsNoUpdate); DEBUG_LOG(m_logger) << "Got NContamination:" << "\nid = " << nContamination.id() << "\nname = " << nContamination.name() << "\neffectStart = " << nContamination.effectStart() << "\neffectDuration = " << nContamination.effectDuration() << "\nchargeTypeId = " << nContamination.chargeTypeId() << "\nimpactPosition = " << nContamination.impactPosition() << "\nborderLengthInner = " << nContamination.borderLengthInner() << "\nborderLengthOuter = " << nContamination.borderLengthOuter() << "\nimpactRadius = " << nContamination.impactRadius() << "\nspanAngle = " << nContamination.spanAngle() << "\nrotationAngle = " << nContamination.rotationAngle() << "\ndetonationValue = " << nContamination.detonationValue() << "\npartyId = " << nContamination.partyId(); return result; } bool CentralAesByteReader::getBCContamination(size_t &pos, AreaEffectSimulation::BCContaminationModifyRequest &bCContamination) const { bool result = getAesItemId(pos, bCContamination.id()); result &= getName(pos, bCContamination.name()); result &= getOptionalNumber(pos, bCContamination.effectStart(), &CentralAesByteReader::getEffectStart); result &= getEffectDuration(pos, bCContamination.effectDuration()); result &= getChargeTypeId(pos, bCContamination.chargeTypeId()); result &= getImpactPosition(pos, bCContamination.impactPosition()); result &= getImpactRadius(pos, bCContamination.impactRadius()); result &= getOptionalNumber(pos, bCContamination.partyId(), &CentralAesByteReader::getPartyId); result &= getOptionalNumber(pos, bCContamination.propagationDirection(), &CentralAesByteReader::getPropagationDirection); result &= getOptionalNumber(pos, bCContamination.windSpeed(), &CentralAesByteReader::getWindSpeed); bCContamination.weatherSource(AreaEffectSimulation::AesWeatherSource::AwsNoUpdate); DEBUG_LOG(m_logger) << "Got BCContamination:" << "\nid = " << bCContamination.id() << "\nname = " << bCContamination.name() << "\neffectStart = " << bCContamination.effectStart() << "\neffectDuration = " << bCContamination.effectDuration() << "\nchargeTypeId = " << bCContamination.chargeTypeId() << "\nimpactPosition = " << bCContamination.impactPosition() << "\nimpactRadius = " << bCContamination.impactRadius() << "\nweatherSource = " << bCContamination.weatherSource() << "\npartyId = " << bCContamination.partyId() << "\npropagationDirection = " << bCContamination.propagationDirection() << "\nwindSpeed = " << bCContamination.windSpeed() << "\nweatherPosition = " << bCContamination.weatherPosition() << "\nweatherTimestamp = " << bCContamination.weatherTimestamp(); return result; } bool CentralAesByteReader::getExplosionArea(size_t &pos, AreaEffectSimulation::ExplosionAreaModifyRequest &explosionArea) const { bool result = getAesItemId(pos, explosionArea.id()); result &= getName(pos, explosionArea.name()); result &= getOptionalNumber(pos, explosionArea.effectStart(), &CentralAesByteReader::getEffectStart); result &= getEffectDuration(pos, explosionArea.effectDuration()); result &= getChargeTypeId(pos, explosionArea.chargeTypeId()); result &= getArea(pos, explosionArea.area()); result &= getOptionalNumber(pos, explosionArea.partyId(), &CentralAesByteReader::getPartyId); result &= getCannonCount(pos, explosionArea.cannonCount()); result &= getCannonRounds(pos, explosionArea.cannonRounds()); result &= getFireRequestTime(pos, explosionArea.fireRequestTime()); result &= getAltitude(pos, explosionArea.altitude()); result &= getPurpose(pos, explosionArea.purpose()); DEBUG_LOG(m_logger) << "Got ExplosionArea:" << "\nid = " << explosionArea.id() << "\nname = " << explosionArea.name() << "\neffectStart = " << explosionArea.effectStart() << "\neffectDuration = " << explosionArea.effectDuration() << "\nchargeTypeId = " << explosionArea.chargeTypeId() << "\narea = " << explosionArea.area() << "\npartyId = " << explosionArea.partyId() << "\ncannonCount = " << explosionArea.cannonCount() << "\ncannonRounds = " << explosionArea.cannonRounds() << "\nfireRequestTime = " << explosionArea.fireRequestTime() << "\naltitude = " << explosionArea.altitude() << "\npurpose = " << explosionArea.purpose(); return result; } bool CentralAesByteReader::getExplosionSingle(size_t &pos, AreaEffectSimulation::ExplosionSingleModifyRequest &explosionSingle) const { bool result = getAesItemId(pos, explosionSingle.id()); result &= getName(pos, explosionSingle.name()); result &= getOptionalNumber(pos, explosionSingle.effectStart(), &CentralAesByteReader::getEffectStart); result &= getChargeTypeId(pos, explosionSingle.chargeTypeId()); result &= getImpactPosition(pos, explosionSingle.impactPosition()); result &= getOptionalNumber(pos, explosionSingle.partyId(), &CentralAesByteReader::getPartyId); result &= getFireRequestTime(pos, explosionSingle.fireRequestTime()); result &= getAltitude(pos, explosionSingle.altitude()); result &= getPurpose(pos, explosionSingle.purpose()); DEBUG_LOG(m_logger) << "Got ExplosionSingle:" << "\nid = " << explosionSingle.id() << "\nname = " << explosionSingle.name() << "\neffectStart = " << explosionSingle.effectStart() << "\nchargeTypeId = " << explosionSingle.chargeTypeId() << "\nimpactPosition = " << explosionSingle.impactPosition() << "\npartyId = " << explosionSingle.partyId() << "\nfireRequestTime = " << explosionSingle.fireRequestTime() << "\naltitude = " << explosionSingle.altitude() << "\npurpose = " << explosionSingle.purpose(); return result; } bool CentralAesByteReader::getMineArea(size_t &pos, AreaEffectSimulation::MineAreaModifyRequest &mineArea) const { bool result = getAesItemId(pos, mineArea.id()); result &= getName(pos, mineArea.name()); result &= getOptionalNumber(pos, mineArea.effectStart(), &CentralAesByteReader::getEffectStart); result &= getEffectDuration(pos, mineArea.effectDuration()); result &= getDensity(pos, mineArea.density()); result &= getWidth(pos, mineArea.width()); result &= getChargeTypeId(pos, mineArea.chargeStruct().chargeTypeId()); result &= getOptionalNumber(pos, mineArea.partyId(), &CentralAesByteReader::getPartyId); result &= getAesMaLayingProcedureType(pos, mineArea.layingProcedureType()); result &= getIsLayedHidden(pos, mineArea.isLaidHidden()); result &= getIsCenterLine(pos, mineArea.isCenterLine()); result &= getSegments(pos, mineArea.segments()); DEBUG_LOG(m_logger) << "Got MineArea:" << "\nid = " << mineArea.id() << "\nname = " << mineArea.name() << "\neffectStart = " << mineArea.effectStart() << "\neffectDuration = " << mineArea.effectDuration() << "\ndensity = " << mineArea.density() << "\nwidth = " << mineArea.width() << "\nchargeTypeId = " << mineArea.chargeStruct().chargeTypeId() << "\npartyId = " << mineArea.partyId() << "\nlayingProcedureType = " << mineArea.layingProcedureType() << "\nisLaidHidden = " << mineArea.isLaidHidden() << "\nisCenterLine = " << mineArea.isCenterLine() << "\nsegments.size = " << mineArea.segments().size(); return result; } bool CentralAesByteReader::getFunctionalArea(size_t &pos, AreaEffectSimulation::FunctionalAreaModifyRequest &functionalArea) const { bool result = getAesItemId(pos, functionalArea.id()); result &= getName(pos, functionalArea.name()); result &= getOptionalNumber(pos, functionalArea.effectStart(), &CentralAesByteReader::getEffectStart); result &= getEffectDuration(pos, functionalArea.effectDuration()); result &= getChargeTypeId(pos, functionalArea.chargeTypeId()); result &= getArea(pos, functionalArea.area()); result &= getOptionalNumber(pos, functionalArea.partyId(), &CentralAesByteReader::getPartyId); std::string pointSymbol; result &= getPointSymbol(pos, pointSymbol); if (pointSymbol != std::string()) functionalArea.pointSymbol().set(pointSymbol); result &= getFunctionalAreaTypeId(pos, functionalArea.functionalAreaTypeId()); result &= getDeconMode(pos, functionalArea.deconMode()); result &= getDeconTime(pos, functionalArea.deconTime()); result &= getMaintMode(pos, functionalArea.maintMode()); result &= getMaintTime(pos, functionalArea.maintTime()); result &= getMedicMode(pos, functionalArea.medicMode()); result &= getMedicTime(pos, functionalArea.medicTime()); DEBUG_LOG(m_logger) << "Got MineArea:" << "\nid = " << functionalArea.id() << "\nname = " << functionalArea.name() << "\neffectStart = " << functionalArea.effectStart() << "\neffectDuration = " << functionalArea.effectDuration() << "\nchargeTypeId = " << functionalArea.chargeTypeId() << "\narea = " << functionalArea.area() << "\npartyId = " << functionalArea.partyId() << "\npointSymbol = " << functionalArea.pointSymbol() << "\nfunctionalAreaTypeId = " << functionalArea.functionalAreaTypeId() << "\ndeconMode = " << functionalArea.deconMode() << "\ndeconTime = " << functionalArea.deconTime() << "\nmaintMode = " << functionalArea.maintMode() << "\nmaintTime = " << functionalArea.maintTime() << "\nmedicMode = " << functionalArea.medicMode() << "\n medicTime= " << functionalArea.medicTime(); return result; } bool CentralAesByteReader::getBoobyTrap(size_t &pos, AreaEffectSimulation::BoobyTrapModifyRequest &boobyTrap) const { bool result = getAesItemId(pos, boobyTrap.id()); result &= getName(pos, boobyTrap.name()); result &= getEffectDuration(pos, boobyTrap.effectDuration()); result &= getChargeTypeId(pos, boobyTrap.chargeTypeId()); result &= getImpactPosition(pos, boobyTrap.impactPosition()); result &= getImpactRadius(pos, boobyTrap.impactRadius()); result &= getTriggerRadius(pos, boobyTrap.triggerRadius()); result &= getOptionalNumber(pos, boobyTrap.rotationAngle(), &CentralAesByteReader::getRotationAngle); result &= getOptionalNumber(pos, boobyTrap.centralAngle(), &CentralAesByteReader::getCentralAngle); result &= getOptionalNumber(pos, boobyTrap.effectStart(), &CentralAesByteReader::getEffectStart); result &= getOptionalNumber(pos, boobyTrap.partyId(), &CentralAesByteReader::getPartyId); DEBUG_LOG(m_logger) << "Got BoobyTrap:" << "\nid = " << boobyTrap.id() << "\nname = " << boobyTrap.name() << "\neffectDuration = " << boobyTrap.effectDuration() << "\nchargeTypeId = " << boobyTrap.chargeTypeId() << "\nimpactPosition = " << boobyTrap.impactPosition() << "\nimpactRadius = " << boobyTrap.impactRadius() << "\ntriggerRadius = " << boobyTrap.triggerRadius() << "\nrotationAngle = " << boobyTrap.rotationAngle() << "\ncentralAngle = " << boobyTrap.centralAngle() << "\neffectStart = " << boobyTrap.effectStart() << "\npartyId = " << boobyTrap.partyId(); return result; } bool CentralAesByteReader::getOffRouteMine(size_t &pos, AreaEffectSimulation::OffRouteMineModifyRequest &offRouteMine) const { bool result = getAesItemId(pos, offRouteMine.id()); result &= getName(pos, offRouteMine.name()); result &= getEffectDuration(pos, offRouteMine.effectDuration()); result &= getChargeTypeId(pos, offRouteMine.chargeTypeId()); result &= getArea(pos, offRouteMine.area()); result &= getOptionalNumber(pos, offRouteMine.impactRadius(), &CentralAesByteReader::getImpactRadius); result &= getOptionalNumber(pos, offRouteMine.effectStart(), &CentralAesByteReader::getEffectStart); result &= getOptionalNumber(pos, offRouteMine.partyId(), &CentralAesByteReader::getPartyId); DEBUG_LOG(m_logger) << "Got OffRouteMine: " << "\nid: " << offRouteMine.id() << "\nname = " << offRouteMine.name() << "\neffectDuration = " << offRouteMine.effectDuration() << "\nchargeTypeId = " << offRouteMine.chargeTypeId() << "\narea = " << offRouteMine.area() << "\nimpactRadius = " << offRouteMine.impactRadius() << "\neffectStart = " << offRouteMine.effectStart() << "\npartyId = " << offRouteMine.partyId(); return result; } bool CentralAesByteReader::getExplosionCluster(size_t &pos, AreaEffectSimulation::ExplosionClusterOcModifyRequest &explosionCluster) const { bool result = getAesItemId(pos, explosionCluster.id()); result &= getName(pos, explosionCluster.name()); result &= getEffectStart(pos, explosionCluster.effectStart()); result &= getEffectDuration(pos, explosionCluster.effectDuration()); result &= getArea(pos, explosionCluster.area()); result &= getMhpCount(pos, explosionCluster.mhpCount()); result &= getMhpRotation(pos, explosionCluster.mhpRotation()); result &= getImpactCount(pos, explosionCluster.impactCount()); result &= getChargeTypeId(pos, explosionCluster.chargeStruct().chargeTypeId()); result &= getPartyId(pos, explosionCluster.partyId()); DEBUG_LOG(m_logger) << "Got ExplosionCluster:" << "\nid: " << explosionCluster.id() << "\nname: " << explosionCluster.name() << "\neffectStart: " << explosionCluster.effectStart() << "\neffectDuration: " << explosionCluster.effectDuration() << "\narea: " << explosionCluster.area() << "\nmhpCount: " << explosionCluster.mhpCount() << "\nmhpRotation: " << explosionCluster.mhpRotation() << "\nimpactCount: " << explosionCluster.impactCount() << "\nchargeTypeId: " << explosionCluster.chargeStruct().chargeTypeId() << "\npartyId: " << explosionCluster.partyId(); return result; } bool CentralAesByteReader::getAesItemId(size_t &pos, int32_t &aesItemId) const { return LtsUtils::get4Byte(m_data, pos, aesItemId); } bool CentralAesByteReader::getAesMaLayingProcedureType(size_t &pos, AreaEffectSimulation::AesMaLayingProcedureType &aesMaLayingProcedureType) const { return getDdsEnumVal(pos, aesMaLayingProcedureType); } bool CentralAesByteReader::getAesType(size_t &pos, AreaEffectSimulation::AesType &aesType) const { return getDdsEnumVal(pos, aesType); } bool CentralAesByteReader::getAltitude(size_t &pos, int32_t &altitude) const { return LtsUtils::get4Byte(m_data, pos, altitude); } bool CentralAesByteReader::getArea(size_t &pos, AreaEffectSimulation::Area &area) const { bool result = getPosition2D(pos, area.cornerBottomLeft()); result &= LtsUtils::get8Byte(m_data, pos, area.width()); result &= LtsUtils::get8Byte(m_data, pos, area.height()); result &= LtsUtils::get8Byte(m_data, pos, area.rotation()); return result; } bool CentralAesByteReader::getBorderLengthInner(size_t &pos, double &borderLengthInner) const { return LtsUtils::get8Byte(m_data, pos, borderLengthInner); } bool CentralAesByteReader::getBorderLengthOuter(size_t &pos, double &borderLengthOuter) const { return LtsUtils::get8Byte(m_data, pos, borderLengthOuter); } bool CentralAesByteReader::getCannonCount(size_t &pos, int32_t &cannonCount) const { return LtsUtils::get4Byte(m_data, pos, cannonCount); } bool CentralAesByteReader::getCannonRounds(size_t &pos, int32_t &cannonRounds) const { return LtsUtils::get4Byte(m_data, pos, cannonRounds); } bool CentralAesByteReader::getChargeTypeId(size_t &pos, int32_t &chargeType) const { return LtsUtils::get4Byte(m_data, pos, chargeType); } bool CentralAesByteReader::getCentralAesChangeType(size_t &pos, OcSituation::CentralAesChangeType &changeType) const { return LtsUtils::get1Byte(m_data, pos, changeType); } bool CentralAesByteReader::getCentralAngle(size_t &pos, double ¢ralAngle) const { return LtsUtils::get8Byte(m_data, pos, centralAngle); } template bool CentralAesByteReader::getDdsEnumVal(size_t &pos, T &ddsEnumVal) const { int32_t tempVal; bool result = LtsUtils::get4Byte(m_data, pos, tempVal); ddsEnumVal = static_cast(tempVal); return result; } bool CentralAesByteReader::getDeconMode(size_t &pos, AreaEffectSimulation::AesOperatingMode &deconMode) const { return getDdsEnumVal(pos, deconMode); } bool CentralAesByteReader::getDeconTime(size_t &pos, int32_t &deconTime) const { return LtsUtils::get4Byte(m_data, pos, deconTime); } bool CentralAesByteReader::getDensity(size_t &pos, double &density) const { return LtsUtils::get8Byte(m_data, pos, density); } bool CentralAesByteReader::getDetonationValue(size_t &pos, double &detonationValue) const { return LtsUtils::get8Byte(m_data, pos, detonationValue); } bool CentralAesByteReader::getEffectDuration(size_t &pos, int32_t &effectDuration) const { return LtsUtils::get4Byte(m_data, pos, effectDuration); } bool CentralAesByteReader::getEffectStart(size_t &pos, rti::core::int64 &effectStart) const { return LtsUtils::get8Byte(m_data, pos, effectStart); } bool CentralAesByteReader::getExplosionGeometry(size_t &pos, AreaEffectSimulation::AesExplosionGeometry &explosionGeometry) const { return getDdsEnumVal(pos, explosionGeometry); } bool CentralAesByteReader::getFireRequestTime(size_t &pos, rti::core::int64 &fireRequestTime) const { return LtsUtils::get8Byte(m_data, pos, fireRequestTime); } bool CentralAesByteReader::getFunctionalAreaTypeId(size_t &pos, int32_t &functionalAreaTypeId) const { return LtsUtils::get4Byte(m_data, pos, functionalAreaTypeId); } bool CentralAesByteReader::getIgniterType(size_t &pos, int32_t igniterTypeId) const { return LtsUtils::get4Byte(m_data, pos, igniterTypeId); } bool CentralAesByteReader::getImpactCount(size_t &pos, int32_t &impactCount) const { return LtsUtils::get4Byte(m_data, pos, impactCount); } bool CentralAesByteReader::getImpactPosition(size_t &pos, Core::GeoPosition2D &position) const { return getPosition2D(pos, position); } bool CentralAesByteReader::getImpactRadius(size_t &pos, double &impactRadius) const { return LtsUtils::get8Byte(m_data, pos, impactRadius); } bool CentralAesByteReader::getIsCenterLine(size_t &pos, bool &isCenterLine) const { return LtsUtils::get1Byte(m_data, pos, isCenterLine); } bool CentralAesByteReader::getIsLayedHidden(size_t &pos, bool &isLayedHidden) const { return LtsUtils::get1Byte(m_data, pos, isLayedHidden); } bool CentralAesByteReader::getMaintMode(size_t &pos, AreaEffectSimulation::AesOperatingMode &maintMode) const { return getDdsEnumVal(pos, maintMode); } bool CentralAesByteReader::getMaintTime(size_t &pos, int32_t &maintTime) const { return LtsUtils::get4Byte(m_data, pos, maintTime); } bool CentralAesByteReader::getMedicMode(size_t &pos, AreaEffectSimulation::AesOperatingMode &medicMode) const { return getDdsEnumVal(pos, medicMode); } bool CentralAesByteReader::getMedicTime(size_t &pos, int32_t &medicTime) const { return LtsUtils::get4Byte(m_data, pos, medicTime); } bool CentralAesByteReader::getMhpCount(size_t &pos, int32_t &mhpCount) const { return LtsUtils::get4Byte(m_data, pos, mhpCount); } bool CentralAesByteReader::getMhpRotation(size_t &pos, double &mhpRotation) const { return LtsUtils::get8Byte(m_data, pos, mhpRotation); } bool CentralAesByteReader::getName(size_t &pos, std::string &name) const { return getString(pos, name); } template bool CentralAesByteReader::getOptionalNumber(size_t &pos, rti::core::optional &optionalNumber, bool(CentralAesByteReader::*method)(size_t &pos, T &number) const) const { T value; bool result = (*this.*method)(pos, value); if (value != -1) optionalNumber.set(value); return result; } bool CentralAesByteReader::getPartyId(size_t &pos, int32_t &partyId) const { return LtsUtils::get4Byte(m_data, pos, partyId); } bool CentralAesByteReader::getPointSymbol(size_t &pos, std::string &pointSymbol) const { return getString(pos, pointSymbol); } bool CentralAesByteReader::getPosition2D(size_t &pos, Core::GeoPosition2D &position) const { bool result = LtsUtils::get8Byte(m_data, pos, position.lon()); result &= LtsUtils::get8Byte(m_data, pos, position.lat()); return result; } bool CentralAesByteReader::getPropagationDirection(size_t &pos, double &propagationDirection) const { return LtsUtils::get8Byte(m_data, pos, propagationDirection); } bool CentralAesByteReader::getPurpose(size_t &pos, std::string &purpose) const { return getString(pos, purpose); } bool CentralAesByteReader::getRotationAngle(size_t &pos, double &rotationAngle) const { return LtsUtils::get8Byte(m_data, pos, rotationAngle); } bool CentralAesByteReader::getSegments(size_t &pos, std::vector &segments) const { int tmp; bool result = LtsUtils::get1Byte(m_data, pos, tmp); size_t len = tmp; if (len < 1) return result; Core::GeoPosition2D geoPos; for (size_t counter = 0; counter < len; ++counter) { result &= getPosition2D(pos, geoPos); segments.push_back(geoPos); } return result; } bool CentralAesByteReader::getSpanAngle(size_t &pos, double &spanAngle) const { return LtsUtils::get8Byte(m_data, pos, spanAngle); } bool CentralAesByteReader::getString(size_t &pos, std::string &str) const { int tmp; bool result = LtsUtils::get1Byte(m_data, pos, tmp); size_t len = tmp; if (static_cast(m_data.size()) < (pos + len)) result = false; if (result) str = m_data.mid(pos, len).toStdString(); pos += len; return result; } bool CentralAesByteReader::getTriggerRadius(size_t &pos, double &triggerRadius) const { return LtsUtils::get8Byte(m_data, pos, triggerRadius); } bool CentralAesByteReader::getWidth(size_t &pos, double &width) const { return LtsUtils::get8Byte(m_data, pos, width); } bool CentralAesByteReader::getWindSpeed(size_t &pos, double &windSpeed) const { return LtsUtils::get8Byte(m_data, pos, windSpeed); } } // namespace OcSituationClient