//Consult https://github.com/Esri/arcade-expressions/ and//https://developers.arcgis.com/arcade/ for more examples//and arcade reference
QueuedTask.Run(()=>{//construct an expressionvarquery=@"Count($layer)";//count of features in "layer"//construct a CIMExpressionInfovararcade_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 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 reference
QueuedTask.Run(()=>{//construct an expressionvarquery=@"$feature.AreaInAcres * 43560.0";//convert acres to ft 2//construct a CIMExpressionInfovararcade_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 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=new StringBuilder();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=new CIMExpressionInfo(){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 reference
QueuedTask.Run(()=>{//construct a queryvarquery=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 CIMExpressionInfovararcade_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 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 reference
QueuedTask.Run(()=>{//construct a queryvarquery=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 CIMExpressionInfovararcade_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 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=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 CIMExpressionInfovararcade_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 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()as CIMFeatureLayer;//Get the label classvarlabel_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 featuresvarexpr_info=new CIMExpressionInfo(){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();//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 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()as CIMFeatureLayer;//Most all feature renderers have a VisualVariable collectionvarrenderer= def.Renderer as CIMUniqueValueRenderer;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(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);}elseif(vv is CIMTransparencyVisualVariable tvv){if(!string.IsNullOrEmpty(tvv.ValueExpressionInfo?.Expression)) vis_var_with_expr.Add("Transparency", tvv.ValueExpressionInfo?.Expression);}elseif(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(varrc= oregon_cnts.Search()){while(rc.MoveNext()){foreach(var kvp in vis_var_with_expr){varexpr_info=new CIMExpressionInfo(){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();//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//// //...//// }//// }//// }////}});
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()as CIMUniqueValueRenderer;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=new CIMExpressionInfo{Expression=expression,Title="Custom"// can be any string used for UI purpose.};//set the renderer's expression uvRenderer.ValueExpressionInfo =updatedExpressionInfo;//SetRenderer on Layer lyr.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()as CIMFeatureLayer;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 expression theLabelClass.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 reference
QueuedTask.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=new CIMExpressionInfo(){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...}}}}});