POST
|
+1 - fairly ridiculous that we can't do this in Pro. I'm on 3.2.2, still no sign on the functionality
... View more
05-18-2025
12:22 PM
|
0
|
0
|
476
|
POST
|
@TonyAlmeida I very much appreciate your keen eye in finding that. I was going crazy - it was a simple copy-paste when trying different options for the sync and I missed changing those two characters. Much appreciated, it solved this issue indeed. And I also provided a nice script if anyone wants to build it out for their needs 🙂 Future readers - change line 34 to be fc instead of fds
... View more
05-02-2025
12:30 PM
|
1
|
0
|
501
|
POST
|
I am having considerable frustration with updating metadata via scripting. I have an enterprise geodatabase with many feature datasets. Inside each feature dataset are many feature classes. All feature datasets and feature classes have metadata, which I need to update. There are 3 sources for my metadata (dynamically-defined items via scripting, synchronized properties, and a template) and I cannot get them to play nice with each other when it comes to displaying the extents of feature classes. Dynamically-defined items include the fd / fc title, summary, description and tags. Synchronized properties are extents, feature classes, fields, crs, etc. The template contains the credits, contact information (a few times), and other information - stuff that doesn't change regardless of what feature dataset or feature class is being shown. The most logical flow (in my head) is reflected in my current order of operations: Import template Update dynamically-defined items Synchronize With that flow, I've tried each of the metadata_sync_option choices; when using 'ALWAYS' everything syncs correctly for feature datasets, and everything syncs correctly EXCEPT Extent for feature classes. How can I get the Extents of feature classes to be properly shown? When I click the Synchronize button everything is perfect, but I need to do this via scripting. I've tried saving the metadata between steps, I've tried syncing before importing the template, after importing the template.... No joy. Here is a minimal example of my code import arcpy
import os
from arcpy import metadata as md
sde_connection = arcpy.GetParameterAsText(0)
metadata_template_path = arcpy.GetParameterAsText(1)
arcpy.env.workspace = sde_connection
fds_list = arcpy.ListDatasets(feature_type='Feature')
for fds in fds_list:
fds_path = os.path.join(sde_connection, fds)
fds_md = md.Metadata(fds_path)
if not fds_md.isReadOnly:
fds_md.importMetadata(metadata_template_path)
# Here I add the metadata that is dynamically generated (title, summary, tags, etc)
fds_md.synchronize(metadata_sync_option='ALWAYS')
fds_md.save()
else:
arcpy.AddWarning(f"Metadata for {fds} is read-only")
arcpy.env.workspace = fds_path
fc_list = []
fc_list = arcpy.ListFeatureClasses()
for fc in fc_list:
fc_path = os.path.join(sde_connection, fds, fc)
fc_md = md.Metadata(fc_path)
if not fc_md.isReadOnly:
fc_md.importMetadata(metadata_template_path)
# Here I add the metadata that is dynamically generated (title, summary, tags, etc)
fds_md.synchronize(metadata_sync_option='ALWAYS')
fc_md.save()
else:
arcpy.AddWarning(f"Metadata for {fds}\{fc} is read-only")
# reset workspace
arcpy.env.workspace = sde_connection
... View more
05-02-2025
09:33 AM
|
0
|
3
|
543
|
POST
|
Ah, that logic makes total sense when I see it like this. I haven't had the opportunity to test this out yet but will do so ASAP. Will do some testing with longName as you suggested, my previous tries included this but didn't use the same logic as you did so might be an excellent building block. Thank you!
... View more
05-21-2022
01:51 AM
|
0
|
0
|
1348
|
POST
|
Yes, fully aware of how to get and set the scale thresholds through the mapping module for individual layers. What I can't figure out is how to apply the thresholds from the group layer to every feature layer that falls within that group layer. I hope that clarifies. Any advice? As for why I'm attempting this - One reason (aside from being told to do so by a boss 😉 ) is that I have a requirement to make these projects more bulletproof so that if a layer gets moved out of place it's still being displayed correctly. I also have to output a config file that shows the properties of every layer and this is how I envision making the scales of grouped layers more easy to understand for some users.
... View more
05-20-2022
10:32 AM
|
0
|
0
|
1360
|
POST
|
Can someone help me to solve this arcpy problem? I'm using ArcGIS Pro 2.5 if that helps. An example of my issue: I have 20 group layers. Inside each group layer are 20 feature layers (all vector). The grouping only goes one level deep (Group layer Roads --> Feature layer Highways, for example). Values for minScale and maxScale have been applied to the top-level group layers (which control visibility for everything in the group), but not to the feature layers within the group. Using arcpy I'd like to get the minScale and maxScale values from the top-level group and set those values to all feature layers within that group. A bonus would be if there was some operation that could comprehend what higher group layer is controlling the minScale / maxScale of a feature layer and apply that, but for now the rigid structure outlined above with just two levels will do. Can someone help me organize the logic and code around this problem?
... View more
05-20-2022
07:01 AM
|
0
|
4
|
1400
|
POST
|
I figured out the problem and it was a stupid amateur mistake that I didn't see until now. I hadn't cleared a selection prior to running the cursor, so the cursor was only running on selected records. Clearing the selection allowed the cursor to run on the entire layer which is what I wanted. Such a silly mistake. Thanks to everyone David Pike Dan Patterson Jeff Kling for their help in organizing the code just a bit better. Here is the code I ended up using (although my original code would've worked just fine too if the selection was cleared beforehand): with arcpy.da.UpdateCursor (in_table="RoadsAnno", field_names=["Status","TextString"] as cursor:
for row in cursor:
if row[1] is None or row[1] =="":
cursor.deleteRow()
else:
row[0] = 0
cursor.updateRow(row)
del cursor
... View more
03-13-2020
08:18 AM
|
1
|
0
|
3252
|
POST
|
No, I don't have access to the software at home in the evenings but I will try out in the morning. As I said in that paragraph however, the order of the updateRow and deleteRow statements didn't seem to affect the functioning of the last example where I changed the attribute to "DeleteMe"
... View more
03-12-2020
04:56 PM
|
0
|
0
|
3252
|
POST
|
Ah yes, that was in the code originally - I was typing out this question from memory at home and forgot that line. I'll amend the question; thanks for the heads up.
... View more
03-12-2020
04:51 PM
|
0
|
0
|
3252
|
POST
|
I have a fairly simple problem, and I've tried everything I can think of to fix it. I am using a data access update cursor in a larger script to update the value of one field, and if the other field is Null I want to delete the record. The update part works fine, but the delete part does not. My input data is an annotation feature class created by ArcMap (turn on labels, right-click layer, create annotation). Nothing fancy or complex. The annotation expression is stored in a field named TextString. If no annotation is created for the feature, the field is Null (as a default, all annotation classes created by ArcMap are nullable). When you look at it the attribute table it appears as <Null>. I cannot use a where clause in this case because of the first update. The following example should work as far as I can tell, but doesn't. with arcpy.da.UpdateCursor (in_table="RoadsAnno", field_names=["Status","TextString"]) as cursor:
for row in cursor:
row[0] = 0
cursor.updateRow(row)
if row[1] is None:
cursor.deleteRow()
del cursor, row (I also tried replacing "if row[1] is None:" with "if row[1] == None:" but no joy. "is None:" is the most proper way to write this according to my Python resources, though "== None:" still works (in other situations) So I then tried the following: with arcpy.da.UpdateCursor (in_table="RoadsAnno", field_names=["Status","TextString"]) as cursor:
for row in cursor:
row[0] = 0
cursor.updateRow(row)
if row[1] is None or row[1] =="" or row[1] == "<Null>":
cursor.deleteRow()
del cursor, row I figured one of those statements would catch the Null value, but it did not. I then changed the value of a previously Null row in the RoadsAnno feature class to read "DeleteMe" (not in quotes) and ran the following just to test if the cursor was picking up the right field: with arcpy.da.UpdateCursor (in_table="RoadsAnno", field_names=["Status","TextString"]) as cursor:
for row in cursor:
row[0] = 0
cursor.updateRow(row)
if row[1] is None or row[1] =="DeleteMe" or row[1] == "<Null>":
cursor.deleteRow()
del cursor, row The row containing the TextString attribute "DeleteMe" was deleted. So what's happening with the Null value? Would anyone be able to help with this? Why doesn't the cursor recognize the Null value in the field? Maybe Arc creates Null values with unseen characters or something that need to be stripped? EDIT: Do I have to put the updateRow statement after the deleteRow statement? Maybe the cursor is moving to the next row with the update and never gets the chance to delete? Although that wasn't the case for the "DeleteMe" example so perhaps this line of thought is not correct.
... View more
03-12-2020
03:45 PM
|
0
|
8
|
3387
|
POST
|
Based on Randy Burton 's reply, I used the following code in the validator which does exactly what I want. Thanks Randy! import arcpy
class ToolValidator(object):
def __init__(self):
self.params = arcpy.GetParameterInfo()
def initializeParameters(self):
self.params[0].filter.list = ["Digital Map", "Paper Map"]
self.params[0].value = "Digital Map"
return
def updateParameters(self):
if self.params[0].value == None:
self.params[0].value = "Digital Map"
if self.params[0].valueAsText == "Digital Map":
self.params[1].filter.list = ["Not applicable"]
self.params[1].value = "Not applicable"
self.params[1].enabled = False
else:
self.params[1].filter.list = ["1:10,000", "1:25,000"]
if self.params[1].value not in self.params[1].filter.list:
self.params[1].value = self.params[1].filter.list[0]
self.params[1].enabled = True
return
def updateMessages(self):
return
... View more
11-25-2019
05:35 AM
|
0
|
0
|
1812
|
POST
|
Sorry for the late reply to this - I was moved to another priority job and just got back to my normal work today. I’ve tried things again and as far as I can tell it is working as expected with no changes. Perhaps I just needed to clear some cobwebs from my understanding of the issue. Regardless, thanks for helping out.
... View more
11-21-2019
07:44 AM
|
0
|
0
|
5709
|
POST
|
I have some simple ArcPy script tool validator code that is giving me grief. I am using desktop at 10.3.1. I'm open to whatever help can be offered to get this to work as intended. I have two parameters for my script tool. The first is the type of product to be created, the second is the scale of the product. Digital Map / No scale required are the default values defined in the Tool Validator code. If it is a paper product, the user selects the appropriate scale from the drop-down list. The problem I can't solve is that if the user changes the value in parameter 0 to paper map, the list of scales becomes available but the value is still the default ("No scale required") so an error is thrown because that option is not in the scale list. The error clears when I select the scale from the list, but I want only those choices available and obviously don't want the error to appear at all. Likewise if I then change parameter 0 back to Digital Map the "No scale required" value appears but the error message is thrown again because that value is not in the scale list, which is somehow still appearing. There is no way to clear the error at this point. I'd really appreciate help with how to get these different combinations to appear and change as intended without any errors. If they pick Paper, only the scales appear. If they switch back to Digital, only the "No scale required" value appears. And so on. I can't guarantee the user's behaviour so I'd like for it to be bulletproof. import arcpy
class ToolValidator(object):
def __init__(self):
self.params = arcpy.GetParameterInfo()
def initializeParameters(self):
# Define the list of product types the user can choose from
self.params[0].filter.list = ["Digital Map", "Paper Map"]
self.params[0].value = "Digital Map"
return
def updateParameters(self):
if self.params[0].value == "Digital Map":
self.params[1].value = "No scale required"
if self.params[0].value == "Paper Map":
self.params[1].filter.list = ["1:10,000", "1:25,000"]
return
def updateMessages(self):
return
... View more
11-21-2019
06:29 AM
|
0
|
2
|
1918
|
POST
|
I'll see what I can do on Friday. Thank you for your insight so far
... View more
10-10-2019
04:03 PM
|
0
|
2
|
5709
|
POST
|
I’m working in ArcMap 10.3.1. If I type in an underscore in my attribute field and type in the same underscore (or copy-paste it into the code) would that ensure it’s the same character? I’ll keep playing with this and I’ll check for white space. I appreciate your help!
... View more
10-10-2019
11:12 AM
|
0
|
4
|
5709
|
Title | Kudos | Posted |
---|---|---|
1 | 05-02-2025 12:30 PM | |
1 | 04-05-2019 09:16 AM | |
1 | 03-20-2019 10:27 AM | |
1 | 03-13-2020 08:18 AM |
Online Status |
Offline
|
Date Last Visited |
2 weeks ago
|