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!
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.
<SPAN class="comment token">#-------------------------------------------------------------------------------</SPAN> <SPAN class="comment token"># Name: xyz.py</SPAN> <SPAN class="comment token"># Purpose: Exports the photos from the Survey123 Photos form from a exported GDB</SPAN> <SPAN class="comment token"># Assumes state dir is already there</SPAN> <SPAN class="comment token"># Will check for and create PrimaryKey dir if needed</SPAN> <SPAN class="comment token"># For now it will overwrite every file as it goes. Plus and minus to this.</SPAN> <SPAN class="comment token">#</SPAN> <SPAN class="comment token"># Author: dbrowning</SPAN> <SPAN class="comment token">#</SPAN> <SPAN class="comment token"># Created: 10/31/2018</SPAN> <SPAN class="comment token"># Modified: 10/31/2018</SPAN> <SPAN class="comment token">#</SPAN> <SPAN class="comment token">#</SPAN> <SPAN class="comment token">#</SPAN> <SPAN class="comment token">#-------------------------------------------------------------------------------</SPAN> <SPAN class="keyword token">import</SPAN> os<SPAN class="punctuation token">,</SPAN> arcpy <SPAN class="comment token"># vars--------------------</SPAN> inDB <SPAN class="operator token">=</SPAN> r<SPAN class="string token">"SomethingIN.gdb"</SPAN> <SPAN class="comment token"># to get the names and PrimaryKey</SPAN> photoForm <SPAN class="operator token">=</SPAN> <SPAN class="string token">"Photos"</SPAN> <SPAN class="comment token"># actual attachements table</SPAN> attachName <SPAN class="operator token">=</SPAN> <SPAN class="string token">"Photos__ATTACH"</SPAN> outDir <SPAN class="operator token">=</SPAN> r<SPAN class="string token">"Something\Photos"</SPAN> <SPAN class="comment token"># should be standard</SPAN> fldBLOB <SPAN class="operator token">=</SPAN> <SPAN class="string token">'DATA'</SPAN> fldAttName <SPAN class="operator token">=</SPAN> <SPAN class="string token">'ATT_NAME'</SPAN> dateLoadedInDb <SPAN class="operator token">=</SPAN> <SPAN class="string token">"2018-09-01"</SPAN> <SPAN class="comment token"># vars--------------------</SPAN> <SPAN class="comment token"># join to Photos form to get the PrimaryKey and state info</SPAN> <SPAN class="comment token"># Note the first year they called it PlotKey instead</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>MakeTableView_management<SPAN class="punctuation token">(</SPAN>inDB <SPAN class="operator token">+</SPAN> <SPAN class="string token">"\\"</SPAN> <SPAN class="operator token">+</SPAN> attachName<SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"attachView"</SPAN><SPAN class="punctuation token">)</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>AddJoin_management<SPAN class="punctuation token">(</SPAN><SPAN class="string token">"attachView"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"REL_GLOBALID"</SPAN><SPAN class="punctuation token">,</SPAN> inDB <SPAN class="operator token">+</SPAN> <SPAN class="string token">"\\"</SPAN> <SPAN class="operator token">+</SPAN> photoForm<SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"globalid"</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="comment token"># funky due to the join</SPAN> fieldList <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN>attachName <SPAN class="operator token">+</SPAN> <SPAN class="string token">"."</SPAN> <SPAN class="operator token">+</SPAN> fldBLOB<SPAN class="punctuation token">,</SPAN> attachName <SPAN class="operator token">+</SPAN> <SPAN class="string token">"."</SPAN> <SPAN class="operator token">+</SPAN> fldAttName<SPAN class="punctuation token">,</SPAN> photoForm <SPAN class="operator token">+</SPAN> <SPAN class="string token">".PlotKey"</SPAN><SPAN class="punctuation token">,</SPAN> photoForm <SPAN class="operator token">+</SPAN> <SPAN class="string token">".Office"</SPAN><SPAN class="punctuation token">,</SPAN> photoForm <SPAN class="operator token">+</SPAN> <SPAN class="string token">".filename_T1"</SPAN><SPAN class="punctuation token">,</SPAN> photoForm <SPAN class="operator token">+</SPAN> <SPAN class="string token">".filename_T2"</SPAN><SPAN class="punctuation token">,</SPAN> photoForm <SPAN class="operator token">+</SPAN> <SPAN class="string token">".filename_T3"</SPAN> \ <SPAN class="punctuation token">,</SPAN>photoForm <SPAN class="operator token">+</SPAN> <SPAN class="string token">".filename_Soil1"</SPAN><SPAN class="punctuation token">,</SPAN> photoForm <SPAN class="operator token">+</SPAN> <SPAN class="string token">".filename_Soil2"</SPAN><SPAN class="punctuation token">,</SPAN> photoForm <SPAN class="operator token">+</SPAN> <SPAN class="string token">".filename_Soil3"</SPAN><SPAN class="punctuation token">,</SPAN> photoForm <SPAN class="operator token">+</SPAN> <SPAN class="string token">".MiscPhoto1filename"</SPAN><SPAN class="punctuation token">,</SPAN> photoForm <SPAN class="operator token">+</SPAN> <SPAN class="string token">".MiscPhoto2filename"</SPAN><SPAN class="punctuation token">,</SPAN> photoForm <SPAN class="operator token">+</SPAN> <SPAN class="string token">".MiscPhoto3filename"</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="keyword token">with</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>da<SPAN class="punctuation token">.</SPAN>SearchCursor<SPAN class="punctuation token">(</SPAN><SPAN class="string token">"attachView"</SPAN><SPAN class="punctuation token">,</SPAN> fieldList<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">as</SPAN> cursor<SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">for</SPAN> row <SPAN class="keyword token">in</SPAN> cursor<SPAN class="punctuation token">:</SPAN> binaryRep <SPAN class="operator token">=</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="comment token"># save to disk</SPAN> <SPAN class="comment token"># build output path of base + State + PrimaryKey (PlotKey + DateLoadedInDb)</SPAN> <SPAN class="comment token"># for now need to check for blank PlotKey and blank Office - which should be fixed already</SPAN> <SPAN class="keyword token">if</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">3</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">==</SPAN> None <SPAN class="operator token">or</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">2</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">==</SPAN> None<SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">print</SPAN> <SPAN class="string token">"Warning Null values found in the Office or PlotKey field. Skipping photo. Must fix!!"</SPAN> <SPAN class="keyword token">print</SPAN> <SPAN class="string token">" ATT_NAME is "</SPAN> <SPAN class="operator token">+</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">1</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="keyword token">else</SPAN><SPAN class="punctuation token">:</SPAN> baseOut <SPAN class="operator token">=</SPAN> outDir <SPAN class="operator token">+</SPAN> <SPAN class="string token">"\\"</SPAN> <SPAN class="operator token">+</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">3</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">:</SPAN><SPAN class="number token">2</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">+</SPAN> <SPAN class="string token">"\\"</SPAN> <SPAN class="operator token">+</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">2</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">+</SPAN> dateLoadedInDb <SPAN class="comment token"># check to see if already PrimaryKey dir there - if not create it</SPAN> <SPAN class="keyword token">if</SPAN> <SPAN class="operator token">not</SPAN> os<SPAN class="punctuation token">.</SPAN>path<SPAN class="punctuation token">.</SPAN>exists<SPAN class="punctuation token">(</SPAN>baseOut<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> os<SPAN class="punctuation token">.</SPAN>makedirs<SPAN class="punctuation token">(</SPAN>baseOut<SPAN class="punctuation token">)</SPAN> <SPAN class="comment token"># 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</SPAN> whichPhoto <SPAN class="operator token">=</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">1</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">.</SPAN>split<SPAN class="punctuation token">(</SPAN><SPAN class="string token">"-"</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="keyword token">if</SPAN> whichPhoto <SPAN class="operator token">==</SPAN> <SPAN class="string token">"T1"</SPAN><SPAN class="punctuation token">:</SPAN> fileName <SPAN class="operator token">=</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">4</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">+</SPAN> <SPAN class="string token">".jpg"</SPAN> <SPAN class="keyword token">elif</SPAN> whichPhoto <SPAN class="operator token">==</SPAN> <SPAN class="string token">"T2"</SPAN><SPAN class="punctuation token">:</SPAN> fileName <SPAN class="operator token">=</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">5</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">+</SPAN> <SPAN class="string token">".jpg"</SPAN> <SPAN class="keyword token">elif</SPAN> whichPhoto <SPAN class="operator token">==</SPAN> <SPAN class="string token">"T3"</SPAN><SPAN class="punctuation token">:</SPAN> fileName <SPAN class="operator token">=</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">6</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">+</SPAN> <SPAN class="string token">".jpg"</SPAN> <SPAN class="keyword token">elif</SPAN> whichPhoto <SPAN class="operator token">==</SPAN> <SPAN class="string token">"Soil1"</SPAN><SPAN class="punctuation token">:</SPAN> fileName <SPAN class="operator token">=</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">7</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">+</SPAN> <SPAN class="string token">".jpg"</SPAN> <SPAN class="keyword token">elif</SPAN> whichPhoto <SPAN class="operator token">==</SPAN> <SPAN class="string token">"Soil2"</SPAN><SPAN class="punctuation token">:</SPAN> fileName <SPAN class="operator token">=</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">8</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">+</SPAN> <SPAN class="string token">".jpg"</SPAN> <SPAN class="keyword token">elif</SPAN> whichPhoto <SPAN class="operator token">==</SPAN> <SPAN class="string token">"Soil3"</SPAN><SPAN class="punctuation token">:</SPAN> fileName <SPAN class="operator token">=</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">9</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">+</SPAN> <SPAN class="string token">".jpg"</SPAN> <SPAN class="keyword token">elif</SPAN> whichPhoto <SPAN class="operator token">==</SPAN> <SPAN class="string token">"MiscPhoto1"</SPAN><SPAN class="punctuation token">:</SPAN> fileName <SPAN class="operator token">=</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">10</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">+</SPAN> <SPAN class="string token">".jpg"</SPAN> <SPAN class="keyword token">elif</SPAN> whichPhoto <SPAN class="operator token">==</SPAN> <SPAN class="string token">"MiscPhoto2"</SPAN><SPAN class="punctuation token">:</SPAN> fileName <SPAN class="operator token">=</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">11</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">+</SPAN> <SPAN class="string token">".jpg"</SPAN> <SPAN class="keyword token">elif</SPAN> whichPhoto <SPAN class="operator token">==</SPAN> <SPAN class="string token">"MiscPhoto3"</SPAN><SPAN class="punctuation token">:</SPAN> fileName <SPAN class="operator token">=</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">12</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">+</SPAN> <SPAN class="string token">".jpg"</SPAN> <SPAN class="comment token"># in case some / got in there. this should not happen now!</SPAN> fileName <SPAN class="operator token">=</SPAN> fileName<SPAN class="punctuation token">.</SPAN>replace<SPAN class="punctuation token">(</SPAN><SPAN class="string token">"/"</SPAN><SPAN class="punctuation token">,</SPAN><SPAN class="string token">""</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="comment token"># save out the file</SPAN> open<SPAN class="punctuation token">(</SPAN>baseOut <SPAN class="operator token">+</SPAN> os<SPAN class="punctuation token">.</SPAN>sep <SPAN class="operator token">+</SPAN> fileName<SPAN class="punctuation token">,</SPAN> <SPAN class="string token">'wb'</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>write<SPAN class="punctuation token">(</SPAN>binaryRep<SPAN class="punctuation token">.</SPAN>tobytes<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">del</SPAN> cursor<SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
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?
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.
You can also do this with an image 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.
Les membres connectés peuvent publier, suivre les mises à jour, et plus encore. Nouveau ici ? Inscrivez-vous gratuitement.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.