ArcGIS Blog

Field Operations

ArcGIS Collector

Simplify weather measurements in the field using Arcade

By Doug Morgenthaler

Understanding current weather conditions is an important facet for many field activities.  Some, like temperature, are easy to collect in the field.  Others, like relative humidity, are more difficult to compute or estimate.  In this post you’ll learn how to use ArcGIS Arcade expressions to simplify these calculations.  In addition, you’ll be able to make this available in the field as well as the office so everyone has the latest key weather statistics.

Weather and wildfires

One field activity where weather has a direct impact is wildfire response. These measurements are an essential part in defining wildfire response plans, as well as a critical aspect of firefighter safety.  Firefighters collect weather measurements at different times and locations throughout the day using a belt weather kit. This information is critical element to understanding how weather may impact fire behavior.

One of the key attributes important to maintaining firefighter safety and wildfire response planning is relative humidity (RH).  Relative humidity provides important insight about the moisture in the air.  The combination of low relative humidity and high temperatures warn firefighters that high-risk weather conditions are present. Another factor in firefighter safety is the heat index. A high heat index is an indication of a heightened risk of heatstroke or heat exhaustion.

You can use Collector for ArcGIS to record the necessary information, and Arcade expressions to compute both relative humidity and heat index in the field.

Collecting measurements in the field

Three measurements are needed to calculate relative humidity:

  • Dry bulb temperature
  • Wet bulb temperature
  • Barometric pressure or elevation

Dry and wet bulb temperatures are collected in the field using a sling psychrometer.

Computing relative humidity (RH)

Once the temperature measurements are collected, typically firefighters determine the relative humidity by reading a chart like this one, based on their current elevation.

However, rather than utilizing the chart above, which is error prone and time consuming, we can simplify this using an Arcade expression to calculate relative humidity in the field.

The firefighter enters  the dry and wet bulb temperatures, and displays the resulting information on the map for key weather measurements.

Let’s look at the Arcade expressions used by Collector to calculate relative humidity.  In this case, the collected GPS location’s altitude is used to determine the barometric pressure.

View Arcade expression to calculate relative humidity

var dryBulbTemperature = $feature["drybulb_temperature"];
var wetBulbTemperature = $feature["wetbulb_temperature"];

var pt = Geometry($feature);
var altitude = pt.Z;


function BarometricPressure(T,h){

    var g = 9.80665; //gravitational acceleration
    var P0 = 101325; // pressure at sea level
    var M = 0.0289644; //molar mass of air
    var R = 8.31432; //universal gas constant
    
    //convert F to Kelvin
    var Tk = (T - 32) * 5/9 + 273.15;

    // calculate barometric pressure
    var P = (P0 * exp((-g * M * h) / (R * Tk))) / 100;
    return P;
}

//Relative Humidity using Wet (Tw) & Dry Bulb (Td) Temps
function RelativeHumidity(Td, Tw, h){
	
    var Tdk = (Td - 32) * 5/9;
    var Twk = (Tw - 32) * 5/9;
    
    var Es = 6.112 * exp((17.67 * Tdk)/(Tdk + 243.5));
    var Ew = 6.112 * exp((17.67 * Twk)/(Twk + 243.5));
    
    //get barometric pressure based on dry temp and altitude
    var Psta = BarometricPressure(Td,h);

    var E = Ew - Psta * (Tdk - Twk) * 0.00066 * 
        (1 + (0.00115 * Twk));
    
    // Relative Humidity
    var RH = (E / Es) * 100;
    
    return RH;
    //return Text(RH,'#') + '%';    
}

return (RelativeHumidity(dryBulbTemperature, 
    wetBulbTemperature, altitude));

Determining the heat index (HI)

We can easily compute the heat index from the weather measurements we’ve collected as well as relative humidity we calculated in the previous Arcade expression.

View Arcade expression to calculate heat index

