Select to view content in your preferred language

Arcade within() actually queries the feature it is within

2126
16
09-06-2023 01:45 PM
JonathanMcDowell1
Occasional Contributor

I am using the within() function to query an underlying feature class. Then calculating fields based on the values pulled from the within(). If the feature is an odd shape it will return nothing or the wrong value. I am using this syntax, within( querylayer   ,centroid($feature)). Sometimes the centroid is outside of the feature.

In the image below, the within function is using the red point to query the 31E33AD polygon. I need the function to query the 31E33 polygon using the green point. If I remove the centroid function, within() returns nothing. 

Red is the centroid used by the within() function.Red is the centroid used by the within() function.

My suggestion is to create a function that uses a center point within the selected feature. Or fix the centroid function to place the point within the feature.

 

Tags (2)
16 Comments
DeanAnderson2

The following code uses intersect and gets the largest intersecting polygon to make the assignment. It appears to be an OK workaround. 

// Get map number from mapindex polygon layer using interesect
// Do interesect and county features.

var fsMapIndex = FeatureSetByName($datastore,"MapIndex",["MapNumber","ORMapNum","County"])
var fsIntersectMap = Intersects(fsMapIndex,$feature)
var MapIndex = first(fsIntersectMap)
var intcount = Count(fsIntersectMap)

// If no features return error

if (MapIndex == null) return {"errorMessage": "No Map Index Feature Found"}
if (MapIndex.Mapnumber == null) return {"errorMessage": "MapNumber is empty"}

// If count is one then return values

if (intcount == 1) return {
"result": {
"attributes" :{
"MapNumber" : MapIndex.MapNumber,
"ORMapNum" : MapIndex.ORMAPNum,
"County" : MapIndex.County
}
}
}

// if county > 1 (taxlot overlaps mapindex) then
// loop thru and keep intersect with largest area.

else {
var MapNumber = " "
var ORMAPNum = " "
var County = 0
var intersectarea = 0
for (var f in fsIntersectMap){
var newintersectarea = Area(Intersection($feature,f))
if (newintersectarea > intersectarea){
var MapNumber = f.MapNumber
var ORMAPNum = f.ORMAPNum
var County = f.County
intersectarea = newintersectarea}
}

return {
"result": {
"attributes" :{
"MapNumber" : MapNumber,
"ORMapNum" : ORMAPNum,
"County" : County
}
}
}
}

MikeMillerGIS
Do not call Count and First on the FeatureSet. This will cause unnecessary database queries. Just loop over the featureset and handle if the results are empty(none) and get the largest.
DeanAnderson2

Thanks - that makes sense.  Built this off of old code and was just pretty focused on making the area check work.  

DeanAnderson2

Better code - Again Thanks !

// Get map number from mapindex polygon layer
var fsMapIndex = FeatureSetByName($datastore,"MapIndex",["MapNumber","ORMapNum","County"])
var fsIntersectMap = Intersects(fsMapIndex,$feature)

if (fsIntersectMap == null) return {"errorMessage": "No Map Index Feature Found"}

var MapNumber = "None"
var ORMAPNum = "None"
var County = 99
var intersectarea = 0
for (var f in fsIntersectMap){
var newintersectarea = Area(Intersection($feature,f))
if (newintersectarea > intersectarea){
var MapNumber = f.MapNumber
var ORMAPNum = f.ORMAPNum
var County = f.County
intersectarea = newintersectarea}
}

return {
"result": {
"attributes" :{
"MapNumber" : MapNumber,
"ORMapNum" : ORMAPNum,
"County" : County
}
}
}

MikeMillerGIS

 

Looking good, just a little clean up

No reason to check the FS for null.  Think of a FS as a database cursor.  Just cycle over it and check if the results are null afterwards

Declare your variables outside the loop

// Get map number from mapindex polygon layer
var fsMapIndex = FeatureSetByName($datastore, "MapIndex", ["MapNumber", "ORMapNum", "County"])
var fsIntersectMap = Intersects(fsMapIndex, $feature)

var MapNumber = null;
var ORMAPNum = null;
var County = null;
var intersectarea = 0
var newintersectarea
for (var f in fsIntersectMap) {
    newintersectarea = Area(Intersection($feature, f))
    if (newintersectarea > intersectarea) {
        MapNumber = f.MapNumber
        ORMAPNum = f.ORMAPNum
        County = f.County
        intersectarea = newintersectarea
    }
}


if (MapNumber == null) {
    return {
        "errorMessage": "No Map Index Feature Found"
    }
}

return {
    "result": {
        "attributes": {
            "MapNumber": MapNumber,
            "ORMapNum": ORMAPNum,
            "County": County
        }
    }
}

 

 

DeanAnderson2

Thanks!  Always good to have somebody cleanup my code.  Much appreciated.