Hello everyone,
I have an aesthetic issue with the pop-ups coming in. all of the images that are attached and collected in the field are only being viewed sideways not up and down. It there a code I can use to rotate the photos so they are correct?
I'm having the same issue. This occurred when we moved form ArcGIS online to ArcGIS Enterprise and they show sideways in portal pop-up window.
Does anybody have a solution for this?
I'm really close to getting this to work, so I'll share my code at the moment. In the field list, I created a new arcade expression (below), then in the popup config, I added a Media element and in the URL parameter, chose the newly created expression:
// ObjectID of the parent feature
var oid = $feature.ObjectID
// GlobalID of the parent feature
var g = $feature.GlobalID
// get the attachment table (must be published as part of the web service)
var as = FeatureSetByPortalItem(portal("https://gis.edenprairie.org/portal"),"5f151f9a28634cb3aa82db7a3d241605",7)
console (count(as))
// Filters based on global id of parent to REL_GLOBALID of child photo
var filterStatement = "REL_GLOBALID = @g"
var attachments = Filter(as,filterStatement)
var photo
// Iterate through attachments. place the objectID and attachmentIDs in the appropriate place in link
for (var p in attachments){
photo += `https://gis.edenprairie.org/maps/rest/services/Internal/ParkAssetInventory/FeatureServer/2/${oid}/attachments/${p.ATTACHMENTID}`
}
/*
var sPhoto = split(photo,TextFormatting.NewLine)
for (var sp in sPhoto){
var URL = sPhoto[sp]+TextFormatting.NewLine
}*/
//var urlList = "<ul>"+Concatenate(photo)+"</ul>"
return `${photo}`
This code works for features where the attachment table was created in pro as a result of the Enable Attachments action (which is where we get the AttachmentID field and the related Global/Rel_GlobalID fields. And in fact this code does work to get the attachment and orient the picture correctly. The top photo is with the Media element, the bottom is with the Attachments element:
However! It only returns one photo at the moment. If there are multiple photos it will fail. I'm still working on how to break apart the URLs that get returned by the expression. If you want to only return one photo and guarantee that works, you could just make the filter a "first filter" and then remove the loop and just return the URL of a single item:
// ObjectID of the parent feature
var oid = $feature.ObjectID
// GlobalID of the parent feature
var g = $feature.GlobalID
// get the attachment table (must be published as part of the web service)
var as = FeatureSetByPortalItem(portal("https://gis.edenprairie.org/portal"),"5f151f9a28634cb3aa82db7a3d241605",7)
console (count(as))
// Filters based on global id of parent to REL_GLOBALID of child photo
var filterStatement = "REL_GLOBALID = @g"
var attachments = first(Filter(as,filterStatement))
var photo = `https://gis.edenprairie.org/maps/rest/services/Internal/ParkAssetInventory/FeatureServer/2/${oid}/attachments/${attachments.ATTACHMENTID}`
Okay, so I found the solution, which still has some potential drawbacks but depends on your need. So the first thing is that you'll need a new expression for every photo you want to return because the Media element in the popup only takes one URL. So for example, if we want three photos, we need three expressions:
Return First Photo:
// ObjectID of the parent feature
var oid = $feature.ObjectID
// GlobalID of the parent feature
var g = $feature.GlobalID
// get the attachment table (must be published as part of the web service)
var as = FeatureSetByPortalItem(portal("https://gis.edenprairie.org/portal"),"5f151f9a28634cb3aa82db7a3d241605",7)
console (count(as))
// Filters based on global id of parent to REL_GLOBALID of child photo
var filterStatement = "REL_GLOBALID = @g"
var attachmentOne = First(Filter(as,filterStatement))
var photo = "https://gis.edenprairie.org/maps/rest/services/Internal/ParkAssetInventory/FeatureServer/2/"+oid+"/attachments/"+attachmentOne.ATTACHMENTID
return photo
Return Second Photo:
// ObjectID of the parent feature
var oid = $feature.ObjectID;
// GlobalID of the parent feature
var g = $feature.GlobalID;
// Get the attachment table (must be published as part of the web service)
var as = FeatureSetByPortalItem(portal("https://gis.edenprairie.org/portal"), "5f151f9a28634cb3aa82db7a3d241605", 7);
console("Number of attachments total: " + count(as));
// Filters based on global ID of parent to REL_GLOBALID of child photo
var filterStatement = "REL_GLOBALID = @g";
var attachments = Filter(as, filterStatement);
var c = count(attachments);
console("Number of attachments to this feature: " + c);
// Ensure that there are attachments before trying to access them
if (c > 0) {
var newArray = [];
// Iterate over the attachments and push them into the newArray
for (var attachment in attachments) {
push(newArray, attachment);
}
// Check if the newArray has enough items to access the second one
if (count(newArray) > 1) {
var photo2 = newArray[1];
var photo = "https://gis.edenprairie.org/maps/rest/services/Internal/ParkAssetInventory/FeatureServer/2/" + oid + "/attachments/" + photo2.ATTACHMENTID;
return photo;
} else {
return ;
}
} else {
return ;
}
Return Third Photo:
// ObjectID of the parent feature
var oid = $feature.ObjectID;
// GlobalID of the parent feature
var g = $feature.GlobalID;
// Get the attachment table (must be published as part of the web service)
var as = FeatureSetByPortalItem(portal("https://gis.edenprairie.org/portal"), "5f151f9a28634cb3aa82db7a3d241605", 7);
console("Number of attachments total: " + count(as));
// Filters based on global ID of parent to REL_GLOBALID of child photo
var filterStatement = "REL_GLOBALID = @g";
var attachments = Filter(as, filterStatement);
var c = count(attachments);
console("Number of attachments to this feature: " + c);
// Ensure that there are attachments before trying to access them
if (c > 0) {
var newArray = [];
// Iterate over the attachments and push them into the newArray
for (var attachment in attachments) {
push(newArray, attachment);
}
// Check if the newArray has enough items to access the second one
if (count(newArray) > 2) {
var photo3 = newArray[2];
var photo = "https://gis.edenprairie.org/maps/rest/services/Internal/ParkAssetInventory/FeatureServer/2/" + oid + "/attachments/" + photo3.ATTACHMENTID;
return photo;
} else {
return ;
}
} else {
return ;
}
From there you can kind of see the pattern, we're just swapping out the array index value incrementally (so then the fourth photo is newArray[3]). Full disclosure, ChatGPT got me over the hump with the last portion of the code - I had tried pushing the attachments to the newArray variable but I think I was just using the wrong variable.
Anyway, the next step is to make your Media element a Media group:
We'll need a new content item for each photo. The result is a scrolling media block that contains as many photos as you've added, correctly oriented:
Okay so downstream effects, which may be pro's or con's depending on the application:
1. You can only see one photo at a time and need to scroll.
2. You can't embiggen the attachment...
3. ...however, you can still save the photo and open it in your photo viewer
4. You have to manually add a new expression for each additional photo, meaning that, theoretically, it will always be possible that photos that have been attached will not show up in the media block. Say you have 12 expressions, the 13th photo wont appear unless you go add one. As long as you know roughly how many photos each feature will have attached, you can kind of plan around that.
@ZachBodenner , you are truly the MVP. Thank you for sharing this. I was able to use this and make it work in ArcGIS Enterprise.