//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 expressionvarquery=@"Count($layer)";//count of features in "layer"//construct a CIMExpressionInfovararcade_expr=newCIMExpressionInfo(){Expression=query.ToString(),//Return type can be string, numeric, or default//When set to default, add-in is responsible for determining//the return typeReturnType=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/usingvararcade=ArcadeScriptEngine.Instance.CreateEvaluator(arcade_expr,ArcadeProfile.Popups);//Provision values for any profile variables referenced...//in our case '$layer'varvariables=newList<KeyValuePair<string,object>>(){new("$layer",featureLayer)};//evaluate the expressiontry{varresult=arcade.Evaluate(variables).GetResult();System.Diagnostics.Debug.WriteLine($"Result: {result}");}//handle any exceptionscatch(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 expressionvarquery=@"$feature.AreaInAcres * 43560.0";//convert acres to ft 2//construct a CIMExpressionInfovararcade_expr=newCIMExpressionInfo(){Expression=query.ToString(),//Return type can be string, numeric, or default//When set to default, add-in is responsible for determining//the return typeReturnType=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/usingvararcade=ArcadeScriptEngine.Instance.CreateEvaluator(arcade_expr,ArcadeProfile.Popups);//we are evaluating the expression against all featuresusingvarrc=featureLayer.Search();while(rc.MoveNext()){//Provision values for any profile variables referenced...//in our case '$feature'varvariables=newList<KeyValuePair<string,object>>(){new("$feature",rc.Current)};//evaluate the expression (per feature in this case)try{varresult=arcade.Evaluate(variables).GetResult();varval=((double)result).ToString("0.0#");System.Diagnostics.Debug.WriteLine($"{rc.Current.GetObjectID()} area: {val} ft2");}//handle any exceptionscatch(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 queryvarquery=newStringBuilder();varlayer_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 CIMExpressionInfovararcade_expr=newCIMExpressionInfo(){Expression=query.ToString(),//Return type can be string, numeric, or default//When set to default, add-in is responsible for determining//the return typeReturnType=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/usingvararcade=ArcadeScriptEngine.Instance.CreateEvaluator(arcade_expr,ArcadeProfile.Popups);//Provision values for any profile variables referenced...//in our case '$map'varvariables=newList<KeyValuePair<string,object>>(){new("$map",map)};//evaluate the expressiontry{varresult=arcade.Evaluate(variables).GetResult();System.Diagnostics.Debug.WriteLine($"Result: {result}");}//handle any exceptionscatch(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 queryvarquery=newStringBuilder();//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 CIMExpressionInfovararcade_expr=newCIMExpressionInfo(){Expression=query.ToString(),//Return type can be string, numeric, or default//When set to default, add-in is responsible for determining//the return typeReturnType=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/usingvararcade=ArcadeScriptEngine.Instance.CreateEvaluator(arcade_expr,ArcadeProfile.Popups);//Provision values for any profile variables referenced...//in our case '$layer'varvariables=newList<KeyValuePair<string,object>>(){new("$layer",featureLayer)};//evaluate the expressiontry{varresult=arcade.Evaluate(variables).GetResult();System.Diagnostics.Debug.WriteLine($"Result: {result}");}//handle any exceptionscatch(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 queryvarquery=newStringBuilder();//https://developers.arcgis.com/arcade/function-reference/math_functionsquery.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 CIMExpressionInfovararcade_expr=newCIMExpressionInfo(){Expression=query.ToString(),//Return type can be string, numeric, or default//When set to default, add-in is responsible for determining//the return typeReturnType=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/usingvararcade=ArcadeScriptEngine.Instance.CreateEvaluator(arcade_expr,ArcadeProfile.Popups);//Provision values for any profile variables referenced...//in our case '$layer'varvariables=newList<KeyValuePair<string,object>>(){new("$layer",featureLayer)};//evaluate the expressiontry{varresult=arcade.Evaluate(variables).GetResult();System.Diagnostics.Debug.WriteLine($"Result: {result}");}//handle any exceptionscatch(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 queryvarquery=newStringBuilder();//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 countquery.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 CIMExpressionInfovararcade_expr=newCIMExpressionInfo(){Expression=query.ToString(),//Return type can be string, numeric, or default//When set to default, add-in is responsible for determining//the return typeReturnType=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/usingvararcade=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 expressiontry{varresult=arcade.Evaluate(variables).GetResult();varresults=result.ToString().Split('|',StringSplitOptions.None);varentries=results.Length/2;inti=0;for(vare=0;e<entries;e++){varname=results[i++];varcount=results[i++];System.Diagnostics.Debug.WriteLine($"'{name}' points count: {count}");}}//handle any exceptionscatch(InvalidProfileVariableException){//something wrong with the profile variable specified//TODO...}catch(EvaluationException){//something wrong with the query evaluation//TODO...}}
Evaluating Expressions
Evaluating an Arcade Labeling Expression
stringArcadeLabelingExpressionName="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...vardef=featureLayer.GetDefinition()asCIMFeatureLayer;//Get the label classvarlabel_class=def.LabelClasses.FirstOrDefault(lc =>{returnlc.Name==ArcadeLabelingExpressionName&&lc.ExpressionEngine==LabelExpressionEngine.Arcade;});if(label_class==null)return;//evaluate the label expression against the featuresvarexpr_info=newCIMExpressionInfo(){Expression=label_class.Expression,ReturnType=ExpressionReturnType.String};//https://developers.arcgis.com/arcade/profiles/labeling/usingvararcade=ArcadeScriptEngine.Instance.CreateEvaluator(expr_info,ArcadeProfile.Labeling);//loop through the featuresusingvarrc=featureLayer.Search();while(rc.MoveNext()){varvariables=newList<KeyValuePair<string,object>>(){new("$feature",rc.Current)};varresult=arcade.Evaluate(variables).GetResult();//outputSystem.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...vardef=featureLayer.GetDefinition()asCIMFeatureLayer;//Most all feature renderers have a VisualVariable collectionvarrenderer=def.RendererasCIMUniqueValueRenderer;List<CIMVisualVariable>vis_variables=renderer.VisualVariables?.ToList()??[];if(vis_variables.Count==0)return;//there are nonevarvis_var_with_expr=newDictionary<string,string>();//see if any are using expressionsforeach(varvvinvis_variables){if(vvisCIMColorVisualVariablecvv){if(!string.IsNullOrEmpty(cvv.ValueExpressionInfo?.Expression))vis_var_with_expr.Add("Color",cvv.ValueExpressionInfo?.Expression);}elseif(vvisCIMTransparencyVisualVariabletvv){if(!string.IsNullOrEmpty(tvv.ValueExpressionInfo?.Expression))vis_var_with_expr.Add("Transparency",tvv.ValueExpressionInfo?.Expression);}elseif(vvisCIMSizeVisualVariablesvv){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)usingRowCursorrc=featureLayer.Search();while(rc.MoveNext()){foreach(varkvpinvis_var_with_expr){varexpr_info=newCIMExpressionInfo(){Expression=kvp.Value,ReturnType=ExpressionReturnType.Default};//per feature eval each expression...usingArcadeEvaluatorarcade=ArcadeScriptEngine.Instance.CreateEvaluator(expr_info,ArcadeProfile.Visualization);varvariables=newList<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));}varresult=arcade.Evaluate(variables).GetResult().ToString();//outputSystem.Diagnostics.Debug.WriteLine($"[{rc.Current.GetObjectID()}] '{kvp.Key}': {result}");}}}
Modify renderer using Arcade
// Note: the following should be embedded in a QueuedTask.Run() statement{// GetRenderer from Layer (assumes it is a unique value renderer)if(featureLayer.GetRenderer()is not CIMUniqueValueRendereruvRenderer){// not a unique value renderer, leavereturn;}//layer has STATE_NAME field if using the community sample Data\Admin\AdminSample.aprxstringexpression="if ($view.scale > 21000000) { return $feature.STATE_NAME } else { return 'All' }";CIMExpressionInfoupdatedExpressionInfo=new(){Expression=expression,Title="Custom"// can be any string used for UI purpose.};//set the renderer's expressionuvRenderer.ValueExpressionInfo=updatedExpressionInfo;//SetRenderer on LayerfeatureLayer.SetRenderer(uvRenderer);}
Modify label expression using Arcade
// Note: the following should be embedded in a QueuedTask.Run() statement{//Get the layer's definition, using the community sample Data\Admin\AdminSample.aprxif(featureLayer.GetDefinition()is not CIMFeatureLayerlyrDefn){// not a feature layer, leavereturn;}//Get the label classes - we need the first onevarlistLabelClasses=lyrDefn.LabelClasses.ToList();vartheLabelClass=listLabelClasses.FirstOrDefault();//set the label class Expression to use the Arcade expressiontheLabelClass.Expression="return $feature.STATE_NAME + TextFormatting.NewLine + $feature.POP2000;";//Set the label definition back to the layer.featureLayer.SetDefinition(lyrDefn);}
Evaluate AttributeRule Expression
//Consult https://github.com/Esri/arcade-expressions/ and//https://developers.arcgis.com/arcade/profiles/attribute-rules/ for//more examples and arcade reference// Note: the following should be embedded in a QueuedTask.Run() statement{//Retrieve the desired feature class/tableFeatureClassDefinitiondef=featureLayer.GetFeatureClass().GetDefinition();//get the desired attribute rule whose expression is to be evaluated.//AttributeRuleType.All, Calculation, Constraint, ValidationAttributeRuleDefinitionvalidation_rule=def.GetAttributeRules(AttributeRuleType.Validation).FirstOrDefault();if(validation_rule==null)return;//Get the expressionvarexpr=validation_rule.GetScriptExpression();//construct a CIMExpressionInfovararcade_expr=newCIMExpressionInfo(){Expression=expr,//Return type can be string, numeric, or defaultReturnType=ExpressionReturnType.Default};System.Diagnostics.Debug.WriteLine($"Evaluating {expr}:");//Construct an evaluator//we are using ArcadeProfile.AttributeRules profile...//Consult: https://developers.arcgis.com/arcade/profiles/usingvararcade=ArcadeScriptEngine.Instance.CreateEvaluator(arcade_expr,ArcadeProfile.AttributeRuleValidation);//we are evaluating the expression against all featuresusingvarrc=featureLayer.Search();while(rc.MoveNext()){// Provision values for any profile variables referenced...// we assume '$feature' here//...use arcade.ProfileVariablesUsed() if necessary...varvariables=newList<KeyValuePair<string,object>>(){new("$feature",rc.Current)};//evaluate the expression per featuretry{varresult=arcade.Evaluate(variables).GetResult();//'Validation' attribute rules return true or false...varvalid=bool.Parse(result.ToString());System.Diagnostics.Debug.WriteLine($"{rc.Current.GetObjectID()} valid: {valid}");}//handle any exceptionscatch(InvalidProfileVariableException){//something wrong with the profile variable specified//TODO...}catch(EvaluationException){//something wrong with the query evaluation//TODO...}}}