//Consult https://github.com/Esri/arcade-expressions/ and//https://developers.arcgis.com/arcade/ for more examples//and arcade referenceQueuedTask.Run(()=>{//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, addin 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/using(vararcade=ArcadeScriptEngine.Instance.CreateEvaluator(arcade_expr,ArcadeProfile.Popups)){//Provision values for any profile variables referenced...//in our case '$layer'varvariables=newList<KeyValuePair<string,object>>(){newKeyValuePair<string,object>("$layer",featLayer)};//evaluate the expressiontry{varresult=arcade.Evaluate(variables).GetResult();System.Diagnostics.Debug.WriteLine($"Result: {result.ToString()}");}//handle any exceptionscatch(InvalidProfileVariableExceptionipe){//something wrong with the profile variable specified//TODO...}catch(EvaluationExceptionee){//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 referenceQueuedTask.Run(()=>{//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, addin 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/using(vararcade=ArcadeScriptEngine.Instance.CreateEvaluator(arcade_expr,ArcadeProfile.Popups)){//we are evaluating the expression against all featuresusing(varrc=featLayer.Search()){while(rc.MoveNext()){//Provision values for any profile variables referenced...//in our case '$feature'varvariables=newList<KeyValuePair<string,object>>(){newKeyValuePair<string,object>("$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(InvalidProfileVariableExceptionipe){//something wrong with the profile variable specified//TODO...}catch(EvaluationExceptionee){//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 referencevarmap=MapView.Active.Map;QueuedTask.Run(()=>{//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, addin 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/using(vararcade=ArcadeScriptEngine.Instance.CreateEvaluator(arcade_expr,ArcadeProfile.Popups)){//Provision values for any profile variables referenced...//in our case '$map'varvariables=newList<KeyValuePair<string,object>>(){newKeyValuePair<string,object>("$map",map)};//evaluate the expressiontry{varresult=arcade.Evaluate(variables).GetResult();System.Diagnostics.Debug.WriteLine($"Result: {result.ToString()}");}//handle any exceptionscatch(InvalidProfileVariableExceptionipe){//something wrong with the profile variable specified//TODO...}catch(EvaluationExceptionee){//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 referenceQueuedTask.Run(()=>{//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, addin 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/using(vararcade=ArcadeScriptEngine.Instance.CreateEvaluator(arcade_expr,ArcadeProfile.Popups)){//Provision values for any profile variables referenced...//in our case '$layer'varvariables=newList<KeyValuePair<string,object>>(){newKeyValuePair<string,object>("$layer",featLayer)};//evaluate the expressiontry{varresult=arcade.Evaluate(variables).GetResult();System.Diagnostics.Debug.WriteLine($"Result: {result.ToString()}");}//handle any exceptionscatch(InvalidProfileVariableExceptionipe){//something wrong with the profile variable specified//TODO...}catch(EvaluationExceptionee){//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 referenceQueuedTask.Run(()=>{//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, addin 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/using(vararcade=ArcadeScriptEngine.Instance.CreateEvaluator(arcade_expr,ArcadeProfile.Popups)){//Provision values for any profile variables referenced...//in our case '$layer'varvariables=newList<KeyValuePair<string,object>>(){newKeyValuePair<string,object>("$layer",featLayer)};//evaluate the expressiontry{varresult=arcade.Evaluate(variables).GetResult();System.Diagnostics.Debug.WriteLine($"Result: {result.ToString()}");}//handle any exceptionscatch(InvalidProfileVariableExceptionipe){//something wrong with the profile variable specified//TODO...}catch(EvaluationExceptionee){//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 referencevarmap=MapView.Active.Map;QueuedTask.Run(()=>{//construct a queryvarquery=newStringBuilder();//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 countquery.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 CIMExpressionInfovararcade_expr=newCIMExpressionInfo(){Expression=query.ToString(),//Return type can be string, numeric, or default//When set to default, addin 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/using(vararcade=ArcadeScriptEngine.Instance.CreateEvaluator(arcade_expr,ArcadeProfile.Popups)){//Provision values for any profile variables referenced...//in our case '$layer' and '$map'varvariables=newList<KeyValuePair<string,object>>(){newKeyValuePair<string,object>("$layer",crimes_layer),newKeyValuePair<string,object>("$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}' crime count: {count}");}}//handle any exceptionscatch(InvalidProfileVariableExceptionipe){//something wrong with the profile variable specified//TODO...}catch(EvaluationExceptionee){//something wrong with the query evaluation//TODO...}}});
Evaluating Expressions
Evaluating an Arcade Labelling Expression
//Consult https://github.com/Esri/arcade-expressions/ and//https://developers.arcgis.com/arcade/ for more examples//and arcade referencevarmap=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...vardef=oregon_cnts.GetDefinition()asCIMFeatureLayer;//Get the label classvarlabel_class=def.LabelClasses.FirstOrDefault(lc =>{returnlc.Name=="Arcade_Example_1"&&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/using(vararcade=ArcadeScriptEngine.Instance.CreateEvaluator(expr_info,ArcadeProfile.Labeling)){//loop through the featuresusing(varrc=oregon_cnts.Search()){while(rc.MoveNext()){varvariables=newList<KeyValuePair<string,object>>(){newKeyValuePair<string,object>("$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 referencevarmv=MapView.Active;varmap=mv.Map;QueuedTask.Run(()=>{//Assume we a layer - Oregon County (poly) that is using Visual Variable//expressions that we want to evaluate interactively...vardef=oregon_cnts.GetDefinition()asCIMFeatureLayer;//Most all feature renderers have a VisualVariable collectionvarrenderer=def.RendererasCIMUniqueValueRenderer;varvis_variables=renderer.VisualVariables?.ToList()??newList<CIMVisualVariable>();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 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(varrc=oregon_cnts.Search()){while(rc.MoveNext()){foreach(varkvpinvis_var_with_expr){varexpr_info=newCIMExpressionInfo(){Expression=kvp.Value,ReturnType=ExpressionReturnType.Default};//per feature eval each expression...using(vararcade=ArcadeScriptEngine.Instance.CreateEvaluator(expr_info,ArcadeProfile.Visualization)){varvariables=newList<KeyValuePair<string,object>>(){newKeyValuePair<string,object>("$feature",rc.Current)};//note 2D maps can also have view scale...//...if necessary...if(mv.ViewingMode==MapViewingMode.Map){variables.Add(newKeyValuePair<string,object>("$view.scale",mv.Camera.Scale));}varresult=arcade.Evaluate(variables).GetResult().ToString();//outputSystem.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//// //...//// }//// }//// }////}});
Modify renderer using Arcade
varlyr=MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault(f =>f.ShapeType==esriGeometryType.esriGeometryPolygon);if(lyr==null)return;QueuedTask.Run(()=>{// GetRenderer from Layer (assumes it is a unique value renderer)varuvRenderer=lyr.GetRenderer()asCIMUniqueValueRenderer;if(uvRenderer==null)return;//layer has STATE_NAME field//community sample Data\Admin\AdminSample.aprxstringexpression="if ($view.scale > 21000000) { return $feature.STATE_NAME } else { return 'All' }";CIMExpressionInfoupdatedExpressionInfo=newCIMExpressionInfo{Expression=expression,Title="Custom"// can be any string used for UI purpose.};//set the renderer's expressionuvRenderer.ValueExpressionInfo=updatedExpressionInfo;//SetRenderer on Layerlyr.SetRenderer(uvRenderer);});
Modify label expression using Arcade
varlyr=MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault(f =>f.ShapeType==esriGeometryType.esriGeometryPolygon);if(lyr==null)return;QueuedTask.Run(()=>{//Get the layer's definition//community sample Data\Admin\AdminSample.aprxvarlyrDefn=lyr.GetDefinition()asCIMFeatureLayer;if(lyrDefn==null)return;//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.lyr.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 referenceQueuedTask.Run(()=>{//Retrieve the desired feature class/tablevardef=featLayer.GetFeatureClass().GetDefinition();//get the desired attribute rule whose expression is to be//evaluated.//AttributeRuleType.All, Calculation, Constraint, Validationvarvalidation_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/using(vararcade=ArcadeScriptEngine.Instance.CreateEvaluator(arcade_expr,ArcadeProfile.AttributeRuleValidation)){//we are evaluating the expression against all featuresusing(varrc=featLayer.Search()){while(rc.MoveNext()){//Provision values for any profile variables referenced...//in our case we assume '$feature'//...use arcade.ProfileVariablesUsed() if necessary...varvariables=newList<KeyValuePair<string,object>>(){newKeyValuePair<string,object>("$feature",rc.Current)};//evaluate the expression per featuretry{varresult=arcade.Evaluate(variables).GetResult();//'Validation' attribute rules return true or false...varvalid=System.Boolean.Parse(result.ToString());System.Diagnostics.Debug.WriteLine($"{rc.Current.GetObjectID()} valid: {valid}");}//handle any exceptionscatch(InvalidProfileVariableExceptionipe){//something wrong with the profile variable specified//TODO...}catch(EvaluationExceptionee){//something wrong with the query evaluation//TODO...}}}}});