Create a centerpoint from a polygon Feature class and add the attributes to another Feature Class.

1368
7
Jump to solution
06-08-2021 01:06 AM
Manniej
New Contributor III

 

Hello, 

In short: I am working on a Calculation Attribute Rule what should should 2 things: 

  1. To create a centerpoint from polygon feature;
  2. To update all the available fields in a second featureclass when inserted or updatet.
    • The original is a polygon, the second fc is a point featureclass.  

I did find and tried to use the following blog. But unfortunately this turned out not to be enough to get it working with my current level of knowledge. 

ArcGis Pro version:  2.7.1 

Could you help me out and help me out to create this beautiful product?   (Thank you in advanced). 

 

0 Kudos
1 Solution

Accepted Solutions
JohannesLindner
MVP Frequent Contributor

 

// get point type from polygon type
var polygon_type = $feature.PolygonFC_type
var point_type = ""
if(polygon_type == "Liftschacht") { point_type = "Lift" }
if(polygon_type == "ABC") { point_type = "DEF" }
if(polygon_type == "UVW") { point_type = "XYZ" }

// centroid

// return point_type as attribute in the newly created point
return {
  "result": $feature.field,
  "edit": [
    {   
      "className" : "g**m.i***************t", 
      "adds" : [
        {
          "attributes": {
            "R****ID": $feature.globalid,
            "PointFC_Type": point_type 
            // other fields
          },
          "geometry": centroidFeatureR****e
        }
      ]
    }
  ]
}

 


Have a great day!
Johannes

View solution in original post

7 Replies
JohannesLindner
MVP Frequent Contributor

Please post the code you already have and tell us what problems you have with it (erro messages etc).

To post code: expand the toolbar in the comment box, insert a code sample, chose Javascript as language.

JohannesLindner_0-1623143269177.png

JohannesLindner_1-1623143284020.png

 


Have a great day!
Johannes
Manniej
New Contributor III

@JohannesLindner  Thank you for the additional information. 

I think I got point 1 & 2 partially working 🎂  But there are still a lot of unanswered questions. For example, why do they use an empty field called "Field" as a central point for the Attribute Rule? Is this necessary? And why return it widhout an action? 

I need to add a "definition query ", am I on the right track with this approach?  And how can I rewrite "A" to "C" and "B" to "D" at this point? 

 

//If value of field X is "A" or "B" proceed, else do nothing (Insert or Update). 
var IsCorrecteWaarde =($feature).X == "A" or ($feature).X == "B" 

else {
return
}​

 

 

This is the current code:

 

//----------------------------------------------------
//Create a centerpoint of the given polygon. Z=Zero, because of the Z-awareness of the FC. 
var centroidFeatureR****e = Point({ 'x': centroid($feature).x, 'y': centroid($feature).y, 'z': 0, 'spatialReference':{'wkid':28992} })
//----------------------------------------------------

return {
       //In the example they used a empty field! So do we! I do'nt really understand why (yet).
      "result": $feature.field,
       //this keyword indicates an edit that need to happen, its an array since we can make many edits [example text]
       "edit": [  
           {  
               //The Point-FC (g**m.i***************t), what is the derivative of the source (g**m.r****e). 
               "className" : "g**m.i***************t", 
                  
               //all fields & Geometry that we want to include in the new Featureclass. 
               "adds" : [
                      {
                            //the attribute of the feature we want to add, 
                            // R****ID & the GlobalID will work as a 'offline relationshipclass'
                            "attributes":  
                             {
                                   "R****ID": $feature.globalid, 
                                   //All the another fields I deleted because of the AVG-law. 
                               }, 

                            //The geometry will be the variable 'centroidFeatureR****e' we determined earlier. 
                            "geometry": centroidFeatureR****e

                      }
             ]
            }
     ]
}

 

 Thank you in advanced

0 Kudos
JohannesLindner
MVP Frequent Contributor

why do they use an empty field called "Field"

Because calculation rules expect a field to be calculated.

A very simple form of a calculation rule would be

// calculate field C as sum of fields A and B
var c = $feature.a + $feature.b
return c

 In this simple form, you don't return a dictionary like in the blog post you linked, but a simple value. In the rule creation window you sspecify the field this value is stored in.

