Select to view content in your preferred language

Within() Arcade Function and multi-layer feature services

66
8
yesterday
Labels (1)
AmyRoust
Frequent Contributor

Is there a trick to using the Within function when referencing a layer in a multi-layer feature layer? I used a simple Within function to add the intersecting parcel PIN number to an address point's pop-up, but when I try to get its zoning, here's what happens:

AmyRoust_0-1759771648220.png

If I comment out the Within function and just tell it to return all zoning data, it works:

AmyRoust_1-1759771695741.png

The difference between my parcel feature layer and my zoning feature layer is that the zoning layer has three layers in it:

AmyRoust_3-1759771834658.png

 

The FeatureSetByName function doesn't seem to care that it's in a group, but maybe Within does?

I did try adding the Lawrence Zoning District sublayer by itself to the map, but I got the same results.

AmyRoust_4-1759771990616.png

 

0 Kudos
8 Replies
RPGIS
by MVP Regular Contributor
MVP Regular Contributor

Hi @AmyRoust,

So the within function returns a feature set of the features that fall within the specified layer. If you have an instance where some layers may overlap others then what I might suggest is any of the following.

var FS = FeatureSetByName($map, 'Zoning Districts - Lawrence Zoning District',['ZoningDistrict'],True)
var Address = $feature
if( TypeOf(Geometry($feature)) == 'Polygon' ){ Address = Centroid($feature) }
var AddrWithin = Within(address,FS)
iif( Count(AddrWithin)>0, AddrWithin, 'No features are within the layer')
/*
Note: the intersects function can also be used if the input layer is a point feature.
*/
0 Kudos
AmyRoust
Frequent Contributor

@RPGIS - no luck, but I appreciate the suggestion.

AmyRoust_0-1759783836518.png

 

0 Kudos
RPGIS
by MVP Regular Contributor
MVP Regular Contributor

Then it might helpful then to use the intersects function to get the information that you need. It may also require that you loop through multiple features to get a dictionary of field values to pull from.

0 Kudos
KenBuja
MVP Esteemed Contributor

It doesn't matter if you have the layer within a group layer. This works on a test I set up.

var fs = FeatureSetByName($map, "USA Census States")
var output = Within($feature,FS)

return { 
	type : 'text', 
	text : first(output).STATE_NAME
}

KenBuja_0-1759791417342.png

Did you test the code on an actual feature in the Zoning District? Running the code in the editor will use the first feature in the FeatureSet, which may or may not give you a feature within the Zoning District layer. You can use a feature you know will work by filtering the parcel to a specific one. In my example, I can filter the earthquakes to a specific event to test it out.

This code 

var feat = First(Filter($layer, "id = 'mb90114598'"))
var fs = FeatureSetByName($map, "USA Census States")
var output = Within(feat,FS)
return output
return { 
	type : 'text', 
	text : first(output).STATE_NAME
}

returns this

KenBuja_1-1759791971984.png

The code in your latest post fails because you're supplying an incorrect name for the FeatureSetByName function, which returns a null. When used in the WIthin function, it's being interpreted as a null feature in the Geometry Within function (which returns a boolean) instead of the FeatureSet Within function (which returns a FeatureSet)

 

0 Kudos
RPGIS
by MVP Regular Contributor
MVP Regular Contributor

Hi @KenBuja,

Correct me if I am wrong but it might appear that @AmyRoust is referencing a grouped layer which, if it is setup correctly, should be a single service in which case the Within function should work. However, if it is created as separate feature services which are then grouped in the map then that would require a different work around. In which case @AmyRoust could try one of the following below.

// Option 1: using union then the within function
var FSets = [
    FeatureSetByName($map,'ConditionalZoning'),['*'],True),
    FeatureSetByName($map,'LawrenceZoningDistrict'),['*'],True),
    FeatureSetByName($map,'DouglasCountyZoningDistrict'),['*'],True)
    ]

var UnionSets = Union(FSets)
var Address = $feature
var Check = Within(Address,UnionSets)
iif( TypeOf( Check ) == 'FeatureSet', Check, 'Nothing Within')
	
// Option 2: looping through a list of layers and getting the appropriate values
var FSets = [
    FeatureSetByName($map,'ConditionalZoning'),['*'],True),
    FeatureSetByName($map,'LawrenceZoningDistrict'),['*'],True),
    FeatureSetByName($map,'DouglasCountyZoningDistrict'),['*'],True)
    ]

var Address = $feature

var TextValues = []
for( var fs in FSets ){
	fs = FSets[i]
	var V = First(Intersects(Address,fs))
	if(TypeOf(intfs)=='Feature'){ Push(TextValues,V['<fieldname>']) }
	}
iif( Count(TextValues)>0, Concatenate(TextValues,'\n'), 'Address does not fall within')
0 Kudos
AmyRoust
Frequent Contributor

@RPGIS your first assumption is correct - all three layers are published as one service. I only need to pull the intersecting value from the Lawrence Zoning District layer, but it wouldn't hurt to pull the value from the Conditional Zoning layer. Either way, neither Within() nor Intersects() works with the zoning service. It does work with our parcel service.

AmyRoust_0-1759867861002.png

The parcel service just has one layer, which is what led me to suspect that the multi-layer service was the issue for me. I took that exact block of code in the screenshot above and just swapped out parcel for zoning, and it returns an error.

@KenBuja you asked, "Did you test the code on an actual feature in the Zoning District?" Yes, I did try that. No luck.

All three of these services are public, so if anyone wants to test on the actual data, here are links to the item pages in AGO:

Address Point: https://lawrenceks.maps.arcgis.com/home/item.html?id=0e4a33c0f05e483284f046c220b8f0c0

Parcel: https://lawrenceks.maps.arcgis.com/home/item.html?id=08285f4b4aca41a785afcc47c5044d2e

Zoning Districts: https://lawrenceks.maps.arcgis.com/home/item.html?id=8cfd05010c2d4cc499cc701c91e3c2b0

0 Kudos
KenBuja
MVP Esteemed Contributor

I've used your layers in a map and it works as expected. The code I'm using is 

var fs = FeatureSetByName($map, "Lawrence Zoning District", ["ZoningDistrict"]);
var WithinFS = Within($feature, fs);
iif(
  Count(WithinFS) == 0,
  "Not in a zoning district.",
  First(WithinFS).ZoningDistrict
);

which returns this when run in the text editor (using iif to return a message if there are no features returned by the Within)

KenBuja_0-1759870093203.png

and this in the popup ("R-2", circled in red)

Screenshot 2025-10-07 165126.png

0 Kudos
RPGIS
by MVP Regular Contributor
MVP Regular Contributor

Hi @AmyRoust . Try the following.

var P = Portal('https://lawrenceks.maps.arcgis.com/')
var Addr = FeatureSetByPortalItem(P, '0e4a33c0f05e483284f046c220b8f0c0',0,['*'],True)
var Parcs = FeatureSetByPortalItem(P, '8cfd05010c2d4cc499cc701c91e3c2b0','*',['*'],True)

var Test = []
for( var i in Parcs){
  var N = First(Intersects( Addr, Geometry(i)))
  if( TypeOf(N)=='Feature' ){
    N = Dictionary(N).attributes
    Console(N)
    Push(Test,N)
    }
  if( Count(Test) <= 10 ){Break}
  }
If( Count(Test)>0){ Console(Concatenate(Test,'\n')) }

You can play around with it in the Arcade Playground.

0 Kudos