ArcGIS Pro 3.7 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
      // Note: the following should be embedded in a QueuedTask.Run() statement
      {
        //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, add-in 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("$layer", featureLayer)
          };
        //evaluate the expression
        try
        {
          var result = arcade.Evaluate(variables).GetResult();
          System.Diagnostics.Debug.WriteLine($"Result: {result}");
        }
        //handle any exceptions
        catch (InvalidProfileVariableException)
        {
          //something wrong with the profile variable specified
          //TODO...
        }
        catch (EvaluationException)
        {
          //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
    
      // Note: the following should be embedded in a QueuedTask.Run() statement
      {
        //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, add-in 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 = featureLayer.Search();
    
        while (rc.MoveNext())
        {
          //Provision  values for any profile variables referenced...
          //in our case '$feature'
          var variables = new List<KeyValuePair<string, object>>() {
              new("$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)
          {
            //something wrong with the profile variable specified
            //TODO...
          }
          catch (EvaluationException)
          {
            //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
    
      // Note: the following should be embedded in a QueuedTask.Run() statement
      {
        //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, add-in 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("$map", map)
          };
        //evaluate the expression
        try
        {
          var result = arcade.Evaluate(variables).GetResult();
          System.Diagnostics.Debug.WriteLine($"Result: {result}");
        }
        //handle any exceptions
        catch (InvalidProfileVariableException)
        {
          //something wrong with the profile variable specified
          //TODO...
        }
        catch (EvaluationException)
        {
          //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
    
      // Note: the following should be embedded in a QueuedTask.Run() statement
      {
        //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, add-in 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("$layer", featureLayer)
          };
        //evaluate the expression
        try
        {
          var result = arcade.Evaluate(variables).GetResult();
          System.Diagnostics.Debug.WriteLine($"Result: {result}");
        }
        //handle any exceptions
        catch (InvalidProfileVariableException)
        {
          //something wrong with the profile variable specified
          //TODO...
        }
        catch (EvaluationException)
        {
          //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
    
      // Note: the following should be embedded in a QueuedTask.Run() statement
      {
        //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, add-in 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("$layer", featureLayer)
          };
        //evaluate the expression
        try
        {
          var result = arcade.Evaluate(variables).GetResult();
          System.Diagnostics.Debug.WriteLine($"Result: {result}");
        }
        //handle any exceptions
        catch (InvalidProfileVariableException)
        {
          //something wrong with the profile variable specified
          //TODO...
        }
        catch (EvaluationException)
        {
          //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
    
      // Note: the following should be embedded in a QueuedTask.Run() statement
      {
        //construct a query
        var query = new StringBuilder();
        //https://developers.arcgis.com/arcade/function-reference/featureset_functions/
    
        //Assume we have two layers - a polygon and a points layer. 
        //Select all points within the relevant polygon boundaries and sum the count
        query.AppendLine("var results = [];");
    
        query.AppendLine("var polygons = FeatureSetByName($map, 'PolygonLayerName', ['*'], true);");
    
        query.AppendLine("var sel_polygons = Filter(polygons, 'IDField IN (2, 15, 16)');");
    
        query.AppendLine("for(var polygon in sel_polygons) {");
        query.AppendLine("   var name = polygon.Name;");
        query.AppendLine("   var PointsInPolygon = Count(Intersects($layer, Geometry(polygon)));");
        query.AppendLine("   Insert(results, 0, pointsInPolygon);");
        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, add-in 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'
        List<KeyValuePair<string, object>> variables = [
            new("$layer", pointsLayer),
            new("$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}' points count: {count}");
          }
        }
        //handle any exceptions
        catch (InvalidProfileVariableException)
        {
          //something wrong with the profile variable specified
          //TODO...
        }
        catch (EvaluationException)
        {
          //something wrong with the query evaluation
          //TODO...
        }
      }
    }
    Evaluating an Arcade Labeling Expression
    {
      string ArcadeLabelingExpressionName = "My Arcade Label Expression";
    
      //Consult https://github.com/Esri/arcade-expressions/ and
      //https://developers.arcgis.com/arcade/ for more examples
      //and arcade reference
    
      // Note: the following should be embedded in a QueuedTask.Run() statement
      {
        //Given a layer that has an arcade labeling
        //expression and we evaluate it interactively...
        var def = featureLayer.GetDefinition() as CIMFeatureLayer;
        //Get the label class
        var label_class = def.LabelClasses
                           .FirstOrDefault(lc =>
                           {
                             return lc.Name == ArcadeLabelingExpressionName &&
                                    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 = featureLayer.Search();
        while (rc.MoveNext())
        {
          var variables = new List<KeyValuePair<string, object>>() {
              new("$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
    
      // Note: the following should be embedded in a QueuedTask.Run() statement
      {
        //Assume we have a layer that is using Visual Variable
        //expressions that we want to evaluate interactively...
        var def = featureLayer.GetDefinition() as CIMFeatureLayer;
    
        //Most all feature renderers have a VisualVariable collection
        var renderer = def.Renderer as CIMUniqueValueRenderer;
        List<CIMVisualVariable> vis_variables = renderer.VisualVariables?.ToList() ??
                              [];
        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 aren't 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 RowCursor rc = featureLayer.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 ArcadeEvaluator arcade = ArcadeScriptEngine.Instance.CreateEvaluator(
                                        expr_info, ArcadeProfile.Visualization);
    
            var variables = new List<KeyValuePair<string, object>>() {
                new("$feature", rc.Current)
              };
            //note 2D maps can also have view scale...
            //...if necessary...
            if (mv.ViewingMode == MapViewingMode.Map)
            {
              variables.Add(new("$view.scale", mv.Camera.Scale));
            }
            var result = arcade.Evaluate(variables).GetResult().ToString();
            //output
            System.Diagnostics.Debug.WriteLine(
               $"[{rc.Current.GetObjectID()}] '{kvp.Key}': {result}");
          }
        }
      }
    }
    Requirements

    Target Platforms: Windows 11 Home, Pro, Enterprise (64 bit)

    ArcGIS Pro version: 3.2 or higher.
    See Also