// Calculate Heat Index using temperature (T) 
// and relative humidity (RH)
function HeatIndex(T, RH){
    //Rothsfusz
    var heatIndex = -42.379 + 2.04901523 * T + 10.14333127 * RH - 
        0.22475541 * T* RH - 0.00683783 * T * T - 0.05481717 * RH * RH + 
        0.00122874 * T * T * RH + 0.00085282 * T * RH * RH - 
        0.00000199 * T * T * RH * RH;
    
    if (T >= 80 && T <= 112 && RH < 13) {
      var HIadjustment = ((13 - RH) / 4) * 
        Sqrt((17 - Abs(T - 95)) / 17);
      heatIndex += HIadjustment;
    }
    
    if (T >= 80 && T <= 87 && RH > 85) {
      var HIadjustment = ((RH - 85) / 10) * ((87 - T) / 5);
      heatIndex += HIadjustment;
    
    }

    Console('Heat Index: ', round(heatIndex,0));

    if (heatIndex < 80) {
        // Use simple
        var heatIndex = 0.5 * (T + 61.0 + ((T - 68.0) * 1.2) + 
        (RH * 0.094));
}

    return round(heatIndex,0);
}
return HeatIndex(dryBulbTemperature,RelativeHumidity(
    dryBulbTemperature,wetBulbTemperature,altitude));

Putting it all together

We can use these expressions in a variety of ways to make this information immediately available to the firefighter in the field.  Let’s put these two expressions into a label expression that can provide immediate visibility. In this case we’ll just use a custom expression with the two values stacked.

View Arcade expression for labeling observations with relative humidity and heat index

var dryBulbTemperature = $feature["drybulb_temperature"];
var wetBulbTemperature = $feature["wetbulb_temperature"];

var pt = Geometry($feature);
var altitude = pt.Z;

function BarometricPressure(T,h){

    var g = 9.80665; //gravitational acceleration
    var P0 = 101325; // pressure at sea level
    var M = 0.0289644; //molar mass of air
    var R = 8.31432; //universal gas constant
    
    //convert F to Kelvin
    var Tk = (T - 32) * 5/9 + 273.15;

    // calculate barometric pressure
    var P = (P0 * exp((-g * M * h) / (R * Tk))) / 100;
    return P;
}

//Relative Humidity using Wet (Tw) & Dry Bulb (Td) Temps
function RelativeHumidity(Td, Tw, h){
	
    var Tdk = (Td - 32) * 5/9;
    var Twk = (Tw - 32) * 5/9;
    
    var Es = 6.112 * exp((17.67 * Tdk)/(Tdk + 243.5));
    var Ew = 6.112 * exp((17.67 * Twk)/(Twk + 243.5));
    
    //get barometric pressure based on dry temp and altitude
    var Psta = BarometricPressure(Td,h);

    var E = Ew - Psta * (Tdk - Twk) * 0.00066 * 
        (1 + (0.00115 * Twk));
    
    // Relative Humidity
    var RH = round((E / Es) * 100,0);
    
    return RH;
}

// Calculate Heat Index using temperature (T) 
// and relative humidity (RH)
function HeatIndex(T, RH){
    //Rothsfusz
    var heatIndex = -42.379 + 2.04901523 * T + 10.14333127 * RH - 
        0.22475541 * T* RH - 0.00683783 * T * T - 0.05481717 * RH * RH + 
        0.00122874 * T * T * RH + 0.00085282 * T * RH * RH - 
        0.00000199 * T * T * RH * RH;
    
    if (T >= 80 && T <= 112 && RH < 13) {
      var HIadjustment = ((13 - RH) / 4) * 
        Sqrt((17 - Abs(T - 95)) / 17);
      heatIndex += HIadjustment;
    }
    
    if (T >= 80 && T <= 87 && RH > 85) {
      var HIadjustment = ((RH - 85) / 10) * ((87 - T) / 5);
      heatIndex += HIadjustment;   
    }

    if (heatIndex < 80) {
        // Use simple
        var heatIndex = 0.5 * (T + 61.0 + ((T - 68.0) * 1.2) + 
        (RH * 0.094));
}

    return round(heatIndex,0);
}

var relativeHumidity = RelativeHumidity(dryBulbTemperature, 
    wetBulbTemperature, altitude);
var heatIndex = HeatIndex(dryBulbTemperature,relativeHumidity);

var result = Concatenate(["RH:" + relativeHumidity, 
    "HI:" + heatIndex],TextFormatting.NewLine);
return result;

Wrapping up

This is just one case of how you can simplify your mobile worker’s tasks and provide timely and accurate information, even while offline.  While this example highlights their use in wildfire response, weather measurements play a critical role in other industries such as agriculture or disease control.

Ready to incorporate these expressions in your own work?  Here’s a map that incorporates these expressions. In addition, these and other Arcade expressions are also available on Github.

Share this article