Could anyone help me work out how to use photos, stored as attachments, to label points in ArcGIS Pro?
From the documentation here (shown in the screenshot below), I'm fairly sure that this is possible, but I can't work out how to go about doing it and haven't been able to find any walkthroughs/tutorials/similar questions.
I have a layer of points with images attached as below:
and have got as far as trying to set attribute-level image marker symbols for the points, but when I click the highlighted button to set the attribute mapping, there are no available options to use the attached images.
Do I need to attach the images in a different format in order to be able to use them in this context?
Additionally (and I fear this may be a deal breaker), I need the actual points to be visible, ie the images should be plotted around the points and not directly on top of them, ideally using the labelling engine used for text labels. There are several areas where there are many points close to each other, and so if I can't control where the images get plotted relative to the point location, I'll end up with lots of images on top of each other and their corresponding points obscured.
In order to place things using the labeling engine, they've got to be labels. But within the labeling settings, you can configure a point symbol to function as a label. I think that's under callout or background, but I'm not at my workstation with Pro at the moment.
Labels don't have quite the same ability to access feature attributes, though. And even if they could, I am not sure that an attachment can be accessed in this way... For instance, how would Pro know which attachment to use, in the event that there were multiple? And what if the attachment were not an image?
Thanks for your speedy response Josh! I've tried to get the functionality I want using labels before, but run into the issue you mention of labels not being able to access feature attributes in the same way that point marker symbols can (or at least should be able to) - do you think there would be any way to do what I want without using labels themselves?
A working, but basic approach:
Basically, that's it. To make it prettier:
Before:
After:
I'm sure you could hack together a border around the picture somehow.
Unlike labels, symbols don't seem to have options for dynamic placement. Position and offset are either taken as values provided by the user or by a table field.
I haven't found a way to use labels for this task. You can't use the Attachments() and FeatureSetBy*() function in the Arcade label expression, and the DATA field of the joined attachment table is also not available.
I thought I had something using a Python label expression and trying to return an HTML <img> tag with a data uri, but it doesn't seem to work (it's because there are only a few text formatting tags allowed; I'll still leave the code here, maybe it helps):
def FindLabel([GlobalID]):
import arcpy
import base64
att_table = 'path:/to/database.sde/Fotos__ATTACH'
sql = "REL_GLOBALID = '{}'".format([GlobalID])
cur = arcpy.da.SearchCursor(att_table, ['CONTENT_TYPE', 'DATA'], sql)
for row in cur:
b64 = base64.encodebytes(row[1])
data_uri = 'data:{};base64,{}'.format(row[0], b64)
#return data_uri[:30] # this returns the start of the data_uri correctly
return '<img src="{}"/>'.format(data_uri) # this returns without error, but doesn't do anything
return "N/A"
Don't know anything about JScript, maybe you can do something with that.
Thanks Johannes! What format do the photos in the attachment table need to be? The ones I have now are saved as attachments (I think they were collected via Field Maps and automatically stored in this way) but I also have them all downloaded to a local folder so could re-upload as a given file type if necessary.
And do you think there would be a way to dynamically offset all the labels so that the points don't get obscured (maybe in Python)? If not, seeing as using actual labels won't work with feature-level attribute mapping, I don't think I'm going to be able to do what I want/need to.
What format do the photos in the attachment table need to be?
The field mapping only recognizes BLOB (Binary Large OBject, so byte data) fields. If you have an ArcGIS Attachment table, there should be a BLOB field in there. If not, you can also create a BLOB field in your feature class and store the images there.
And do you think there would be a way to dynamically offset all the labels so that the points don't get obscured (maybe in Python)?
Dynamically? Probably not, for that you need to work with labels, not symbology. Maaaaaybe with Point Clustering in 2.9, but it doesn't seem likely.
With Python? You could map X and Y offset to fields in your feature class. You could then calculate these fields with Python, using the distance to nearby points as input. This could work for a fixed map scale and picture marker size. But as soon as you zoom out, the images will overlap each other again.
A simple approach to that with Arcade:
// calculate field OffsetX
// load other features
var gid = $feature.GlobalID
var fs = Filter(FeatureSetByName($datastore, "FeatureClass"), "GlobalID <> @gid")
// get nearby features
var nearby_features = Intersects(fs, Buffer($feature, 50))
// gravitational force in horizontal direction
var force = 0
for(var f in nearby_features) {
var dist = Distance($feature, f)
var dx = Geometry(f).X - Geometry($feature).X
force -= dx / (dist * dist)
}
// magical number dependent on map scale and picture marker size
var magic_factor = 100
return force * magic_factor
// calculate field OffsetY
// load other features
var gid = $feature.GlobalID
var fs = Filter(FeatureSetByName($datastore, "FeatureClass"), "GlobalID <> @gid")
// get nearby features
var nearby_features = Intersects(fs, Buffer($feature, 50))
// gravitational force in vertical direction
var force = 0
for(var f in nearby_features) {
var dist = Distance($feature, f)
var dy = Geometry(f).Y - Geometry($feature).Y
force -= dy / (dist * dist)
}
// magical number dependent on map scale and picture marker size
var magic_factor = 100
return force * magic_factor
Without offsets:
With offsets:
But it only works for a fix scale. When you zoom out, the images overlap again:
Hi Johannes. I'm keen to try this out (while I patiently wait for the Dev team as ESRI to implement my ideas below!). Could this be done using ArcGIS Online feature service features and attachments? I can't figure out where to find the attachments table data source path to try. Don't want to have to download attachments if possible!
Add feature attachment as callout to map - Esri Community
Create dynamic feature attachment element in ArcGI... - Esri Community
I don't think so.
Attachments in AGOL/Portal aren't stored as joinable table. Instead, each attachment has its own url:
"portal/rest/services/ServiceName/FeatureServer/LayerID/FeatureOID/attachments/AttachmentID"
For example:
"https://services.arcgis.com/xxxyyyzzz/arcgis/rest/services/TestService/FeatureServer/1/5/attachments/5"
Things I tried:
Thanks for trying - if you tried all that, I doubt I'm going to make it work. Will look at options for modelling a download of the data to feed to a pre-configured layer.