Select to view content in your preferred language

Use of Arcade featureSetByAssociation

2432
9
Jump to solution
10-02-2023 06:41 PM
PierreloupDucroix
Frequent Contributor

Hi,

I'm struggling with the use of featureSetByAssociation in an attribute rule

What I'm trying to do is select the features attached to a pole, then count individual assetGroups. But I can't find how to use the className result of fsByAssociation function.

The documentation says it returns :

className: Text - The class name based on the value of TONETWORKSOURCEID or FROMNETWORKSOURCEID.

First, how do I know if I am querying TO or FROM field ?

Second, how do I know how to format the query ?

Looking here (https://pro.arcgis.com/fr/pro-app/latest/help/data/geodatabases/overview/attribute-rule-dictionary-k...) I see several query formatting (electricdistributionassembly, StructureJunctionObject...)

Looking here (https://www.esri.com/arcgis-blog/products/utility-network/data-management/featuresetbyassocaitions-n...) they tell

`className:` String based on value of (TONETWORKSOURCEID or FROMNETWORKSOURCEID )

Ex : var devicesRows = Filter(allContent, "className = 'Electric Device'")

But when looking at the Assicoation View in ArcGIS Pro, I have 4 or 12 as values for FROM/TONETWORKSOURCEID

Any help is welcome

Note that I am working in a mobile geotatabase

Also, if anyone has info about how to user terminalName  in the same function...

 

CEO of MAGIS
0 Kudos
2 Solutions

Accepted Solutions
RobertKrisher
Esri Regular Contributor

If all you want is the attachments, you can just pass in the feature and the association type ("attachment"). You only need to pass in the other information if you want to be more specific about the types of associations returned.

You can find many example arcade expressions in the following github repository from Esri (Esri/arcade-expressions: ArcGIS Arcade expression templates for all supported profiles in the ArcGIS...). There are 16 rules that include examples of using the featureSetByAssociation command and while most of them only pass in the feature and the association type you can find one example that makes use of the class name parameter here (although as I said I think you can use the simpler form of the function): arcade-expressions/popup/has_proposed_features.md at 801d086d4bdc6ad10ebb9c7fde9fdc7b4717a9c6 · Esri...

View solution in original post

0 Kudos
RobertKrisher
Esri Regular Contributor

In a file geodatabase the class name will not be qualified

var assoList = featureSetByAssociation($feature, "attached");
for(var asso in assoList)
console(asso);

produces the correct result in a mobile geodatabase, but doesn't work in a file geodatabase. Here's an example of a result from a mobile geodatabase.

{"geometry":null,"attributes":{"className":"ElectricJunction","globalId":"{0B531F4D-3886-4C8E-B4C0-2D85B8F7A7D1}","isContentVisible":0,"ObjectID":8730,"OID":8730,"percentAlong":0,"side":"","terminal":-1}}

A "Mobile Geodatabase" is a sqllite database that is stored in a single *.geodatabase file. A File Geodatabase is a file-based structure contained in a folder with a .gdb extension.

In a file geodatabase, I was able to get this expression to produce a result when a structure has a junction attached:

var assoList = featureSetByAssociation($feature, "attached");
for(var asso in assoList)
console(asso);

var filterList = Filter(assoList, "className = 'main.ElectricJunction'");
console(count(filterList));

return count(filterList)

RobertKrisher_0-1696371410762.png

 

View solution in original post

9 Replies
MikeMillerGIS
Esri Frequent Contributor

Classname is converted from the SourceID to the SourceName.  In mobile GDB, I am pretty sure it will be main.ElectricDevice for example.

Classname represents either the from or to.  So in a containment and your feature is content, it will be the From, since containment associations are always From(Container), To(Content).  But for Junction Junction, the From/To does not matter.  So if you feature is on the From side, the Classname represents the To.  So, ignore the fact that there is a from/to in the association table, FSbyAssocation returns all associations(filtered by type if passed in) to the feature and the name of the associated item.

 

TerminalName is the name of the terminal, not the code.

 

If you want the codes, you will have to create a query to a FeatureSet on the association table.

0 Kudos
RobertKrisher
Esri Regular Contributor

If all you want is the attachments, you can just pass in the feature and the association type ("attachment"). You only need to pass in the other information if you want to be more specific about the types of associations returned.

You can find many example arcade expressions in the following github repository from Esri (Esri/arcade-expressions: ArcGIS Arcade expression templates for all supported profiles in the ArcGIS...). There are 16 rules that include examples of using the featureSetByAssociation command and while most of them only pass in the feature and the association type you can find one example that makes use of the class name parameter here (although as I said I think you can use the simpler form of the function): arcade-expressions/popup/has_proposed_features.md at 801d086d4bdc6ad10ebb9c7fde9fdc7b4717a9c6 · Esri...

0 Kudos
PierreloupDucroix
Frequent Contributor

Hi Mike and Robert,

What I want to do is count each AssetGroup's features within my associations :

Ex : for "attached" feature of a pole, I need to count how many streetlights, LV connection points and MV connection points. At first, I understood that the ClassName represented the ASSETGROUP and not the Layer.

I ended up getting the globaIDs from the FSbyAssociation in a list, and filtering a featureSetByName with those GIDs and the proper ASSETGROUPs. Then counting the results.

Robert, in the second link you provided, what are the parameters after the association_type ? They are not provided in the Arcade documentation.

--> var associations = FeatureSetByAssociation(feature, association_type, null, null, ['className'], false);

Mike, anyway it doesn't seem to work in a mobile geodatabase.

Ex without classname :

var assoList = featureSetByAssociation(eqpt, "attached")
console(count(assoList)) --> 3

with className :

var assoList = filter(featureSetByAssociation(eqpt, "attached"), "className = 'main.ElectricDevice'"),
console(count(assoList))

--> No result, no console log

 

 

CEO of MAGIS
0 Kudos
RobertKrisher
Esri Regular Contributor

In a file geodatabase the class name will not be qualified

var assoList = featureSetByAssociation($feature, "attached");
for(var asso in assoList)
console(asso);

produces the correct result in a mobile geodatabase, but doesn't work in a file geodatabase. Here's an example of a result from a mobile geodatabase.

{"geometry":null,"attributes":{"className":"ElectricJunction","globalId":"{0B531F4D-3886-4C8E-B4C0-2D85B8F7A7D1}","isContentVisible":0,"ObjectID":8730,"OID":8730,"percentAlong":0,"side":"","terminal":-1}}

A "Mobile Geodatabase" is a sqllite database that is stored in a single *.geodatabase file. A File Geodatabase is a file-based structure contained in a folder with a .gdb extension.

In a file geodatabase, I was able to get this expression to produce a result when a structure has a junction attached:

var assoList = featureSetByAssociation($feature, "attached");
for(var asso in assoList)
console(asso);

var filterList = Filter(assoList, "className = 'main.ElectricJunction'");
console(count(filterList));

return count(filterList)

RobertKrisher_0-1696371410762.png

 

PierreloupDucroix
Frequent Contributor

Thank you very much for these explanations and examples.

Regards

CEO of MAGIS
0 Kudos
Reeti_05
Emerging Contributor

Hi @MikeMillerGIS  @RobertKrisher , can we use featureSetByAssociation on electricdevice to read the associated structurejunction(pole)? I see examples here to do the opposites here: https://www.esri.com/arcgis-blog/products/utility-network/data-management/featuresetbyassocaitions-n...

I basically want to read the uniqueid of the attached pole and populate an attribute value of electric device with the same. Any lead would be really helpful. Thank you in advance!

0 Kudos
MikeMillerGIS
Esri Frequent Contributor

Yes, you would use "Structure"

structure” – will return the feature the specified feature is attached to through a structural attachment association

0 Kudos
Reeti_05
Emerging Contributor

Thank you @MikeMillerGIS , I am using a code to get my elecdevice associated with a nearby Pole(structure junction). The code am using is here: https://github.com/Esri/arcade-expressions/blob/master/attribute-rules/attribute_rule_calculation/Cr...  that works alright. When am adding another AT rule: 

var fs = featuresetbyassociation($feature, "structure")
var polecount= count(fs);
return polecount;

This is returning 1 item.

Next am trying to read an uniqueid from the structure: 

var fs = featuresetbyassociation($feature, "structure")
//var polecount= count(fs);
//return polecount;

var buf = Buffer($feature, 8, "feet");
var fs_filtered = Intersects(fs, buf);
var cnt = Count(fs_filtered);
var min_dist = 999;
var nearest_uniquefid = 0;

if (cnt > 0) {
for (var f in fs_filtered) {
var dist = Distance($feature, f);
if (dist < min_dist) {
min_dist = dist;
nearest_uniquefid = f.uniquefid; // Assuming 'uniquefid' is the field name
}
}
}
return nearest_uniquefid;

I know this works if i use it as featuresetbyname($datastore, "structurejunction") but not being able to make it work with efaturesetbyassociation, any lead would be helpful!

0 Kudos
MikeMillerGIS
Esri Frequent Contributor

The result of FSbyAssociation is a table.  You can get the pole GlobalID from that table to query the pole layer to get the pole.  Take a look at the function below(from https://github.com/Esri/arcade-expressions/blob/master/attribute-rules/attribute_rule_calculation/Up...)

Please post code as a code sample

function get_associated_feature_ids(feature, association_type) {
    // 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 (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
    return associated_ids;
}

 

 

0 Kudos