Select to view content in your preferred language

Run spatial query when a new feature has been created in a feature layer

1601
17
Jump to solution
12-08-2022 07:04 AM
AndrewReynoldsDevon
Occasional Contributor

I have a feature layer with 3 values that exist in other layers that contain information that I want stored in the point layer. I need to run a spatial query when a new feature has been created to look up data in these other 2 layers & then record this data in the main point layer. How can you achieve this?

Tags (1)
0 Kudos
17 Replies
AndrewReynoldsDevon
Occasional Contributor

If I create a point & it saves it returns the value of Null

 

0 Kudos
JohannesLindner
MVP Frequent Contributor

Sorry, I forgot to answer yesterday...

 

does all of the required data need to live within the same project/map service or can the code work with other layers that already exist on our enterprise server?

The data has to be in the same datastore for the FeaturesetByName() function. If you have data in your Portal, you can use that with the FeaturesetByPortalItem()  function.

 

The arcade code can't find the name of the feature?

There's a space in the name ("Feature X"), which is not allowed for feature classes. You're probably trying to input the feature class's alias. You have to use the actual name.

 

I have a field in the point feature class with the same name as the field that I'm looking up in the other layer. I specified this field when creating the expression but do you need to specify it in the code?

Yes. The f.Field in my sample expressions was meant as a placeholder for the actual field names.

 

rather than intersecting I need to use 'contains within'.

It doesn't work that way around, which is also why you get null. This is the signature of Contains():

Contains(containerGeometry, insideFeatures)

It expects a geometry or feature as first argument and a featureset as second argument. You're supplying a featureset (the polygons) as first argument and a feature (the point) as second. And even if you do it the right way, it won't return any results, because a point can't contain a polygon. You have to use Intersects(), which is OK, because if a polygon contains a point, that point will intersect the polygon.

 

Therefore the query will need to be something like  - when a point is created in this particular polygon look up these 2 values - the name of the person who is responsible for the polygon & the polygon area name. These 2 values will the populate the fields in the point class. 

So the rule would look like this (mashup of my two previous examples, with more descriptive variable names)

 

// field for the rule: empty


// load the polygon feature class
var polygons = FeaturesetByName($datastore, "NameOfThePolygonFeatureClass")

// get the first polygon that intersects this point
var i_polygon = First(Intersects(polygons, $feature))

// get the responsible person
var person = Iif(i_polygon == null, null, i_polygon.ResponsiblePeron)

// get the polygon's name
var name = Iif(i_polygon == null, null, i_polygon.PolygonName)

// return
return {
    result: {attributes: {
        ResponsiblePerson: person,
        PolygonName: name
    }}
}

 

Things you have to change:

  • name (not alias!) of the polygon feature class, line 5
  • field name (not alias!) for the person in the polygon fc (line 11) and the point fc (line 19)
  • field name (not alias!) for the polygon's name (lines 14 and 20)

 


Have a great day!
Johannes
0 Kudos
AndrewReynoldsDevon
Occasional Contributor

@JohannesLindner 

Thanks for you explanation above. The code I'm using now is below where I have replaced the names of the fields as you said.

On line 5 I used the name of the Polygon feature

On line 11 & 19 I've used 'ElectoralArea'  which is the field that I want to obtain the value from.

On line 14 & 20 I've used 'ElectoralArea' again.

I have the the field 'ElectoralArea' in the point fc which is blank & the values are contained within the polygon layer.  When I create the attribute rule I set the field to ElectoralArea. 

 

// field for the rule: empty

// load the polygon feature class
var polygons = FeatureSetByName($datastore, "Highways.HIGHWAYMGR.HWDataCollectionPoly")

// get the first polygon that intersects this point
var i_polygon = First(Intersects(polygons, $feature))

// get the responsible person
var person = Iif(i_polygon == null, null, i_polygon.ElectoralArea)

// get the polygon's name
var name = Iif(i_polygon == null, null, i_polygon.ElectoralArea)

// return
return {
    result: {attributes: {
        ElectoralArea: person,
        ElectoralArea: name
    }}
}

edit error.JPG

0 Kudos
AndrewReynoldsDevon
Occasional Contributor

Both the polygon & the point features are manager connections & I looked at the design of both features & the field's that I'm interested in aren't set to Read Only so not sure why I'm getting the error saying 'Field is not Editable' 

0 Kudos
JohannesLindner
MVP Frequent Contributor

Hmmm. I tested the rule again, and it works for me. Are you sure that the field "HWDataCollectionPoints.ElectoralArea" is editable?

Can you send me the two feature classes (export them into a new gdb or as shapefiles), either here or in a private message?


Have a great day!
Johannes
0 Kudos
AndrewReynoldsDevon
Occasional Contributor

ok so I've had some success with the code below which I have added 3 times with 3 rules so that each field is working. The test polygon layer is in the same geodb but the 'real' data lives in 2 different geodb's. I tried to reference by name in the same manner but it says 'can't find the table'.  I could move this data so that it all resides in the same geodb but then the data lives in those geodb's for a reason as it's done by datatype. I can't use the getfromportal as the data is sensitive - how can I get around this issue?

// load the other featureset
var fs = FeatureSetByName($datastore, "EnvGIS.ENVMGR.Highway_Officer_AreasPoly")
// 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.HighwaysOfficer

 

0 Kudos
AndrewReynoldsDevon
Occasional Contributor

I was playing around so moved the data as a test so all in the same geodb. In my test above the field HighwaysOfficer for example was the same in both the point & polygon fc which worked fine. But as you can see in the schema below the point field names are on the left & the polygon names are on the right. I updated the code by returning the field name of the polygon feature at the end of the code but that doesn't work?

field names.JPG

0 Kudos
AndrewReynoldsDevon
Occasional Contributor

I managed to get it working in the end by deleting the fields in the point feature, creating them again to match the polygon features & then using those in the code. I'm now going to publish to the portal to see if the rules persist & it works as it does in the Pro Project 

0 Kudos