Dynamically Select Feature in Map with Python Addin

4003
1
Jump to solution
09-24-2013 12:21 PM
JohnDye
Occasional Contributor III
Hi guys,
I'm trying to create a Python Addin to allow a user to dynamically select a feature in the Map Display Window in ArcMap, grab the ID of that feature and populate it in a variable, then select from a second feature class the features within the second feature class which have that ID, exporting those features to a new FC and then symbolizing with a layer file and adding the result to the data frame.

Here's what I have so far:

import arcpy import pythonaddins mxd = arcpy.mapping.MapDocument("Current") df = arcpy.mapping.ListDataFrames(mxd)[0]  class ShowMe_This(object):     """Implementation for ShowMe.This (ComboBox)"""     def __init__(self):         self.items = ["Predictive Trade Area", "Existing Trade Area", "ReDomiciled Customers"]         self.editable = False         self.enabled = True         self.dropdownWidth = 'XXXXXXXXXXXXXXXXXXXXXXXXXX'         self.width = 'XXXXXXXXXXXXXXXXXXXXXXXXXX'     def onSelChange(self, selection):         global FeatureGeometry         global SelFC         if selection == "ReDomiciled Customers":             FeatureGeometry = "Point"             SelFC = r"C:\ArcGIS\SYSTEM\COF\Data\MyGeodatabase.gdb\Customers"         elif selection == "Predictive Trade Area":             FeatureGeometry = "Polygon"             SelFC = r"C:\ArcGIS\SYSTEM\COF\Data\MyGeodatabase.gdb\PTAs"         elif selection == "Existing Trade Area":             FeatureGeometry = "Polygon"             SelFC = r"C:\ArcGIS\SYSTEM\COF\Data\MyGeodatabase.gdb\ETAs"         else:             FeatureGeometry = ""             SelFC = ""     def onEditChange(self, text):         pass     def onFocus(self, focused):         pass     def onEnter(self):         pass     def refresh(self):         pass  class ShowMe_LikeThat(object):     """Implementation for ShowMe.LikeThat (ComboBox)"""     def __init__(self):         self.items = ["Red", "Blue", "Orange", "Green", "Purple", "Pink", "Yellow"]         self.editable = False         self.enabled = True         self.dropdownWidth = 'XXXXXXXXXXXXXXXXXXXXXXXXXX'         self.width = 'XXXXXXXXXXXXXXXXXXXXXXXXXX'     def onSelChange(self, selection):         global Color         Color = selection     def onEditChange(self, text):         pass     def onFocus(self, focused):         pass     def onEnter(self):         pass     def refresh(self):         pass  class ShowMe_ForThis(object):     """Implementation for ShowMe.ForThis (Tool)"""     def __init__(self):         self.enabled = True         self.shape = "Rectangle"         self.cursor = 3     def onRectangle(self, rectangle_geometry):         global SelExtent         SelExtent = rectangle_geometry  class ShowMe_Execute(object):     """Implementation for ShowMe.Execute (Button)"""     def __init__(self):         self.enabled = True         self.checked = False     def onClick(self):         # Establish a reference to the appropriate Layer File based on the users selections         LYRfile = r"C:\ArcGIS\SYSTEM\COF\Data\Layer Files\ShowMe" + "\\" + FeatureGeometry + "\\" + Color + ".lyr"         print LYRfile         if FeatureGeometry == "":             pythonaddins.MessageBox("You must select a Feature from the 'Show Me This' drop-down menu.", "ERROR", 0)         elif Color == "":             pythonaddins.MessageBox("You must select a color to symbolize the feature from the 'Like That' drop-down menu.", "ERROR", 0)         elif FeatureGeometry == "" and Color == "":             pythonaddins.MessageBox("You must select both a Feature from the 'Show Me This' drop-down menu and a color from the 'Like This' drop-down menu.", "ERROR", 0)         else:             pass         # How do I select the feature from 'SelFC' that falls within the extent provided by 'SelExtent'???


Problem is, I can't figure out how to use the extent generated by 'SelExtent', which is really just the 'rectangle_geometry' produced by the tool, to select the particular feature from 'SelFC' that falls within the extent.

I'm thinking maybe I should use onCircle instead as that produces a polygon object I might be able to do a Select By Location with for an Intersect, but thought I would see if any of the big brains here knew better...

Thanks in advance
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
JohnDye
Occasional Contributor III
I reached out to Jason Pardy from ESRI to get the answer and am posting it here as a courtesy in case anyone else finds themself searching for a similar solution.

The answer was to create a Polygon from the extent returned by the rectangle_geometry function and to use that polygon in the SBL Intersect.

