|
POST
|
Does anyone know what determines the units on the measure tool in Field Maps? I've got a map where all data is in state plane, except the Esri basemaps, which are of course Web Mercator. We want to be able to measure in feet. Do the units of the spatial reference of the basemap determine the units in the measure tool, since the basemap determines the spatial reference of the web map? If so, that would mean that meters are the only option when using Esri basemaps?
... View more
11-21-2024
01:21 PM
|
0
|
6
|
904
|
|
POST
|
I replied to your other post, but for anyone coming across this post, here's how I did this: 1. In the app configuration, go to Interactivity -> Share, and toggle on Sharing. 2. Publish then open the app and select any feature by clicking on it. 3. Click the Sharing button, then Copy Link. This copies a shortened link to the clipboard. 3. Paste the link in the address bar and press Enter to load the app. This changes the shortened link to the full link in the address bar. It looks like this: https://civiclens-demo.maps.arcgis.com/apps/instant/attachmentviewer/index.html?appid=bc91f23560d9436fa069f28d980db38c&defaultObjectId=14&attachmentIndex=0&layerFeatureIndex=0&selectedLayerId=190ffe37ae2-layer-4¢er=-114.05;46.8919&level=19 4. From my testing, you can just swap out the defaultObjectId value to open the app to the feature of interest. You can also omit the layerFeatureIndex parameter (I'm not sure what it does), but it looks like you need most or all of the others. Hope this helps.
... View more
08-13-2024
11:33 AM
|
0
|
1
|
1305
|
|
POST
|
Hi, this is possible; here's how: 1. In the app configuration, go to Interactivity -> Share, and toggle on Sharing. 2. Publish then open the app and select any feature by clicking on it. 3. Click the Sharing button, then Copy Link. This copies a shortened link to the clipboard. 3. Paste the link in the address bar and press Enter to load the app. This changes the shortened link to the full link in the address bar. It looks like this: https://civiclens-demo.maps.arcgis.com/apps/instant/attachmentviewer/index.html?appid=bc91f23560d9436fa069f28d980db38c&defaultObjectId=14&attachmentIndex=0&layerFeatureIndex=0&selectedLayerId=190ffe37ae2-layer-4¢er=-114.05;46.8919&level=19 4. From my testing, you can just swap out the defaultObjectId value to open the app to the feature of interest. You can also omit the layerFeatureIndex parameter (I'm not sure what it does), but it looks like you need most or all of the others. Hope this helps.
... View more
08-13-2024
11:31 AM
|
1
|
0
|
682
|
|
POST
|
I discovered a partial solution, which is to construct the attachment URLs and generate an API key to append to the URLs for access, then return as a mediaInfos element. API keys only last for up to one year, so I'm still curious if this is possible without a token or API key. Here's how I did it by constructing the attachment URLs and using an API key: var keyword = "my_keyword"; // keyword to filter by
var atts = Attachments($feature);
var filteredAttachments = [];
var mediaInfos = []
var apiKey = YOUR_API_KEY_GOES_HERE
for (var i = 0; i < Count(atts); i++) {
var attachment = atts[i];
if (attachment.keywords == keyword) {
Push(filteredAttachments, attachment);
}
}
var baseUrl = "https://services9.arcgis.com/iERBXXD4hiy1L6en/ArcGIS/rest/services/Testing_Attachments/FeatureServer/0";
for (var j = 0; j < Count(filteredAttachments); j++) {
var attachment = filteredAttachments[j];
var attachmentUrl = baseUrl + "/" + $feature.OBJECTID + "/attachments/" + attachment.id + "?token=" + apiKey;
Push(mediaInfos, {
"type": "image",
"caption": "test",
"value": {"sourceURL": attachmentUrl}
}
)
}
return {
"mediaInfos": mediaInfos,
"type": "media"
};
... View more
07-24-2024
12:44 PM
|
1
|
0
|
865
|
|
POST
|
I need to display attachments from a secure service in a popup, filtered by keyword. I can retrieve and filter the attachments using Arcade, but I can't seem to return the attachments to the popup. I'm hoping it's just a syntax issue, but I'm starting to wonder if this is even possible. Here's my latest attempt: var keyword = "my_keyword";
var atts = Attachments($feature);
var filteredAttachments = [];
for (var i = 0; i < Count(atts); i++) {
var attachment = atts[i];
if (attachment.keywords == keyword) {
Push(filteredAttachments, attachment);
}
}
Console(filteredAttachments)
return {
"attachment": filteredAttachments,
"type": "attachment",
"displayType": "auto"
} This logs the following to the console, so everything is good up to the return statement. [{"id":2,"name":"Discrepancies_image-20240321-155540-91b088a433494fb5aebd156de9c225e4-75a31dfa6c20461183d7004d680f0a78.jpg","contenttype":"image/jpeg","size":244565,"exifinfo":null,"keywords":"my_keyword"}] I can't use the method of constructing the attachment URL because there's no way to provide a token. I've tried a dozen different iterations of the return statement. Is it possible to filter attachments by keyword in Map Viewer popups?
... View more
07-23-2024
06:56 PM
|
2
|
1
|
928
|
|
POST
|
Looks like this is still an issue in ArcGIS Pro 3.3./Python API 2.3.0. If arcpy is available, @Vincentvd's solution works, but we had a need to find a workaround when arcpy wasn't available. I've had success using the authenticated session object for REST API and Sharing API calls to secured services instead of passing the token explicitly, like so (only tested on AGOL): import json
from arcgis.gis import GIS
gis = GIS("pro")
# Use the session from the GIS object
session = gis._con._session
# Example secured URL, doesn't have to be admin, just an example
update_definition_url = "https://services8.arcgis.com/XXXXXXXXXXXXXXXX/arcgis/rest/admin/services/XXXXXXXXXXX/FeatureServer/updateDefinition"
# Define some parameters for the update; again, just an example
update_def_params = {
'updateDefinition': json.dumps({
"capabilities": "Query,Editing,Create,Update,Delete,Sync"
}),
'async': 'false',
'f': 'json'
}
response = session.post(update_definition_url, data=update_def_params, timeout=10)
result = response.json()
print(result) This apparently provides a subclass of a Requests session, so you can use it in place of requests; e.g., session.get, session.post, etc. Your mileage may vary, but this solved the problem for me in a workflow where arcpy wasn't an option.
... View more
06-03-2024
04:01 PM
|
1
|
1
|
2515
|
|
POST
|
Try this: import copy
def update_cyano_status(cyanoponds_features, overlap_rows, cyanoponds_lyr):
for CCC_GIS_ID in overlap_rows['CCC_GIS_ID']:
cyanopond_feature = [f for f in cyanoponds_features if f.attributes['CCC_GIS_ID'] == CCC_GIS_ID][0]
row = overlap_rows[overlap_rows['CCC_GIS_ID'] == CCC_GIS_ID].iloc[0]
cyanopond_feature_copy = copy.deepcopy(cyanopond_feature)
cyanopond_feature_copy.attributes['Cyano_Status'] = row['cyano_risk_tier']
resp = cyanoponds_lyr.edit_features(updates=[cyanopond_feature_copy])
print(f"Attempted to update Cyano_Status for {CCC_GIS_ID} to {row['cyano_risk_tier']}. Response: {resp}")
... View more
05-14-2024
03:22 PM
|
0
|
2
|
1569
|
|
POST
|
Hi Samantha, can you remove the try-except so it just errors out with a traceback, so we can see what line it's tripping up on? Regarding the other post, I noticed that error. I'm reaching to out Esri to ask for permission to edit it (seems like you can't edit old posts).
... View more
05-14-2024
12:08 PM
|
0
|
4
|
1579
|
|
POST
|
For Issue #2: try this to get a list of CCC_GIS_ID values where there has not been a sample in 30 days: def query_for_no_inspection_in_thirty_days(layer):
threshold_date = datetime.now() - timedelta(days=30)
query_result = layer.query(where=f"fluorometry_date < '{threshold_date}'", out_fields='CCC_GIS_ID')
ccc_gis_ids = [record.attributes['CCC_GIS_ID'] for record in query_result.features]
return ccc_gis_ids
no_fluorometry_in_30 = query_for_no_inspection_in_thirty_days(fluorsamples_lyr)
print(no_fluorometry_in_30) Then you can loop over those CCC_GIS_ID values and update the ponds: for CCC_GIS_ID in no_fluorometry_in_30:
cyanopond_feature = [f for f in cyanoponds_features if f.attributes['CCC_GIS_ID'] == CCC_GIS_ID]
cyanopond_feature.attributes['Cyano_Status'] = 'No updated information'
resp = cyanoponds_lyr.edit_features(updates=[cyanopond_feature]) Then do the same for the microscopy. Let me know how that works.
... View more
05-14-2024
10:49 AM
|
0
|
0
|
1585
|
|
POST
|
Hi Samantha, regarding Issues #1 and #3: It's hard to tell for sure without access to your data, but it looks to me like you're writing a value from the fluorsample layer to the cyanoponds layer to populate Cyano_Status, instead of pulling the value from the dataframe you've built. Same for prior_activity. This might put you on the right track (let me know if I misunderstood something): def update_cyano_status(cyanoponds_features, overlap_rows, cyanoponds_lyr):
for CCC_GIS_ID in overlap_rows['CCC_GIS_ID']:
cyanopond_feature = [f for f in cyanoponds_features if f.attributes['CCC_GIS_ID'] == CCC_GIS_ID][0]
row = overlap_rows[overlap_rows['CCC_GIS_ID'] == CCC_GIS_ID].iloc[0] # get the matching row from the dataframe
cyanopond_feature.attributes['Cyano_Status'] = row['cyano_risk_tier'] # add the matching status value from the dataframe to the update dictionary
resp = cyanoponds_lyr.edit_features(updates=[cyanopond_feature]) # call the update
print(f"Attempted to update Cyano_Status for {CCC_GIS_ID} to {row['cyano_risk_tier']}. Response: {resp}")
... View more
05-14-2024
10:20 AM
|
0
|
6
|
2192
|
|
POST
|
Old thread but thought I'd post this here in case Google brings anyone here. There is an update_definition method in the arcgis.features.managers module of the Python API, but it's been inconsistent for me. So I just make the call through the REST API. The code below enables layer optimization for the specified feature service item and layer index: from arcgis.gis import GIS
import requests
import json
gis = (portal_url, username, password)
item_id = '' # item id of feature service wih layer to optimize
item = gis.content.get(item_id)
layer_index = 0 # layer index in feature service for layer to optimize
update_def_url = f"{item.layers[layer_index].url}/updateDefinition".replace(r'rest/services',r'rest/admin/services')
token = gis._con.token
data = {'token':token,
'f': 'json',
'async': 'true',
'updateDefinition': r'{"multiScaleGeometryInfo":{"levels":[]}}'
}
result = requests.post(update_def_url, data=data, timeout=10)
status_url = f"{result.json().get('statusURL')}?token={token}&f=json"
status = None
while not status == 'Completed' and not status == 'Failed':
status = requests.get(status_url, timeout=10).json().get('status')
print(f"Optimization status: {status}")
time.sleep(10)
else:
if status == 'Completed':
logging.info(f"Layer drawing optimized successfully for {item.title} ({item.id})")
if status == 'Failed':
status = requests.get(status_url, timeout=10).json()
logging.error(f"Layer optimization failed for {item.title} ({item.id}). Status: {status.json()}")
... View more
05-07-2024
08:35 AM
|
1
|
1
|
1321
|
|
POST
|
Thanks Brett, I added a vote for your idea. It's interesting that the status of your bug report is "In Review". Perhaps that's a hopeful sign.
... View more
04-30-2024
08:47 AM
|
0
|
1
|
1243
|
|
POST
|
Yep, sounds like a job for Python. Feel free to tag me or PM me if you get stuck. My post from 2020 is a bit outdated now that you can schedule tasks in Notebooks (no need to have a computer always on, or use a third-party cloud environment).
... View more
04-27-2024
09:37 AM
|
0
|
0
|
1432
|
|
POST
|
Just noticed that you have matching IDs (I missed that on the original post because I saw you were doing an intersect). In that case, a joined view should work. Did you set the join operation as one-to-one, only keep the first matching record, then sort by EditDate descending?
... View more
04-26-2024
03:56 PM
|
0
|
2
|
1454
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 07-24-2024 12:44 PM | |
| 1 | 08-13-2024 11:31 AM | |
| 1 | 02-06-2023 05:52 PM | |
| 1 | 09-05-2020 01:13 PM | |
| 2 | 12-24-2024 11:19 AM |
| Online Status |
Offline
|
| Date Last Visited |
09-16-2025
04:51 PM
|