ArcGIS Pro 3.3 API Reference Guide
ArcGIS.Core.Arcade Namespace / ArcadeEvaluator Class / Evaluate Method
Supported types
Example

In This Topic
    Evaluate Method (ArcadeEvaluator)
    In This Topic
    Evaluates the expression given the profile variable set. This method must be called on the MCT. Use QueuedTask.Run.
    Syntax
    Exceptions
    ExceptionDescription
    Exception thrown when a profile variable is invalid
    Exception thrown when the expression evaluation has failed
    This method or property must be called within the lambda passed to QueuedTask.Run.
    Remarks
    The profile variables that can be used to evaluate a given expression are controlled by the selected ArcadeProfile used to create the evaluator. Refer to Arcade Profiles for a complete list of the supported profile variables for each arcade profile.
    Example
    Basic Query
    //Consult https://github.com/Esri/arcade-expressions/ and
    //https://developers.arcgis.com/arcade/ for more examples
    //and arcade reference
    
    QueuedTask.Run(() =>
    {
      //construct an expression
      var query = @"Count($layer)";//count of features in "layer"
    
      //construct a CIMExpressionInfo
      var arcade_expr = new CIMExpressionInfo()
      {
        Expression = query.ToString(),
        //Return type can be string, numeric, or default
        //When set to default, addin is responsible for determining
        //the return type
        ReturnType = ExpressionReturnType.Default
      };
    
      //Construct an evaluator
      //select the relevant profile - it must support Pro and it must
      //contain any profile variables you are using in your expression.
      //Consult: https://developers.arcgis.com/arcade/profiles/
      using (var arcade = ArcadeScriptEngine.Instance.CreateEvaluator(
                              arcade_expr, ArcadeProfile.Popups))
      {
        //Provision  values for any profile variables referenced...
        //in our case '$layer'
        var variables = new List<KeyValuePair<string, object>>() {
            new KeyValuePair<string, object>("$layer", featLayer)
          };
        //evaluate the expression
        try
        {
          var result = arcade.Evaluate(variables).GetResult();
          System.Diagnostics.Debug.WriteLine($"Result: {result.ToString()}");
        }
        //handle any exceptions
        catch (InvalidProfileVariableException ipe)
        {
          //something wrong with the profile variable specified
          //TODO...
        }
        catch (EvaluationException ee)
        {
          //something wrong with the query evaluation
          //TODO...
        }
    
      }
    });
    
    Basic Query using Features
    //Consult https://github.com/Esri/arcade-expressions/ and
    //https://developers.arcgis.com/arcade/ for more examples
    //and arcade reference
    
    QueuedTask.Run(() =>
    {
      //construct an expression
      var query = @"$feature.AreaInAcres * 43560.0";//convert acres to ft 2
    
      //construct a CIMExpressionInfo
      var arcade_expr = new CIMExpressionInfo()
      {
        Expression = query.ToString(),
        //Return type can be string, numeric, or default
        //When set to default, addin is responsible for determining
        //the return type
        ReturnType = ExpressionReturnType.Default
      };
    
      //Construct an evaluator
      //select the relevant profile - it must support Pro and it must
      //contain any profile variables you are using in your expression.
      //Consult: https://developers.arcgis.com/arcade/profiles/
      using (var arcade = ArcadeScriptEngine.Instance.CreateEvaluator(
                              arcade_expr, ArcadeProfile.Popups))
      {
        //we are evaluating the expression against all features
        using (var rc = featLayer.Search())
        {
    
          while (rc.MoveNext())
          {
            //Provision  values for any profile variables referenced...
            //in our case '$feature'
            var variables = new List<KeyValuePair<string, object>>() {
              new KeyValuePair<string, object>("$feature", rc.Current)
            };
            //evaluate the expression (per feature in this case)
            try
            {
              var result = arcade.Evaluate(variables).GetResult();
              var val = ((double)result).ToString("0.0#");
              System.Diagnostics.Debug.WriteLine(
                $"{rc.Current.GetObjectID()} area: {val} ft2");
            }
            //handle any exceptions
            catch (InvalidProfileVariableException ipe)
            {
              //something wrong with the profile variable specified
              //TODO...
            }
            catch (EvaluationException ee)
            {
              //something wrong with the query evaluation
              //TODO...
            }
          }
        }
      }
    });
    
    Retrieve features using FeatureSetByName
    //Consult https://github.com/Esri/arcade-expressions/ and
    //https://developers.arcgis.com/arcade/ for more examples
    //and arcade reference
    
    var map = MapView.Active.Map;
    QueuedTask.Run(() =>
    {
      //construct a query
      var query = new StringBuilder();
      var layer_name = "USA Current Wildfires - Current Incidents";
      //https://developers.arcgis.com/arcade/function-reference/featureset_functions/
      query.AppendLine(
        $"var features = FeatureSetByName($map,'{layer_name}', ['*'], false);");
      query.AppendLine("return Count(features);");
    
      //construct a CIMExpressionInfo
      var arcade_expr = new CIMExpressionInfo()
      {
        Expression = query.ToString(),
        //Return type can be string, numeric, or default
        //When set to default, addin is responsible for determining
        //the return type
        ReturnType = ExpressionReturnType.Default
      };
    
      //Construct an evaluator
      //select the relevant profile - it must support Pro and it must
      //contain any profile variables you are using in your expression.
      //Consult: https://developers.arcgis.com/arcade/profiles/
      using (var arcade = ArcadeScriptEngine.Instance.CreateEvaluator(
                              arcade_expr, ArcadeProfile.Popups))
      {
        //Provision  values for any profile variables referenced...
        //in our case '$map'
        var variables = new List<KeyValuePair<string, object>>() {
            new KeyValuePair<string, object>("$map", map)
          };
        //evaluate the expression
        try
        {
          var result = arcade.Evaluate(variables).GetResult();
          System.Diagnostics.Debug.WriteLine($"Result: {result.ToString()}");
        }
        //handle any exceptions
        catch (InvalidProfileVariableException ipe)
        {
          //something wrong with the profile variable specified
          //TODO...
        }
        catch (EvaluationException ee)
        {
          //something wrong with the query evaluation
          //TODO...
        }
      }
    });
    
    Retrieve features using Filter
    //Consult https://github.com/Esri/arcade-expressions/ and
    //https://developers.arcgis.com/arcade/ for more examples
    //and arcade reference
    
    QueuedTask.Run(() =>
    {
      //construct a query
      var query = new StringBuilder();
      //https://developers.arcgis.com/arcade/function-reference/featureset_functions/
      query.AppendLine(
        "var features = Filter($layer, 'DailyAcres is not NULL');");
      query.AppendLine("return Count(features);");
    
      //construct a CIMExpressionInfo
      var arcade_expr = new CIMExpressionInfo()
      {
        Expression = query.ToString(),
        //Return type can be string, numeric, or default
        //When set to default, addin is responsible for determining
        //the return type
        ReturnType = ExpressionReturnType.Default
      };
    
      //Construct an evaluator
      //select the relevant profile - it must support Pro and it must
      //contain any profile variables you are using in your expression.
      //Consult: https://developers.arcgis.com/arcade/profiles/
      using (var arcade = ArcadeScriptEngine.Instance.CreateEvaluator(
                              arcade_expr, ArcadeProfile.Popups))
      {
        //Provision  values for any profile variables referenced...
        //in our case '$layer'
        var variables = new List<KeyValuePair<string, object>>() {
            new KeyValuePair<string, object>("$layer", featLayer)
          };
        //evaluate the expression
        try
        {
          var result = arcade.Evaluate(variables).GetResult();
          System.Diagnostics.Debug.WriteLine($"Result: {result.ToString()}");
        }
        //handle any exceptions
        catch (InvalidProfileVariableException ipe)
        {
          //something wrong with the profile variable specified
          //TODO...
        }
        catch (EvaluationException ee)
        {
          //something wrong with the query evaluation
          //TODO...
        }
      }
    });
    
    Calculate basic statistics with Math functions
    //Consult https://github.com/Esri/arcade-expressions/ and
    //https://developers.arcgis.com/arcade/ for more examples
    //and arcade reference
    
    QueuedTask.Run(() =>
    {
      //construct a query
      var query = new StringBuilder();
      //https://developers.arcgis.com/arcade/function-reference/math_functions
    
      query.AppendLine("var features = Filter($layer, 'DailyAcres is not NULL');");
    
      query.AppendLine("var count_feat = Count(features);");
      query.AppendLine("var sum_feat = Sum(features, 'DailyAcres');");
      query.AppendLine("var max_feat = Max(features, 'DailyAcres');");
      query.AppendLine("var min_feat = Min(features, 'DailyAcres');");
      query.AppendLine("var avg_feat = Average(features, 'DailyAcres');");
    
      query.AppendLine("var answer = [count_feat, sum_feat, max_feat, min_feat, avg_feat]");
      query.AppendLine("return Concatenate(answer,'|');");
    
      //construct a CIMExpressionInfo
      var arcade_expr = new CIMExpressionInfo()
      {
        Expression = query.ToString(),
        //Return type can be string, numeric, or default
        //When set to default, addin is responsible for determining
        //the return type
        ReturnType = ExpressionReturnType.Default
      };
    
      //Construct an evaluator
      //select the relevant profile - it must support Pro and it must
      //contain any profile variables you are using in your expression.
      //Consult: https://developers.arcgis.com/arcade/profiles/
      using (var arcade = ArcadeScriptEngine.Instance.CreateEvaluator(
                              arcade_expr, ArcadeProfile.Popups))
      {
        //Provision  values for any profile variables referenced...
        //in our case '$layer'
        var variables = new List<KeyValuePair<string, object>>() {
            new KeyValuePair<string, object>("$layer", featLayer)
          };
        //evaluate the expression
        try
        {
          var result = arcade.Evaluate(variables).GetResult();
          System.Diagnostics.Debug.WriteLine($"Result: {result.ToString()}");
        }
        //handle any exceptions
        catch (InvalidProfileVariableException ipe)
        {
          //something wrong with the profile variable specified
          //TODO...
        }
        catch (EvaluationException ee)
        {
          //something wrong with the query evaluation
          //TODO...
        }
      }
    });
    
    Using FeatureSet functions Filter and Intersects
    //Consult https://github.com/Esri/arcade-expressions/ and
    //https://developers.arcgis.com/arcade/ for more examples
    //and arcade reference
    
    var map = MapView.Active.Map;
    QueuedTask.Run(() =>
    {
      //construct a query
      var query = new StringBuilder();
      //https://developers.arcgis.com/arcade/function-reference/featureset_functions/
    
      //Assume we have two layers - Oregon Counties (poly) and Crimes (points). Crimes
      //is from the Pro SDK community sample data.
      //Select all crime points within the relevant county boundaries and sum the count
      query.AppendLine("var results = [];");
    
      query.AppendLine("var counties = FeatureSetByName($map, 'Oregon_Counties', ['*'], true);");
    
      //'Clackamas','Multnomah','Washington'
      query.AppendLine("var sel_counties = Filter(counties, 'DHS_Districts IN (2, 15, 16)');");
    
      query.AppendLine("for(var county in sel_counties) {");
      query.AppendLine("   var name = county.County_Name;");
      query.AppendLine("   var cnt_crime = Count(Intersects($layer, Geometry(county)));");
      query.AppendLine("   Insert(results, 0, cnt_crime);");
      query.AppendLine("   Insert(results, 0, name);");
      query.AppendLine("}");
    
      query.AppendLine("return Concatenate(results,'|');");
    
      //construct a CIMExpressionInfo
      var arcade_expr = new CIMExpressionInfo()
      {
        Expression = query.ToString(),
        //Return type can be string, numeric, or default
        //When set to default, addin is responsible for determining
        //the return type
        ReturnType = ExpressionReturnType.Default
      };
    
      //Construct an evaluator
      //select the relevant profile - it must support Pro and it must
      //contain any profile variables you are using in your expression.
      //Consult: https://developers.arcgis.com/arcade/profiles/
      using (var arcade = ArcadeScriptEngine.Instance.CreateEvaluator(
                              arcade_expr, ArcadeProfile.Popups))
      {
        //Provision  values for any profile variables referenced...
        //in our case '$layer' and '$map'
        var variables = new List<KeyValuePair<string, object>>() {
            new KeyValuePair<string, object>("$layer", crimes_layer),
            new KeyValuePair<string, object>("$map", map)
          };
        //evaluate the expression
        try
        {
          var result = arcade.Evaluate(variables).GetResult();
    
          var results = result.ToString().Split('|', StringSplitOptions.None);
          var entries = results.Length / 2;
          int i = 0;
          for (var e = 0; e < entries; e++)
          {
            var name = results[i++];
            var count = results[i++];
            System.Diagnostics.Debug.WriteLine($"'{name}' crime count: {count}");
          }
        }
        //handle any exceptions
        catch (InvalidProfileVariableException ipe)
        {
          //something wrong with the profile variable specified
          //TODO...
        }
        catch (EvaluationException ee)
        {
          //something wrong with the query evaluation
          //TODO...
        }
      }
    });
    
    Evaluating an Arcade Labelling Expression
    //Consult https://github.com/Esri/arcade-expressions/ and
    //https://developers.arcgis.com/arcade/ for more examples
    //and arcade reference
    
    var map = MapView.Active.Map;
    QueuedTask.Run(() =>
    {
      //Assume we a layer - Oregon County (poly) that has an arcade labelling
      //expression and we want to evaluate that interactively...
      var def = oregon_cnts.GetDefinition() as CIMFeatureLayer;
      //Get the label class
      var label_class = def.LabelClasses
                         .FirstOrDefault(lc => {
                           return lc.Name == "Arcade_Example_1" &&
                                  lc.ExpressionEngine == LabelExpressionEngine.Arcade;
                         });
      if (label_class == null)
        return;
    
      //evaluate the label expression against the features
      var expr_info = new CIMExpressionInfo()
      {
        Expression = label_class.Expression,
        ReturnType = ExpressionReturnType.String
      };
    
      //https://developers.arcgis.com/arcade/profiles/labeling/
      using (var arcade = ArcadeScriptEngine.Instance.CreateEvaluator(
                                                expr_info, ArcadeProfile.Labeling))
      {
        //loop through the features
        using (var rc = oregon_cnts.Search())
        {
          while (rc.MoveNext())
          {
            var variables = new List<KeyValuePair<string, object>>() {
              new KeyValuePair<string, object>("$feature", rc.Current)
            };
            var result = arcade.Evaluate(variables).GetResult();
            //output
            System.Diagnostics.Debug.WriteLine(
               $"[{rc.Current.GetObjectID()}]: {result}");
          }
        }
      }
    });
    
    Evaluating Arcade Visual Variable Expressions on a Renderer
    //Consult https://github.com/Esri/arcade-expressions/ and
    //https://developers.arcgis.com/arcade/ for more examples
    //and arcade reference
    
    var mv = MapView.Active;
    var map = mv.Map;
    
    QueuedTask.Run(() =>
    {
      //Assume we a layer - Oregon County (poly) that is using Visual Variable
      //expressions that we want to evaluate interactively...
      var def = oregon_cnts.GetDefinition() as CIMFeatureLayer;
    
      //Most all feature renderers have a VisualVariable collection
      var renderer = def.Renderer as CIMUniqueValueRenderer;
      var vis_variables = renderer.VisualVariables?.ToList() ??
                            new List<CIMVisualVariable>();
      if (vis_variables.Count == 0)
        return;//there are none
      var vis_var_with_expr = new Dictionary<string, string>();
      //see if any are using expressions
      foreach (var vv in vis_variables)
      {
        if (vv is CIMColorVisualVariable cvv)
        {
          if (!string.IsNullOrEmpty(cvv.ValueExpressionInfo?.Expression))
            vis_var_with_expr.Add("Color", cvv.ValueExpressionInfo?.Expression);
        }
        else if (vv is CIMTransparencyVisualVariable tvv)
        {
          if (!string.IsNullOrEmpty(tvv.ValueExpressionInfo?.Expression))
            vis_var_with_expr.Add("Transparency", tvv.ValueExpressionInfo?.Expression);
        }
        else if (vv is CIMSizeVisualVariable svv)
        {
          if (!string.IsNullOrEmpty(svv.ValueExpressionInfo?.Expression))
            vis_var_with_expr.Add("Outline", svv.ValueExpressionInfo?.Expression);
        }
      }
      if (vis_var_with_expr.Count == 0)
        return;//there arent any with expressions
    
      //loop through the features (outer)
      //per feature evaluate each visual variable.... (inner)
      //....
      //the converse is to loop through the expressions (outer)
      //then per feature evaluate the expression (inner)
      using (var rc = oregon_cnts.Search())
      {
        while (rc.MoveNext())
        {
          foreach (var kvp in vis_var_with_expr)
          {
            var expr_info = new CIMExpressionInfo()
            {
              Expression = kvp.Value,
              ReturnType = ExpressionReturnType.Default
            };
            //per feature eval each expression...
            using (var arcade = ArcadeScriptEngine.Instance.CreateEvaluator(
                                        expr_info, ArcadeProfile.Visualization))
            {
    
              var variables = new List<KeyValuePair<string, object>>() {
                new KeyValuePair<string, object>("$feature", rc.Current)
              };
              //note 2D maps can also have view scale...
              //...if necessary...
              if (mv.ViewingMode == MapViewingMode.Map)
              {
                variables.Add(new KeyValuePair<string, object>(
                  "$view.scale", mv.Camera.Scale));
              }
              var result = arcade.Evaluate(variables).GetResult().ToString();
              //output
              System.Diagnostics.Debug.WriteLine(
                 $"[{rc.Current.GetObjectID()}] '{kvp.Key}': {result}");
            }
          }
        }
      }
    
      ////foreach (var kvp in vis_var_with_expr)
      ////{
      ////  var expr_info = new CIMExpressionInfo()
      ////  {
      ////    Expression = kvp.Value,
      ////    ReturnType = ExpressionReturnType.Default
      ////  };
    
      ////  using (var arcade = ArcadeScriptEngine.Instance.CreateEvaluator(
      ////                                  expr_info, ArcadeProfile.Visualization))
      ////  {
      ////    //loop through the features
      ////    using (var rc = oregon_cnts.Search())
      ////    {
      ////      while (rc.MoveNext())
      ////      {
      ////        var variables = new List<KeyValuePair<string, object>>() {
      ////          new KeyValuePair<string, object>("$feature", rc.Current)
      ////        };
    
      ////        var result = arcade.Evaluate(variables).GetResult();
      ////        //output
      ////        //...
      ////      }
      ////    }
      ////  }
      ////}
    });
    
    Requirements

    Target Platforms: Windows 11, Windows 10

    ArcGIS Pro version: 3.2 or higher.
    See Also