GEOG 863:
Web Application Development for Geospatial Professionals

2.3.2 Deriving the Impact and Restoration values


2.3.2 Deriving the Impact and Restoration values

Recall from the scenario that one of the ratings that contributes to a Species_HMZ record’s priority score is the Impact_Value ("regular bad" or "super bad"), which is dependent on which species is present and what type of habitat it’s invading (Mature Forest, Wetland, etc.).  The application could be built with the expectation that the staffer would look up the impact value and enter it manually, but that lookup can be handled automatically with another calculated expression since we have the data needed in the Impact table.  For example, looking in that table, we can see that the garlic mustard species in the Wetlands habitat type has an impact value of 1 (super bad). 

Hopefully you’re already thinking through the steps that are required for this calculation.  As in the previous one, we’ll want to obtain a reference to the associated HMZ feature.  We can then get the value from the Type field.  Another data point we’ll need is which species we’re dealing with.  That we can access through the $feature variable.  Having those two data points, we can query the Impact table to get the impact value associated with that species+habitat type combination.  We’ll get to the Impact table through the $datastore variable. 

One wrinkle involved in this query is that the Impact lookup table has been populated such that it contains only those species+habitat type combinations that have an impact value of 1 (the "super bad" ones).  Thus, if a species+habitat type combination cannot be found in the table, it can be assumed that the impact value is 0 (i.e., that it’s a "regular bad" situation).   

  1. Back in Field Maps, pull up the Species_HMZ form again.
  2. Click to select the Impact_Value field.
  3. Create a new Calculated expression for that field.  (Note that the Calculated expressions area of the Properties panel will list all expressions you’ve written for this web map, not just for the field you currently have selected.)
  4. Copy and paste this expression (or type it manually, if you prefer):
    var species = $feature["Common_Name"]
    var hmz_guid = $feature["HMZ_GUID"]
    // remember your layer might not be called "HMZ" but
    // "ISMP Web Layer aaa123 - HMZ" so adjust it accordingly
    var hmz_lyr = FeatureSetByName($map, "HMZ")
    var hmz_qry = "GlobalID = '" + hmz_guid + "'"
    var feat_set = Filter(hmz_lyr, hmz_qry)
    var feat = First(feat_set)
    var habitat_type = feat["Type"]
    var impact_tbl = FeatureSetByName($datastore, "Impact")
    var impact_qry = "Habitat_Type = '" + habitat_type +
        "' and Common_Name = '" + species + "'"
    var impact_rows = Filter(impact_tbl, impact_qry)
    if (Count(impact_rows) == 0) {
        //no match on this species+habitat, so impact is 0 (regular bad)
        return 0
    } else {
        //there is a match on this species+habitat, let's get the impact value
        var impact_row = First(impact_rows)
        var impact_val = impact_row["Impact_Value"]
        return impact_val

    Hopefully you’re able to follow everything going on in this expression.  Here are a couple of points of clarification:
    - Based on the design decision to omit records where the impact value is 0, note the use of the Count function to determine whether the query on the Impact table found any rows.  The expression’s return value is set to 0 if a match is not found; otherwise, the return value is set to whatever is held in the Impact_Value field.  (This field only holds values of 1, so alternatively the expression could just be set to return 1 when the query finds a match, but explicitly retrieving the value has the advantage of offering flexibility in the event that the impact rating scale were to change from something other than just 0-1.)
    - The expression contains a couple of comments intended to clarify the logic involved.  These are the lines that begin with double slashes (//).

  5. Assign a name to the expression of getImpact, then close out of the expression editor and Save your changes to the web map.

  6. Return to the Field Maps app on your mobile device to test. (Remember to reload the map first.)

  7. Again, select the Campground Management Area, and add a new species. 

    When the Species_HMZ form first opens, you should see the Impact_Value field automatically take on a 0 - regular bad value because the species name has not been specified yet. 

  8. Choose a species found in the Impact table associated with the MF habitat type (wavyleaf basketgrass is one) and confirm that the Impact_Value field updates itself to 1 - super bad

  9. Cancel out of the edit once you’ve confirmed your expression is working as intended.

    Recall from the scenario that the restoration effort rating is another field on the form that is derived from other user-supplied values.  Specifically, it depends on the species in question and the extent of its infestation.  Unlike the calculation of the impact value, which required obtaining one value from the Species_HMZ form and another from the HMZ form, the values needed for the restoration calculation are both found in the Species_HMZ form.  So this expression will be a bit less complicated.

  10. Return to Field Maps in AGO and re-open the Species_HMZ form for editing.  

  11. Select the Restoration_Value field and open up the expression builder.

  12. Take a crack at writing the expression yourself. 

    As noted above, you’ll need the user-entered species name and extent rating.  You can then query the Restoration lookup table to get the restoration value associated with the species+extent combination.  Like the Impact lookup table, combinations that yield a 0 value have been omitted from the table.  Unlike it, however, the possible restoration values range from 0-3 rather than 0-1, so you would not have the option of assuming a value of 1 if a match for the species+extent combination is found.

    Code that completes the task can be found here:

    var species = $feature["Common_Name"]
    var ext = $feature["Extent_Value"]
    var rest_tbl = FeatureSetByName($datastore, "Restoration")
    var rest_qry = "Common_Name = '" + species +
        "' and Extent_Value = " + ext
    var rest_rows = Filter(rest_tbl, rest_qry)
    if (Count(rest_rows) == 0) {
        return 0
    } else {
        var rest_row = First(rest_rows)
        var rest_val = rest_row["Restoration_Value"]
        return rest_val

    We’ve now written expressions to automatically populate two of the important ratings fields, eliminating the need for a staffer to look them up manually. Recall that the ultimate purpose of populating those fields, and of the map itself, is to derive an overall remediation priority score. We’re now ready to build one last expression to carry out that calculation.

  13. In the Field Maps form designer, select the Priority field and open up the expression builder.

    Recall from the discussion earlier that the priority score is computed as the sum of the following five values:
    Stewardship and Outreach (from the HMZ table)
    Extent, Impact, and Restoration (from the Species_HMZ table).

  14. Using your expression building experience, see if you can come up with the code needed to populate the Priority field with the correct score.
    Code that completes the task can be found here:

    //Get the extent, impact, and restoration vals from the current Species_HMZ record
    var extent_val = $feature["Extent_Value"]
    var impact_val = $feature["Impact_Value"]
    var rest_val = $feature["Restoration_Value"]
    //Get the stewardship and outreach vals from the related HMZ record
    var hmz_guid = $feature["HMZ_GUID"]
    var hmz_lyr = FeatureSetByName($map, "HMZ")
    var feat_set = Filter(hmz_lyr, "GlobalID = '" + hmz_guid + "'")
    var feat = First(feat_set)
    var steward_val = feat["Stewardship"]
    var outreach_val = feat["Outreach"]
    //Sum and return the result
    var priority_val = steward_val + outreach_val + extent_val +
        impact_val + rest_val
    return priority_val
  15. Save the expression with a name of calcPriority.

  16. Save your changes to the Species_HMZ form.

  17. Return to the Field Maps app on your mobile device and go through the addition of a Species_HMZ row (woody vines, extent of 2, and butterfly bush, extent of 1, are other species found in the Campground Area).  Confirm that both the Restoration_Value and Priority fields are populated automatically.