4

Does anyone know how to find the path to a feature class within a label expression using ArcGIS?

I don’t need to simply display the path. My overall goal is to create a python function to display x,y coordinates directly from the Shape geometry, as shown in this answer. But this code will fail if the user changes the layer name, so I want to make the code more robust by finding the path to the feature class.

I know it is possible to find the path from the selected layer from the code below. But this will of course display varying paths depending on what layer is selected.

import pythonaddins
def FindLabel ( [OBJECTID] ):
  mxd = arcpy.mapping.MapDocument("CURRENT")
  df = pythonaddins.GetSelectedTOCLayerOrDataFrame()
  return df.dataSource

I need something similar to __file__ for arcpy/ArcGIS with reference to the dataset. Does such a thing exists or is there another solution I can use?

5
  • dataSource property of the Layer? resources.arcgis.com/en/help/main/10.1/index.html#//… Commented Mar 4, 2015 at 12:12
  • Yes that will get the path, but then I need to manual write the name of the layer in the code as in this example gis.stackexchange.com/questions/124398/…. To make the code robust I need a general reference to the layer/path, so the path will be found regardless of the user change the layer name in the TOC in ArcMap. Commented Mar 4, 2015 at 12:39
  • The dataSource would not change if the user changes the layer name, it still refers to the same feature class in a geodatabase. Once you get the layer name that was selected by user (df), you can get its dataSource. I can't understand what your problem is really. Commented Mar 4, 2015 at 12:41
  • If the label Expression code refers to a layer with the name "Layer1", and the user later on in the TOC change the name to "Layer2" the code still refers to "Layer1" and then the code will fail. If I use path = pythonaddins.GetSelectedTOCLayerOrDataFrame().dataSource the code will change the reference depending on which layer is active Commented Mar 4, 2015 at 13:30
  • The problem is that neither solutions create a robust code that will work regardless of which layer is active or if the user changes the layer name Commented Mar 4, 2015 at 13:31

1 Answer 1

1

First use this script to print all of your layer DataSources :

mxd = arcpy.mapping.MapDocument("CURRENT")
for lyr in arcpy.mapping.ListLayers(mxd, "*"):
    print lyr.dataSource 

Then use this code:

def FindLabel([OBJECTID]):
    mxd = arcpy.mapping.MapDocument("CURRENT")
    for lyr in arcpy.mapping.ListLayers(mxd, "*"):
        if not lyr.supports("DATASOURCE"):
            continue
        if lyr.dataSource.find("FeatureClassName") != -1:
            with arcpy.da.SearchCursor(lyr, 'Shape@XY',r'"OBJECTID"='+str( [OBJECTID] )) as cursor:
                for row in cursor:
                    a=row[0]
                    return str(a[0])+', '+str(a[1])
    return ""

Instead of using the layer name, we have used the layer data source name to identify the current layer. This method is resistant to changes made to layer names.

9
  • Hi, thanks for your answer. Yes your solution will work regardless of the layer name. But unfortunately the code now contains a static reference to a specific dataset. Your code would be able to handle change of layer names but the label expression in a map document with relative paths that is moved will not work any longer. So unfortunately the solution is not as robust as I would like it to be. But so far your solution is the closest I have seen. Commented Mar 6, 2015 at 0:32
  • You should declare this constraint in your question, however this is rather easy to handle within the code. instead of checking for the whole path to the featureclass, just check for the FeatureClass Name. I will update the answer to reflect the changes Commented Mar 6, 2015 at 0:56
  • Change: if lyr.datasource == r"D:\SEPDC.gdb\elec\pd_district": to if lyr.datasource.find("FeatureClassName"): Commented Mar 6, 2015 at 1:01
  • Sorry if my question was unclear. I looked at your altered solution. I think there is a small typo: datasource should be dataSource? But when I try it, it label features from the top layer in the TOC also. Try replacing "return str(a[0])+', '+str(a[1])" with "return lyr.name" and you will see what I mean. I also tried replacing 'lyr.datasource.find("FeatureClassName"' with 'lyr.datasource.find("qwerty"' and it did not have any effect on the labels. Are you sure 'lyr.datasource.find("FeatureClassName"' does what you think it does? Commented Mar 6, 2015 at 2:11
  • You are right. I thought -1 returns false in python but it returns True! This is the correct form: if lyr.dataSource.find("FeatureClassName") != -1: Sorry Commented Mar 6, 2015 at 10:51

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.