ArcGIS Pro

Domain, Subtypes and the Schema Arcade Functions in ArcGIS Pro 2.6

In this blog I’ll discuss the new Arcade functions in 2.6. Mainly Domain, Subtypes and Schema Arcade functions that will help us write better expressions and unlock more capabilities in the software.

Schema

The new Schema Arcade function provides metadata about a featureset such as fields, globalId and ObjectId field names, geometry Types and other information.

 

Here is how you can use this function, you can either call Schema and pass in feature or a featureset and Schema function will return a dictionary.

{
  "objectIdField": "string",
  "globalObjectIdField": "string",
  "geometryType": "string",
  "fields": [
    {
      "name": "string",
      "alias": "string",
      "length": "number",
      "editable": "bool",
      "nullable": "bool",
      "domain": "string"
    }
  ]
}

Here is a sample output of schema.

Sample Output

 

{
  "objectIdField": "OBJECTID",
  "globalObjectIdField": "GlobalID",
  "geometryType": "esriGeometryPoint",
  "fields": [
    {
      "name": "OBJECTID",
      "alias": "OBJECTID",
      "length": 4,
      "editable": false,
      "nullable": false,
      "domain": null
    },
    {
      "name": "lifecycle",
      "alias": "lifecycle",
      "length": 2,
      "editable": true,
      "nullable": true,
      "domain": "LifeCycle"
    },
    {
      "name": "GlobalID",
      "alias": "GlobalID",
      "length": 38,
      "editable": false,
      "nullable": false,
      "domain": null
    }
  ]
}

 

One simple use case for Schema is to avoid hard coding fieldnames. For example, instead of hard coding the objectId field in filter where clauses, we can ask the Schema function to give us the objectId field name and execute the query.

 

This code will fail if the objectId field of the class County is not called “OBJECTID”


var fs = FeatureSetByName($datastore, "County");
var s = Schema(fs);
var oid = 1;
return text(first(filter(fs, `OBJECTID = ${oid}`)))

 

We can rewrite the code in a generic manner using Schema function


var fs = FeatureSetByName($datastore, "County");
var s = Schema(fs);
var oid = 1;
return text(first(filter(fs, `${s.objectIdField} = ${oid}`)))

 

 

 

Domain

The new Domain Arcade function returns the domain metadata assigned to a field. This works for coded-value and ranged domain. If the class supports subtypes, the domain returned will be the one assigned at the subtype level to that field. If none is assigned at the subtype level, the field level domain is returned.

Here is how you can use it.

Domain ($feature, “fieldname”);

{
  "type": "codedValue|range",
  "name": "Domain_Name",
  "dataType": "",
  "min?": "number",
  "max?": "number",
  "codedValues?": [
    {
      "name": "string",
      "code": "any"
    }
  ]
}

In this example, poleType is a field and we want to return the domain assigned to that field.

var d = Domain($feature, "poleType")
{
  "type": "codedValue",
  "name": "LifeCycle",
  "dataType": "esriFieldTypeSmallInteger",
  "codedValues": [
    {
      "name": "In Service",
      "code": 0
    },
    {
      "name": "Proposed",
      "code": 1
    },
    {
      "name": "Abandoned",
      "code": 2
    }
  ]
}

 

A popular use case for using the Domain Arcade function is to write a constraint attribute rule that prevents values that are outside range of a coded value domain. As follows.


function exists(ar, e) {
    for (var i = 0; i < count(ar); i++)
        if (ar[i].code == e) return true
    return false
} 
//get the domain of the lifecycle
var d = Domain ($feature, "lifecycle");

//search the domain and see if the value is inside the domain.
return exists(d.codedValues, $feature.lifecycle);

 

 

 

 

Subtypes function

There are many new functions related to geodatabase subtypes in Arcade. The Subtypes function returns theĀ  subtypes list, SubtypeCode returns the raw subtype for a given feature/row, and SubtypeName returns the description of the the subtype the feature is assigned to.

 

Subtypes ($feature | featureset)
=>  Dictionary{ subtypeField: string,
                subtypes: [{name: string,
                            code: number}]}

var s = SubtypeCode($feature)  //returns the subtype code of $feature - the raw value of the field
=>  7

var s = SubtypeName($feature)  //returns the Name of the subtype of the $feature which the code maps to
=>  Three Phase Overhead

Here is a sample output of the subtypes function.

 

{
  "subtypeField": "ASSETGROUP",
  "subtypes": [
    {
      "name": "Unknown",
      "code": 0
    },
    {
      "name": "Circuit Breaker",
      "code": 1
    },
    {
      "name": "Fuse",
      "code": 2
    },
    {
      "name": "Generation",
      "code": 3
    },
    {
      "name": "Service Point",
      "code": 4
    },
    {
      "name": "Street Light",
      "code": 5
    },
    {
      "name": "Switch",
      "code": 6
    },
    {
      "name": "Transformer",
      "code": 7
    },
    {
      "name": "Central Office",
      "code": 8
    }
  ]
}

 

A popular use case for using the Subtypes Arcade function is to write a constraint attribute rule that prevents values that are outside range of a subtypes range. As follows.


function exists(ar, e) {


    for (var i = 0; i < count(ar); i++)

        if (ar[i].code == e) return true


    return false

}



//get the subtypes

var d = Subtypes($feature);

//search to make sure the value being supplied is valid
return exists(d.subtypes, subtypecode($feature))

 

About the author

Product Engineer at Esri, Author of several GIS books and Software Engineering Content Creator on YouTube and a podcast host.

Connect:

Leave a Reply

Please Login to comment

Next Article

Learn How to Download a SSL Certificate for a Secured Portal

Read this article