Select to view content in your preferred language

Feature Service with Related Table Symbology and Popup

314
1
09-01-2022 07:22 AM
aam
by
Frequent Contributor

I am looking to get some help with popups and symbology. Here is the situation;

We get severe windstorms in our City which a lot of times damage the trees, the trees fall on properties or on the roads. So, I am building an ArcGIS Online reporting application where the residents can report a damaged tree.

We have inventory of all the trees and I have the point data layer. The idea is to have a mapping app where the user can see individual point for a tree and has the capability to click and report using survey123. As the Report is received/verified by the staff I want the symbology to change on the map to show regular trees and trees that have been reported. I also want the popups to be different for the regular trees and the damaged ones that have been reported. Essentially when someone clicks on a reported tree they should not see the link to survey123 and instead a message that says "tree has already been reported".

I’ve already done most of the things mentioned above; however, I am stuck at the symbology/popup part of the process. Can someone suggest what would be the ideal way to have two different symbology and a popup?

0 Kudos
1 Reply
KimOllivier
Honored Contributor

I am trying to do the same. My hope was that you might be able to do this with Arcade from a parent/child relation. Maybe you can. However it will be quite complex because you will need to allow for multiple child records and you will need to use the last record. So turn on EditTracking. I have then found it would be possible to update the parent feature with the latest record using the Python API by offloading all the hard work to Pandas.

Get a list of visit records and find the latest date for each GUID that is a foreign key to the GlobalID. Now you have a dataframe of these records to update the main layer with whatever you want to calculate into a status field ready to be symbolised. Note the magic one-liner at line 24. This script was in Pro, so there are a few changes to get a featureset in AGOL using fl.query_related_records()

 

# excess WeedLocations fields joined when adding extra visit events will be cleaned up...

# dictionary of field mappings so far from Visits_Table to WeedLocations
visit_to_weed = {
    'Guid_visits': 'GlobalID', # foreign key -> primary key
    'EditDate_1':'DateVisitMadeFromLastVisit', # for latest date
    "WeedVisitStatus":'StatusFromLastVisit', # as inspected
    'DifficultyChild':'DifficultyFromLastVisit', # as inspected
    'VisitStage':'LatestVisitStage', # as inspected
    'Area':'LatestArea' # as inspected
    }
# extract the data required from the database Visits_Table, don't even need a primary key eg GlobalID
# In the future we will put on a filter greater than the last update
filter = '' #"""EditDate_1 > date '{}'""".format('2022-07-01')
in_flds = list(visit_to_weed.keys()) # ['Guid_visits','EditDate_1','WeedVisitStatus','DifficultyChild','VisitStage','Area']
out_flds = list(visit_to_weed.values())
vdate =[row for row in arcpy.da.SearchCursor(visits,in_flds,filter)]
print('vdate:',len(vdate))
# put in a pandas dataframe 
df = pd.DataFrame(vdate,columns=in_flds)
# find the record with max edit date by visit and keep the other details all in one line!
idx = df.groupby(['Guid_visits'])['EditDate_1'].transform(max) == df['EditDate_1']
# print(df[idx])
dVisit = df.set_index('Guid_visits').T.to_dict('list')
# print(dVisit.get('{08125D4D-4725-4A26-BAC9-98BE7EF0784C}',"Missing"))
# {08125D4D-4725-4A26-BAC9-98BE7EF0784C}, 2022-08-23 03:04:01.644000, None, None, None, NaN
# Count visits for each location
vguid = [row[0] for row in arcpy.da.SearchCursor(visits,['GUID_visits'], "GUID_visits is not NULL")]
# dict of counts by GlobalID for updating
vguid_counts = collections.Counter(vguid)

# put counts in new field VisitCount for now
if len(arcpy.ListFields(weeds,'VisitCount')) == 0:
    arcpy.management.AddField(weeds,'VisitCount','LONG')
with arcpy.da.UpdateCursor(weeds, ['VisitCount'] + out_flds) as cur:
    n = 0
    for row in cur:
        try:
            row[1] = vguid_counts[row[0]]
            if dVisit.get(row[0],None):
                row[2] = dVisit.get(row[0],None)[0]
                row[3] = dVisit.get(row[0],None)[1]
                row[4] = dVisit.get(row[0],None)[2]
                row[5] = dVisit.get(row[0],None)[3]
                row[6] = dVisit.get(row[0],None)[4]
            cur.updateRow(row)
            n+=1
        except Exception as e:
            arcpy.AddMessage(row)
            arcpy.AddMessage(e)
arcpy.AddMessage("Well Done, {} records updated".format(n))

 

 

0 Kudos