I have two polygon feature classes, Municipality and District. There is a many-to-many relationship between the two, and therefore an intermediate table called Municipality_District_Rel. The relationships are automatically handled with attribute rules, based on a municipality must overlap a district with 80% or more for them to be related. And if a municipality cover less than 80% percent, the relationship has to be deleted.
The Arcade expression is:
// Arrays to store edits
var edits = [];
var adds = [];
var deletes = [];
// Get all District features
var allDistricts = FeatureSetByName($datastore, "District");
// Find District features that intersect this Municipality feature
var intersectingDistricts = Intersects(allDistricts, $feature);
// Determine which District features that this Municipality overlaps with 80% or more
var overlappingDistrictGlobalIds = [];
for (var district in intersectingDistricts) {
var districtGeometry = Geometry(district);
var districtArea = Area(districtGeometry);
var intersectionGeometry = Intersection(Geometry($feature), districtGeometry);
var intersectionArea = Area(intersectionGeometry);
if ((intersectionArea / districtArea) >= 0.8) {
// This district overlaps, so store the GlobalID for it
Push(overlappingDistrictGlobalIds, district.GlobalID);
}
}
// Determine which relationships to add (new District features that overlaps with at least 80%)
var relatedDistricts = FeatureSetByRelationshipName($feature, "Municipality_District_Rel", ["GlobalID"]);
for (var index in overlappingDistrictGlobalIds) {
var districtGlobalId = overlappingDistrictGlobalIds[index];
Console(districtGlobalId);
var relatedDistrict = First(Filter(relatedDistricts, "GlobalID = '" + districtGlobalId + "'"));
if (relatedDistrict == null) {
// A relationship didn't exist, so add it
Push(adds, {
'attributes': {
'Municipality_GlobalID': $feature.GlobalID,
'District_GlobalID': districtGlobalId
}
});
}
}
// Get existing relationships between Municipality and District features
var allRelationships = FeatureSetByName($datastore, "Municipality_District_Rel", ["*"]);
var relationships = Filter(allRelationships, "Municipality_GlobalID = '" + $feature.GlobalID + "'");
// Determine which relationships to delete (no longer overlapping with at least 80%)
for (var relationship in relationships) {
if (!Includes(overlappingDistrictGlobalIds, relationship.District_GlobalID)) {
// No longer overlapping enough, so delete the relationship
Push(deletes, {'GlobalID': relationship.GlobalID});
}
}
// Return edits dictionary if there are changes to the relatio
if (Count(adds) > 0 || Count(deletes) > 0) {
Push(edits, {
'className': "Municipality_District_Rel",
'adds': adds,
'deletes': deletes
});
return {'edit': edits};
}When I click Analyze I get:
But when I try to save the attribute rule I get this:
What am I doing wrong?
Try this, my only guess is that adds or deletes is an empty array and maybe that is causing an issue
// Arrays to store edits
var edits = [];
var adds = [];
var deletes = [];
// Get all District features
var allDistricts = FeatureSetByName($datastore, "District");
// Find District features that intersect this Municipality feature
var intersectingDistricts = Intersects(allDistricts, $feature);
// Determine which District features that this Municipality overlaps with 80% or more
var overlappingDistrictGlobalIds = [];
for (var district in intersectingDistricts) {
var districtGeometry = Geometry(district);
var districtArea = Area(districtGeometry);
var intersectionGeometry = Intersection(Geometry($feature), districtGeometry);
var intersectionArea = Area(intersectionGeometry);
if ((intersectionArea / districtArea) >= 0.8) {
// This district overlaps, so store the GlobalID for it
Push(overlappingDistrictGlobalIds, district.GlobalID);
}
}
// Determine which relationships to add (new District features that overlaps with at least 80%)
var relatedDistricts = FeatureSetByRelationshipName($feature, "Municipality_District_Rel", ["GlobalID"]);
for (var index in overlappingDistrictGlobalIds) {
var districtGlobalId = overlappingDistrictGlobalIds[index];
Console(districtGlobalId);
var relatedDistrict = First(Filter(relatedDistricts, "GlobalID = @districtGlobalId"));
if (relatedDistrict == null) {
// A relationship didn't exist, so add it
Push(adds, {
'attributes': {
'Municipality_GlobalID': $feature.GlobalID,
'District_GlobalID': districtGlobalId
}
});
}
}
// Get existing relationships between Municipality and District features
var allRelationships = FeatureSetByName($datastore, "Municipality_District_Rel", ["*"]);
var relationships = Filter(allRelationships, "Municipality_GlobalID = '" + $feature.GlobalID + "'");
// Determine which relationships to delete (no longer overlapping with at least 80%)
for (var relationship in relationships) {
if (!Includes(overlappingDistrictGlobalIds, relationship.District_GlobalID)) {
// No longer overlapping enough, so delete the relationship
Push(deletes, {'GlobalID': relationship.GlobalID});
}
}
// Return edits dictionary if there are changes to the relatio
if (Count(adds) == 0 && Count(deletes) == 0) {
return;
}
var edit_payload = {
'className': "Municipality_District_Rel",
}
if (Count(adds)){
edit_payload['adds'] = adds
}
if (Count(deletes)){
edit_payload['deletes'] = deletes
}
Push(edits, edit_payload);
return {
'edit': edits
};
Thanks Mike,
but unfortunately I get the same error. My initial though was a version issue. I am using ArcGIS Pro 3.3, but I get the same error message on ArcGIS 3.5.
The line that causes the error is: var allRelationships = FeatureSetByName($datastore, "Municipality_District_Rel", ["*"]);
But, it's the only way I can think of to delete the existing relationships.
Could this be a bug?
Could be, I never tried to work with a M:N in arcade.