Match Survey123 Photo Attachments to Feature in Field Maps

02-24-2021 01:50 PM
Occasional Contributor III

We have a Field Maps app that shows floor plans at our sites. Custodians click on the room they are in and launch a Survey123 survey. The room data (space ID, room number, room type, etc) are passed to S123 in a custom URL. The problem we're having is that photo attachments don't contain any attributes that tie them to the room they are coming from. There is a REL_GLOBALID field in the attachment table but it doesn't match the Global ID of the room feature. Is there a way to pass the room's space ID to the attachment so we can batch export them and know what room they are associated with?

2 Replies
MVP Esteemed Contributor

What I do is create names for the photos in the form that has the ID.  I then use GlobalID to join and export while renaming the photo to what I want.  I also create a dir for each photo.

Here is the code.  I create based on a ID created on the fly which makes it longer so hope this makes sense.

import os, arcpy

# vars--------------------
inDB = r"CA2020RawDownload.gdb"
# to get the names and PrimaryKey
photoForm = "Photos"
# actual attachements table
attachName = "Photos__ATTACH"

outDir = r"C:\tmp\Photos"

# should be standard
fldBLOB = 'DATA'
fldAttName = 'ATT_NAME'

dateLoadedInDb = "2020-09-01"

# vars--------------------

print "Starting"

# join to Photos form to get the PrimaryKey and state info
# Note the first year they called it PlotKey instead
arcpy.MakeTableView_management(inDB + "\\" + attachName, "attachView")
arcpy.AddJoin_management("attachView", "REL_GLOBALID", inDB + "\\" + photoForm, "globalid")
# funky due to the join
fieldList = [attachName + "." + fldBLOB, attachName + "." + fldAttName, photoForm + ".PlotKey", photoForm + ".Office", photoForm + ".filename_T1", photoForm + ".filename_T2", photoForm + ".filename_T3" \
            ,photoForm + ".filename_Soil", photoForm + ".MiscPhoto1filename", photoForm + ".MiscPhoto2filename", photoForm + ".MiscPhoto3filename", photoForm + ".MiscPhoto4filename", photoForm + ".MiscPhoto5filename"]
with arcpy.da.SearchCursor("attachView", fieldList) as cursor:
   for row in cursor:
      binaryRep = row[0]

      # save to disk
      # build output path of base + State + PrimaryKey (PlotKey + DateLoadedInDb)
      # for now need to check for blank PlotKey and blank Office - which should be fixed already
      if row[3] == None or row[2] == None:
        print "Warning Null values found in the Office or PlotKey field.  Skipping photo.  Must fix!!"
        print "   ATT_NAME is " + row[1]
        # 2020 change Office no longer a code so using first 2 letters of PlotKey which should be StateCode
        baseOut = outDir + "\\" + row[2][:2] + "\\" + row[2] + dateLoadedInDb
        # check to see if already PrimaryKey dir there - if not create it
        if not os.path.exists(baseOut):

        # Need to get the actual file name from the right field.  No real other way to do it with a SC so had to write it out
        whichPhoto = row[1].split("-")[0]
        if whichPhoto == "T1":
            fileName = row[4] + ".jpg"
        elif whichPhoto == "T2":
            fileName = row[5] + ".jpg"
        elif whichPhoto == "T3":
            fileName = row[6] + ".jpg"
        elif whichPhoto == "Soil":
            fileName = row[7] + ".jpg"
        elif whichPhoto == "MiscPhoto1":
            fileName = row[8] + ".jpg"
        elif whichPhoto == "MiscPhoto2":
            fileName = row[9] + ".jpg"
        elif whichPhoto == "MiscPhoto3":
            fileName = row[10] + ".jpg"
        elif whichPhoto == "MiscPhoto4":
            fileName = row[11] + ".jpg"
        elif whichPhoto == "MiscPhoto5":
            fileName = row[12] + ".jpg"

        # in case some / got in there.  this should not happen now!
        fileName = fileName.replace("/","")

        # save out the file
        open(baseOut + os.sep + fileName, 'wb').write(binaryRep.tobytes())

del cursor
print "All Done"


Occasional Contributor III

Ah, thank you. I realized I need to relate the attachment table not to the feature class, but the survey form that is related to the feature. That's where the attachment REL_GLOBALID matches the survey global ID.