### Example: Configure Fields for Election Data Source: https://github.com/esri/arcade-expressions/blob/master/visualization/predominance-strength.md An example of how to configure the 'fields' array for a layer containing voting data, referencing specific fields for Republican, Democrat, and Other votes. ```javascript var fields = [ $feature.REPUBLICAN_VOTES, $feature.DEMOCRAT_VOTES, $feature.OTHER_VOTES ]; ``` -------------------------------- ### Configure Fields for Predominance Example Source: https://github.com/esri/arcade-expressions/blob/master/visualization/predominance.md An example of how to configure the `fields` array for a layer containing voting data. Replace placeholder field names and aliases with actual values from your data, such as `$feature.REPUBLICAN_VOTES` and its corresponding alias. ```javascript var fields = [ { value: $feature.REPUBLICAN_VOTES, alias: "Trump" }, { value: $feature.DEMOCRAT_VOTES, alias: "Clinton" }, { value: $feature.OTHER_VOTES, alias: "Other" } ]; ``` -------------------------------- ### Example: Forest Area Change Source: https://github.com/esri/arcade-expressions/blob/master/visualization/change-over-time.md An example of calculating change in forest area between two years, classifying it as 'Gain' or 'Loss'. ```javascript var change = $feature.F2015-$feature.F1990 When (change > 0, "Gain", change < 0, "Loss", null) ``` -------------------------------- ### Get Start and End Points of a Line Source: https://github.com/esri/arcade-expressions/blob/master/attribute-rules/attribute_rule_calculation/CreateStrandFiberContent.md Extracts the start and end points from a line geometry. Also retrieves the spatial reference of the geometry. ```Arcade // Get the start and end vertex of the line var geo = Geometry($feature); var vertices = geo['paths'][0]; var sr = geo.spatialReference; var start_point = vertices[0]; var end_point = vertices[-1]; ``` -------------------------------- ### Configured Arcade Expression for 'PreDesign' Phase Source: https://github.com/esri/arcade-expressions/blob/master/popup/project-phase.md An example of a configured Arcade expression for the 'PreDesign' phase. It sets the background color for features in the 'PreDesign' phase and a default color for others. This expression should be adapted for each project phase. ```js IIF($feature.PROJPHASE == 'PreDesign', 'background-color:#1987bb', 'background-color:#DDDDDD') ``` -------------------------------- ### Create Perpendicular Lines and Densify Source: https://github.com/esri/arcade-expressions/blob/master/attribute-rules/attribute_rule_calculation/CreateStrandFiberContent.md Generates perpendicular lines at the start and end points of a given line, adjusts their Z-values, and densifies them based on the number of child elements. It then filters the vertices to keep only specific points for creating new start and end line segments. ```Arcade if (create_end_junctions) { var end_line = create_perp_line(end_point, geo, identifier * .1, 2 + identifier * .1); end_line = adjust_z(end_line, identifier); end_line = densify(end_line, (length(end_line) / num_childs))['paths'][0]; var vertex_cnt = count(end_line); var new_end = []; for (var v = 0; v < count(end_line); v++) { if (v == 0 || v == vertex_cnt - 1 || v % (vertex_cnt / num_childs) < 1) { new_end[Count(new_end)] = end_line[v] } } end_line = new_end; var start_line = create_perp_line(start_point, geo, identifier * .1, 2 + identifier * .1); start_line = adjust_z(start_line, identifier); start_line = densify(start_line, (length(start_line) / num_childs))['paths'][0]; var vertex_cnt = count(start_line); var new_start = []; for (var v = 0; v < count(start_line); v++) { if (v == 0 || v == vertex_cnt - 1 || v % (vertex_cnt / num_childs) < 1) { new_start[Count(new_start)] = start_line[v] } } start_line = new_start; } ``` -------------------------------- ### Create Perpendicular Line and Offset Source: https://github.com/esri/arcade-expressions/blob/master/attribute-rules/attribute_rule_calculation/CreateStrandFiberContent.md Calculates a perpendicular line segment from a given line and offsets it based on calculated distance. Handles cases where the segment start point matches the line start point. ```Arcade var search = Extent(Buffer(location, length_line)); var segment = Clip(line_geo, search); var segment_vertices = segment['paths'][0]; var segment_start_point = segment_vertices[0]; segment = Rotate(segment, 90); var offset_dist = iif(length_line / 2 > dist, length_line / 2 - dist, -(dist - length_line / 2)); if (Round(segment_start_point['x'], 2) == Round(line_start_point['x'], 2) && Round(segment_start_point['y'], 2) == Round(line_start_point['y'], 2)) { segment = offset(segment, -offset_dist); } else { segment = offset(segment, offset_dist); } return segment; ``` -------------------------------- ### HTML Template for Popup Display Source: https://github.com/esri/arcade-expressions/blob/master/popup/numeric-difference.md Configure the popup with a custom attribute display using this HTML. Update expression references to match your created expressions. This example styles 'under budget' in green and 'over budget' in red. ```html The project isĀ {expression/expr0}{expression/expr1} ``` -------------------------------- ### Find Container GUIDs Source: https://github.com/esri/arcade-expressions/blob/master/attribute-rules/attribute_rule_calculation/CreateStrandFiberContent.md Searches for intersecting features in a container feature set using the start and end points of a line. Retrieves the global ID of the first intersecting container feature found for both start and end points. ```Arcade var start_container_guid = null; var end_container_guid = null; if (IsEmpty(container_fs) == false) { var container_feat = First(Filter(Intersects(container_fs, Point(start_point)), container_sql)); if (container_feat != null && IsEmpty(container_feat) == false) { start_container_guid = container_feat.globalid } container_feat = First(Filter(Intersects(container_fs, Point(end_point)), container_sql)); if (container_feat != null && IsEmpty(container_feat) == false) { end_container_guid = container_feat.globalid } } ``` -------------------------------- ### Initialize Sandbag Wall Variables Source: https://github.com/esri/arcade-expressions/blob/master/any/sandbag-wall-estimation/sandbag-estimate.md Sets up variables for the finished height and sandbag type from feature attributes. Ensure these field names match your data. ```javascript var finishedHeight = $feature.FinishedHeight; var sandbagType = $feature.SandbagType; ``` -------------------------------- ### Basic URL Construction with Field Values Source: https://github.com/esri/arcade-expressions/blob/master/popup/url-basic.md Use this template to build a base URL combined with field values and a file extension. Replace 'Your Base URL', 'field_name_1', and 'field_name_2' with your specific values. ```javascript "Your Base URL" + Left($feature.field_name_1, 3) + "/" + $feature.field_name_1 + ".pdf" ``` ```javascript "https://www.ontario.ca/sites/default/files/moe_mapping/downloads/2Water/Wells_pdfs/" + Left($feature.WELL_ID, 3) + "/" + $feature.WELL_ID + ".pdf" ``` ```javascript "Your Base URL" + $feature.field_name_1 + "/" + $feature.field_name_2 + ".pdf" ``` -------------------------------- ### Initial Placeholder for Conversion Source: https://github.com/esri/arcade-expressions/blob/master/any/unit-conversion.md This is an initial placeholder code block showing how to set up a field to convert and a factor, before specific values are applied. ```javascript var fieldToConvert = $feature.FIELD_NAME; var factor = 1; fieldToConvert * factor; ``` -------------------------------- ### Helper Function: Get Associated Features Source: https://github.com/esri/arcade-expressions/blob/master/attribute-rules/attribute_rule_calculation/UpdateAssociatedFeatures.md Fetches actual feature objects for associated IDs obtained from `get_associated_feature_ids`. It uses `get_features_switch_yard` to get feature sets and filters them by GlobalID. ```javascript function get_features(associated_ids){ // dict to store the features by class name var associated_features = {}; // loop over classes for (var class_name in associated_ids) { // Get a feature set of the class var feature_set = get_features_switch_yard(class_name, ['*'], false); // Store the GlobalIDs as a variable to use in SQL var global_ids = associated_ids[class_name]; // Filter the class for only the associated features var features = Filter(feature_set, "globalid IN @global_ids"); // Loop over the features and store them into a dict by class name associated_features[class_name] = []; for(var feat in features) { associated_features[class_name][Count(associated_features[class_name])] = feat; } } // Return the features return associated_features; } ``` -------------------------------- ### Helper Function: Get Associated Features Source: https://github.com/esri/arcade-expressions/blob/master/attribute-rules/attribute_rule_calculation/UpdateContainerViaAssociations.md Fetches detailed feature objects for associated IDs, organized by class name. It uses a switchyard function to get the correct feature set for each class. ```javascript function get_features(associated_ids){ // dict to store the features by class name var associated_features = {}; // loop over classes for (var class_name in associated_ids) { // Get a feature set of the class var feature_set = get_features_switch_yard(class_name, ['*'], false); // Store the GlobalIDs as a variable to use in SQL var global_ids = associated_ids[class_name]; // Filter the class for only the associated features var features = Filter(feature_set, "globalid IN @global_ids"); // Loop over the features and store them into a dict by class name associated_features[class_name] = [] for(var feat in features) { associated_features[class_name][Count(associated_features[class_name])] = feat; } } // Return the features return associated_features } ``` -------------------------------- ### Configured HTML Template with 4 Project Phases Source: https://github.com/esri/arcade-expressions/blob/master/popup/project-phase.md An updated HTML table structure for displaying four project phases: PreDesign, Design, Construction, and Closeout. Ensure the 'expression/expr' references align with the corresponding Arcade expressions created for each phase. ```html Phase
PreDesign Design Construction Closeout
``` -------------------------------- ### Dictionary Configuration Source: https://github.com/esri/arcade-expressions/blob/master/visualization/dictionary_renderer/Conduit/Readme.md JSON configuration for the dictionary renderer, defining colors and symbol fields. ```json { "configuration": [{ "name": "colors", "value": "LIGHT", "domain": ["LIGHT", "MEDIUM", "DARK"], "info": "color themes for frame fills" } ], "symbol": ["NumTubesX","NumTubesY"], "text": [] } ``` -------------------------------- ### Initialize Attributes and Lists Source: https://github.com/esri/arcade-expressions/blob/master/attribute-rules/attribute_rule_calculation/CreateStrandFiberContent.md Initializes an attributes dictionary and two lists, 'line_adds' and 'junction_adds', for storing data during feature creation. ```Arcade var attributes = {}; var line_adds = []; var junction_adds = []; ``` -------------------------------- ### HTML Template for Project Phase Display Source: https://github.com/esri/arcade-expressions/blob/master/popup/project-phase.md This HTML structure is used within a pop-up to display project phases. Update the 'expression/expr' references to match your created Arcade expressions and replace 'PHASE1', 'PHASE2', etc., with your actual project phase names. ```html Phase
PHASE1 PHASE2 PHASE3
``` -------------------------------- ### Get X Coordinate from Geometry Source: https://github.com/esri/arcade-expressions/blob/master/form_calculation/GeometryAsAttribute.md Extracts the X coordinate from a feature's geometry. Returns null if the geometry is empty. ```javascript var geom = Geometry($feature) if (IsEmpty(geom)) { return null; } else { return geom.X; } ``` -------------------------------- ### Get Feature Set by Name Source: https://github.com/esri/arcade-expressions/blob/master/attribute-rules/attribute_rule_calculation/UpdateContainersGeometryViaAssociations.md Retrieves a feature set by its name, optionally including geometry. This function handles different utility network classes. ```javascript // This rule will update an Z of the container if the edited point has a different Z and is the lowest // ************* User Variables ************* // This section has the functions and variables that need to be adjusted based on your implementation // The field the rule is assigned to var field_value = $feature.ownedby; // Get Feature Switch yard, adjust the string literals to match your GDB feature class names function get_features_switch_yard(class_name, fields, include_geometry) { var class_name = Split(class_name, '.')[-1]; var feature_set = null; if (class_name == 'SewerDevice') { feature_set = FeatureSetByName($datastore, 'SewerDevice', fields, include_geometry); } else if (class_name == 'SewerJunction') { feature_set = FeatureSetByName($datastore, 'SewerJunction', fields, include_geometry); } else if (class_name == 'SewerAssembly') { feature_set = FeatureSetByName($datastore, 'SewerAssembly', fields, include_geometry); } else if (class_name == 'SewerLine') { feature_set = FeatureSetByName($datastore, 'SewerLine', fields, include_geometry); } else if (class_name == 'StructureJunction') { feature_set = FeatureSetByName($datastore, 'StructureJunction', fields, include_geometry); } else if (class_name == 'StructureLine') { feature_set = FeatureSetByName($datastore, 'StructureLine', fields, include_geometry); } else if (class_name == 'StructureBoundary') { feature_set = FeatureSetByName($datastore, 'StructureBoundary', fields, include_geometry); } else { feature_set = FeatureSetByName($datastore, 'StructureBoundary', fields, include_geometry); } return feature_set; } // ************* End User Variables Section ************* // Converts dict to required return edits format function convert_to_edits(record_dict) { // Convert the dict to a return edit statement var contained_features = []; for (var k in record_dict) { contained_features[count(contained_features)] = { 'className': k, 'updates': record_dict[k] } } return contained_features; } // Function to check if a bit is in an int value function has_bit(num, test_value) { // num = number to test if it contains a bit // test_value = the bit value to test for // determines if num has the test_value bit set // Equivalent to num AND test_value == test_value // first we need to determine the bit position of test_value var bit_pos = -1; for (var i = 0; i < 64; i++) { // equivalent to test_value >> 1 var test_value = Floor(test_value / 2); bit_pos++; if (test_value == 0) break; } // now that we know the bit position, we shift the bits of // num until we get to the bit we care about for (var i = 1; i <= bit_pos; i++) { var num = Floor(num / 2); } if (num % 2 == 0) { return false } else { return true } } // Function to pop empty values in a dict function pop_empty(dict) { var new_dict = {} for (var k in dict) { if (IsNan(dict[k])) { //new_dict[k] = null; continue; } if (IsEmpty(dict[k])) { //new_dict[k] = null; continue; } new_dict[k] = dict[k]; } return new_dict } // Function to get UN associated features function get_associated_feature_ids(feature, association_type, ignore_ids) { // feautre(Feature): A feature object used to lookup assoications // association_type(String): Type of association to look up // Values = content, container, structure // ignore_ids(List[Global Ids]): A list of global IDs to ignore and not include in the results if (IsEmpty(ignore_ids)) { ignore_ids = [] } // Query to get all the content associations var associations = FeatureSetByAssociation(feature, association_type); // If there is no content, exit the function if (count(associations) == 0) { return null; } // loop over all associated records to get a list of the associated classes and the IDs of the features var associated_ids = {}; for (var row in associations) { // If the Globalid is in the ignore list, skip it if (IndexOf(ignore_ids, row.globalId) >= 0) { continue; } if (HasKey(associated_ids, row.className) == false) { associated_ids[row.className] = []; } associated_ids[row.className][Count(associated_ids[row.className])] = row.globalId; } //return a dict by class name with GlobalIDs of features, if empty, return null if (Text(associated_ids) == '{}') { return null; } return associated_ids; } // Get features using a dict with keys of classname and values of Global IDs function get_features(associated_ids, only_geometry, fields) { ``` -------------------------------- ### Line Splitting Configuration and Helper Functions Source: https://github.com/esri/arcade-expressions/blob/master/attribute-rules/attribute_rule_calculation/SplitIntersectingLine.md This snippet defines user-configurable variables for line splitting logic, such as exit conditions, fields to remove, class names, coordinate precision, and tolerance values. It also includes helper functions for retrieving fields by type, setting date types, calculating point-to-line distance, comparing coordinates, and removing dictionary keys. Adjust these variables to customize the splitting behavior. ```javascript var exit_early_values = Dictionary('SplitInt', [200],'SplitText', ['DontSplitTheLine']); var remove_fields_from_new_feature = ['SHAPE_LENGTH', 'GLOBALID', 'OBJECTID']; var point_class_name = "point"; var line_class_name = "line"; var point_fs = FeatureSetByName($datastore, "point", ['*'], true); var decimal_degrees = false; var compare_coordinate_round_value = 2; var point_on_line_tol = 0.1; var buffer_pnt_distance = .02; if (decimal_degrees) { compare_coordinate_round_value = 9; point_on_line_tol = 0.00001; if (buffer_pnt_distance != 0) { buffer_pnt_distance = 0.00000002; } } var remove_dup_vertex = true; function get_fields_by_type(feat, convert_string, param, value) { var fields = Schema(feat).fields; var return_fields = []; var func = Decode(Lower(convert_string), "lower", Lower, "upper", Upper, Text); for (var f in fields) { if (fields[f][param] == value) { var fld_name = fields[f].name; if (!IsEmpty(convert_string)) { fld_name = func(fld_name); } Push(return_fields, fld_name); } } return return_fields; } function set_date_type(feat, dict) { var dt_keys = get_fields_by_type(feat, 'upper', 'type', 'esriFieldTypeDate'); for (var k in dict) { if (IndexOf(dt_keys, Upper(k)) == -1) { continue; } dict[k] = Date(dict[k]); } return dict; } function pDistance(x, y, x1, y1, x2, y2) { var A = x - x1; var B = y - y1; var C = x2 - x1; var D = y2 - y1; var dot = A * C + B * D; var len_sq = C * C + D * D; var param = -1; if (len_sq != 0) param = dot / len_sq; var xx, yy; var is_vertex = true; if (param < 0) { is_vertex = true; xx = x1; yy = y1; } else if (param > 1) { is_vertex = true; xx = x2; yy = y2; } else { is_vertex = false; xx = x1 + param * C; yy = y1 + param * D; } var dx = x - xx; var dy = y - yy; return [Sqrt(dx * dx + dy * dy), [xx, yy], is_vertex]; } function compare_coordinate(x, y, x1, y1) { if ((Round(x1, compare_coordinate_round_value) != Round(x, compare_coordinate_round_value)) || (Round(y1, compare_coordinate_round_value) != Round(y, compare_coordinate_round_value)) ){ return false; } return true; } function pop_keys(dict, keys) { var new_dict = {}; for (var k in dict) { if (IndexOf(keys, Upper(k)) != -1) { continue; } new_dict[k] = dict[k]; } return new_dict; } function remove_vertex(path_array) { if (!remove_dup_vertex){ ``` -------------------------------- ### Get First Container with Z Value Source: https://github.com/esri/arcade-expressions/blob/master/attribute-rules/attribute_rule_calculation/UpdateContainersGeometryViaAssociations.md Iterates through associated features to find the first point geometry that has a Z value. Returns the class name and the feature itself. ```Arcade // Loop over the associated features and get the first point feature with a Z function get_first_container(features) { for (var class_name in features) { for (var globalid in associated_features[class_name]) { var feat = associated_features[class_name][globalid]; var geom = Geometry(feat); var geom_dict = Dictionary(Text(geom)); if (TypeOf(geom) == 'Point' && HasKey(geom_dict, 'z')) { return [class_name, feat]; } } } return null; } ``` -------------------------------- ### Get First New Vertex Source: https://github.com/esri/arcade-expressions/blob/master/attribute-rules/attribute_rule_calculation/SplitIntersectingLine.md This function identifies the first new vertex in a geometry compared to an original geometry. It's crucial for determining where a line might have been modified. ```Arcade function get_first_new_vertex(new_geom, orig_geom) { var new_vertex = null; for (var i = 0; i < Count(new_geom.paths); i++) { var k = 0; for (var j = 0; j < Count(new_geom.paths[i]); j++) { if (!Equals(new_geom.paths[i][j], orig_geom.paths[i][k])) { if (new_vertex == null) { new_vertex = new_geom.paths[i][j]; k--; } else { return null; } } k++; } } return new_vertex; } ``` -------------------------------- ### Configure Operating Hours Settings Source: https://github.com/esri/arcade-expressions/blob/master/popup/operating-hours.md Set up variables to define operating hours data source, holidays, display preferences, and status messages. This section configures how operating hours are interpreted and presented. ```javascript //Specify the Field with operating hours var field = $feature.operhours //Specify any holidays when location is not open [Month, Day] var holidays = [[1,1],[7,4],[12,25]] /*Specify any variable holidays where location is not open, [Occurrence, Month, Day of the Week (Sunday = 0, Saturday = 6)] These are holidays that don't fall on the same date every year, i.e. Memorial Day, Labor Day, Thanksgiving [-1,5,1] corresponds to Memorial Day -> Last occurrence in May of a Monday [1,9,1] corresponds to Labor Day -> 1st occurrence in September of a Monday [4,11,4] corresponds to Thanksgiving -> 4th occurrence in November of a Thursday*/ var variableHolidays = [[-1,5,1],[1,9,1],[4,11,4],[3,1,1]]; //Specifies if only the status will be shown. If True, all following settings are ignored var status_only = "False" // or "True" //Specify the number of following days to return in the display var tot_days = 7 //Specify if the date display is static (always starts on a specific day) var static = "False" //or "True" //Specify the 3 letter day of the week to start on. Only applies when Static is true var start_day = "Mon" //or "Tue", "Wed" etc. //Specify if the values are returned in 24-hour clock or standard time var time_type="Standard" // or "24" //Specify if AM/PM will be shown. Only applies with Standard Time var AM_PM = "False" // or "True" //Specify if the current status of will be shown. Only applies if Static is False var show_status = "False" // or "False" //Specify text to show if open. Only applies when current status is shown var open_text= "Open Now" //Specify text to show if closed. Only applies when current status is shown var closed_text= "Closed" //Specify text to show if Holiday hours may apply. Only applies when current status is shown var holiday_text= "Holiday Hours May Apply" /*DO NOT CHANGE ANYTHING BELOW THIS LINE -------------------------------------------------------------------------*/ var start ``` -------------------------------- ### Get User's Email Address with Arcade Source: https://github.com/esri/arcade-expressions/blob/master/form_calculation/FetchUserInfo.md Use this expression to retrieve the email address of the signed-in user. Ensure the $layer variable is correctly defined in your context. ```javascript GetUser($layer).email; ``` -------------------------------- ### Dictionary Script for Knockouts Source: https://github.com/esri/arcade-expressions/blob/master/visualization/dictionary_renderer/Conduit/Readme.md Arcade script to generate symbol keys based on the number of tubes in X and Y directions. It calculates spacing and offsets for each symbol. ```javascript // Set the spacing to match your symbols var x_spacing = 16; var y_spacing = 16; // Get the values from the feature, return 0 when not set var tubes_y = DefaultValue($feature.NumTubesY, 0); var tubes_x = DefaultValue($feature.NumTubesX, 0); // Return keys var keys = ""; // Total points added, used for indexing of symbols var total_points = 0; // Return default symbol when fields not defined or value not set in field if (tubes_x == 0 || tubes_y == 0) { return "ConduitPoint_0"; } // If only one row, center var start_x = 0; if (tubes_x > 1) { start_x = 0 - (x_spacing * (tubes_x - 1) / 2); } var start_y = 0; if (tubes_y > 1) { start_y = 0 - (y_spacing * (tubes_y - 1) / 2); } // Loop over rows and columns and add symbol for each var current_y = start_y; for (var v = 0; v < tubes_y; v++) { var current_x = start_x; for (var h = 0; h < tubes_x; h++) { if (keys == "") { keys = 'ConduitPoint_' + total_points; } else { keys += ';ConduitPoint_' + total_points; } keys += ';po:' + 'Conduit_' + total_points + '|OffsetX|' + current_x; keys += ';po:' + 'Conduit_' + total_points + '|OffsetY|' + current_y; current_x += x_spacing; total_points += 1; } current_y += y_spacing; } // return keys return keys; ``` -------------------------------- ### Get User's Full Name with Arcade Source: https://github.com/esri/arcade-expressions/blob/master/form_calculation/FetchUserInfo.md Use this expression to retrieve the full name of the signed-in user. Ensure the $layer variable is correctly defined in your context. ```javascript GetUser($layer).fullName; ``` -------------------------------- ### Split Intersecting Line Configuration and Helper Functions Source: https://github.com/esri/arcade-expressions/blob/master/attribute-rules/attribute_rule_calculation/SplitIntersectingLine.md This snippet contains user-configurable variables and helper functions for splitting lines. It includes settings for coordinate rounding, point-on-line tolerance, and buffering, along with functions to manage feature attributes and perform geometric calculations. ```javascript var exit_early_values = Dictionary('SplitInt', [200],'SplitText', ['DontSplitTheLine']); // The field to not move to a new field, edit tracking fields need to be remove // All fields listed here, need to be in upper case, they are forced to upper in the logic below. var remove_fields_from_new_feature = ['SHAPE_LENGTH', 'GLOBALID', 'OBJECTID']; // The line class to split, this must match what you specify in the FeatureSetByName below var line_class_name = "line"; // This is used to get Non Editable fields, do not change the fields from * var line_fs = FeatureSetByName($datastore, "line", ['*'], true); // Set this when using decimal degrees, it adjust the tolerances var decimal_degrees = false; // How man decimals to round coordinates to check if identical // GCS should use a large value, such as 9 // PCS should use a value such as 4 var compare_coordinate_round_value = 2; // When walking the line to split, a line is created between pairs of vertex // this value is the distance ito determine if the created point is on that line // GCS should use a small value, such as 0.0001 // PCS should use a larger value, such as 0.1 var point_on_line_tol = 0.1; // For some scales, and large GCS lines, intersect does not return intersecting lines // Setting this value uses a polygon buffer of the point for the intersect // PCS should use a value such as 0.02 // GCS should use a value such as 0.00000002 var buffer_pnt_distance = 0; if (decimal_degrees) { compare_coordinate_round_value = 9; point_on_line_tol = 0.00001; if (buffer_pnt_distance != 0) { buffer_pnt_distance = 0.00000002; } } // option to skip logic to remove duplicate vertex at the start and end of line, this may be caused by splitting on // a vertex var remove_dup_vertex = true; // When the point and line are un controlled, we cannot split a line when the point is midspan(not at a vertex) var is_un_controlled = true; // ************* End User Variables Section ************* function get_fields_by_type(feat, convert_string, param, value) { var fields = Schema(feat).fields; var return_fields = []; var func = Decode(Lower(convert_string), "lower", Lower, "upper", Upper, Text); for (var f in fields) { if (fields[f][param] == value) { var fld_name = fields[f].name; if (!IsEmpty(convert_string)) { fld_name = func(fld_name); } Push(return_fields, fld_name); } } return return_fields; } function set_date_type(feat, dict) { // Dates need to be set to date types for some platforms var dt_keys = get_fields_by_type(feat, 'upper', 'type', 'esriFieldTypeDate'); for (var k in dict) { if (IndexOf(dt_keys, Upper(k)) == -1) { continue; } dict[k] = Date(dict[k]); } return dict; } function pDistance(x, y, x1, y1, x2, y2) { // adopted from https://stackoverflow.com/a/6853926 var A = x - x1; var B = y - y1; var C = x2 - x1; var D = y2 - y1; var dot = A * C + B * D; var len_sq = C * C + D * D; var param = -1; if (len_sq != 0) //in case of 0 length line param = dot / len_sq; var xx, yy; var is_vertex = false; if (compare_coordinate(x, y, x1, y1)) { is_vertex = true; } if (compare_coordinate(x, y, x2, y2)) { is_vertex = true; } if (param < 0) { // is_vertex = true; xx = x1; yy = y1; } else if (param > 1) { // is_vertex = true; xx = x2; yy = y2; } else { // is_vertex = false; xx = x1 + param * C; yy = y1 + param * D; } var dx = x - xx; var dy = y - yy; return [Sqrt(dx * dx + dy * dy), [xx, yy], is_vertex]; } function compare_coordinate(x, y, x1, y1) { // TODO, probably move to Equals and compare the geometry if ((Round(x1, compare_coordinate_round_value) != Round(x, compare_coordinate_round_value)) || (Round(y1, compare_coordinate_round_value) != Round(y, compare_coordinate_round_value)) ){ return false; } return true; // TODO - Figure out Z if (Count(coordinate > 2) && IsEmpty(source_geo.Z) == false) { if (Round(coordinate[2], 2) != Round(source_geo.Z, 2)) { return false; } } return true; } function pop_keys(dict, keys) { var new_dict = {}; for (var k in dict) { if (IndexOf(keys, Upper(k)) != -1) { continue; } new_dict[k] = dict[k]; } return new_dict; } function remove_vertex(path_array) { ``` -------------------------------- ### Clean Line Path Array Source: https://github.com/esri/arcade-expressions/blob/master/attribute-rules/attribute_rule_calculation/SplitIntersectingLine.md Removes duplicate start and end vertices from a line path array. Ensures the first and last points are unique if they are identical to their adjacent points. ```Arcade function clean_line_path_array(path_array) { if (IsEmpty(path_array) || Count(path_array) == 0) { return path_array; } // Remove duplicate start vertex if (Count(path_array[0]) > 2) { if (compare_coordinate(path_array[0][0][0], path_array[0][0][1], path_array[0][1][0], path_array[0][1][1])) { path_array[0] = Slice(path_array[0], 1); } } // Remove duplicate end vertex var last_path_index = Count(path_array) - 1; var last_path = path_array[last_path_index]; var last_vertex_index = Count(last_path) - 1; if (Count(last_path) > 2) { if (compare_coordinate(last_path[last_vertex_index][0], last_path[last_vertex_index][1], last_path[last_vertex_index - 1][0], last_path[last_vertex_index - 1][1])) { path_array[last_path_index] = Slice(last_path, 0, last_vertex_index); } } return path_array; } ``` -------------------------------- ### Remove Duplicate Vertices from a Line Path Source: https://github.com/esri/arcade-expressions/blob/master/attribute-rules/attribute_rule_calculation/SplitIntersectingLine.md This function removes duplicate vertices from the start and end of a line path. It handles cases where the first or last two vertices are identical. ```Arcade if (!remove_dup_vertex){ return path_array; } var new_path = []; var current_path = path_array[0]; var vertex_count = Count(current_path); if (vertex_count > 2) { if (compare_coordinate(current_path[0][0],current_path[0][1],current_path[1][0],current_path[1][1])) { for (var i in current_path) { if (i != 1) { Push(new_path, current_path[i]); } } current_path = new_path; } } new_path = []; path_array[0] = current_path; current_path = path_array[-1]; vertex_count = Count(current_path); if (Count(current_path) > 2) { if (compare_coordinate(current_path[-1][0],current_path[-1][1],current_path[-2][0],current_path[-2][1])) { for (var i in current_path) { if (i != vertex_count - 2) { Push(new_path, current_path[i]); } } current_path = new_path; } } path_array[-1] = current_path; return path_array; ``` -------------------------------- ### Require Reducer Expression Template Source: https://github.com/esri/arcade-expressions/blob/master/attribute-rules/attribute_rule_validation/require_reducer.md This expression template demonstrates how to use the 'require' reducer. It checks if any results are found and returns an error message if so, otherwise it returns true. ```Arcade if (Count(results) > 0) { return { "errorMessage": Concatenate(results, TextFormatting.NewLine) }; } return true; ``` -------------------------------- ### Display Days of the Week with Formatting Source: https://github.com/esri/arcade-expressions/blob/master/popup/operating-hours.md Use this Arcade expression to generate a list of days of the week, with options to customize the number of days displayed, the length of the day name, and whether to include the date. It supports static start days and various date formatting options. ```javascript //Specify the number of following days to return in the display var tot_days = 7 //Specify the number of characters to display for day of the week. //9 will show the full day name for each day of the week. var day_length = 9 //Specify if the date display is static (always starts on a specific day) var static = "False" //or "True" //Specify the 3 letter day of the week to start on. Only applies when Static is true var start_day = "Mon" //or "Tue", "Wed" etc. //Display Date with Day of the week. Only applies when static is False var display_date = "False" //or "True" //Month format. Only applies when display date is true var Month_display= "MMM" // or "MMM" //Full date format. Only applies when display date is true var full_display= "WMD" // Weekday, Month, Day /*DO NOT CHANGE ANYTHING BELOW THIS LINE -------------------------------------------------------------------------*/ var start function start_date(){ if (static == "True"){ var date_ = decode(start_day,"Sun",5,"Mon",6,"Tue",7,"Wed",8,"Thu",9,"Fri",10,"Sat",11,today()) start = date(2020,0,date_) } else{ start = today() } } function Final(){ var final_text start_date() for(var counter=0; counter