Calculate longest length of polygon

1277
7
Jump to solution
12-06-2022 09:44 AM
RhettZufelt
MVP Frequent Contributor

I am trying to make an attribute rule that automatically calculates the length of the longest side of a polygon, but having difficulty figuring it out.

Polygon will always be a 4 sided rectangle, but may be oriented in any direction.

Does any know of a way to accomplish this as an attribute rule?

Basically, need the X value here:

RhettZufelt_1-1670348539705.png

Thanks for any help,

R_

0 Kudos
1 Solution

Accepted Solutions
JohannesLindner
MVP Frequent Contributor
var distances = []
// get the polygon parts
var rings = Geometry($feature).rings
// loop over the parts
for(var r in rings) {
    var ring = rings[r]
    // loop over the vertices (skip first)
    for(var v = 1; v < Count(ring); v++) {
        Push(distances, Distance(ring[v - 1], ring[v]))
    }
}
return Max(distances)

 

This will get the longest side of any polygon, no matter the part count or the form. You could simplify it by only extracting the first ring and checking only the first three vertices (giving you the two sides), but it would not make any noticeable time difference.


Have a great day!
Johannes

View solution in original post

7 Replies
JohannesLindner
MVP Frequent Contributor
var distances = []
// get the polygon parts
var rings = Geometry($feature).rings
// loop over the parts
for(var r in rings) {
    var ring = rings[r]
    // loop over the vertices (skip first)
    for(var v = 1; v < Count(ring); v++) {
        Push(distances, Distance(ring[v - 1], ring[v]))
    }
}
return Max(distances)

 

This will get the longest side of any polygon, no matter the part count or the form. You could simplify it by only extracting the first ring and checking only the first three vertices (giving you the two sides), but it would not make any noticeable time difference.


Have a great day!
Johannes
JohannesLindner
MVP Frequent Contributor

For completeness, here's the simple expression for a rectangle:

var ring = Geometry($feature).rings[0]
var d1 = Distance(ring[0], ring[1])
var d2 = Distance(ring[1], ring[2])
return Max(d1, d2)

JohannesLindner_0-1670399501541.png

 


Have a great day!
Johannes
CESPEDESLUISITD
New Contributor III

Hello Johannes,

Your solution helped me out, but on my end, it seems to be off by .10.

I am using miles, and when measuring with the ruler widget, say I get .85 miles, your code gives me .95.

Or another one says 1.25 on the widget, the code returns 1.35 miles. 

Does the State Plane have anything to do with this?

Thanks

0 Kudos
JohannesLindner
MVP Frequent Contributor

Hmm. For me, the widget returns slightly larger values, but that's because it only displays two significant digits and seems to always round up.

It might be the coordinate system, but I have absolutely no experience working in State Plane, so I can't say anything about it.

 

If your polygons cover great distances, you might want to use DistanceGeodetic to account for Earth's curvature. Make sure that your polygons are inside your state zone.

 

Also, make sure that the code and the measure widget use the same distance method (planar or geodesic), and that you actually snap to the polygon's vertices.

 

All the Arcade Geometry functions warn about generalization errors when using them for labeling or symbology:

Feature geometries in the visualization and labeling profiles are generalized according to the view's scale resolution to improve drawing performance. Therefore, using a feature's geometry (i.e. $feature) as input to any geometry function in these contexts will return different results at each scale level. Other profiles, such as popup, provide the full resolution geometry.

I haven't seen this effect yet, but I expect it would show up for polygons with many vertices.

 

If none of these help, I suggest doing the distance calculation manually and comparing it to both measuring widget and code. At least then you know which one is correct.


Have a great day!
Johannes
0 Kudos
CESPEDESLUISITD
New Contributor III

Thank you very much for your prompt response.

Yes, my polygons do have multiple vertices.

I will try your suggestions.

Thanks again for your help.

0 Kudos
CESPEDESLUISITD
New Contributor III

You are a genius.

I used the distanceGeodetic function and I got the same as the widget.

I just need to update for multiple segments for the sides, so it can add up for the longest side made up of multiple segments.

Thanks so much!

0 Kudos
RhettZufelt
MVP Frequent Contributor

Thank you  @JohannesLindner, this is exactly what I needed.

Only thing I see that is weird, is that it was reporting distances in meters, even though my map and data are in State Plane feet.

Documentation says 'Distance' defaults to the spatial reference of the data, but that does not seem to be the case with a calculation attribute rule.

Adding the units parameter did the trick though:

Push(distances, Distance(ring[v - 1], ring[v], 'feet'))

Thanks again,

R_

0 Kudos