Associating Batch Downloaded Photos from Survey123 to Certain Records

1437
4
04-18-2019 11:21 AM
deleted-user-j8u2waHrLNX3
New Contributor II

Hi there,

I was wondering how photos that have been batch downloaded from Survey123 can be associated to the record with which it was submitted. The field workers that will be using the form need to take pictures at a site but when the photos are batched downloaded using a Python script there is no additional information. The survey contains a SiteID question and I wanted to associate each photo to the site at which it was taken. The photo question is a repeat because several photos need to be taken at each site. Is there anyway for site information to be attached to each photo? Maybe changing the name of the photos to something that involves the site name?

Thanks for your help!

Tags (2)
0 Kudos
4 Replies
DougBrowning
MVP Esteemed Contributor

Yep.  Here is my script that names the photos based on fields in the survey.  It also creates dirs to export to based on fields.  It was adapted from the standard one Esri posted in the past.

#-------------------------------------------------------------------------------
# Name:        XX.py
# Purpose:     Exports the photos from the Survey123 Photos form from a exported GDB
#               Assumes state dir is already there
#               Will check for and create PrimaryKey dir if needed
#               For now it will overwrite every file as it goes.  Plus and minus to this.
#
# Author:      dbrowning
#
# Created:     10/31/2018
# Modified:    10/31/2018
#
#
#
#-------------------------------------------------------------------------------

import os, arcpy

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

outDir = r"Something\Photos"

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

dateLoadedInDb = "2018-09-01"

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

# 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_Soil1", photoForm + ".filename_Soil2", photoForm + ".filename_Soil3", photoForm + ".MiscPhoto1filename", photoForm + ".MiscPhoto2filename", photoForm + ".MiscPhoto3filename"]
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]
      else:
        baseOut = outDir + "\\" + row[3][:2] + "\\" + row[2] + dateLoadedInDb
        # check to see if already PrimaryKey dir there - if not create it
        if not os.path.exists(baseOut):
            os.makedirs(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 == "Soil1":
            fileName = row[7] + ".jpg"
        elif whichPhoto == "Soil2":
            fileName = row[8] + ".jpg"
        elif whichPhoto == "Soil3":
            fileName = row[9] + ".jpg"
        elif whichPhoto == "MiscPhoto1":
            fileName = row[10] + ".jpg"
        elif whichPhoto == "MiscPhoto2":
            fileName = row[11] + ".jpg"
        elif whichPhoto == "MiscPhoto3":
            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
0 Kudos
deleted-user-j8u2waHrLNX3
New Contributor II

Hi Doug,

Thanks for the reply, I'm having a bit if trouble working through your script. At line 36 what does the "attachView" refer to? Also, within the field list are all the fields in quotes the names of fields in the survey?

0 Kudos
DougBrowning
MVP Esteemed Contributor

See the line right above it. You must make a view first in order to do a join.  Did you set he inDB and all that?

Yes those are field names.  See when you do a join it names the fields joinname.fieldname (just like when joining in ArcMap).  So you must reference then that way.

Note I am only doing the join because in mine i need to get some attributes from a another table in my service.  You prob do not need that part.

0 Kudos
PaulCone2
Occasional Contributor III

You can also do this with an image repeat...

begin repeatbuilding_photos
imageimage
end repeat

and then point your survey to an existing feature service which is built from a FGDB that has relationships between the records and the attached photos...

Then the photos are in the database, attached to the appropriate parent records.

0 Kudos