Get Attribute Value from Selected Feature

16815
3
Jump to solution
05-03-2013 08:35 AM
by Anonymous User
Not applicable
Original User: wjackson

I'm trying to write python-addin code to create a tool that would enable a user to click on a feature and get an attribute value. The attribute value would be used as a parameter to open an MS Access form (much later). In 10.1 the arcpy.SelectLayerByLocation should be able to use a point geometry but I cannot get it to work and need help. I know I need to create a layer from the feature I'm trying to select on. So, in my code I try to add the layer to the TOC just so I can see that it gets created and the feature selected. I cannot get the layer to add so do not know if a selection is made or not.

 import arcpy
from arcpy import env
import pythonaddins
import os
import subprocess

class ToolClass2(object):
    """Implementation for ArcGISAddins_addin.tool (Tool)"""
    def __init__(self):
        self.enabled = True
        self.shape = "NONE" # Can set to "Line", "Circle" or "Rectangle" for interactive shape drawing and to activate the onLine/Polygon/Circle event sinks.
    def onMouseDownMap(self, x, y, button, shift):
      
        # Local variables:
        arcpy.env.workspace = "C:/temp/python/test.gdb"
        Parcels = "C:/temp/python/test.gdb/Parcels"
        #message = "Your mouse clicked:" + str(x) + ", " + str(y)
        #pythonaddins.MessageBox(message, "My Coordinates")
        mxd = arcpy.mapping.MapDocument("current")
        pointGeom = arcpy.PointGeometry(arcpy.Point(x, y), mxd.activeDataFrame.spatialReference)
        df = mxd.activeDataFrame
        searchdistance = getSearchDistanceInches(df.scale, 3)
        #lyr = arcpy.mapping.ListLayers(mxd)[0].name # assumes you want to select features from 1st layer in TOC
        # Make a layer from the feature class
        arcpy.MakeFeatureLayer_management(Parcels, "feature_layer")
        arcpy.SaveToLayerFile_management("feature_layer", "C:/temp/python/test.gdg/Parcels.lyr")
        addlayer = arcpy.mapping.Layer("C:/temp/python/Parcels.lyr")
        arcpy.mapping.AddLayer(df, addlayer, "BOTTOM")
        arcpy.SelectLayerByLocation_management("feature_layer", "INTERSECT", pointGeom, "%d INCHES" % searchdistance,"NEW_SELECTION")
        arcpy.RefreshActiveView()
        #arcpy.Delete_management("feature_layer")
0 Kudos
1 Solution

Accepted Solutions
MikeHunter
Occasional Contributor
You are making it way too hard on yourself. Let's simplify the code a little:
    def onMouseDownMap(self, x, y, button, shift):
        
        # set up environment
        arcpy.env.workspace = "C:/temp/python/test.gdb"
        Parcels = "C:/temp/python/test.gdb/Parcels"
        mxd = arcpy.mapping.MapDocument("current")
        df = mxd.activeDataFrame

        # build point geometry, run your getSearchDistanceInches function    
        pointGeom = arcpy.PointGeometry(arcpy.Point(x, y), mxd.activeDataFrame.spatialReference)
        searchdistance = getSearchDistanceInches(df.scale, 3)

        # make an arcpy.mapping layer obj and do the selection by location
        plyr = arcpy.mapping.Layer(Parcels)
        arcpy.SelectLayerByLocation_management(plyr, "INTERSECT", pointGeom, "%d INCHES" % searchdistance, "NEW_SELECTION")

        # all done, now add our layer to the map
        arcpy.mapping.AddLayer(df, plyr, "BOTTOM")
        arcpy.RefreshActiveView()



There are 2 kinds of feature layers used in arcpy code. The type made by MakeFeatureLayer_management is a geoprocessing layer and does not work with some parts arcpy.mapping, like AddLayer. The other kind is an arcpy.mapping layer object, which can be a feature layer or a number of other kinds of layers.  If it is feature layer, then it will work with at least some of the geoprocessing tools like SelectLayerByLocation that expect a feature layer. If this seems confusing, don't feel bad. It confuses me too.

Here's some more confusing stuff: You can create an arcpy.mapping.Layer object from a saved .lyr file, like you were doing. Now, the documentation doesn't tell you this, but you can also make a layer object from a feature class on a disk, from another layer in the toc, or even from a geoprocessing layer made with MakeFeatureLayer_management.  So all the work you were doing to make a .lyr file was unnecessary.  Just make an arcpy.mapping layer straight from the feature class, select against that layer, and add it to the map.

You were raising an error in your code so that's why it seemed nothing was happening. The addin environment is really tough to debug in, since you don't get to see the traceback and usually don't even know an error has occurred.  So I get my code running first by executing it in the Python window. Then, when everything is running correctly, I stick the code into a method or function in the addin.

good luck,
Mike

View solution in original post

