1
0
Fork 0

Fix crash on METAR without cloud coverage set

As suggested by Scott, when a layer has no coverage set,
use the coverage of preceeding layer (lower down, closer to
the ground)

SF-ID: https://sourceforge.net/p/flightgear/codetickets/2765/
This commit is contained in:
James Turner 2022-10-06 09:05:37 +01:00
parent a7d13e0736
commit 86f82994be

View file

@ -358,6 +358,11 @@ void MetarProperties::setMetar( SGSharedPtr<FGMetar> m )
bool setGroundCloudLayer = _rootNode->getBoolValue("set-ground-cloud-layer", false ) && bool setGroundCloudLayer = _rootNode->getBoolValue("set-ground-cloud-layer", false ) &&
!fgGetBool("/sim/rendering/clouds3d-enable", false); !fgGetBool("/sim/rendering/clouds3d-enable", false);
// track the coverage of the previous layer, so we can use it
// for higher layers which don't have coverage set
// see: https://sourceforge.net/p/flightgear/codetickets/2765/
SGMetarCloud::Coverage coverageBelow = SGMetarCloud::COVERAGE_NIL;
if( setGroundCloudLayer ) { if( setGroundCloudLayer ) {
// create a cloud layer #0 starting at the ground if its fog, mist or haze // create a cloud layer #0 starting at the ground if its fog, mist or haze
@ -406,22 +411,30 @@ void MetarProperties::setMetar( SGSharedPtr<FGMetar> m )
_min_visibility = _max_visibility = _min_visibility = _max_visibility =
fgGetDouble("/environment/params/fog-mist-haze-layer/visibility-above-layer-m",20000.0); // assume good visibility above the fog fgGetDouble("/environment/params/fog-mist-haze-layer/visibility-above-layer-m",20000.0); // assume good visibility above the fog
layerOffset = 1; // shudder layerOffset = 1; // shudder
coverageBelow = coverage;
} }
} }
for( unsigned i = 0; i < 5-layerOffset; i++ ) { for( unsigned i = 0; i < 5-layerOffset; i++ ) {
SGPropertyNode_ptr layerNode = cloudsNode->getChild(LAYER, i+layerOffset, true ); SGPropertyNode_ptr layerNode = cloudsNode->getChild(LAYER, i+layerOffset, true );
SGMetarCloud::Coverage coverage = i < metarClouds.size() ? metarClouds[i].getCoverage() : SGMetarCloud::COVERAGE_CLEAR; SGMetarCloud::Coverage coverage = i < metarClouds.size() ? metarClouds[i].getCoverage() : SGMetarCloud::COVERAGE_CLEAR;
if (coverage == SGMetarCloud::COVERAGE_NIL) {
coverage = coverageBelow; // invalid coverage, use value of layer below
} else {
coverageBelow = coverage; // valid coverage, save for future layers
}
if (coverage == SGMetarCloud::COVERAGE_NIL) {
SG_LOG(SG_ENVIRONMENT, SG_WARN, "METAR: skipping cloud layer " << i << " becuase no coverage is set");
continue;
}
double elevation = double elevation =
i >= metarClouds.size() || coverage == SGMetarCloud::COVERAGE_CLEAR ? i >= metarClouds.size() || coverage == SGMetarCloud::COVERAGE_CLEAR ?
-9999.0 : -9999.0 :
metarClouds[i].getAltitude_ft() + _station_elevation; metarClouds[i].getAltitude_ft() + _station_elevation;
// crash https://sourceforge.net/p/flightgear/codetickets/2765/
if (coverage >= coverage_string.size()) {
throw sg_range_exception("Invalid cloud coverage value:" + to_string(coverage));
}
layerNode->setDoubleValue( "alpha", 1.0 ); layerNode->setDoubleValue( "alpha", 1.0 );
layerNode->setStringValue( "coverage", coverage_string[coverage] ); layerNode->setStringValue( "coverage", coverage_string[coverage] );
layerNode->setDoubleValue( "coverage-type", SGCloudLayer::getCoverageType(coverage_string[coverage]) ); layerNode->setDoubleValue( "coverage-type", SGCloudLayer::getCoverageType(coverage_string[coverage]) );