David,
While this is the reverse of what you want, I think it should be able to give you some ideas. I will need to do the same as you soon, but just havn't had the opportunity to do so just yet.
I think you will need get the properties of the DataFrame to convert from page units to preferred projected coordinates.
http://gis.stackexchange.com/questions/21514/convert-point-xy-to-page-units-xy-using-arcpy
Here's what I discovered when using the onMouseDown and onMouseDownMap in a Python add-in.The function onMouseDown will return a set of pixel values showing the coordinates of where you clicked, measured in pixels from the upper left of the map display window.The function onMouseDownMap is sensitive to your current view. If you are in data view, it returns coordinates in the map's coordinate system. If you are in layout view, it returns coordinates in page units - but only allows you to click inside the data frame element.The fix is as suggested by James (Thanks!!). Convert the page coordinates to map coordinates. To do this, I find the lower left page X coordinate and the click point X value and subtract the two. That's how far over from the edge of the data frame I clicked in inches. Then (for feet) divide by twelve and multiply by the scale of the map. That's the distance in map units I am from the edge of the data frame. Then I find the data frame's minimum X value in map units and add the calculated distance. Repeat for Y. Here's the code for a tool in my add-in that lets you click in the map while in layout view and select a feature from a layer called "Cadastre".class Sel_Property(object):
"""Implementation for Notifications_addin.selectproperty (Tool)"""
def __init__(self):
self.enabled = False
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):
thisMap = arcpy.mapping.MapDocument("CURRENT")
data_frame = arcpy.mapping.ListDataFrames(thisMap)[0]
page_x = x
page_y = y
"""Convert page coordinates to projected coordinates"""
#get the data frame dimensions in page units
df_page_w = data_frame.elementWidth
df_page_h = data_frame.elementHeight
df_page_x_min = data_frame.elementPositionX
df_page_y_min = data_frame.elementPositionY
df_page_x_max = df_page_w + df_page_x_min
df_page_y_max = df_page_h + df_page_y_min
#get the data frame projected coordinates
df_min_x = data_frame.extent.XMin
df_min_y = data_frame.extent.YMin
df_max_x = data_frame.extent.XMax
df_max_y = data_frame.extent.YMax
df_proj_w = data_frame.extent.width
df_proj_h = data_frame.extent.height
#ensure the coordinates are in the dataframe
if page_x < df_page_x_min or page_x > df_page_x_max:
raise ValueError ('X coordinate is not within map portion of the page.')
if page_y < df_page_y_min or page_y > df_page_y_max:
raise ValueError ('Y coordinate is not within map portion of the page.')
#scale the projected coordinates to map units from the lower left of the data frame
scale = data_frame.scale/12 # converting scale factor to feet per inch
map_x = df_min_x + ((page_x - df_page_x_min)*scale)
map_y = df_min_y + ((page_y - df_page_y_min)*scale)
# pythonaddins.MessageBox("Coordiantes are" + str(map_x) + " and " + str(map_y),"Title")
pointGeom = arcpy.PointGeometry(arcpy.Point(map_x,map_y), thisMap.activeDataFrame.spatialReference)
layers = arcpy.mapping.ListLayers(thisMap)
for lyr in layers:
if lyr.name == "Cadastre":
arcpy.SelectLayerByLocation_management(lyr,"INTERSECT",pointGeom)
thisMap.activeView = "PAGE_LAYOUT"
arcpy.RefreshActiveView()
data_frame.zoomToSelectedFeatures()
data_frame.scale = data_frame.scale * 5.2