3 Replies
MikeHunter
Occasional Contributor
You are making it way too hard on yourself. Let's simplify the code a little:
    def onMouseDownMap(self, x, y, button, shift):
        
        # set up environment
        arcpy.env.workspace = "C:/temp/python/test.gdb"
        Parcels = "C:/temp/python/test.gdb/Parcels"
        mxd = arcpy.mapping.MapDocument("current")
        df = mxd.activeDataFrame

        # build point geometry, run your getSearchDistanceInches function    
        pointGeom = arcpy.PointGeometry(arcpy.Point(x, y), mxd.activeDataFrame.spatialReference)
        searchdistance = getSearchDistanceInches(df.scale, 3)

        # make an arcpy.mapping layer obj and do the selection by location
        plyr = arcpy.mapping.Layer(Parcels)
        arcpy.SelectLayerByLocation_management(plyr, "INTERSECT", pointGeom, "%d INCHES" % searchdistance, "NEW_SELECTION")

        # all done, now add our layer to the map
        arcpy.mapping.AddLayer(df, plyr, "BOTTOM")
        arcpy.RefreshActiveView()



There are 2 kinds of feature layers used in arcpy code. The type made by MakeFeatureLayer_management is a geoprocessing layer and does not work with some parts arcpy.mapping, like AddLayer. The other kind is an arcpy.mapping layer object, which can be a feature layer or a number of other kinds of layers.  If it is feature layer, then it will work with at least some of the geoprocessing tools like SelectLayerByLocation that expect a feature layer. If this seems confusing, don't feel bad. It confuses me too.

Here's some more confusing stuff: You can create an arcpy.mapping.Layer object from a saved .lyr file, like you were doing. Now, the documentation doesn't tell you this, but you can also make a layer object from a feature class on a disk, from another layer in the toc, or even from a geoprocessing layer made with MakeFeatureLayer_management.  So all the work you were doing to make a .lyr file was unnecessary.  Just make an arcpy.mapping layer straight from the feature class, select against that layer, and add it to the map.

You were raising an error in your code so that's why it seemed nothing was happening. The addin environment is really tough to debug in, since you don't get to see the traceback and usually don't even know an error has occurred.  So I get my code running first by executing it in the Python window. Then, when everything is running correctly, I stick the code into a method or function in the addin.

good luck,
Mike
by Anonymous User
Not applicable
Original User: wjackson

Mike,


Thanks very much for your response and explanation of the feature layers. It works quite well now. I'm going to submit another post on the piece to open an MS Access form. Almost there...

-Bill Jackson

You are making it way too hard on yourself. Let's simplify the code a little:
    def onMouseDownMap(self, x, y, button, shift):
        
        # set up environment
        arcpy.env.workspace = "C:/temp/python/test.gdb"
        Parcels = "C:/temp/python/test.gdb/Parcels"
        mxd = arcpy.mapping.MapDocument("current")
        df = mxd.activeDataFrame

        # build point geometry, run your getSearchDistanceInches function    
        pointGeom = arcpy.PointGeometry(arcpy.Point(x, y), mxd.activeDataFrame.spatialReference)
        searchdistance = getSearchDistanceInches(df.scale, 3)

        # make an arcpy.mapping layer obj and do the selection by location
        plyr = arcpy.mapping.Layer(Parcels)
        arcpy.SelectLayerByLocation_management(plyr, "INTERSECT", pointGeom, "%d INCHES" % searchdistance, "NEW_SELECTION")

        # all done, now add our layer to the map
        arcpy.mapping.AddLayer(df, plyr, "BOTTOM")
        arcpy.RefreshActiveView()



There are 2 kinds of feature layers used in arcpy code. The type made by MakeFeatureLayer_management is a geoprocessing layer and does not work with some parts arcpy.mapping, like AddLayer. The other kind is an arcpy.mapping layer object, which can be a feature layer or a number of other kinds of layers.  If it is feature layer, then it will work with at least some of the geoprocessing tools like SelectLayerByLocation that expect a feature layer. If this seems confusing, don't feel bad. It confuses me too.

Here's some more confusing stuff: You can create an arcpy.mapping.Layer object from a saved .lyr file, like you were doing. Now, the documentation doesn't tell you this, but you can also make a layer object from a feature class on a disk, from another layer in the toc, or even from a geoprocessing layer made with MakeFeatureLayer_management.  So all the work you were doing to make a .lyr file was unnecessary.  Just make an arcpy.mapping layer straight from the feature class, select against that layer, and add it to the map.

You were raising an error in your code so that's why it seemed nothing was happening. The addin environment is really tough to debug in, since you don't get to see the traceback and usually don't even know an error has occurred.  So I get my code running first by executing it in the Python window. Then, when everything is running correctly, I stick the code into a method or function in the addin.

good luck,
Mike
0 Kudos
curtvprice
MVP Esteemed Contributor

I'd add that once you have the feature selected, an easy way to grab the attribute value is with arcpy.da.SearchCursor:

line_id = arcpy.da.SearchCursor(plyr, "LINE_ID").next()[0]

0 Kudos