-
Notifications
You must be signed in to change notification settings - Fork 120
ProSnippets Arcade
UmaHarano edited this page Nov 6, 2024
·
3 revisions
Language: C#
Subject: Arcade
Contributor: ArcGIS Pro SDK Team <[email protected]>
Organization: esri, http://www.esri.com
Date: 10/22/2024
ArcGIS Pro: 3.4
Visual Studio: 2022
.NET Target Framework: .Net 8
//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...
}
}
});
//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...
}
}
}
}
});
//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...
}
}
});
//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...
}
}
});
//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...
}
}
});
//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...
}
}
});
//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}");
}
}
}
});
//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
//// //...
//// }
//// }
//// }
////}
});
var lyr = 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)
var uvRenderer = lyr.GetRenderer() as CIMUniqueValueRenderer;
if (uvRenderer == null) return;
//layer has STATE_NAME field
//community sample Data\Admin\AdminSample.aprx
string expression = "if ($view.scale > 21000000) { return $feature.STATE_NAME } else { return 'All' }";
CIMExpressionInfo updatedExpressionInfo = 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);
});
var lyr = 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.aprx
var lyrDefn = lyr.GetDefinition() as CIMFeatureLayer;
if (lyrDefn == null) return;
//Get the label classes - we need the first one
var listLabelClasses = lyrDefn.LabelClasses.ToList();
var theLabelClass = 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);
});
//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/table
var def = featLayer.GetFeatureClass().GetDefinition();
//get the desired attribute rule whose expression is to be
//evaluated.
//AttributeRuleType.All, Calculation, Constraint, Validation
var validation_rule = def.GetAttributeRules(
AttributeRuleType.Validation).FirstOrDefault();
if (validation_rule == null)
return;
//Get the expression
var expr = validation_rule.GetScriptExpression();
//construct a CIMExpressionInfo
var arcade_expr = new CIMExpressionInfo()
{
Expression = expr,
//Return type can be string, numeric, or default
ReturnType = 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 (var arcade = ArcadeScriptEngine.Instance.CreateEvaluator(
arcade_expr, ArcadeProfile.AttributeRuleValidation))
{
//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 we assume '$feature'
//...use arcade.ProfileVariablesUsed() if necessary...
var variables = new List<KeyValuePair<string, object>>() {
new KeyValuePair<string, object>("$feature", rc.Current)
};
//evaluate the expression per feature
try
{
var result = arcade.Evaluate(variables).GetResult();
//'Validation' attribute rules return true or false...
var valid = System.Boolean.Parse(result.ToString());
System.Diagnostics.Debug.WriteLine(
$"{rc.Current.GetObjectID()} valid: {valid}");
}
//handle any exceptions
catch (InvalidProfileVariableException ipe)
{
//something wrong with the profile variable specified
//TODO...
}
catch (EvaluationException ee)
{
//something wrong with the query evaluation
//TODO...
}
}
}
}
});
Home | API Reference | Requirements | Download | Samples