Select to view content in your preferred language

Creating Logic rules with Attribute Rules in Pro

574
4
01-24-2023 01:50 AM
AndrewReynoldsDevon
Regular Contributor

I have the code below which runs a spatial query against an overlaying polygon fc which gains values that are then saved into the new fc. This works fine when the feature is exactly within that fc however when working with lines & poly's quite often these new features go over the overlaying polygon overlay. What are the default rules of logic for the lookup below to use. I need code or be able to modify this so that the line/poly has the majority of it's area in one poly the intersect takes the majority rather than the minority area. Is that possible?

 

// load the other featureset
var fs = FeatureSetByName($datastore, "Highways.HIGHWAYMGR.ElectoralDivisions")
// get the first feature from fs that intersects the current $feature
var f = First(Intersects(fs, $feature))
// abort if we didn't find something
if(f == null) { return }
// return the intersecting feature's value
return f.ElectDiv

 

 

0 Kudos
4 Replies
JohannesLindner
MVP Frequent Contributor

It's possible, just a little more complicated.

Instead of getting the First() intersecting feature, you need to get all of them, and then get the one with the greatest intersection length / area.

// load the other featureset
var fs = FeatureSetByName($datastore, "Highways.HIGHWAYMGR.ElectoralDivisions")
// get all features from fs that intersect the current $feature
var i_fs = Intersects(fs, $feature)
// find the ElectDiv of the feature with the greatest intersection with $feature
var greatest = 0
var electdiv = null
for(var i_f in i_fs) {
    var current = Length(Intersection($feature, i_f))
    if(current <= greatest) { continue }
    greatest = current
    electdiv = i_f.ElectDiv
}
return electdiv

 

If both featuresets ($featureset and fs) are polygon fcs, you should use Area() instead of Length() in line 9.


Have a great day!
Johannes
0 Kudos
AndrewReynoldsDevon
Regular Contributor

Thanks @JohannesLindner  for the point fc shall I use Length or Area on line 9?

What about points that are on the boundary of the polygon - technically they are on the boundary of 2 polygons?

0 Kudos
AndrewReynoldsDevon
Regular Contributor

For the next 2 fields that use the lookup is the code going to be something like this.

I've updated the field ElectDiv to the name field. Are the changes below ok?

// load the other featureset
var fs = FeatureSetByName($datastore, "Highways.HIGHWAYMGR.ElectoralDivisions")
// get all features from fs that intersect the current $feature
var i_fs = Intersects(fs, $feature)
// find the ElectDiv of the feature with the greatest intersection with $feature
var greatest = 0
var name = null
for(var i_f in i_fs) {
    var current = Length(Intersection($feature, i_f))
    if(current <= greatest) { continue }
    greatest = current
    name = i_f.Name
}
return name

 

0 Kudos
JohannesLindner
MVP Frequent Contributor

for the point fc shall I use Length or Area on line 9?

What about points that are on the boundary of the polygon - technically they are on the boundary of 2 polygons?

Hmmm. If your ElectoralDivisions do not overlap each other, then a point will only be on one polygon, except when it is on the boundary, as you said.

So either use your original code (take the first intersecting polygon) or create a small buffer around the point and use Area(). Note that we intersect the buffer, not the $feature:

// load the other featureset
var fs = FeatureSetByName($datastore, "Highways.HIGHWAYMGR.ElectoralDivisions")
// get all features from fs that intersect the current $feature
var f_buffer = Buffer($feature, 1 "meters")
var i_fs = Intersects(fs, f_buffer)
// find the ElectDiv of the feature with the greatest intersection with $feature
var greatest = 0
var name = null
for(var i_f in i_fs) {
    var current = Area(Intersection(f_buffer, i_f))
    if(current <= greatest) { continue }
    greatest = current
    name = i_f.Name
}
return name

 

But this will probably still return the same result as First(i_fs). You could also sort the intersecting polygons by some column and the return the First(). For example, if you have a field ElectoralDivisions.Population and you want to return the name of the polygon with the highest population when the point is on the border of 2 polygons:

// load the other featureset
var fs = FeatureSetByName($datastore, "Highways.HIGHWAYMGR.ElectoralDivisions")
// get all features from fs that intersect the current $feature
var i_fs = Intersects(fs, $feature)
// sort the intersecting features by population, descending
var sorted = OrderBy(i_fs, "Population DESC")
// return the name of the intersecting feature with the highest population
var greatest_pop = First(sorted)
if(greatest_pop == null) { return null }
return greatest_pop.Name

 

 

 

I've updated the field ElectDiv to the name field. Are the changes below ok?

Yeah, looks good

 


Have a great day!
Johannes
0 Kudos