3

I have a process that I'm trying to streamline. On a regular basis I have to produce ArcPad base maps for low end GPS units. The area that I need to cover is very large (ca. 7 million acres). I've found that if I strip the attribute tables down to just the necessary fields, I can make the maps work, even with the memory limitations on Windows mobile devices. The process currently goes like this...

I have a base map (mxd) connected to the corporate data sources. I use xTools to export all of the data in the table of contents to shapefiles and also create a new mxd pointing to the new shape files. This maintains any symbology, definition queries and labels.

Here's the part that I want to streamline:

I edit each shapefile and delete all fields that are not used for symbology, definition queries or labels.

I would like to be able to script this part of the process. I know that some layer properties like definition queries can be accessed with ArcPy. What I'd like to do is create a list of attribute fields for each shapefile to delete, but exclude any attributes that are being used for symbology, definition queries or labels. Most of this is easy to figure out. What I can't figure out is how to get the information about which attributes are being used.

nmtoken
13.6k5 gold badges39 silver badges91 bronze badges
asked Mar 9, 2016 at 19:42
2
  • 1
    You'd need layer properties to decide what attributes to keep, but it/they wouldn't be the only critical values. Python (arcpy) could certainly do this, but Python coding questions are expected to contain Python code (initial effort, up until the point where you got stuck). Commented Mar 9, 2016 at 20:00
  • Sorry about not including code. I didn't realize it was it was a requirement. I hadn't fleshed out the code because I wasn't sure how to access the layer properties in question. Commented Mar 9, 2016 at 21:35

1 Answer 1

6

This code prints each layer's data source followed by a list of attributes that are used in the layer's definition query, labels, or symbology. Note that a single data source may be behind multiple layers. Also, not that I couldn't figure out a way to identify the fields used in "unique values, many fields" or "dot density" symbology.

import arcpy, os
mxd = arcpy.mapping.MapDocument(r'C:\temp\Untitled.mxd')
for layer in arcpy.mapping.ListLayers(mxd):
 print layer
 # If you can't identify the layer's source data (e.g., web services, group
 # layers), then skip it
 if not layer.supports('dataSource'):
 continue
 ds = layer.dataSource
 # Fields in the layer
 fields = [i.name for i in arcpy.ListFields(ds)]
 fields.sort(key=lambda s: len(s), reverse=True)
 # A list of fields used in the map
 fieldsUsed = list()
 # Get the fields used in its symbology; note that this will only work
 # for layers that have basic "Unique Values" symbology. Dot Density symbology
 # and "unique values, many fields" symbology won't return the fields used.
 if hasattr(layer, 'symbology'):
 sym = layer.symbology
 if hasattr(sym, 'valueField'):
 field = sym.valueField
 fieldsUsed.append(field)
 if hasattr(sym, 'normalization'):
 field = sym.normalization
 fieldsUsed.append(field)
 # Get the fields used in its definition query
 if hasattr(layer, 'definitionQuery'):
 dq = layer.definitionQuery
 for field in fields:
 if field in dq:
 fieldsUsed.append(field)
 dq = dq.replace(field, '')
 if hasattr(layer, 'labelClasses'):
 # Get the fields used in the labels
 lcs = layer.labelClasses
 for lc in lcs:
 lcSQL = lc.SQLQuery
 lcExp = lc.expression
 for field in fields:
 if field in lcSQL:
 fieldsUsed.append(field)
 lcSQL = lcSQL.replace(field, '')
 if field in lcExp:
 fieldsUsed.append(field)
 lcExp = lcExp.replace(field, '')
 # Remove repeated field names
 fieldsUsed = list(set(fieldsUsed))
 # Print out the fields used
 print '{}:'.format(ds)
 for f in fieldsUsed:
 print '\t{}'.format(f)

EDIT: Updated the code to be more versatile and not crash in the face of rasters, group layers, and feature services.

Here are details on the layer properties. For the symbology properties, see the paragraph that begins "Depending on the symbology type". As it mentions there, the "OTHER" symbologyType "represents an unsupported layer symbology class". Unfortunately, this includes the many fields symbology. However, tweaking the work-around presented here, you might be able to pull it off.

Also, note that this script may over-select fields. For example, if you have field named 'F1' and you have a definition query or a label class query like "MyTextField = 'Blah blah and F1 blah'". Then, F1 would be returned, even though the literal string 'F1' is being used in the query and not the field name. It turns out that these types of scenarios are extremely difficult to account for, and based on a google search, no one has been able to accomplish the feat. That said, you could address many query scenarios with some relatively simple regex.

EDIT: Updated the code to prevent conflation of fields named, e.g., 'F1', 'F11', 'F111'. In the previous version, the appearance of F111 in a definition query or label query would have yielded all three field names in the output.

answered Mar 9, 2016 at 20:24
3
  • That gets me 90% there. I do have one layer that uses unique values, many fields. So I'll have to sort that out, but thanks for the info on accessing the layer properties. Commented Mar 9, 2016 at 21:37
  • How can I get a list of attributes for objects like layer.symbology or layer.definitionQuery? I want to dig deeper into this but can't find any documentation. Commented Mar 9, 2016 at 22:25
  • @kkovacs, I've added a paragraph to my answer to direct you to more detail. Commented Mar 9, 2016 at 22:39

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.