|
POST
|
I am indeed using concat. I've experimented with all of the calculation modes, to no avail. I had hoped by forcing the calculation for the point whenEmpty (can't have it be always, as it could get overwritten, and it was defaulted as empty) would have worked, as it would have actively calculated, but it didn't really work as expected. Instead the map is hidden and you're just prompted to hit the refresh. When doing so the map appears with the point and the subsequent calculation works but it's not the behavior I'm looking for.
... View more
06-05-2025
10:25 AM
|
0
|
1
|
647
|
|
POST
|
@DougBrowning Those are good thoughts. A few things: I did not have a relevant telling it it wait until the ${treatments_point} is not empty, but the parser didn't like it due to dependency issues. I did, however, add two dummy fields to extract the x and y values from the ${treatments_point} and it does, so the form certainly thinks the point has a value. I can also submit the form, and the point carries over, even if I don't touch the map. The other oddity in all of this is that occasionally I will launch the survey and it will work just fine without me doing anything. I can't find rhyme or reason to it. As the survey is launched from URL parameters I can replicate it, and one will work fine then I'll do the same parameters again and it does the goofy behavior.
... View more
06-05-2025
09:17 AM
|
0
|
3
|
662
|
|
POST
|
I have a survey created in Survey123 Connect 3.20.63. My issue: two questions with dynamic choice lists using search appearance work very inconsistently. They take a geopoint question, buffer it by a specified distance, an use that buffer to query a layer with ~6k polygons. Sometimes it works perfectly, and pulls in the 2-4 polygons near the point, as appropriate. Other times it pulls in all 6k records until you've moved the point it references. Questions are configured exactly has recommended here: LINK Note: the whole operation takes place within a repeat. Additional background: This survey has two geopoint questions. The first is the 'incident point' and the second is the 'treatment point.' The impact point is calculated initially from the incident point as its default location, and the user is urged to move it. The survey was originally configured to use the dynamic choice list based on the incident point. When that was the case I never had this issue. When switching the choice list to the treatment point these inconsistent results started happening. There is a bit of a chain of calculations that generate the treatment point, but I've added some dummy fields to make sure the values are pulled and they are. searchUrl: concat("TRMTName?url=https://myurl.gov/arcgis/rest/services/CalMapper/CM_GDTreatments/FeatureServer/2&units=esriSRUnit_StatuteMile&orderByFields=TREATMENT_NAME ASC","&distance=",${SearchDistance}) Search appearnce: w1 field-list search(${searchURL},'intersects','@geopoint',${Treatments_point}) ${Treatments_point} is generated by concatenating the extracted X and Y values from ${Incidents_point}. This whole part works just fine. It's only since the search appearance came from the ${Treatments_point} rather than the ${Incidents_point} that I've had issues. Any ideas what gives?
... View more
06-04-2025
01:57 PM
|
0
|
6
|
721
|
|
BLOG
|
Is it possible to pull the entire EXIF structure as a JSON? I'd like to have a note in a survey that tells users to submit a different photo if the right EXIF data doesn't exist. I'm only grabbing angle, latitude, and longitude, so could just key off those, but I'm wondering if I could key off the parent GPS data to check if any exists.
... View more
04-08-2025
02:04 PM
|
0
|
0
|
1846
|
|
POST
|
Replying to my own post in case this helps anyone...I at least found a method to do so in Python after the fact. Forgive me for sloppy code... import requests
import arcgis
from PIL import Image
from PIL.ExifTags import TAGS, GPSTAGS, IFD
from io import BytesIO
import arcpy
userName = ''
print("Log in to Org Account")
gis = arcgis.GIS("https://yourOrg.maps.arcgis.com", username= userName)
print("Successfully logged in as " + str(gis.properties.user.username)
def get_exif_data(self):
exif_data = {}
info = self._getexif()
if info:
for tag, value in info.items():
decoded = TAGS.get(tag, tag)
if decoded == "GPSInfo":
gps_data = {}
for t in value:
sub_decoded = GPSTAGS.get(t, t)
gps_data[sub_decoded] = value[t]
exif_data[decoded] = gps_data
else:
exif_data[decoded] = value
return exif_data
def convert_to_degress(value):
"""Helper function to convert the GPS coordinates
stored in the EXIF to degress in float format"""
d = float(value[0])
m = float(value[1])
s = float(value[2])
return d + (m / 60.0) + (s / 3600.0)
def get_lat(self):
if 'GPSInfo' in self:
gps_info = self['GPSInfo']
if 'GPSLatitude' and 'GPSLatitudeRef' in gps_info:
gps_lat = gps_info['GPSLatitude']
gps_lat_ref = gps_info['GPSLatitudeRef']
if gps_lat and gps_lat_ref:
lat = convert_to_degress(gps_lat)
if gps_lat_ref !='N':
lat = 0-lat
print(f'GPSLatitude: {lat}')
return lat
else:
print('GPSLatitude not found!')
return None
else:
return None
def get_long(self):
if 'GPSInfo' in self:
gps_info = self['GPSInfo']
if 'GPSLongitude' and 'GPSLongitudeRef' in gps_info:
gps_long = gps_info['GPSLongitude']
gps_long_ref = gps_info['GPSLongitudeRef']
if gps_long and gps_long_ref:
long = convert_to_degress(gps_long)
if gps_long_ref !='E':
long = 0-long
print(f'GPSLongitude: {long}')
return long
else:
print("GPSLongitude not found!")
return None
else:
return None
def get_angle(self):
if 'GPSInfo' in self:
gps_info = self['GPSInfo']
if 'GPSImgDirection' in gps_info:
gps_angle = gps_info['GPSImgDirection']
if gps_angle:
print(f'GPSImgDirection: {gps_angle}')
return gps_angle
else:
print(f'GPSImgDirection not found!')
return None
else:
return None
layerID = ''
layerItem = arcgis.gis.Item(gis, layerID)
photoPointLayer = layerItem.layers[]
where_clause = "PhotoAngle IS NULL OR PhotoLat IS NULL OR PhotoLong IS NULL"
photoPointFSet = photoPointLayer.query(where=where_clause, return_geometry=False)
runCount = len(photoPointFSet)
if runCount > 0:
print(f"---{runCount} features returned that require EXIF metadata updates---")
fieldsList = ['OBJECTID', 'PhotoAngle', 'PhotoLat', 'PhotoLong']
with arcpy.da.UpdateCursor(photoPointLayer.url, fieldsList, where_clause) as cursor:
for row in cursor:
OID = row[0]
attachmentInfo = photoPointLayer.attachments.search(object_ids=[OID])
for attachment in attachmentInfo:
downloadURL = attachment["DOWNLOAD_URL"]
response = requests.get(downloadURL, stream=True)
if response.status_code == 200:
img = Image.open(BytesIO(response.content))
exif_data = get_exif_data(img)
if exif_data:
# exif = {TAGS.get(tag, tag): value for tag, value in exif_data.items()}
print(f"EXIF metadata for {attachment['NAME']}:\n", exif_data)
exifAngle = get_angle(exif_data)
exifLat = get_lat(exif_data)
exifLong = get_long(exif_data)
if exifAngle or exifLat or exifLong:
if exifAngle:
row[1] = exifAngle
if exifLat:
row[2] = exifLat
if exifLong:
row[3] = exifLong
cursor.updateRow(row)
else:
print(f"No EXIF metadata found for {attachment['NAME']}")
else:
print(f"Failed to access {attachment['NAME']}")
else:
print('No features require updating. Have a nice day.') This is also apparently possible with a Power Automate connector but haven't tried it yet.
... View more
04-07-2025
11:21 AM
|
0
|
0
|
430
|
|
POST
|
@DavidSolari Thanks for the comment. This is another unfortunate episode of Esri's platform being so disjointed...somethings work great in some workflows but are darn near impossible in others. As per this workaround, it's certainly a workaround but good lord is that cumbersome. I've done some tooling around with Pillow and have managed to get what I need out of a given image....but the idea of needing to pull down all of the images that need their data updated is such a pain. I'd rather not be in the business of needing to download hundreds of images just to get data that's immediately extractable if using Survey123.
... View more
04-01-2025
11:56 AM
|
0
|
0
|
446
|
|
POST
|
tl;dr: the layer.attachments.get_list() returns 'none' for EXIF metadata for a given attachment with the metadata is definitely there. The same record, pulling the latitude via an Arcade form calculation: What gives? Premise: I have a feature service with photo points, whose orientation I'd like to be reflected in our maps. As such, there are fields to store orientation angle, as well as latitude and longitude in the photo. These points are captured both in Survey123 and Field Maps, depending on the situation. Pulling EXIF data is simple in S123 and relatively simply when editing in a form in a web app. However, capturing the EXIF data for photos collected in Field Maps has been challenging. Form calculations in Field Maps do not work, as the photo is not actually part of the service yet. As such, my idea is to run a script and update them post-facto. However, the attachments call seems to ignore metadata, which makes the workaround not so good.
... View more
03-27-2025
01:50 PM
|
0
|
3
|
560
|
|
POST
|
See the edit at the bottom of the post. Sub-Admin just doesn't cut it, even though there are delete privileges associated with the role. This was a while ago and I haven't messed with it since.
... View more
03-25-2025
02:38 PM
|
0
|
0
|
586
|
|
POST
|
@RemcoBr Did you ever make progress on this? I have a dataset that needs to be accessed from both Survey123 and Field Maps. I am struggling to get the Exif calculations to fire while collecting in Field Maps. My Arcade works fine when a photo is already attached, but there seem to be issues with pulling it pre-attachment.
... View more
03-25-2025
02:35 PM
|
0
|
0
|
551
|
|
BLOG
|
@JeffreyThompson2 is the workflow reasonable if you do not have administrative rights on your machine? I'm wading through videos and documentation to try and figure out where this slots in.
... View more
05-03-2024
04:25 PM
|
0
|
0
|
1498
|
|
DOC
|
@tmichael_wpjwa was this after the recent update or before?
... View more
03-21-2024
08:35 AM
|
0
|
0
|
6525
|
|
POST
|
Wondering what gives here... Basic premise: I can delete users through the GUI just fine, but when attempting to call .delete() through a script I get this: Exception: You do not have permissions to access this resource or perform this operation.
(Error Code: 403) Slightly longer: I have a script that creates community accounts in our Hub based on information gathered in a feature service through Survey123 and assigns them to groups. I am creating a last script to delete (or disable) those users if they're marked for deletion, since the project is temporary. All other aspects of this process (creating users/inviting users, adding them to and removing them from groups) has worked great. The accounts that I'm testing this on are brand new, never been logged into and don't own any groups or content. I can delete users using the GUI just fine, but somehow the call to delete them via a script seems to fail. Basic example below: hubUsername = 'My.Username'
hubUrl = "https://OurHub.maps.arcgis.com"
hubOrg = arcgis.GIS(hubUrl, username= hubUsername)
username = 'Test.Username'
user = hubOrg.users.get(username)
# Storing the result so we can update the master table
deleteResult = user.delete()
# This also fails...
disableResult = hubOrg.users.disable_users([username]) All attempts result in the same exception that I do not have permission. However... me = hubOrg.users.me
me.role
#returns...
'org_admin'
me.privileges
#returns....
['features:user:edit',
'portal:admin:assignToGroups',
'portal:admin:createUpdateCapableGroup',
'portal:admin:deleteUsers',
'portal:admin:inviteUsers',
'portal:admin:updateUsers',
'portal:admin:viewGroups',
'portal:admin:viewUsers',
'portal:publisher:publishFeatures',
'portal:user:addExternalMembersToGroup',
'portal:user:createGroup',
'portal:user:createItem',
'portal:user:invitePartneredCollaborationMembers',
'portal:user:joinGroup',
'portal:user:joinNonOrgGroup',
'portal:user:shareGroupToOrg',
'portal:user:shareToGroup',
'portal:user:shareToOrg',
'portal:user:viewOrgGroups',
'portal:user:viewOrgUsers',
'premium:publisher:createNotebooks'] Based on the .privileges all, and the fact that I can delete a user through the GUI, I clearly have permission. So....what gives? Edit: I was in a sub Admin role. When I had another admin bump me up to proper Admin I could delete/disable just fine. However...the privileges listed in the code snippet above still say I can delete a user, and I can delete them in the GUI....so what's the difference using the API?
... View more
02-15-2024
03:50 PM
|
0
|
3
|
1301
|
|
POST
|
I had to upgrade ArcGIS Pro and then create a new clone. It wouldn't let me upgrade the cloned environment afterwards. I stopped investigating as this fixed it and I could move on.
... View more
01-08-2024
05:01 PM
|
0
|
0
|
2306
|
|
DOC
|
@JakeSkinner Thanks for the heads up. You say 'you believe...' Who knows the answer definitively?
... View more
12-14-2023
08:23 AM
|
0
|
0
|
7154
|
|
POST
|
@PeterKnoop You were right. After faffing through upgrading Pro, getting my python environments switched out (since Pro wouldn't accommodate updating my previous ones), I now have the updated 2.2 version of the arcgis module which allows the email parameter. So far it successfully created the account but there's not an email in sight. So I revert to my original question: is something like 'add members and notify via email' possible?
... View more
12-13-2023
09:58 AM
|
0
|
0
|
1818
|
| Title | Kudos | Posted |
|---|---|---|
| 7 | 10-31-2025 09:00 AM | |
| 1 | 08-21-2025 04:41 PM | |
| 1 | 08-14-2025 01:24 PM | |
| 1 | 07-27-2025 10:25 AM | |
| 1 | 07-23-2025 11:30 AM |
| Online Status |
Offline
|
| Date Last Visited |
11-06-2025
12:24 PM
|