Hi community. I have the data expression below pulling some data from one of my hosted layers with point features, and reformatting it to drive some charts in my Dashboard. So far so good.
What I'm needing to do now is add an attribute to every point/record based on the REGION polygon that it falls within (a good old spatial join)
I think what I need to do is to use the Contains() function and loop through each point in fs, find the polygon in poly_fs that it falls within, grab the value in the NAME field of poly_fs, and append it to the dictionary that I'm building that contains my modified fs table.
Seeking any advice on an efficient way to loop through this given that the geometry function may make this slow to execute anyway.
The only change that I've made to prepare for this new function is adding a new variable in line 13
//ground actions - time of day
//obtains the hour in military (long) format from the creation_date field
// Write an expression that returns a FeatureSet.
// Documentation: https://arcg.is/3c419TD
// Samples: https://arcg.is/38SEWWz
// Create a FeatureSet from the Feature Layer containing the Ground action data.
var fs =FeatureSetByPortalItem(Portal('https://gis.ABCCD.au/portal'), '0116ef7ee89c4de0829fe554315e2177', 0)
var poly_fs =FeatureSetByPortalItem(Portal('https://gis.ABCCD.au/portal'), 'e09bf35374724d04b413bbb09db9ff40', 3)
var outDict = {
'fields': [{ 'name': 'hr_num', 'type': 'esriFieldTypeInteger'},
{'name': 'OBJECTID','type': 'esriFieldTypeInteger'},
{'name': 'creation_date','type': 'esriFieldTypeDate'},
{'name': 'militaryhr', 'type': 'esriFieldTypeString'},
{'name': 'ABC_Organisation','type': 'esriFieldTypeString'},
{'name': 'Operation_Number','type': 'esriFieldTypeString'},
{'name': 'species', 'type': 'esriFieldTypeString'}],
'geometryType': '',
'features': []
};
var index = 0;
for (var feature in fs) {
outDict.features[index] = {
'attributes': {
'hr_num': Hour(feature['creation_date']),
'objectid': feature['OBJECTID'],
'creation_date': number(feature['creation_date']),
'militaryhr': Text(feature['creation_date'], 'HH'),
'ABC_Organisation': feature['ABC_Organisation'],
'Operation_Number': feature['Operation_Number'],
'species': feature['species_common_name']
}}
index++;}
// Convert dictionary to feature set.
var fs_dict = FeatureSet(Text(outDict));
// Return data
return fs_dict;
Solved! Go to Solution.
Try using a real if/else statement, rather than iif.
var int_poly = Intersects(feature, poly_fs)
if (Count(int_poly) > 0){
var poly_name = First(int_poly)['VEA_NAME']
} else {
var poly_name = 'None'
}
Any luck?
Since you're working with points (that is, there's no possibility for partial containment), you can just do Intersects. Throw these lines into your for loop:
var xs_poly = First(Intersects(feature, poly_fs))
var poly_name = xs_poly['NAME']
Then pipe poly_name into the feature attributes. Oh, and make a field for it in your dictionary, obviously.
thanks @jcarlson that's almost got me over the line. I was chasing an error until I realised that the test polygon dataset that I'm using doesn't always completely cover the point dataset. When I switch over to the real polygon dataset this should be unlikely, but there's still the chance that a user may add a point over the ocean somewhere, so best I counter this in the code!! Thus I've been trying to check for where the Intersects returns a null but without much success
What I was trying to do with line 42 was to insert "None" into the table if there wasn't a result from the point in polygon intersection, otherwise use the real value from xs_poly. Line 43 will work, but when I switch this out and replace it with line 42 still fails everytime time a 0 is encountered
//ground action - time of day
//obtains the hour in military (long) format from the creation_date field
// Write an expression that returns a FeatureSet.
// Documentation: https://arcg.is/3c419TD
// Samples: https://arcg.is/38SEWWz
// Create a FeatureSet from the Feature Layer containing the Ground action data.
var fs =FeatureSetByPortalItem(Portal('https://gis.ABCD.au/portal'), '0116ef7ee89c4de0829fe554315e2177', 0)
var poly_fs =FeatureSetByPortalItem(Portal('https://gis.ABCD.au/portal'), 'e09bf35374724d04b413bbb09db9ff40', 3)
var outDict = {
'fields': [{ 'name': 'hr_num', 'type': 'esriFieldTypeInteger'},
{'name': 'OBJECTID','type': 'esriFieldTypeInteger'},
{'name': 'creation_date','type': 'esriFieldTypeDate'},
{'name': 'militaryhr', 'type': 'esriFieldTypeString'},
{'name': 'actioner_Organisation','type': 'esriFieldTypeString'},
{'name': 'Operation_Number','type': 'esriFieldTypeString'},
{'name': 'species', 'type': 'esriFieldTypeString'},
{'name': 'pvregion', 'type': 'esriFieldTypeString'}],
'geometryType': '',
'features': []
};
var index = 0;
for (var feature in fs) {
var int_poly = Intersects(feature, poly_fs)
var xs_poly = First(int_poly)
//var poly_name = xs_poly['VEA_NAME']
var countPolys = Count(int_poly)
Console(countPolys)
// var poly_name = iif(countPolys>0,'None',xs_poly['VEA_NAME'])
var poly_name = iif(countPolys>0,'PolygonIntersected','NoPolygonintersection')
Console(poly_name)
outDict.features[index] = {
'attributes': {
'hr_num': Hour(feature['creation_date']),
'objectid': feature['OBJECTID'],
'creation_date': number(feature['creation_date']),
'militaryhr': Text(feature['creation_date'], 'HH'),
'actioner_Organisation': feature['actioner_Organisation'],
'Operation_Number': feature['Operation_Number'],
'species': feature['species_common_name'],
'pvregion': poly_name
}}
index++;}
// Convert dictionary to feature set.
var fs_dict = FeatureSet(Text(outDict));
// Return data
return fs_dict;
Try using a real if/else statement, rather than iif.
var int_poly = Intersects(feature, poly_fs)
if (Count(int_poly) > 0){
var poly_name = First(int_poly)['VEA_NAME']
} else {
var poly_name = 'None'
}
Any luck?
perfect!! Thanks @jcarlson Hope you have a lovely weekend wherever you are!
final code:
//ground action - time of day
//obtains the hour in military (long) format from the creation_date field
// Write an expression that returns a FeatureSet.
// Documentation: https://arcg.is/3c419TD
// Samples: https://arcg.is/38SEWWz
// Create a FeatureSet from the Feature Layer containing the Ground action data.
var fs =FeatureSetByPortalItem(Portal('https://gis.ABCD.au/portal'), '0116ef7ee89c4de0829fe554315e2177', 0)
var poly_fs =FeatureSetByPortalItem(Portal('https://gis.ABCD.au/portal'), 'e09bf35374724d04b413bbb09db9ff40', 3)
var outDict = {
'fields': [{ 'name': 'hr_num', 'type': 'esriFieldTypeInteger'},
{'name': 'OBJECTID','type': 'esriFieldTypeInteger'},
{'name': 'creation_date','type': 'esriFieldTypeDate'},
{'name': 'militaryhr', 'type': 'esriFieldTypeString'},
{'name': 'actioner_Organisation','type': 'esriFieldTypeString'},
{'name': 'Operation_Number','type': 'esriFieldTypeString'},
{'name': 'species', 'type': 'esriFieldTypeString'},
{'name': 'pvregion', 'type': 'esriFieldTypeString'}],
'geometryType': '',
'features': []
};
var index = 0;
for (var feature in fs) {
var int_poly = Intersects(feature, poly_fs)
var xs_poly = First(int_poly)
// If statement to check if there is a successful point in polygon intersection.
// If successful, then relevant values from the VEA_NAME field are appended to the Ground action table. If not, then insert 'None' into the table.
if (Count(int_poly) > 0){
var poly_name = First(int_poly)['VEA_NAME']
} else {
var poly_name = 'None'
}
outDict.features[index] = {
'attributes': {
'hr_num': Hour(feature['creation_date']),
'objectid': feature['OBJECTID'],
'creation_date': number(feature['creation_date']),
'militaryhr': Text(feature['creation_date'], 'HH'),
'actioner_Organisation': feature['actioner_Organisation'],
'Operation_Number': feature['Operation_Number'],
'species': feature['species_common_name'],
'pvregion': poly_name
}}
index++;}
// Convert dictionary to feature set.
var fs_dict = FeatureSet(Text(outDict));
// Return data
return fs_dict;