The advanced attribute rules enhance this behavior, so that by editing one table, you can do stuff in other tables. The basic behavior stays the same: the rule still wants to know what value to return and in which field to store the returned value.

In the blog post, they don't care about calculating attributes for the point, they just want to automatically create a polygon around the point (the inverse of what you are doing). But because the rule expects a return value and a field, they just use an empty field and return the value that is already there. You don't have to create an extra field for that. Just take a field that is already in your polygon FC (you have to be able to edit it, so not things like ObjectID or GlobalID) and return its value. By returning the value that is already stored in the field, you ensure that nothing is actually changed.

For eample, my calculation rules for primary keys look something like this:

// Calculation rule for a primary key field
// Field: BauwerkID
// Triggers: Insert, Update

// check if the field is empty
if(IsEmpty($feature.BauwerkID)) {
  // yes -> return a new value
  return NextSequenceValue("SequenceBauwerkID")
}
// no -> return the field's value (change nothing)
return $feature.BauwerkID

 

I need to add a "definition query ", am I on the right track with this approach?

//If value of field X is "A" or "B" proceed, else do nothing (Insert or Update).
if($feature.X == "A" || $feature.X == "B") {
  // do stuff
}
else {
  return $feature.Field  // return the value that is already stored in your field. In this case, no point feature will be created.
}


// Personally, I find code easier to read if you do it the other way around:
if($feature.X != "A" && $feature.X != "B") {
  return $feature.Field
}
// Do stuff

 

And how can I rewrite "A" to "C" and "B" to "D" at this point?

I'm not sure I understand you correctly: You have a polygon feature with X = "A", so you want to create a point feature and then change X to "C"?

In this case, your field for the calculation rule would be X.

// if field X is not "A" or "B", do nothing
if($feature.X != "A" && $feature.X !="B") {
  return $feature.X
}

// else get the new value for X
var new_x = IIF($feature.X == "A", "C", "D")  // $feature.X can only be "A" or "B" at this point (else we would have returned above)
// get the centroid
var centroid = ...

// return
return {
  "result": new_x,
  "edit": ...
}

Have a great day!
Johannes
Manniej
New Contributor III

@JohannesLindner , thank you once again for the explaination, this is much appreciated.  

Here's a little clarification on the last part, I need to rewrite a value after a point is created and we did the check. 

For example: In the Polygon FC: $feature.PolygonFC_type == "Liftschacht"   it should be $feature.PointFC_Type == "Lift" in the destinated pointFC.

0 Kudos
JohannesLindner
MVP Frequent Contributor

 

// get point type from polygon type
var polygon_type = $feature.PolygonFC_type
var point_type = ""
if(polygon_type == "Liftschacht") { point_type = "Lift" }
if(polygon_type == "ABC") { point_type = "DEF" }
if(polygon_type == "UVW") { point_type = "XYZ" }

// centroid

// return point_type as attribute in the newly created point
return {
  "result": $feature.field,
  "edit": [
    {   
      "className" : "g**m.i***************t", 
      "adds" : [
        {
          "attributes": {
            "R****ID": $feature.globalid,
            "PointFC_Type": point_type 
            // other fields
          },
          "geometry": centroidFeatureR****e
        }
      ]
    }
  ]
}

 


Have a great day!
Johannes
Manniej
New Contributor III

Thank you @JohannesLindner for your time and energy, you helped me a lot,  It is working! 

I still need to learn a lot!  But I see the potentional of attribute rules!  Mercy for this insight! 

0 Kudos
JohannesLindner
MVP Frequent Contributor

Glad to help!

Yeah, attribute rules (and Arcade in other instances, like popups, field calculation, advanced symbology and labels) can be pretty powerful, and they're still adding stuff to it. But you have to learn the language, it certainly helps if you have experience in other programming/script languages.

You kinda jumped in at the deep end, here. There's a reason the blog is titled "Advanced Attribute Rules" 🙂

 

In case you haven't found it yet: The Arcace Guide and the Function Reference are great resources.


Have a great day!
Johannes
0 Kudos