import pythonaddins mxd = arcpy.mapping.MapDocument("Current") df = arcpy.mapping.ListDataFrames(mxd)[0]  class ShowMe_This(object):     """Implementation for ShowMe.This (ComboBox)"""     def __init__(self):         self.items = ["Item1", "Item2", "Item3"]         self.editable = False         self.enabled = True         self.dropdownWidth = 'XXXXXXXXXXXXXXXXXXXXXXXXXX'         self.width = 'XXXXXXXXXXXXXXXXXXXXXXXXXX'     def onSelChange(self, selection):         global FeatureGeometry         global SelFC         if selection == "Item1":             FeatureGeometry = "Point"             SelFC = r"C:\ArcGIS\MyGeodatabase.gdb\Feature1"         elif selection == "Item2":             FeatureGeometry = "Polygon"             SelFC = r"C:\ArcGIS\MyGeodatabase.gdb\Feature2"         elif selection == "Item3":             FeatureGeometry = "Polygon"             SelFC = r"C:\ArcGIS\MyGeodatabase.gdb\Feature3"         else:             FeatureGeometry = ""             SelFC = ""     def refresh(self):         self.refresh()  class ShowMe_LikeThat(object):     """Implementation for ShowMe.LikeThat (ComboBox)"""     def __init__(self):         self.items = ["Red", "Blue", "Orange", "Green", "Purple", "Pink", "Yellow"]         self.editable = False         self.enabled = True         self.dropdownWidth = 'XXXXXXXXXXXXXXXXXXXXXXXXXX'         self.width = 'XXXXXXXXXXXXXXXXXXXXXXXXXX'     def onSelChange(self, selection):         global Color         Color = selection     def refresh(self):         self.refresh()  class ShowMe_ForThis(object):     """Implementation for ShowMe.ForThis (Tool)"""     def __init__(self):         self.enabled = True         self.shape = "Rectangle"         self.cursor = 3     def onRectangle(self, rectangle_geometry):         SelExtent = rectangle_geometry         # Get the Extent         Extent = rectangle_geometry         # Create a Polygon from the Extent Object         ExtentPoly = arcpy.Polygon(arcpy.Array([arcpy.Point(Extent.XMin, Extent.YMin), arcpy.Point(Extent.XMin, Extent.YMax), arcpy.Point(Extent.XMax, Extent.YMax), arcpy.Point(Extent.XMax, Extent.YMin)]))         # Select the Feature that intersects the Extent Polygon         arcpy.management.SelectLayerByLocation(SelFC, "INTERSECT", ExtentPoly, "", "NEW_SELECTION")  class ShowMe_Execute(object):     """Implementation for ShowMe.Execute (Button)"""     def __init__(self):         self.enabled = True         self.checked = False     def onClick(self):         # Do whatever you want to do. Technically, you could completely remove this class and just put it all in the ShowMe_ForThis class, so that your logic occurs as soon as the selections are complete.

View solution in original post

0 Kudos
1 Reply
JohnDye
Occasional Contributor III
I reached out to Jason Pardy from ESRI to get the answer and am posting it here as a courtesy in case anyone else finds themself searching for a similar solution.

The answer was to create a Polygon from the extent returned by the rectangle_geometry function and to use that polygon in the SBL Intersect.

import pythonaddins mxd = arcpy.mapping.MapDocument("Current") df = arcpy.mapping.ListDataFrames(mxd)[0]  class ShowMe_This(object):     """Implementation for ShowMe.This (ComboBox)"""     def __init__(self):         self.items = ["Item1", "Item2", "Item3"]         self.editable = False         self.enabled = True         self.dropdownWidth = 'XXXXXXXXXXXXXXXXXXXXXXXXXX'         self.width = 'XXXXXXXXXXXXXXXXXXXXXXXXXX'     def onSelChange(self, selection):         global FeatureGeometry         global SelFC         if selection == "Item1":             FeatureGeometry = "Point"             SelFC = r"C:\ArcGIS\MyGeodatabase.gdb\Feature1"         elif selection == "Item2":             FeatureGeometry = "Polygon"             SelFC = r"C:\ArcGIS\MyGeodatabase.gdb\Feature2"         elif selection == "Item3":             FeatureGeometry = "Polygon"             SelFC = r"C:\ArcGIS\MyGeodatabase.gdb\Feature3"         else:             FeatureGeometry = ""             SelFC = ""     def refresh(self):         self.refresh()  class ShowMe_LikeThat(object):     """Implementation for ShowMe.LikeThat (ComboBox)"""     def __init__(self):         self.items = ["Red", "Blue", "Orange", "Green", "Purple", "Pink", "Yellow"]         self.editable = False         self.enabled = True         self.dropdownWidth = 'XXXXXXXXXXXXXXXXXXXXXXXXXX'         self.width = 'XXXXXXXXXXXXXXXXXXXXXXXXXX'     def onSelChange(self, selection):         global Color         Color = selection     def refresh(self):         self.refresh()  class ShowMe_ForThis(object):     """Implementation for ShowMe.ForThis (Tool)"""     def __init__(self):         self.enabled = True         self.shape = "Rectangle"         self.cursor = 3     def onRectangle(self, rectangle_geometry):         SelExtent = rectangle_geometry         # Get the Extent         Extent = rectangle_geometry         # Create a Polygon from the Extent Object         ExtentPoly = arcpy.Polygon(arcpy.Array([arcpy.Point(Extent.XMin, Extent.YMin), arcpy.Point(Extent.XMin, Extent.YMax), arcpy.Point(Extent.XMax, Extent.YMax), arcpy.Point(Extent.XMax, Extent.YMin)]))         # Select the Feature that intersects the Extent Polygon         arcpy.management.SelectLayerByLocation(SelFC, "INTERSECT", ExtentPoly, "", "NEW_SELECTION")  class ShowMe_Execute(object):     """Implementation for ShowMe.Execute (Button)"""     def __init__(self):         self.enabled = True         self.checked = False     def onClick(self):         # Do whatever you want to do. Technically, you could completely remove this class and just put it all in the ShowMe_ForThis class, so that your logic occurs as soon as the selections are complete.
0 Kudos